diff --git a/itest/assertions.go b/itest/assertions.go index 422f9716f..ccb0f4a4e 100644 --- a/itest/assertions.go +++ b/itest/assertions.go @@ -265,14 +265,42 @@ func verifyProofBlob(t *testing.T, tapd *tapdHarness, anchorTxBlockHeight := rpcAsset.ChainAnchor.BlockHeight require.Greater(t, anchorTxBlockHeight, uint32(0)) - headerVerifier := func(blockHeader wire.BlockHeader) error { - hash := blockHeader.BlockHash() + headerVerifier := func(header wire.BlockHeader, height uint32) error { + hash := header.BlockHash() req := &chainrpc.GetBlockRequest{ BlockHash: hash.CloneBytes(), } _, err := tapd.cfg.LndNode.RPC.ChainKit.GetBlock(ctxb, req) - return err + if err != nil { + return err + } + + //// Ensure that the block hash matches the hash of the block + //// found at the given height. + //blockHashReq := &chainrpc.GetBlockHashRequest{ + // BlockHeight: int64(height), + //} + //blockHashResp, err := tapd.cfg.LndNode.RPC.ChainKit.GetBlockHash( + // ctxb, blockHashReq, + //) + //if err != nil { + // return err + //} + // + //var heightHash chainhash.Hash + //copy(heightHash[:], blockHashResp.BlockHash) + // + //expectedHash := hash + //if heightHash != expectedHash { + // return fmt.Errorf("block hash and block height "+ + // "mismatch; (height: %x, hashAtHeight: %x, "+ + // "expectedHash: %x)", height, heightHash, + // expectedHash) + //} + + return nil } + snapshot, err := f.Verify(ctxt, headerVerifier) require.NoError(t, err) diff --git a/proof/mock.go b/proof/mock.go index 6ef547cc7..e0971a1bf 100644 --- a/proof/mock.go +++ b/proof/mock.go @@ -39,6 +39,6 @@ func (m *MockVerifier) Verify(_ context.Context, _ io.Reader, // Header verification usually involves cross-referencing with chain data. // Chain data is not available in unit tests. This function is useful for unit // tests which are not primarily concerned with block header verification. -func MockHeaderVerifier(blockHeader wire.BlockHeader) error { +func MockHeaderVerifier(header wire.BlockHeader, height uint32) error { return nil } diff --git a/proof/proof_test.go b/proof/proof_test.go index 65827efe5..306c52155 100644 --- a/proof/proof_test.go +++ b/proof/proof_test.go @@ -487,10 +487,10 @@ func TestProofBlockHeaderVerification(t *testing.T) { // Header verifier compares given header to expected header. Verifier // does not return error. errHeaderVerifier := fmt.Errorf("invalid block header") - headerVerifier := func(blockHeader wire.BlockHeader) error { + headerVerifier := func(header wire.BlockHeader, height uint32) error { // Compare given block header against base reference block // header. - if blockHeader != originalBlockHeader { + if header != originalBlockHeader { return errHeaderVerifier } return nil diff --git a/proof/verifier.go b/proof/verifier.go index e95096c51..709d6156c 100644 --- a/proof/verifier.go +++ b/proof/verifier.go @@ -288,7 +288,7 @@ func (p *Proof) verifyMetaReveal() error { // HeaderVerifier is a callback function which returns an error if the given // block header is invalid (usually: not present on chain). -type HeaderVerifier func(blockHeader wire.BlockHeader) error +type HeaderVerifier func(blockHeader wire.BlockHeader, blockHeight uint32) error // Verify verifies the proof by ensuring that: // @@ -313,7 +313,7 @@ func (p *Proof) Verify(ctx context.Context, prev *AssetSnapshot, } // Cross-check block header with a bitcoin node. - err := headerVerifier(p.BlockHeader) + err := headerVerifier(p.BlockHeader, p.BlockHeight) if err != nil { return nil, fmt.Errorf("failed to validate proof block "+ "header: %w", err) diff --git a/tapgarden/caretaker.go b/tapgarden/caretaker.go index f22c0cdc9..f9b1566c9 100644 --- a/tapgarden/caretaker.go +++ b/tapgarden/caretaker.go @@ -1025,12 +1025,32 @@ func GetTxFee(pkt *psbt.Packet) (int64, error) { // GenHeaderVerifier generates a block header on-chain verification callback // function given a chain bridge. func GenHeaderVerifier(ctx context.Context, - chainBridge ChainBridge) func(header wire.BlockHeader) error { + chainBridge ChainBridge) func(wire.BlockHeader, uint32) error { - return func(blockHeader wire.BlockHeader) error { + return func(header wire.BlockHeader, height uint32) error { _, err := chainBridge.GetBlock( - ctx, blockHeader.BlockHash(), + ctx, header.BlockHash(), ) - return err + if err != nil { + return err + } + + // Ensure that the block hash matches the hash of the block + // found at the given height. + hash, err := chainBridge.GetBlockHash( + ctx, int64(height), + ) + if err != nil { + return err + } + + expectedHash := header.BlockHash() + if hash != expectedHash { + return fmt.Errorf("block hash and block height "+ + "mismatch; (height: %x, hashAtHeight: %x, "+ + "expectedHash: %x)", height, hash, expectedHash) + } + + return nil } }