diff options
author | Jack Mulrow <jack.mulrow@mongodb.com> | 2017-03-27 15:40:32 -0400 |
---|---|---|
committer | Jack Mulrow <jack.mulrow@mongodb.com> | 2017-03-28 18:05:58 -0400 |
commit | 399ba02faf7124d4b4c52f8b7e91f5aeb307ee1b (patch) | |
tree | 86f1fa09b54bc0f9984081fb3652398ca895a9c2 /src | |
parent | ea0e436f77b1a1e7977df55d6fd4d70c5aa7b9b8 (diff) | |
download | mongo-399ba02faf7124d4b4c52f8b7e91f5aeb307ee1b.tar.gz |
SERVER-28438 Add keyId field to logicalTime object
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/logical_clock.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/logical_clock_test.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/logical_time_test.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/signed_logical_time.h | 11 | ||||
-rw-r--r-- | src/mongo/rpc/metadata/logical_time_metadata.cpp | 33 | ||||
-rw-r--r-- | src/mongo/rpc/metadata/logical_time_metadata.h | 5 | ||||
-rw-r--r-- | src/mongo/rpc/metadata/logical_time_metadata_test.cpp | 58 |
7 files changed, 103 insertions, 16 deletions
diff --git a/src/mongo/db/logical_clock.cpp b/src/mongo/db/logical_clock.cpp index 34a11fc163c..32e0b22184e 100644 --- a/src/mongo/db/logical_clock.cpp +++ b/src/mongo/db/logical_clock.cpp @@ -93,7 +93,9 @@ SignedLogicalTime LogicalClock::getClusterTime() { } SignedLogicalTime LogicalClock::_makeSignedLogicalTime(LogicalTime logicalTime) { - return SignedLogicalTime(logicalTime, _timeProofService->getProof(logicalTime)); + // TODO: SERVER-28436 Implement KeysCollectionManager + // Replace dummy keyId with real id from key manager. + return SignedLogicalTime(logicalTime, _timeProofService->getProof(logicalTime), 0); } Status LogicalClock::advanceClusterTime(const SignedLogicalTime& newTime) { diff --git a/src/mongo/db/logical_clock_test.cpp b/src/mongo/db/logical_clock_test.cpp index a0b8dbaf30e..156232fc386 100644 --- a/src/mongo/db/logical_clock_test.cpp +++ b/src/mongo/db/logical_clock_test.cpp @@ -63,7 +63,7 @@ protected: } SignedLogicalTime makeSignedLogicalTime(LogicalTime logicalTime) { - return SignedLogicalTime(logicalTime, _timeProofService->getProof(logicalTime)); + return SignedLogicalTime(logicalTime, _timeProofService->getProof(logicalTime), 0); } const unsigned currentWallClockSecs() { diff --git a/src/mongo/db/logical_time_test.cpp b/src/mongo/db/logical_time_test.cpp index f0f0d7b4477..b55d4fee950 100644 --- a/src/mongo/db/logical_time_test.cpp +++ b/src/mongo/db/logical_time_test.cpp @@ -107,15 +107,19 @@ TEST(LogicalTime, toUnsignedArray) { TEST(SignedLogicalTime, roundtrip) { Timestamp tX(1); + std::array<std::uint8_t, 20> tempKey = {}; TimeProofService::Key key(std::move(tempKey)); TimeProofService tps(std::move(key)); auto time = LogicalTime(tX); auto proof = tps.getProof(time); - SignedLogicalTime signedTime(time, proof); + long long keyId = 1; + + SignedLogicalTime signedTime(time, proof, keyId); ASSERT_TRUE(time == signedTime.getTime()); ASSERT_TRUE(proof == signedTime.getProof()); + ASSERT_TRUE(keyId == signedTime.getKeyId()); } } // unnamed namespace diff --git a/src/mongo/db/signed_logical_time.h b/src/mongo/db/signed_logical_time.h index 7b96e51df79..fde222efb39 100644 --- a/src/mongo/db/signed_logical_time.h +++ b/src/mongo/db/signed_logical_time.h @@ -44,8 +44,8 @@ public: SignedLogicalTime() = default; - explicit SignedLogicalTime(LogicalTime time, TimeProof proof) - : _time(std::move(time)), _proof(std::move(proof)) {} + explicit SignedLogicalTime(LogicalTime time, TimeProof proof, long long keyId) + : _time(std::move(time)), _proof(std::move(proof)), _keyId(keyId) {} LogicalTime getTime() const { return _time; @@ -55,11 +55,18 @@ public: return _proof; } + long long getKeyId() const { + return _keyId; + } + std::string toString() const; + static const SignedLogicalTime kUninitialized; + private: LogicalTime _time; TimeProof _proof; + long long _keyId{0}; }; } // namespace mongo diff --git a/src/mongo/rpc/metadata/logical_time_metadata.cpp b/src/mongo/rpc/metadata/logical_time_metadata.cpp index 9d79a892e3a..8abdd91edd4 100644 --- a/src/mongo/rpc/metadata/logical_time_metadata.cpp +++ b/src/mongo/rpc/metadata/logical_time_metadata.cpp @@ -40,6 +40,8 @@ namespace { const char kClusterTimeFieldName[] = "clusterTime"; const char kSignatureFieldName[] = "signature"; +const char kSignatureHashFieldName[] = "hash"; +const char kSignatureKeyIdFieldName[] = "keyId"; } // unnamed namespace @@ -64,30 +66,49 @@ StatusWith<LogicalTimeMetadata> LogicalTimeMetadata::readFromMetadata( return status; } - // Extract BinData type signature and construct a SHA1Block instance from it. BSONElement signatureElem; - status = bsonExtractTypedField(obj, kSignatureFieldName, BinData, &signatureElem); + status = bsonExtractTypedField(obj, kSignatureFieldName, Object, &signatureElem); + if (!status.isOK()) { + return status; + } + + const auto& signatureObj = signatureElem.Obj(); + + // Extract BinData type signature hash and construct a SHA1Block instance from it. + BSONElement hashElem; + status = bsonExtractTypedField(signatureObj, kSignatureHashFieldName, BinData, &hashElem); if (!status.isOK()) { return status; } int hashLength = 0; - auto rawBinSignature = signatureElem.binData(hashLength); - BSONBinData proofBinData(rawBinSignature, hashLength, signatureElem.binDataType()); + auto rawBinSignature = hashElem.binData(hashLength); + BSONBinData proofBinData(rawBinSignature, hashLength, hashElem.binDataType()); auto proofStatus = SHA1Block::fromBinData(proofBinData); if (!proofStatus.isOK()) { return proofStatus.getStatus(); } + long long keyId; + status = bsonExtractIntegerField(signatureObj, kSignatureKeyIdFieldName, &keyId); + if (!status.isOK()) { + return status; + } + return LogicalTimeMetadata( - SignedLogicalTime(LogicalTime(ts), std::move(proofStatus.getValue()))); + SignedLogicalTime(LogicalTime(ts), std::move(proofStatus.getValue()), keyId)); } void LogicalTimeMetadata::writeToMetadata(BSONObjBuilder* metadataBuilder) const { BSONObjBuilder subObjBuilder(metadataBuilder->subobjStart(fieldName())); _clusterTime.getTime().asTimestamp().append(subObjBuilder.bb(), kClusterTimeFieldName); - _clusterTime.getProof().appendAsBinData(subObjBuilder, kSignatureFieldName); + + BSONObjBuilder signatureObjBuilder(subObjBuilder.subobjStart(kSignatureFieldName)); + _clusterTime.getProof().appendAsBinData(signatureObjBuilder, kSignatureHashFieldName); + signatureObjBuilder.append(kSignatureKeyIdFieldName, _clusterTime.getKeyId()); + signatureObjBuilder.doneFast(); + subObjBuilder.doneFast(); } diff --git a/src/mongo/rpc/metadata/logical_time_metadata.h b/src/mongo/rpc/metadata/logical_time_metadata.h index 2ff792b58b1..2ec6b7f03b5 100644 --- a/src/mongo/rpc/metadata/logical_time_metadata.h +++ b/src/mongo/rpc/metadata/logical_time_metadata.h @@ -42,7 +42,10 @@ namespace rpc { * Format: * logicalTime: { * clusterTime: <Timestamp>, - * signature: <SHA1 hash of clusterTime as BinData> + * signature: { + * hash: <SHA1 hash of clusterTime as BinData>, + * keyId: <long long> + * } * } */ class LogicalTimeMetadata { diff --git a/src/mongo/rpc/metadata/logical_time_metadata_test.cpp b/src/mongo/rpc/metadata/logical_time_metadata_test.cpp index 61106f3d469..73e9ad64208 100644 --- a/src/mongo/rpc/metadata/logical_time_metadata_test.cpp +++ b/src/mongo/rpc/metadata/logical_time_metadata_test.cpp @@ -48,7 +48,9 @@ TEST(LogicalTimeMetadataTest, Roundtrip) { proof[19] = 6; proof[0] = 12; - SignedLogicalTime signedTs(LogicalTime(ts), proof); + long long keyId = 1; + + SignedLogicalTime signedTs(LogicalTime(ts), proof, keyId); LogicalTimeMetadata origMetadata(signedTs); BSONObjBuilder builder; @@ -62,15 +64,34 @@ TEST(LogicalTimeMetadataTest, Roundtrip) { const auto& parsedTs = parsedMetadata.getSignedTime(); ASSERT_EQ(ts.asTimestamp(), parsedTs.getTime().asTimestamp()); ASSERT_TRUE(SHA1Block(proof) == parsedTs.getProof()); + ASSERT_TRUE(keyId == parsedTs.getKeyId()); } TEST(LogicalTimeMetadataTest, MissingClusterTimeShouldFailToParse) { std::array<uint8_t, 20> proof; proof.fill(0); + long long keyId = 1; + + BSONObjBuilder builder; + BSONObjBuilder subObjBuilder(builder.subobjStart("logicalTime")); + BSONObjBuilder signatureObjBuilder(subObjBuilder.subobjStart("signature")); + signatureObjBuilder.append("hash", BSONBinData(proof.data(), proof.size(), BinDataGeneral)); + signatureObjBuilder.append("keyId", keyId); + signatureObjBuilder.doneFast(); + subObjBuilder.doneFast(); + + auto serializedObj = builder.done(); + auto status = LogicalTimeMetadata::readFromMetadata(serializedObj).getStatus(); + ASSERT_EQ(ErrorCodes::NoSuchKey, status); +} + +TEST(LogicalTimeMetadataTest, MissingSignatureShouldFailToParse) { + const auto ts = Timestamp(100, 200); + BSONObjBuilder builder; BSONObjBuilder subObjBuilder(builder.subobjStart("logicalTime")); - subObjBuilder.append("signature", BSONBinData(proof.data(), proof.size(), BinDataGeneral)); + ts.append(subObjBuilder.bb(), "clusterTime"); subObjBuilder.doneFast(); auto serializedObj = builder.done(); @@ -78,12 +99,36 @@ TEST(LogicalTimeMetadataTest, MissingClusterTimeShouldFailToParse) { ASSERT_EQ(ErrorCodes::NoSuchKey, status); } -TEST(LogicalTimeMetadataTest, MissingProofShouldFailToParse) { +TEST(LogicalTimeMetadataTest, MissingHashShouldFailToParse) { const auto ts = Timestamp(100, 200); + long long keyId = 1; + BSONObjBuilder builder; BSONObjBuilder subObjBuilder(builder.subobjStart("logicalTime")); ts.append(subObjBuilder.bb(), "clusterTime"); + BSONObjBuilder signatureObjBuilder(subObjBuilder.subobjStart("signature")); + signatureObjBuilder.append("keyId", keyId); + signatureObjBuilder.doneFast(); + subObjBuilder.doneFast(); + + auto serializedObj = builder.done(); + auto status = LogicalTimeMetadata::readFromMetadata(serializedObj).getStatus(); + ASSERT_EQ(ErrorCodes::NoSuchKey, status); +} + +TEST(LogicalTimeMetadataTest, MissingKeyIdShouldFailToParse) { + const auto ts = Timestamp(100, 200); + + std::array<uint8_t, 20> proof; + proof.fill(0); + + BSONObjBuilder builder; + BSONObjBuilder subObjBuilder(builder.subobjStart("logicalTime")); + ts.append(subObjBuilder.bb(), "clusterTime"); + BSONObjBuilder signatureObjBuilder(subObjBuilder.subobjStart("signature")); + signatureObjBuilder.append("hash", BSONBinData(proof.data(), proof.size(), BinDataGeneral)); + signatureObjBuilder.doneFast(); subObjBuilder.doneFast(); auto serializedObj = builder.done(); @@ -97,10 +142,15 @@ TEST(LogicalTimeMetadataTest, ProofWithWrongLengthShouldFailToParse) { std::array<uint8_t, 10> proof; proof.fill(0); + long long keyId = 1; + BSONObjBuilder builder; BSONObjBuilder subObjBuilder(builder.subobjStart("logicalTime")); ts.append(subObjBuilder.bb(), "clusterTime"); - subObjBuilder.append("signature", BSONBinData(proof.data(), proof.size(), BinDataGeneral)); + BSONObjBuilder signatureObjBuilder(subObjBuilder.subobjStart("signature")); + signatureObjBuilder.append("hash", BSONBinData(proof.data(), proof.size(), BinDataGeneral)); + signatureObjBuilder.append("keyId", keyId); + signatureObjBuilder.doneFast(); subObjBuilder.doneFast(); auto serializedObj = builder.done(); |