github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/etherman/etherman_test.go (about)

     1  package etherman
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"math"
     8  	"math/big"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/0xPolygon/supernets2-node/etherman/smartcontracts/polygonzkevmbridge"
    13  	"github.com/0xPolygon/supernets2-node/etherman/smartcontracts/supernets2"
    14  	"github.com/0xPolygon/supernets2-node/etherman/smartcontracts/supernets2datacommittee"
    15  	ethmanTypes "github.com/0xPolygon/supernets2-node/etherman/types"
    16  	"github.com/0xPolygon/supernets2-node/log"
    17  	"github.com/0xPolygon/supernets2-node/state"
    18  	"github.com/ethereum/go-ethereum"
    19  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    20  	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/core/types"
    23  	"github.com/ethereum/go-ethereum/crypto"
    24  	"github.com/stretchr/testify/assert"
    25  	"github.com/stretchr/testify/require"
    26  )
    27  
    28  func init() {
    29  	log.Init(log.Config{
    30  		Level:   "debug",
    31  		Outputs: []string{"stderr"},
    32  	})
    33  }
    34  
    35  // This function prepare the blockchain, the wallet with funds and deploy the smc
    36  func newTestingEnv() (
    37  	ethman *Client,
    38  	ethBackend *backends.SimulatedBackend,
    39  	auth *bind.TransactOpts,
    40  	maticAddr common.Address,
    41  	br *polygonzkevmbridge.Polygonzkevmbridge,
    42  	da *supernets2datacommittee.Supernets2datacommittee,
    43  ) {
    44  	privateKey, err := crypto.GenerateKey()
    45  	if err != nil {
    46  		log.Fatal(err)
    47  	}
    48  	auth, err = bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337))
    49  	if err != nil {
    50  		log.Fatal(err)
    51  	}
    52  	ethman, ethBackend, maticAddr, br, da, err = NewSimulatedEtherman(Config{}, auth)
    53  	if err != nil {
    54  		log.Fatal(err)
    55  	}
    56  	err = ethman.AddOrReplaceAuth(*auth)
    57  	if err != nil {
    58  		log.Fatal(err)
    59  	}
    60  
    61  	return ethman, ethBackend, auth, maticAddr, br, da
    62  }
    63  
    64  func TestGEREvent(t *testing.T) {
    65  	// Set up testing environment
    66  	etherman, ethBackend, auth, _, br, _ := newTestingEnv()
    67  
    68  	// Read currentBlock
    69  	ctx := context.Background()
    70  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
    71  	require.NoError(t, err)
    72  
    73  	amount := big.NewInt(1000000000000000)
    74  	auth.Value = amount
    75  	_, err = br.BridgeAsset(auth, 1, auth.From, amount, common.Address{}, true, []byte{})
    76  	require.NoError(t, err)
    77  
    78  	// Mine the tx in a block
    79  	ethBackend.Commit()
    80  
    81  	// Now read the event
    82  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
    83  	require.NoError(t, err)
    84  	finalBlockNumber := finalBlock.NumberU64()
    85  	blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
    86  	require.NoError(t, err)
    87  	t.Log("Blocks: ", blocks)
    88  	assert.Equal(t, uint64(2), blocks[1].GlobalExitRoots[0].BlockNumber)
    89  	assert.NotEqual(t, common.Hash{}, blocks[1].GlobalExitRoots[0].MainnetExitRoot)
    90  	assert.Equal(t, common.Hash{}, blocks[1].GlobalExitRoots[0].RollupExitRoot)
    91  }
    92  
    93  func TestForcedBatchEvent(t *testing.T) {
    94  	// Set up testing environment
    95  	etherman, ethBackend, auth, _, _, _ := newTestingEnv()
    96  
    97  	// Read currentBlock
    98  	ctx := context.Background()
    99  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   100  	require.NoError(t, err)
   101  
   102  	amount, err := etherman.Supernets2.GetForcedBatchFee(&bind.CallOpts{Pending: false})
   103  	require.NoError(t, err)
   104  	rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
   105  	data, err := hex.DecodeString(rawTxs)
   106  	require.NoError(t, err)
   107  	_, err = etherman.Supernets2.ForceBatch(auth, data, amount)
   108  	require.NoError(t, err)
   109  
   110  	// Mine the tx in a block
   111  	ethBackend.Commit()
   112  
   113  	// Now read the event
   114  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   115  	require.NoError(t, err)
   116  	finalBlockNumber := finalBlock.NumberU64()
   117  	blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   118  	require.NoError(t, err)
   119  	t.Log("Blocks: ", blocks)
   120  	assert.Equal(t, uint64(2), blocks[1].BlockNumber)
   121  	assert.Equal(t, uint64(2), blocks[1].ForcedBatches[0].BlockNumber)
   122  	assert.NotEqual(t, common.Hash{}, blocks[1].ForcedBatches[0].GlobalExitRoot)
   123  	assert.NotEqual(t, time.Time{}, blocks[1].ForcedBatches[0].ForcedAt)
   124  	assert.Equal(t, uint64(1), blocks[1].ForcedBatches[0].ForcedBatchNumber)
   125  	assert.Equal(t, rawTxs, hex.EncodeToString(blocks[1].ForcedBatches[0].RawTxsData))
   126  	assert.Equal(t, auth.From, blocks[1].ForcedBatches[0].Sequencer)
   127  }
   128  
   129  func TestSequencedBatchesEvent(t *testing.T) {
   130  	// Set up testing environment
   131  	etherman, ethBackend, auth, _, br, _ := newTestingEnv()
   132  
   133  	// Read currentBlock
   134  	ctx := context.Background()
   135  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   136  	require.NoError(t, err)
   137  
   138  	// Make a bridge tx
   139  	auth.Value = big.NewInt(1000000000000000)
   140  	_, err = br.BridgeAsset(auth, 1, auth.From, auth.Value, common.Address{}, true, []byte{})
   141  	require.NoError(t, err)
   142  	ethBackend.Commit()
   143  	auth.Value = big.NewInt(0)
   144  
   145  	// Get the last ger
   146  	ger, err := etherman.GlobalExitRootManager.GetLastGlobalExitRoot(nil)
   147  	require.NoError(t, err)
   148  
   149  	amount, err := etherman.Supernets2.GetForcedBatchFee(&bind.CallOpts{Pending: false})
   150  	require.NoError(t, err)
   151  	rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
   152  	data, err := hex.DecodeString(rawTxs)
   153  	require.NoError(t, err)
   154  	_, err = etherman.Supernets2.ForceBatch(auth, data, amount)
   155  	require.NoError(t, err)
   156  	require.NoError(t, err)
   157  	ethBackend.Commit()
   158  
   159  	// Now read the event
   160  	currentBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   161  	require.NoError(t, err)
   162  	currentBlockNumber := currentBlock.NumberU64()
   163  	blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &currentBlockNumber)
   164  	require.NoError(t, err)
   165  	t.Log("Blocks: ", blocks)
   166  	var sequences []supernets2.Supernets2BatchData
   167  	sequences = append(sequences, supernets2.Supernets2BatchData{
   168  		GlobalExitRoot:     ger,
   169  		Timestamp:          currentBlock.Time(),
   170  		MinForcedTimestamp: uint64(blocks[2].ForcedBatches[0].ForcedAt.Unix()),
   171  		TransactionsHash:   crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)),
   172  	})
   173  	sequences = append(sequences, supernets2.Supernets2BatchData{
   174  		GlobalExitRoot:     ger,
   175  		Timestamp:          currentBlock.Time() + 1,
   176  		MinForcedTimestamp: 0,
   177  		TransactionsHash:   crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)),
   178  	})
   179  	_, err = etherman.Supernets2.SequenceBatches(auth, sequences, auth.From, []byte{})
   180  	require.NoError(t, err)
   181  
   182  	// Mine the tx in a block
   183  	ethBackend.Commit()
   184  
   185  	// Now read the event
   186  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   187  	require.NoError(t, err)
   188  	finalBlockNumber := finalBlock.NumberU64()
   189  	blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   190  	require.NoError(t, err)
   191  	t.Log("Blocks: ", blocks)
   192  	assert.Equal(t, 4, len(blocks))
   193  	assert.Equal(t, 1, len(blocks[3].SequencedBatches))
   194  	assert.Equal(t, crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)), common.Hash(blocks[3].SequencedBatches[0][1].TransactionsHash))
   195  	assert.Equal(t, currentBlock.Time(), blocks[3].SequencedBatches[0][0].Timestamp)
   196  	assert.Equal(t, ger, blocks[3].SequencedBatches[0][0].GlobalExitRoot)
   197  	assert.Equal(t, auth.From, blocks[3].SequencedBatches[0][0].Coinbase)
   198  	assert.Equal(t, auth.From, blocks[3].SequencedBatches[0][0].SequencerAddr)
   199  	assert.Equal(t, currentBlock.Time(), blocks[3].SequencedBatches[0][0].MinForcedTimestamp)
   200  	assert.Equal(t, 0, order[blocks[3].BlockHash][0].Pos)
   201  }
   202  
   203  func TestVerifyBatchEvent(t *testing.T) {
   204  	// Set up testing environment
   205  	etherman, ethBackend, auth, _, _, _ := newTestingEnv()
   206  
   207  	// Read currentBlock
   208  	ctx := context.Background()
   209  
   210  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   211  	require.NoError(t, err)
   212  
   213  	rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
   214  	tx := supernets2.Supernets2BatchData{
   215  		GlobalExitRoot:     common.Hash{},
   216  		Timestamp:          initBlock.Time(),
   217  		MinForcedTimestamp: 0,
   218  		TransactionsHash:   crypto.Keccak256Hash(common.Hex2Bytes(rawTxs)),
   219  	}
   220  	_, err = etherman.Supernets2.SequenceBatches(auth, []supernets2.Supernets2BatchData{tx}, auth.From, []byte{})
   221  	require.NoError(t, err)
   222  
   223  	// Mine the tx in a block
   224  	ethBackend.Commit()
   225  
   226  	_, err = etherman.Supernets2.VerifyBatchesTrustedAggregator(auth, uint64(0), uint64(0), uint64(1), [32]byte{}, [32]byte{}, []byte{})
   227  	require.NoError(t, err)
   228  
   229  	// Mine the tx in a block
   230  	ethBackend.Commit()
   231  
   232  	// Now read the event
   233  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   234  	require.NoError(t, err)
   235  	finalBlockNumber := finalBlock.NumberU64()
   236  	blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   237  	require.NoError(t, err)
   238  	t.Log("Blocks: ", blocks)
   239  	assert.Equal(t, uint64(3), blocks[2].BlockNumber)
   240  	assert.Equal(t, uint64(1), blocks[2].VerifiedBatches[0].BatchNumber)
   241  	assert.NotEqual(t, common.Address{}, blocks[2].VerifiedBatches[0].Aggregator)
   242  	assert.NotEqual(t, common.Hash{}, blocks[2].VerifiedBatches[0].TxHash)
   243  	assert.Equal(t, GlobalExitRootsOrder, order[blocks[2].BlockHash][0].Name)
   244  	assert.Equal(t, TrustedVerifyBatchOrder, order[blocks[2].BlockHash][1].Name)
   245  	assert.Equal(t, 0, order[blocks[2].BlockHash][0].Pos)
   246  	assert.Equal(t, 0, order[blocks[2].BlockHash][1].Pos)
   247  }
   248  
   249  func TestSequenceForceBatchesEvent(t *testing.T) {
   250  	// Set up testing environment
   251  	etherman, ethBackend, auth, _, _, _ := newTestingEnv()
   252  
   253  	// Read currentBlock
   254  	ctx := context.Background()
   255  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   256  	require.NoError(t, err)
   257  
   258  	amount, err := etherman.Supernets2.GetForcedBatchFee(&bind.CallOpts{Pending: false})
   259  	require.NoError(t, err)
   260  	rawTxs := "f84901843b9aca00827b0c945fbdb2315678afecb367f032d93f642f64180aa380a46057361d00000000000000000000000000000000000000000000000000000000000000048203e9808073efe1fa2d3e27f26f32208550ea9b0274d49050b816cadab05a771f4275d0242fd5d92b3fb89575c070e6c930587c520ee65a3aa8cfe382fcad20421bf51d621c"
   261  	data, err := hex.DecodeString(rawTxs)
   262  	require.NoError(t, err)
   263  	_, err = etherman.Supernets2.ForceBatch(auth, data, amount)
   264  	require.NoError(t, err)
   265  	ethBackend.Commit()
   266  
   267  	err = ethBackend.AdjustTime((24*7 + 1) * time.Hour)
   268  	require.NoError(t, err)
   269  	ethBackend.Commit()
   270  
   271  	// Now read the event
   272  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   273  	require.NoError(t, err)
   274  	finalBlockNumber := finalBlock.NumberU64()
   275  	blocks, _, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   276  	require.NoError(t, err)
   277  	t.Log("Blocks: ", blocks)
   278  
   279  	forceBatchData := supernets2.Supernets2ForcedBatchData{
   280  		Transactions:       blocks[1].ForcedBatches[0].RawTxsData,
   281  		GlobalExitRoot:     blocks[1].ForcedBatches[0].GlobalExitRoot,
   282  		MinForcedTimestamp: uint64(blocks[1].ForcedBatches[0].ForcedAt.Unix()),
   283  	}
   284  	_, err = etherman.Supernets2.SequenceForceBatches(auth, []supernets2.Supernets2ForcedBatchData{forceBatchData})
   285  	require.NoError(t, err)
   286  	ethBackend.Commit()
   287  
   288  	// Now read the event
   289  	finalBlock, err = etherman.EthClient.BlockByNumber(ctx, nil)
   290  	require.NoError(t, err)
   291  	finalBlockNumber = finalBlock.NumberU64()
   292  	blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   293  	require.NoError(t, err)
   294  	t.Log("Blocks: ", blocks)
   295  	assert.Equal(t, uint64(4), blocks[2].BlockNumber)
   296  	assert.Equal(t, uint64(1), blocks[2].SequencedForceBatches[0][0].BatchNumber)
   297  	assert.Equal(t, uint64(20), blocks[2].SequencedForceBatches[0][0].MinForcedTimestamp)
   298  	assert.Equal(t, 0, order[blocks[2].BlockHash][0].Pos)
   299  }
   300  
   301  func TestSendSequences(t *testing.T) {
   302  	// Set up testing environment
   303  	etherman, ethBackend, auth, _, br, _ := newTestingEnv()
   304  
   305  	// Read currentBlock
   306  	ctx := context.Background()
   307  	initBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   308  	require.NoError(t, err)
   309  
   310  	// Make a bridge tx
   311  	auth.Value = big.NewInt(1000000000000000)
   312  	_, err = br.BridgeAsset(auth, 1, auth.From, auth.Value, common.Address{}, true, []byte{})
   313  	require.NoError(t, err)
   314  	ethBackend.Commit()
   315  	auth.Value = big.NewInt(0)
   316  
   317  	// Get the last ger
   318  	ger, err := etherman.GlobalExitRootManager.GetLastGlobalExitRoot(nil)
   319  	require.NoError(t, err)
   320  
   321  	currentBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   322  	require.NoError(t, err)
   323  
   324  	tx1 := types.NewTransaction(uint64(0), common.Address{}, big.NewInt(10), uint64(1), big.NewInt(10), []byte{})
   325  	batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx1})
   326  	require.NoError(t, err)
   327  	sequence := ethmanTypes.Sequence{
   328  		GlobalExitRoot: ger,
   329  		Timestamp:      int64(currentBlock.Time() - 1),
   330  		BatchL2Data:    batchL2Data,
   331  	}
   332  	tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, []byte{})
   333  	require.NoError(t, err)
   334  	log.Debug("TX: ", tx.Hash())
   335  	ethBackend.Commit()
   336  
   337  	// Now read the event
   338  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   339  	require.NoError(t, err)
   340  	finalBlockNumber := finalBlock.NumberU64()
   341  	blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, initBlock.NumberU64(), &finalBlockNumber)
   342  	require.NoError(t, err)
   343  	t.Log("Blocks: ", blocks)
   344  	assert.Equal(t, 3, len(blocks))
   345  	assert.Equal(t, 1, len(blocks[2].SequencedBatches))
   346  	assert.Equal(t, currentBlock.Time()-1, blocks[2].SequencedBatches[0][0].Timestamp)
   347  	assert.Equal(t, ger, blocks[2].SequencedBatches[0][0].GlobalExitRoot)
   348  	assert.Equal(t, auth.From, blocks[2].SequencedBatches[0][0].Coinbase)
   349  	assert.Equal(t, auth.From, blocks[2].SequencedBatches[0][0].SequencerAddr)
   350  	assert.Equal(t, uint64(0), blocks[2].SequencedBatches[0][0].MinForcedTimestamp)
   351  	assert.Equal(t, 0, order[blocks[2].BlockHash][0].Pos)
   352  }
   353  
   354  func TestGasPrice(t *testing.T) {
   355  	// Set up testing environment
   356  	etherman, _, _, _, _, _ := newTestingEnv()
   357  	etherscanM := new(etherscanMock)
   358  	ethGasStationM := new(ethGasStationMock)
   359  	etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
   360  	ctx := context.Background()
   361  
   362  	etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625003), nil)
   363  	ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625002), nil)
   364  	gp := etherman.GetL1GasPrice(ctx)
   365  	assert.Equal(t, big.NewInt(765625003), gp)
   366  
   367  	etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
   368  
   369  	gp = etherman.GetL1GasPrice(ctx)
   370  	assert.Equal(t, big.NewInt(765625002), gp)
   371  }
   372  
   373  func TestErrorEthGasStationPrice(t *testing.T) {
   374  	// Set up testing environment
   375  	etherman, _, _, _, _, _ := newTestingEnv()
   376  	ethGasStationM := new(ethGasStationMock)
   377  	etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, ethGasStationM}
   378  	ctx := context.Background()
   379  
   380  	ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from ethGasStation"))
   381  	gp := etherman.GetL1GasPrice(ctx)
   382  	assert.Equal(t, big.NewInt(765625001), gp)
   383  
   384  	etherscanM := new(etherscanMock)
   385  	etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
   386  
   387  	etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625003), nil)
   388  	gp = etherman.GetL1GasPrice(ctx)
   389  	assert.Equal(t, big.NewInt(765625003), gp)
   390  }
   391  
   392  func TestErrorEtherScanPrice(t *testing.T) {
   393  	// Set up testing environment
   394  	etherman, _, _, _, _, _ := newTestingEnv()
   395  	etherscanM := new(etherscanMock)
   396  	ethGasStationM := new(ethGasStationMock)
   397  	etherman.GasProviders.Providers = []ethereum.GasPricer{etherman.EthClient, etherscanM, ethGasStationM}
   398  	ctx := context.Background()
   399  
   400  	etherscanM.On("SuggestGasPrice", ctx).Return(big.NewInt(0), fmt.Errorf("error getting gasPrice from etherscan"))
   401  	ethGasStationM.On("SuggestGasPrice", ctx).Return(big.NewInt(765625002), nil)
   402  	gp := etherman.GetL1GasPrice(ctx)
   403  	assert.Equal(t, big.NewInt(765625002), gp)
   404  }
   405  
   406  func TestGetForks(t *testing.T) {
   407  	// Set up testing environment
   408  	etherman, _, _, _, _, _ := newTestingEnv()
   409  	ctx := context.Background()
   410  	forks, err := etherman.GetForks(ctx, 0)
   411  	require.NoError(t, err)
   412  	assert.Equal(t, 1, len(forks))
   413  	assert.Equal(t, uint64(1), forks[0].ForkId)
   414  	assert.Equal(t, uint64(1), forks[0].FromBatchNumber)
   415  	assert.Equal(t, uint64(math.MaxUint64), forks[0].ToBatchNumber)
   416  	assert.Equal(t, "v1", forks[0].Version)
   417  	// Now read the event
   418  	finalBlock, err := etherman.EthClient.BlockByNumber(ctx, nil)
   419  	require.NoError(t, err)
   420  	finalBlockNumber := finalBlock.NumberU64()
   421  	blocks, order, err := etherman.GetRollupInfoByBlockRange(ctx, 0, &finalBlockNumber)
   422  	require.NoError(t, err)
   423  	t.Logf("Blocks: %+v", blocks)
   424  	assert.Equal(t, 1, len(blocks))
   425  	assert.Equal(t, 1, len(blocks[0].ForkIDs))
   426  	assert.Equal(t, 0, order[blocks[0].BlockHash][0].Pos)
   427  	assert.Equal(t, ForkIDsOrder, order[blocks[0].BlockHash][0].Name)
   428  	assert.Equal(t, uint64(0), blocks[0].ForkIDs[0].BatchNumber)
   429  	assert.Equal(t, uint64(1), blocks[0].ForkIDs[0].ForkID)
   430  	assert.Equal(t, "v1", blocks[0].ForkIDs[0].Version)
   431  }