4545 // is valid.
4646 emptyKey btcec.PublicKey
4747
48- // ErrProofNotFound is returned when a user attempts to look up a proof
49- // based on a Locator, but we can't find it on disk.
48+ // ErrProofNotFound reports that no proof satisfies the lookup criteria.
5049 ErrProofNotFound = fmt .Errorf ("unable to find proof" )
5150
5251 // ErrInvalidLocatorID is returned when a specified has an invalid
@@ -1090,61 +1089,62 @@ func (m *MultiArchiver) RemoveSubscriber(
10901089// NotifyArchiver interface.
10911090var _ NotifyArchiver = (* MultiArchiver )(nil )
10921091
1093- // ReplaceProofInBlob attempts to replace a proof in all proof files we have for
1094- // assets of the same ID. This is useful when we want to update the proof with a
1095- // new one after a re-org.
1096- func ReplaceProofInBlob (ctx context.Context , p * Proof , archive Archiver ,
1097- vCtx VerifierCtx ) error {
1098-
1099- // This is a bit of a hacky part. If we have a chain of transactions
1100- // that were re-organized, we can't verify the whole chain until all of
1101- // the transactions were confirmed and all proofs were updated with the
1102- // new blocks and merkle roots. So we'll skip the verification here
1103- // since we don't know if the whole chain has been updated yet (the
1104- // confirmations might come in out of order).
1105- // TODO(guggero): Find a better way to do this.
1106- vCtx .HeaderVerifier = func (wire.BlockHeader , uint32 ) error {
1107- return nil
1108- }
1092+ // ReplaceProofInFiles attempts to replace a proof in all provided proof files
1093+ // for assets of the same ID and returns the updated proof blobs. This is useful
1094+ // when we want to update the proof with a new one after a re-org.
1095+ func ReplaceProofInFiles (newProof * Proof ,
1096+ proofFiles []* AnnotatedProof ) ([]* AnnotatedProof , error ) {
11091097
1110- assetID := p . Asset . ID ()
1111- scriptPubKeyOfUpdate := p . Asset . ScriptKey . PubKey
1098+ var (
1099+ updatedProofs [] * AnnotatedProof
11121100
1113- // We now fetch all proofs of that same asset ID and filter out those
1114- // that need updating.
1115- proofs , err := archive .FetchProofs (ctx , assetID )
1116- if err != nil {
1117- return fmt .Errorf ("unable to fetch all proofs for asset ID " +
1118- "%x: %w" , assetID [:], err )
1119- }
1101+ scriptPubKeyOfUpdate = newProof .Asset .ScriptKey .PubKey
1102+ targetAssetID = newProof .Asset .ID ()
1103+ )
11201104
1121- for idx := range proofs {
1122- existingProof := proofs [idx ]
1105+ for idx := range proofFiles {
1106+ proofFile := proofFiles [idx ]
1107+
1108+ // Sanity check: make sure the asset ID of the proof file
1109+ // matches the target asset ID.
1110+ if * proofFile .Locator .AssetID != targetAssetID {
1111+ return nil , fmt .Errorf ("mismatched asset ID: " +
1112+ "expected %s, got %s" ,
1113+ proofFile .Locator .AssetID .String (),
1114+ targetAssetID .String ())
1115+ }
11231116
11241117 f := & File {}
1125- err := f .Decode (bytes .NewReader (existingProof .Blob ))
1118+ err := f .Decode (bytes .NewReader (proofFile .Blob ))
11261119 if err != nil {
1127- return fmt .Errorf ("unable to decode current proof: %w" ,
1128- err )
1120+ return nil , fmt .Errorf ("unable to decode current " +
1121+ "proof: %w" , err )
11291122 }
11301123
11311124 // We only need to update proofs that contain this asset in the
11321125 // chain and haven't been updated yet (i.e. the block hash of
11331126 // the proof is different from the block hash of the proof we
11341127 // want to update).
11351128 _ , indexToUpdate , err := f .LocateProof (func (fp * Proof ) bool {
1136- fileScriptKey := fp .Asset .ScriptKey .PubKey
1137- fileTxHash := fp .AnchorTx .TxHash ()
1138- fileBlockHash := fp .BlockHeader .BlockHash ()
1139- return fileScriptKey .IsEqual (scriptPubKeyOfUpdate ) &&
1140- fileTxHash == p .AnchorTx .TxHash () &&
1141- fileBlockHash != p .BlockHeader .BlockHash ()
1129+ fScriptKey := fp .Asset .ScriptKey .PubKey
1130+ fTxHash := fp .AnchorTx .TxHash ()
1131+ fBlockHash := fp .BlockHeader .BlockHash ()
1132+
1133+ return fScriptKey .IsEqual (scriptPubKeyOfUpdate ) &&
1134+ fTxHash == newProof .AnchorTx .TxHash () &&
1135+ fBlockHash != newProof .BlockHeader .BlockHash ()
11421136 })
1143- if err != nil {
1144- // Either we failed to decode the proof for some reason,
1145- // or we didn't find a proof that needs updating. In
1146- // either case, we can skip this file.
1137+ switch {
1138+ // This proof file doesn't contain a proof that needs to be
1139+ // updated, so we can skip it.
1140+ case errors . Is ( err , ErrProofNotFound ):
11471141 continue
1142+
1143+ // Any other error during proof location is fatal and should be
1144+ // returned.
1145+ case err != nil :
1146+ return nil , fmt .Errorf ("unable to locate " +
1147+ "proof to update: %w" , err )
11481148 }
11491149
11501150 log .Debugf ("Updating descendant proof at index %d " +
@@ -1154,29 +1154,25 @@ func ReplaceProofInBlob(ctx context.Context, p *Proof, archive Archiver,
11541154
11551155 // All good, we can now replace the proof in the file with the
11561156 // new one.
1157- err = f .ReplaceProofAt (indexToUpdate , * p )
1157+ err = f .ReplaceProofAt (indexToUpdate , * newProof )
11581158 if err != nil {
1159- return fmt .Errorf ("unable to replace proof at index " +
1160- "%d with updated one: %w" , indexToUpdate , err )
1159+ return nil , fmt .Errorf ("unable to replace proof at " +
1160+ "index %d with updated one: %w" , indexToUpdate ,
1161+ err )
11611162 }
11621163
11631164 var buf bytes.Buffer
11641165 if err := f .Encode (& buf ); err != nil {
1165- return fmt .Errorf ("unable to encode updated proof: %w" ,
1166- err )
1166+ return nil , fmt .Errorf ("unable to encode updated " +
1167+ "proof: %w" , err )
11671168 }
11681169
1169- // We now update this direct proof in the archive.
1170- directProof := & AnnotatedProof {
1171- Locator : existingProof .Locator ,
1170+ updatedProof := & AnnotatedProof {
1171+ Locator : proofFile .Locator ,
11721172 Blob : buf .Bytes (),
11731173 }
1174- err = archive .ImportProofs (ctx , vCtx , true , directProof )
1175- if err != nil {
1176- return fmt .Errorf ("unable to import updated proof: %w" ,
1177- err )
1178- }
1174+ updatedProofs = append (updatedProofs , updatedProof )
11791175 }
11801176
1181- return nil
1177+ return updatedProofs , nil
11821178}
0 commit comments