@@ -442,19 +442,19 @@ func (db *merkleDB) CommitRangeProof(ctx context.Context, start, end maybe.Maybe
442
442
return database .ErrClosed
443
443
}
444
444
445
- ops := make ([]database.BatchOp , len (proof .KeyValues ))
446
- keys := set.NewSet [string ](len (proof .KeyValues ))
447
- for i , kv := range proof .KeyValues {
445
+ ops := make ([]database.BatchOp , len (proof .KeyChanges ))
446
+ keys := set.NewSet [string ](len (proof .KeyChanges ))
447
+ for i , kv := range proof .KeyChanges {
448
448
keys .Add (string (kv .Key ))
449
449
ops [i ] = database.BatchOp {
450
450
Key : kv .Key ,
451
- Value : kv .Value ,
451
+ Value : kv .Value . Value () ,
452
452
}
453
453
}
454
454
455
455
largestKey := end
456
- if len (proof .KeyValues ) > 0 {
457
- largestKey = maybe .Some (proof .KeyValues [len (proof .KeyValues )- 1 ].Key )
456
+ if len (proof .KeyChanges ) > 0 {
457
+ largestKey = maybe .Some (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key )
458
458
}
459
459
keysToDelete , err := db .getKeysNotInSet (start , largestKey , keys )
460
460
if err != nil {
@@ -1094,86 +1094,66 @@ func (db *merkleDB) VerifyChangeProof(
1094
1094
end maybe.Maybe [[]byte ],
1095
1095
expectedEndRootID ids.ID ,
1096
1096
) error {
1097
- switch {
1098
- case start .HasValue () && end .HasValue () && bytes .Compare (start .Value (), end .Value ()) > 0 :
1099
- return ErrStartAfterEnd
1100
- case proof .Empty ():
1097
+ if proof == nil {
1101
1098
return ErrEmptyProof
1102
- case end .HasValue () && len (proof .KeyChanges ) == 0 && len (proof .EndProof ) == 0 :
1103
- // We requested an end proof but didn't get one.
1104
- return ErrNoEndProof
1105
- case start .HasValue () && len (proof .StartProof ) == 0 && len (proof .EndProof ) == 0 :
1106
- // We requested a start proof but didn't get one.
1107
- // Note that we also have to check that [proof.EndProof] is empty
1108
- // to handle the case that the start proof is empty because all
1109
- // its nodes are also in the end proof, and those nodes are omitted.
1110
- return ErrNoStartProof
1111
- }
1112
-
1113
- // Make sure the key-value pairs are sorted and in [start, end].
1114
- if err := verifyKeyChanges (proof .KeyChanges , start , end ); err != nil {
1115
- return err
1116
1099
}
1117
1100
1118
- smallestKey := maybe .Bind (start , ToKey )
1101
+ startProofKey := maybe .Bind (start , ToKey )
1102
+ endProofKey := maybe .Bind (end , ToKey )
1119
1103
1120
- // Make sure the start proof, if given, is well-formed.
1121
- if err := verifyProofPath (proof .StartProof , smallestKey ); err != nil {
1122
- return err
1123
- }
1124
-
1125
- // Find the greatest key in [proof.KeyChanges]
1126
- // Note that [proof.EndProof] is a proof for this key.
1127
- // [largestKey] is also used when we add children of proof nodes to [trie] below.
1128
- largestKey := maybe .Bind (end , ToKey )
1104
+ // Update [endProofKey] with the largest key in [keyValues].
1129
1105
if len (proof .KeyChanges ) > 0 {
1130
- // If [proof] has key-value pairs, we should insert children
1131
- // greater than [end] to ancestors of the node containing [end]
1132
- // so that we get the expected root ID.
1133
- largestKey = maybe .Some (ToKey (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key ))
1106
+ endProofKey = maybe .Some (ToKey (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key ))
1134
1107
}
1135
1108
1136
- // Make sure the end proof, if given, is well-formed.
1137
- if err := verifyProofPath (proof .EndProof , largestKey ); err != nil {
1109
+ // Validate proof.
1110
+ if err := validateChangeProof (
1111
+ startProofKey ,
1112
+ maybe .Bind (end , ToKey ),
1113
+ proof .StartProof ,
1114
+ proof .EndProof ,
1115
+ proof .KeyChanges ,
1116
+ endProofKey ,
1117
+ db .tokenSize ,
1118
+ ); err != nil {
1138
1119
return err
1139
1120
}
1140
1121
1141
- keyValues := make (map [Key ]maybe.Maybe [[]byte ], len (proof .KeyChanges ))
1142
- for _ , keyValue := range proof .KeyChanges {
1143
- keyValues [ToKey (keyValue .Key )] = keyValue .Value
1144
- }
1145
-
1146
- // want to prevent commit writes to DB, but not prevent DB reads
1122
+ // Prevent commit writes to DB, but not prevent DB reads
1147
1123
db .commitLock .RLock ()
1148
1124
defer db .commitLock .RUnlock ()
1149
1125
1150
1126
if db .closed {
1151
1127
return database .ErrClosed
1152
1128
}
1153
1129
1154
- if err := verifyAllChangeProofKeyValuesPresent (
1130
+ // Ensure that the [startProof] has correct values.
1131
+ if err := verifyChangeProofKeyValues (
1155
1132
ctx ,
1156
1133
db ,
1134
+ proof .KeyChanges ,
1157
1135
proof .StartProof ,
1158
- smallestKey ,
1159
- largestKey ,
1160
- keyValues ,
1136
+ startProofKey ,
1137
+ endProofKey ,
1138
+ db . hasher ,
1161
1139
); err != nil {
1162
- return err
1140
+ return fmt . Errorf ( "failed to verify start proof nodes: %w" , err )
1163
1141
}
1164
1142
1165
- if err := verifyAllChangeProofKeyValuesPresent (
1143
+ // Ensure that the [endProof] has correct values.
1144
+ if err := verifyChangeProofKeyValues (
1166
1145
ctx ,
1167
1146
db ,
1147
+ proof .KeyChanges ,
1168
1148
proof .EndProof ,
1169
- smallestKey ,
1170
- largestKey ,
1171
- keyValues ,
1149
+ startProofKey ,
1150
+ endProofKey ,
1151
+ db . hasher ,
1172
1152
); err != nil {
1173
- return err
1153
+ return fmt . Errorf ( "failed to validate end proof nodes: %w" , err )
1174
1154
}
1175
1155
1176
- // Insert the key-value pairs into the trie .
1156
+ // Prepare ops for the creation of the view .
1177
1157
ops := make ([]database.BatchOp , len (proof .KeyChanges ))
1178
1158
for i , kv := range proof .KeyChanges {
1179
1159
ops [i ] = database.BatchOp {
@@ -1189,32 +1169,34 @@ func (db *merkleDB) VerifyChangeProof(
1189
1169
return err
1190
1170
}
1191
1171
1192
- // For all the nodes along the edges of the proof , insert the children whose
1172
+ // For all the nodes along the edges of the proofs , insert the children whose
1193
1173
// keys are less than [insertChildrenLessThan] or whose keys are greater
1194
1174
// than [insertChildrenGreaterThan] into the trie so that we get the
1195
1175
// expected root ID (if this proof is valid).
1196
1176
if err := addPathInfo (
1197
1177
view ,
1198
1178
proof .StartProof ,
1199
- smallestKey ,
1200
- largestKey ,
1179
+ startProofKey ,
1180
+ endProofKey ,
1201
1181
); err != nil {
1202
- return err
1182
+ return fmt . Errorf ( "failed to add start proof path info: %w" , err )
1203
1183
}
1184
+
1204
1185
if err := addPathInfo (
1205
1186
view ,
1206
1187
proof .EndProof ,
1207
- smallestKey ,
1208
- largestKey ,
1188
+ startProofKey ,
1189
+ endProofKey ,
1209
1190
); err != nil {
1210
- return err
1191
+ return fmt . Errorf ( "failed to add end proof path info: %w" , err )
1211
1192
}
1212
1193
1213
1194
// Make sure we get the expected root.
1214
1195
calculatedRoot , err := view .GetMerkleRoot (ctx )
1215
1196
if err != nil {
1216
1197
return err
1217
1198
}
1199
+
1218
1200
if expectedEndRootID != calculatedRoot {
1219
1201
return fmt .Errorf ("%w:[%s], expected:[%s]" , ErrInvalidProof , calculatedRoot , expectedEndRootID )
1220
1202
}
0 commit comments