Skip to content

Commit

Permalink
feat: Add unit tests for ValidateHeader of btcutils (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitsalis authored Jul 14, 2022
1 parent 5d15ff1 commit 90ca850
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 18 deletions.
24 changes: 23 additions & 1 deletion types/btcutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ import (
"github.com/btcsuite/btcd/wire"
)

// ValidateBTCHeader
// Perform the checks that [checkBlockHeaderSanity](https://github.com/btcsuite/btcd/blob/master/blockchain/validate.go#L430) of btcd does
//
// We skip the "timestamp should not be 2 hours into the future" check
// since this might introduce undeterministic behavior
func ValidateHeader(header *wire.BlockHeader, powLimit *big.Int) error {
func ValidateBTCHeader(header *wire.BlockHeader, powLimit *big.Int) error {
msgBlock := &wire.MsgBlock{Header: *header}

block := btcutil.NewBlock(msgBlock)
Expand All @@ -36,3 +37,24 @@ func ValidateHeader(header *wire.BlockHeader, powLimit *big.Int) error {

return nil
}

func GetBaseBTCHeaderHex() string {
// TODO: get this from a configuration file
hex := "00006020c6c5a20e29da938a252c945411eba594cbeba021a1e20000000000000000000039e4bd0cd0b5232bb380a9576fcfe7d8fb043523f7a158187d9473e44c1740e6b4fa7c62ba01091789c24c22"
return hex
}

func GetBaseBTCHeaderHeight() uint64 {
// TODO: get this from a configuration file
height := uint64(736056)
return height
}

func GetBaseBTCHeaderBytes() BTCHeaderBytes {
hex := GetBaseBTCHeaderHex()
headerBytes, err := NewBTCHeaderBytesFromHex(hex)
if err != nil {
panic("Base BTC header hex cannot be converted to bytes")
}
return headerBytes
}
63 changes: 63 additions & 0 deletions types/btcutils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package types_test

import (
"github.com/babylonchain/babylon/types"
btcchaincfg "github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/wire"
"github.com/stretchr/testify/suite"
"math/big"
"testing"
"time"
)

type btcutilsTestSuite struct {
suite.Suite
mainnetHeader, testnetHeader, mainnetHeaderInvalidTs *wire.BlockHeader
mainnetPowLimit, testnetPowLimit *big.Int
}

func TestBtcutilsTestSuite(t *testing.T) {
suite.Run(t, new(btcutilsTestSuite))
}

func (s *btcutilsTestSuite) SetupSuite() {
s.T().Parallel()
mainnetHeaderHex := "00006020c6c5a20e29da938a252c945411eba594cbeba021a1e20000000000000000000039e4bd0cd0b5232bb380a9576fcfe7d8fb043523f7a158187d9473e44c1740e6b4fa7c62ba01091789c24c22"
testnetHeaderHex := "0000202015f76d6c7147a1cd3cca4ec31b75ac0218199e863ebd040c6000000000000000d321bbe2d2e323781b4ab89abc24d37c6ad70d92a5169f9775b650447548711162957a626fa4001a90376af4"
mainnetHeaderBytes, _ := types.NewBTCHeaderBytesFromHex(mainnetHeaderHex)
testnetHeaderBytes, _ := types.NewBTCHeaderBytesFromHex(testnetHeaderHex)

s.mainnetHeader = mainnetHeaderBytes.ToBlockHeader()
s.testnetHeader = testnetHeaderBytes.ToBlockHeader()

mainnetHeader := *s.mainnetHeader
s.mainnetHeaderInvalidTs = &mainnetHeader
s.mainnetHeaderInvalidTs.Timestamp = time.Now()

s.mainnetPowLimit = btcchaincfg.MainNetParams.PowLimit
s.testnetPowLimit = btcchaincfg.TestNet3Params.PowLimit
}

func (s *btcutilsTestSuite) TestValidateBTCHeader() {
data := []struct {
name string
header *wire.BlockHeader
powLimit *big.Int
hasErr bool
}{
{"valid mainnet", s.mainnetHeader, s.mainnetPowLimit, false},
{"valid testnet", s.testnetHeader, s.testnetPowLimit, false},
{"mainnet invalid limit", s.mainnetHeader, big.NewInt(0), true},
{"testnet invalid limit", s.testnetHeader, big.NewInt(0), true},
{"mainnet invalid timestamp", s.mainnetHeaderInvalidTs, s.mainnetPowLimit, true},
}

for _, d := range data {
err := types.ValidateBTCHeader(d.header, d.powLimit)
if d.hasErr {
s.Require().Error(err, d.name)
} else {
s.Require().NoError(err, d.name)
}
}
}
2 changes: 1 addition & 1 deletion x/btccheckpoint/btcutils/btcutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func ParseProof(

header := types.BTCHeaderBytes(btcHeader).ToBlockHeader()

e = types.ValidateHeader(header, powLimit)
e = types.ValidateBTCHeader(header, powLimit)

if e != nil {
return nil, e
Expand Down
5 changes: 3 additions & 2 deletions x/btclightclient/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (
)

func TestGenesis(t *testing.T) {
headerBytes, _ := bbl.NewBTCHeaderBytesFromHex(types.DefaultBaseHeaderHex)
headerBytes := bbl.GetBaseBTCHeaderBytes()
headerHeight := bbl.GetBaseBTCHeaderHeight()
headerHash := headerBytes.Hash()
headerWork := types.CalcWork(&headerBytes)
baseHeaderInfo := types.NewBTCHeaderInfo(&headerBytes, headerHash, types.DefaultBaseHeaderHeight, &headerWork)
baseHeaderInfo := types.NewBTCHeaderInfo(&headerBytes, headerHash, headerHeight, &headerWork)

genesisState := types.GenesisState{
Params: types.DefaultParams(),
Expand Down
2 changes: 1 addition & 1 deletion x/btclightclient/types/btc_header_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func FuzzNewHeaderInfo(f *testing.F) {
defaultHeader, _ := bbl.NewBTCHeaderBytesFromHex(types.DefaultBaseHeaderHex)
defaultHeader := bbl.GetBaseBTCHeaderBytes()
btcdHeader := defaultHeader.ToBlockHeader()
f.Add(
btcdHeader.Version,
Expand Down
11 changes: 3 additions & 8 deletions x/btclightclient/types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@ import (
bbl "github.com/babylonchain/babylon/types"
)

// TODO: get these from a configuration file
const (
DefaultBaseHeaderHex string = "00006020c6c5a20e29da938a252c945411eba594cbeba021a1e20000000000000000000039e4bd0cd0b5232bb380a9576fcfe7d8fb043523f7a158187d9473e44c1740e6b4fa7c62ba01091789c24c22"
DefaultBaseHeaderHeight uint64 = 736056
)

// DefaultGenesis returns the default Capability genesis state
func DefaultGenesis() *GenesisState {
headerBytes, _ := bbl.NewBTCHeaderBytesFromHex(DefaultBaseHeaderHex)
headerBytes := bbl.GetBaseBTCHeaderBytes()
headerHeight := bbl.GetBaseBTCHeaderHeight()
headerHash := headerBytes.Hash()
// The cumulative work for the Base BTC header is only the work
// for that particular header. This means that it is very important
// that no forks will happen that discard the base header because we
// will not be able to detect those. Cumulative work will build based
// on the sum of the work of the chain starting from the base header.
headerWork := CalcWork(&headerBytes)
baseHeaderInfo := NewBTCHeaderInfo(&headerBytes, headerHash, DefaultBaseHeaderHeight, &headerWork)
baseHeaderInfo := NewBTCHeaderInfo(&headerBytes, headerHash, headerHeight, &headerWork)

return &GenesisState{
Params: DefaultParams(),
Expand Down
2 changes: 1 addition & 1 deletion x/btclightclient/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (msg *MsgInsertHeader) ValidateBasic() error {
}

func (msg *MsgInsertHeader) ValidateHeader(powLimit *big.Int) error {
return bbl.ValidateHeader(msg.Header.ToBlockHeader(), powLimit)
return bbl.ValidateBTCHeader(msg.Header.ToBlockHeader(), powLimit)
}

func (msg *MsgInsertHeader) GetSigners() []sdk.AccAddress {
Expand Down
4 changes: 2 additions & 2 deletions x/btclightclient/types/msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func FuzzMsgInsertHeader(f *testing.F) {
addressBytes := []byte("from________________")
defaultHeader, _ := bbl.NewBTCHeaderBytesFromHex(types.DefaultBaseHeaderHex)
defaultHeader := bbl.GetBaseBTCHeaderBytes()
defaultBtcdHeader := defaultHeader.ToBlockHeader()

// Maximum btc difficulty possible
Expand Down Expand Up @@ -44,7 +44,7 @@ func FuzzMsgInsertHeader(f *testing.F) {
// If the header hex is the same as the default one, then this is the seed input
headerBytes := bbl.NewBTCHeaderBytesFromBlockHeader(btcdHeader)
headerHex := headerBytes.MarshalHex()
seedInput := types.DefaultBaseHeaderHex == headerHex
seedInput := defaultHeader.MarshalHex() == headerHex

// Make the address have a proper size
if len(addressBytes) == 0 || len(addressBytes) >= 256 {
Expand Down
4 changes: 2 additions & 2 deletions x/btclightclient/types/querier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestNewQueryParamsRequest(t *testing.T) {
}

func TestNewQueryHashesRequest(t *testing.T) {
headerBytes, _ := bbl.NewBTCHeaderBytesFromHex(types.DefaultBaseHeaderHex)
headerBytes := bbl.GetBaseBTCHeaderBytes()
headerHashBytes := headerBytes.Hash()
req := query.PageRequest{
Key: headerHashBytes.MustMarshal(),
Expand Down Expand Up @@ -68,7 +68,7 @@ func FuzzNewQueryContainsRequest(f *testing.F) {
}

func TestNewQueryMainChainRequest(t *testing.T) {
headerBytes, _ := bbl.NewBTCHeaderBytesFromHex(types.DefaultBaseHeaderHex)
headerBytes := bbl.GetBaseBTCHeaderBytes()
req := query.PageRequest{
Key: headerBytes.MustMarshal(),
}
Expand Down

0 comments on commit 90ca850

Please sign in to comment.