github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/test/e2e/forced_batches_vector_test.go (about)

     1  package e2e
     2  
     3  import (
     4  	"context"
     5  	"math/big"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/0xPolygon/supernets2-node/etherman/smartcontracts/supernets2"
    13  	"github.com/0xPolygon/supernets2-node/hex"
    14  	"github.com/0xPolygon/supernets2-node/log"
    15  	"github.com/0xPolygon/supernets2-node/state"
    16  	"github.com/0xPolygon/supernets2-node/test/constants"
    17  	"github.com/0xPolygon/supernets2-node/test/operations"
    18  	"github.com/0xPolygon/supernets2-node/test/vectors"
    19  	"github.com/ethereum/go-ethereum"
    20  	"github.com/ethereum/go-ethereum/accounts/abi/bind"
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/ethereum/go-ethereum/ethclient"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  func TestForcedBatchesVectorFiles(t *testing.T) {
    27  
    28  	if testing.Short() {
    29  		t.Skip()
    30  	}
    31  	vectorFilesDir := "./../vectors/src/state-transition/forced-tx"
    32  	ctx := context.Background()
    33  	err := filepath.Walk(vectorFilesDir, func(path string, info os.FileInfo, err error) error {
    34  		if err != nil {
    35  			return err
    36  		}
    37  		if !info.IsDir() && !strings.HasSuffix(info.Name(), "list.json") {
    38  
    39  			t.Run(info.Name(), func(t *testing.T) {
    40  
    41  				defer func() {
    42  					require.NoError(t, operations.Teardown())
    43  				}()
    44  
    45  				// Load test vectors
    46  				log.Info("=====================================================================")
    47  				log.Info(path)
    48  				log.Info("=====================================================================")
    49  				testCase, err := vectors.LoadStateTransitionTestCaseV2(path)
    50  				require.NoError(t, err)
    51  
    52  				opsCfg := operations.GetDefaultOperationsConfig()
    53  				opsCfg.State.MaxCumulativeGasUsed = 80000000000
    54  				opsman, err := operations.NewManager(ctx, opsCfg)
    55  				require.NoError(t, err)
    56  
    57  				// Setting Genesis
    58  				log.Info("###################")
    59  				log.Info("# Setting Genesis #")
    60  				log.Info("###################")
    61  				genesisActions := vectors.GenerateGenesisActions(testCase.Genesis)
    62  				require.NoError(t, opsman.SetGenesis(genesisActions))
    63  				require.NoError(t, opsman.Setup())
    64  
    65  				// Check initial root
    66  				log.Info("################################")
    67  				log.Info("# Verifying initial state root #")
    68  				log.Info("################################")
    69  				actualOldStateRoot, err := opsman.State().GetLastStateRoot(ctx, nil)
    70  				require.NoError(t, err)
    71  				require.Equal(t, testCase.ExpectedOldStateRoot, actualOldStateRoot.Hex())
    72  				decodedData, err := hex.DecodeHex(testCase.BatchL2Data)
    73  				require.NoError(t, err)
    74  				_, txBytes, err := state.DecodeTxs(decodedData)
    75  				forcedBatch, err := sendForcedBatchForVector(t, txBytes, opsman)
    76  				require.NoError(t, err)
    77  				actualNewStateRoot := forcedBatch.StateRoot
    78  				isClosed, err := opsman.State().IsBatchClosed(ctx, forcedBatch.BatchNumber, nil)
    79  				require.NoError(t, err)
    80  
    81  				// wait until is closed
    82  				for !isClosed {
    83  					time.Sleep(1 * time.Second)
    84  					isClosed, err = opsman.State().IsBatchClosed(ctx, forcedBatch.BatchNumber, nil)
    85  					require.NoError(t, err)
    86  				}
    87  
    88  				log.Info("#######################")
    89  				log.Info("# Verifying new leafs #")
    90  				log.Info("#######################")
    91  				merkleTree := opsman.State().GetTree()
    92  				for _, expectedNewLeaf := range testCase.ExpectedNewLeafs {
    93  					if expectedNewLeaf.IsSmartContract {
    94  						log.Info("Smart Contract Address: ", expectedNewLeaf.Address)
    95  					} else {
    96  						log.Info("Account Address: ", expectedNewLeaf.Address)
    97  					}
    98  					log.Info("Verifying Balance...")
    99  					actualBalance, err := merkleTree.GetBalance(ctx, common.HexToAddress(expectedNewLeaf.Address), actualNewStateRoot.Bytes())
   100  					require.NoError(t, err)
   101  					require.Equal(t, expectedNewLeaf.Balance.String(), actualBalance.String())
   102  
   103  					log.Info("Verifying Nonce...")
   104  					actualNonce, err := merkleTree.GetNonce(ctx, common.HexToAddress(expectedNewLeaf.Address), actualNewStateRoot.Bytes())
   105  					require.NoError(t, err)
   106  					require.Equal(t, expectedNewLeaf.Nonce, actualNonce.String())
   107  					if expectedNewLeaf.IsSmartContract {
   108  						log.Info("Verifying Storage...")
   109  						for positionHex, expectedNewStorageHex := range expectedNewLeaf.Storage {
   110  							position, ok := big.NewInt(0).SetString(positionHex[2:], 16)
   111  							require.True(t, ok)
   112  							expectedNewStorage, ok := big.NewInt(0).SetString(expectedNewStorageHex[2:], 16)
   113  							require.True(t, ok)
   114  							actualStorage, err := merkleTree.GetStorageAt(ctx, common.HexToAddress(expectedNewLeaf.Address), position, actualNewStateRoot.Bytes())
   115  							require.NoError(t, err)
   116  							require.Equal(t, expectedNewStorage, actualStorage)
   117  						}
   118  
   119  						log.Info("Verifying HashBytecode...")
   120  						actualHashByteCode, err := merkleTree.GetCodeHash(ctx, common.HexToAddress(expectedNewLeaf.Address), actualNewStateRoot.Bytes())
   121  						require.NoError(t, err)
   122  						require.Equal(t, expectedNewLeaf.HashBytecode, common.BytesToHash(actualHashByteCode).String())
   123  					}
   124  				}
   125  				return
   126  			})
   127  
   128  			return nil
   129  		}
   130  		return nil
   131  	})
   132  	require.NoError(t, err)
   133  }
   134  
   135  func sendForcedBatchForVector(t *testing.T, txs []byte, opsman *operations.Manager) (*state.Batch, error) {
   136  	ctx := context.Background()
   137  	st := opsman.State()
   138  	// Connect to ethereum node
   139  	ethClient, err := ethclient.Dial(operations.DefaultL1NetworkURL)
   140  	require.NoError(t, err)
   141  
   142  	// Create smc client
   143  	zkEvmAddr := common.HexToAddress(operations.DefaultL1Supernets2SmartContract)
   144  	zkEvm, err := supernets2.NewSupernets2(zkEvmAddr, ethClient)
   145  	require.NoError(t, err)
   146  
   147  	auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID)
   148  	require.NoError(t, err)
   149  
   150  	log.Info("Using address: ", auth.From)
   151  	num, err := zkEvm.LastForceBatch(&bind.CallOpts{Pending: false})
   152  	require.NoError(t, err)
   153  	log.Info("Number of forceBatches in the smc: ", num)
   154  
   155  	// Get tip
   156  	tip, err := zkEvm.GetForcedBatchFee(&bind.CallOpts{Pending: false})
   157  	require.NoError(t, err)
   158  
   159  	disallowed, err := zkEvm.IsForcedBatchDisallowed(&bind.CallOpts{Pending: false})
   160  	require.NoError(t, err)
   161  	if disallowed {
   162  		tx, err := zkEvm.ActivateForceBatches(auth)
   163  		require.NoError(t, err)
   164  		err = operations.WaitTxToBeMined(ctx, ethClient, tx, operations.DefaultTimeoutTxToBeMined)
   165  		require.NoError(t, err)
   166  	}
   167  
   168  	// Send forceBatch
   169  	tx, err := zkEvm.ForceBatch(auth, txs, tip)
   170  	require.NoError(t, err)
   171  
   172  	log.Info("Forced Batch Submit to L1 TxHash: ", tx.Hash())
   173  	time.Sleep(1 * time.Second)
   174  
   175  	err = operations.WaitTxToBeMined(ctx, ethClient, tx, operations.DefaultTimeoutTxToBeMined)
   176  	require.NoError(t, err)
   177  
   178  	currentBlock, err := ethClient.BlockByNumber(ctx, nil)
   179  	require.NoError(t, err)
   180  	log.Debug("currentBlock.Time(): ", currentBlock.Time())
   181  
   182  	query := ethereum.FilterQuery{
   183  		FromBlock: currentBlock.Number(),
   184  		Addresses: []common.Address{zkEvmAddr},
   185  	}
   186  	logs, err := ethClient.FilterLogs(ctx, query)
   187  	require.NoError(t, err)
   188  
   189  	var forcedBatch *state.Batch
   190  	for _, vLog := range logs {
   191  		if vLog.Topics[0] != constants.ForcedBatchSignatureHash {
   192  			logs, err = ethClient.FilterLogs(ctx, query)
   193  			require.NoError(t, err)
   194  			continue
   195  		}
   196  		fb, err := zkEvm.ParseForceBatch(vLog)
   197  		if err != nil {
   198  			log.Errorf("failed to parse force batch log event, err: ", err)
   199  		}
   200  		log.Debugf("log decoded: %+v", fb)
   201  		ger := fb.LastGlobalExitRoot
   202  		log.Info("GlobalExitRoot: ", ger)
   203  		log.Info("Transactions: ", common.Bytes2Hex(fb.Transactions))
   204  		fullBlock, err := ethClient.BlockByHash(ctx, vLog.BlockHash)
   205  		if err != nil {
   206  			log.Errorf("error getting hashParent. BlockNumber: %d. Error: %v", vLog.BlockNumber, err)
   207  			return nil, err
   208  		}
   209  		log.Info("MinForcedTimestamp: ", fullBlock.Time())
   210  		forcedBatch, err = st.GetBatchByForcedBatchNum(ctx, fb.ForceBatchNum, nil)
   211  		for err == state.ErrStateNotSynchronized {
   212  			time.Sleep(1 * time.Second)
   213  			forcedBatch, err = st.GetBatchByForcedBatchNum(ctx, fb.ForceBatchNum, nil)
   214  		}
   215  		require.NoError(t, err)
   216  		require.NotNil(t, forcedBatch)
   217  
   218  		log.Info("Waiting Forced Batch to be virtualized ...")
   219  		err = operations.WaitBatchToBeVirtualized(forcedBatch.BatchNumber, 4*time.Minute, st)
   220  		require.NoError(t, err)
   221  
   222  		log.Info("Waiting Forced Batch to be consolidated ...")
   223  		err = operations.WaitBatchToBeConsolidated(forcedBatch.BatchNumber, 4*time.Minute, st)
   224  		require.NoError(t, err)
   225  	}
   226  
   227  	return forcedBatch, nil
   228  }