return bitcoin transaction from sequence computation.

This commit is contained in:
fiatjaf
2024-10-27 09:37:17 -03:00
parent 4cb1ec89c0
commit a0aba28a2a
3 changed files with 33 additions and 16 deletions

View File

@@ -1,10 +1,9 @@
package opentimestamps
import (
"bytes"
"fmt"
"slices"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
)
@@ -14,33 +13,35 @@ type Bitcoin interface {
GetBlockHeader(hash *chainhash.Hash) (*wire.BlockHeader, error)
}
func (seq Sequence) Verify(bitcoin Bitcoin, initial []byte) error {
// Verify validates sequence of operations that starts with digest and ends on a Bitcoin attestation against
// an actual Bitcoin block, as given by the provided Bitcoin interface.
func (seq Sequence) Verify(bitcoin Bitcoin, digest []byte) (*wire.MsgTx, error) {
if len(seq) == 0 {
return fmt.Errorf("empty sequence")
return nil, fmt.Errorf("empty sequence")
}
att := seq[len(seq)-1]
if att.Attestation == nil || att.BitcoinBlockHeight == 0 {
return fmt.Errorf("sequence doesn't include a bitcoin attestation")
return nil, fmt.Errorf("sequence doesn't include a bitcoin attestation")
}
blockHash, err := bitcoin.GetBlockHash(int64(att.BitcoinBlockHeight))
if err != nil {
return fmt.Errorf("failed to get block %d hash: %w", att.BitcoinBlockHeight, err)
return nil, fmt.Errorf("failed to get block %d hash: %w", att.BitcoinBlockHeight, err)
}
blockHeader, err := bitcoin.GetBlockHeader(blockHash)
if err != nil {
return fmt.Errorf("failed to get block %s header: %w", blockHash, err)
return nil, fmt.Errorf("failed to get block %s header: %w", blockHash, err)
}
merkleRoot := blockHeader.MerkleRoot[:]
result, tx := seq.Compute(digest)
result := seq.Compute(initial)
if !slices.Equal(result, merkleRoot) {
return fmt.Errorf("sequence result '%x' doesn't match the bitcoin merkle root for block %d: %x",
if !bytes.Equal(result, merkleRoot) {
return nil, fmt.Errorf("sequence result '%x' doesn't match the bitcoin merkle root for block %d: %x",
result, att.BitcoinBlockHeight, merkleRoot)
}
return nil
return tx, nil
}