diff --git a/ci/e2e-group10/forced_batches_test.go b/ci/e2e-group10/forced_batches_test.go index 50b5164d64..d2e2efb080 100644 --- a/ci/e2e-group10/forced_batches_test.go +++ b/ci/e2e-group10/forced_batches_test.go @@ -24,6 +24,7 @@ import ( const ( toAddressHex = "0x4d5Cf5032B2a844602278b01199ED191A86c93ff" gerFinalityBlocks = uint64(250) + forkID5 = 5 ) var ( @@ -60,7 +61,7 @@ func TestForcedBatches(t *testing.T) { unsignedTx := types.NewTransaction(nonce, toAddress, amount, gasLimit, gasPrice, nil) signedTx, err := auth.Signer(auth.From, unsignedTx) require.NoError(t, err) - encodedTxs, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage) + encodedTxs, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage, forkID5) require.NoError(t, err) forcedBatch, err := sendForcedBatch(t, encodedTxs, opsman) require.NoError(t, err) diff --git a/ci/e2e-group10/forced_batches_vector_group2_test.go b/ci/e2e-group10/forced_batches_vector_group2_test.go index e6549f8935..0faf78a046 100644 --- a/ci/e2e-group10/forced_batches_vector_group2_test.go +++ b/ci/e2e-group10/forced_batches_vector_group2_test.go @@ -71,7 +71,7 @@ func TestForcedBatchesVectorFiles(t *testing.T) { require.Equal(t, testCase.ExpectedOldStateRoot, actualOldStateRoot.Hex()) decodedData, err := hex.DecodeHex(testCase.BatchL2Data) require.NoError(t, err) - _, txBytes, _, err := state.DecodeTxs(decodedData) + _, txBytes, _, err := state.DecodeTxs(decodedData, forkID5) forcedBatch, err := sendForcedBatchForVector(t, txBytes, opsman) require.NoError(t, err) actualNewStateRoot := forcedBatch.StateRoot diff --git a/ci/e2e-group11/forced_batches_vector_group3_test.go b/ci/e2e-group11/forced_batches_vector_group3_test.go index 13d0445be9..4bbf4b508b 100644 --- a/ci/e2e-group11/forced_batches_vector_group3_test.go +++ b/ci/e2e-group11/forced_batches_vector_group3_test.go @@ -23,6 +23,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID5 = 5 +) + func TestForcedBatchesVectorFiles(t *testing.T) { if testing.Short() { @@ -71,7 +75,7 @@ func TestForcedBatchesVectorFiles(t *testing.T) { require.Equal(t, testCase.ExpectedOldStateRoot, actualOldStateRoot.Hex()) decodedData, err := hex.DecodeHex(testCase.BatchL2Data) require.NoError(t, err) - _, txBytes, _, err := state.DecodeTxs(decodedData) + _, txBytes, _, err := state.DecodeTxs(decodedData, forkID5) forcedBatch, err := sendForcedBatchForVector(t, txBytes, opsman) require.NoError(t, err) actualNewStateRoot := forcedBatch.StateRoot diff --git a/ci/e2e-group9/forced_batches_vector_group1_test.go b/ci/e2e-group9/forced_batches_vector_group1_test.go index 84c086f097..9949fdaeee 100644 --- a/ci/e2e-group9/forced_batches_vector_group1_test.go +++ b/ci/e2e-group9/forced_batches_vector_group1_test.go @@ -23,6 +23,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID5 = 5 +) + func TestForcedBatchesVectorFiles(t *testing.T) { if testing.Short() { @@ -71,7 +75,7 @@ func TestForcedBatchesVectorFiles(t *testing.T) { require.Equal(t, testCase.ExpectedOldStateRoot, actualOldStateRoot.Hex()) decodedData, err := hex.DecodeHex(testCase.BatchL2Data) require.NoError(t, err) - _, txBytes, _, err := state.DecodeTxs(decodedData) + _, txBytes, _, err := state.DecodeTxs(decodedData, forkID5) require.NoError(t, err) forcedBatch, err := sendForcedBatchForVector(t, txBytes, opsman) require.NoError(t, err) diff --git a/cmd/run.go b/cmd/run.go index c100015f0e..0bc866ffd0 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -129,6 +129,8 @@ func start(cliCtx *cli.Context) error { log.Infof("Fork ID read from POE SC = %v", currentForkID) c.Aggregator.ChainID = l2ChainID c.Aggregator.ForkId = currentForkID + c.Sequencer.DBManager.ForkID = currentForkID + c.Sequencer.Finalizer.ForkID = currentForkID log.Infof("Chain ID read from POE SC = %v", l2ChainID) ctx := context.Background() diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 5b885cfb35..7912fdd30d 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -26,6 +26,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID5 = 5 +) + func init() { log.Init(log.Config{ Level: "debug", @@ -315,7 +319,7 @@ func TestSendSequences(t *testing.T) { require.NoError(t, err) tx1 := types.NewTransaction(uint64(0), common.Address{}, big.NewInt(10), uint64(1), big.NewInt(10), []byte{}) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx1}, constants.EffectivePercentage) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx1}, constants.EffectivePercentage, forkID5) require.NoError(t, err) sequence := ethmanTypes.Sequence{ GlobalExitRoot: ger, diff --git a/jsonrpc/endpoints_zkevm_test.go b/jsonrpc/endpoints_zkevm_test.go index 1e478eca5d..64ec311ff0 100644 --- a/jsonrpc/endpoints_zkevm_test.go +++ b/jsonrpc/endpoints_zkevm_test.go @@ -20,6 +20,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID5 = 5 +) + func TestConsolidatedBlockNumber(t *testing.T) { s, m, _ := newSequencerMockedServer(t) defer s.Stop() @@ -708,7 +712,7 @@ func TestGetBatchByNumber(t *testing.T) { batchTxs = append(batchTxs, *tx) effectivePercentages = append(effectivePercentages, state.MaxEffectivePercentage) } - batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages) + batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages, forkID5) require.NoError(t, err) tc.ExpectedResult.BatchL2Data = batchL2Data batch := &state.Batch{ @@ -821,7 +825,7 @@ func TestGetBatchByNumber(t *testing.T) { batchTxs = append(batchTxs, *tx) effectivePercentages = append(effectivePercentages, state.MaxEffectivePercentage) } - batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages) + batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages, forkID5) require.NoError(t, err) batch := &state.Batch{ @@ -959,7 +963,7 @@ func TestGetBatchByNumber(t *testing.T) { batchTxs = append(batchTxs, *tx) effectivePercentages = append(effectivePercentages, state.MaxEffectivePercentage) } - batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages) + batchL2Data, err := state.EncodeTransactions(batchTxs, effectivePercentages, forkID5) require.NoError(t, err) batch := &state.Batch{ BatchNumber: 1, diff --git a/pool/pool_test.go b/pool/pool_test.go index 3b6539b570..4b85cd78ff 100644 --- a/pool/pool_test.go +++ b/pool/pool_test.go @@ -37,6 +37,7 @@ import ( ) const ( + forkID5 = 5 senderPrivateKey = "0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e" senderAddress = "0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D" ) @@ -271,7 +272,7 @@ func Test_AddPreEIP155Tx(t *testing.T) { batchL2Data := "0xe580843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae98808464fbb77c6b39bdc5f8e458aba689f2a1ff8c543a94e4817bda40f3fe34080c4ab26c1e3c2fc2cda93bc32f0a79940501fd505dcf48d94abfde932ebf1417f502cb0d9de81bff" b, err := hex.DecodeHex(batchL2Data) require.NoError(t, err) - txs, _, _, err := state.DecodeTxs(b) + txs, _, _, err := state.DecodeTxs(b, forkID5) require.NoError(t, err) tx := txs[0] diff --git a/sequencer/config.go b/sequencer/config.go index e8d47883f2..6fe62ca353 100644 --- a/sequencer/config.go +++ b/sequencer/config.go @@ -124,6 +124,9 @@ type FinalizerCfg struct { // TimestampResolution is the resolution of the timestamp used to close a batch TimestampResolution types.Duration `mapstructure:"TimestampResolution"` + + // ForkID is the fork id of the chain + ForkID uint64 `mapstructure:"ForkID"` } // WorkerCfg contains the Worker's configuration properties @@ -136,6 +139,7 @@ type WorkerCfg struct { type DBManagerCfg struct { PoolRetrievalInterval types.Duration `mapstructure:"PoolRetrievalInterval"` L2ReorgRetrievalInterval types.Duration `mapstructure:"L2ReorgRetrievalInterval"` + ForkID uint64 `mapstructure:"ForkID"` } // EffectiveGasPriceCfg contains the configuration properties for the effective gas price diff --git a/sequencer/dbmanager.go b/sequencer/dbmanager.go index 4c248e3ef9..2bd7e7ace3 100644 --- a/sequencer/dbmanager.go +++ b/sequencer/dbmanager.go @@ -183,7 +183,7 @@ func (d *dbManager) StoreProcessedTxAndDeleteFromPool(ctx context.Context, tx tr return err } - txData, err := state.EncodeTransaction(tx.response.Tx, uint8(tx.response.EffectivePercentage)) + txData, err := state.EncodeTransaction(tx.response.Tx, uint8(tx.response.EffectivePercentage), d.cfg.ForkID) if err != nil { return err } @@ -236,7 +236,7 @@ func (d *dbManager) GetWIPBatch(ctx context.Context) (*WipBatch, error) { previousLastBatch = lastBatches[1] } - lastBatchTxs, _, _, err := state.DecodeTxs(lastBatch.BatchL2Data) + lastBatchTxs, _, _, err := state.DecodeTxs(lastBatch.BatchL2Data, d.cfg.ForkID) if err != nil { return nil, err } @@ -244,7 +244,7 @@ func (d *dbManager) GetWIPBatch(ctx context.Context) (*WipBatch, error) { var prevLastBatchTxs []types.Transaction if previousLastBatch != nil { - prevLastBatchTxs, _, _, err = state.DecodeTxs(previousLastBatch.BatchL2Data) + prevLastBatchTxs, _, _, err = state.DecodeTxs(previousLastBatch.BatchL2Data, d.cfg.ForkID) if err != nil { return nil, err } @@ -395,7 +395,7 @@ func (d *dbManager) CloseBatch(ctx context.Context, params ClosingBatchParameter ClosingReason: params.ClosingReason, } - batchL2Data, err := state.EncodeTransactions(params.Txs, params.EffectivePercentages) + batchL2Data, err := state.EncodeTransactions(params.Txs, params.EffectivePercentages, d.cfg.ForkID) if err != nil { return err } diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 97182d7f8e..8412525801 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -1014,7 +1014,7 @@ func (f *finalizer) reprocessFullBatch(ctx context.Context, batchNum uint64, exp Caller: stateMetrics.SequencerCallerLabel, } log.Infof("reprocessFullBatch: BatchNumber: %d, OldStateRoot: %s, Ger: %s", batch.BatchNumber, f.batch.initialStateRoot.String(), batch.GlobalExitRoot.String()) - txs, _, _, err := state.DecodeTxs(batch.BatchL2Data) + txs, _, _, err := state.DecodeTxs(batch.BatchL2Data, f.cfg.ForkID) if err != nil { log.Errorf("reprocessFullBatch: error decoding BatchL2Data before reprocessing full batch: %d. Error: %v", batch.BatchNumber, err) diff --git a/state/batch.go b/state/batch.go index 5b57b264f8..0891ad737b 100644 --- a/state/batch.go +++ b/state/batch.go @@ -148,9 +148,10 @@ func (s *State) ProcessSequencerBatch(ctx context.Context, batchNumber uint64, b } txs := []types.Transaction{} + forkID := GetForkIDByBatchNumber(s.cfg.ForkIDIntervals, batchNumber) if processBatchResponse.Responses != nil && len(processBatchResponse.Responses) > 0 { - txs, _, _, err = DecodeTxs(batchL2Data) + txs, _, _, err = DecodeTxs(batchL2Data, forkID) if err != nil && !errors.Is(err, ErrInvalidData) { return nil, err } @@ -195,7 +196,7 @@ func (s *State) ProcessBatch(ctx context.Context, request ProcessRequest, update return nil, err } - txs, _, effP, err := DecodeTxs(request.Transactions) + txs, _, effP, err := DecodeTxs(request.Transactions, forkID) if err != nil && !errors.Is(err, ErrInvalidData) { return nil, err } @@ -407,7 +408,8 @@ func (s *State) CloseBatch(ctx context.Context, receipt ProcessingReceipt, dbTx // ProcessAndStoreClosedBatch is used by the Synchronizer to add a closed batch into the data base func (s *State) ProcessAndStoreClosedBatch(ctx context.Context, processingCtx ProcessingContext, encodedTxs []byte, dbTx pgx.Tx, caller metrics.CallerLabel) (common.Hash, error) { // Decode transactions - decodedTransactions, _, _, err := DecodeTxs(encodedTxs) + forkID := GetForkIDByBatchNumber(s.cfg.ForkIDIntervals, processingCtx.BatchNumber) + decodedTransactions, _, _, err := DecodeTxs(encodedTxs, forkID) if err != nil && !errors.Is(err, ErrInvalidData) { log.Debugf("error decoding transactions: %v", err) return common.Hash{}, err diff --git a/state/helper.go b/state/helper.go index 9e77ab00c5..2947febc86 100644 --- a/state/helper.go +++ b/state/helper.go @@ -12,6 +12,7 @@ import ( ) const ( + forkID5 = 5 double = 2 ether155V = 27 etherPre155V = 35 @@ -30,7 +31,7 @@ const ( ) // EncodeTransactions RLP encodes the given transactions -func EncodeTransactions(txs []types.Transaction, effectivePercentages []uint8) ([]byte, error) { +func EncodeTransactions(txs []types.Transaction, effectivePercentages []uint8, forkID uint64) ([]byte, error) { var batchL2Data []byte for i, tx := range txs { @@ -40,11 +41,13 @@ func EncodeTransactions(txs []types.Transaction, effectivePercentages []uint8) ( } batchL2Data = append(batchL2Data, txData...) - effectivePercentageAsHex, err := hex.DecodeHex(fmt.Sprintf("%x", effectivePercentages[i])) - if err != nil { - return nil, err + if forkID >= forkID5 { + effectivePercentageAsHex, err := hex.DecodeHex(fmt.Sprintf("%x", effectivePercentages[i])) + if err != nil { + return nil, err + } + batchL2Data = append(batchL2Data, effectivePercentageAsHex...) } - batchL2Data = append(batchL2Data, effectivePercentageAsHex...) } return batchL2Data, nil @@ -109,8 +112,8 @@ func EncodeTransactionWithoutEffectivePercentage(tx types.Transaction) ([]byte, } // EncodeTransaction RLP encodes the given transaction -func EncodeTransaction(tx types.Transaction, effectivePercentage uint8) ([]byte, error) { - return EncodeTransactions([]types.Transaction{tx}, []uint8{effectivePercentage}) +func EncodeTransaction(tx types.Transaction, effectivePercentage uint8, forkID uint64) ([]byte, error) { + return EncodeTransactions([]types.Transaction{tx}, []uint8{effectivePercentage}, forkID) } // EncodeUnsignedTransaction RLP encodes the given unsigned transaction @@ -157,7 +160,7 @@ func EncodeUnsignedTransaction(tx types.Transaction, chainID uint64, forcedNonce } // DecodeTxs extracts Transactions for its encoded form -func DecodeTxs(txsData []byte) ([]types.Transaction, []byte, []uint8, error) { +func DecodeTxs(txsData []byte, forkID uint64) ([]types.Transaction, []byte, []uint8, error) { // Process coded txs var pos uint64 var txs []types.Transaction @@ -196,7 +199,11 @@ func DecodeTxs(txsData []byte) ([]types.Transaction, []byte, []uint8, error) { length = n + num - f7 // num - f7 is the header. For example 0xf7 } - endPos := pos + length + rLength + sLength + vLength + headerByteLength + efficiencyPercentageByteLength + endPos := pos + length + rLength + sLength + vLength + headerByteLength + + if forkID >= forkID5 { + endPos += efficiencyPercentageByteLength + } if endPos > txDataLength { err := fmt.Errorf("endPos %d is bigger than txDataLength %d", endPos, txDataLength) @@ -222,8 +229,11 @@ func DecodeTxs(txsData []byte) ([]types.Transaction, []byte, []uint8, error) { rData := txsData[dataStart : dataStart+rLength] sData := txsData[dataStart+rLength : dataStart+rLength+sLength] vData := txsData[dataStart+rLength+sLength : dataStart+rLength+sLength+vLength] - efficiencyPercentage := txsData[dataStart+rLength+sLength+vLength : endPos] - efficiencyPercentages = append(efficiencyPercentages, uint8(efficiencyPercentage[0])) + + if forkID >= forkID5 { + efficiencyPercentage := txsData[dataStart+rLength+sLength+vLength : endPos] + efficiencyPercentages = append(efficiencyPercentages, uint8(efficiencyPercentage[0])) + } pos = endPos diff --git a/state/helper_test.go b/state/helper_test.go index 430136654e..f1c510d38a 100644 --- a/state/helper_test.go +++ b/state/helper_test.go @@ -13,6 +13,11 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID5 = 5 + forkID4 = 4 +) + func init() { log.Init(log.Config{ Level: "debug", @@ -22,28 +27,59 @@ func init() { func TestDecodeRandomBatchL2Data(t *testing.T) { randomData := []byte("Random data") - txs, _, _, err := state.DecodeTxs(randomData) + txs, _, _, err := state.DecodeTxs(randomData, forkID5) require.Error(t, err) assert.Equal(t, []types.Transaction{}, txs) t.Log("Txs decoded 1: ", txs) randomData = []byte("Esto es autentica basura") - txs, _, _, err = state.DecodeTxs(randomData) + txs, _, _, err = state.DecodeTxs(randomData, forkID5) require.Error(t, err) assert.Equal(t, []types.Transaction{}, txs) t.Log("Txs decoded 2: ", txs) randomData = []byte("beef") - txs, _, _, err = state.DecodeTxs(randomData) + txs, _, _, err = state.DecodeTxs(randomData, forkID5) require.Error(t, err) assert.Equal(t, []types.Transaction{}, txs) t.Log("Txs decoded 3: ", txs) } -func TestDecodePre155BatchL2Data(t *testing.T) { +func TestDecodePre155BatchL2DataPreForkID5(t *testing.T) { + pre155, err := hex.DecodeString("e480843b9aca00826163941275fbb540c8efc58b812ba83b0d0b8b9917ae98808464fbb77cb7d2a666860f3c6b8f5ef96f86c7ec5562e97fd04c2e10f3755ff3a0456f9feb246df95217bf9082f84f9e40adb0049c6664a5bb4c9cbe34ab1a73e77bab26ed1b") + require.NoError(t, err) + txs, _, _, err := state.DecodeTxs(pre155, forkID4) + require.NoError(t, err) + t.Log("Txs decoded: ", txs, len(txs)) + assert.Equal(t, 1, len(txs)) + v, r, s := txs[0].RawSignatureValues() + assert.Equal(t, "0x1275fbb540c8efC58b812ba83B0D0B8b9917AE98", txs[0].To().String()) + assert.Equal(t, "1b", fmt.Sprintf("%x", v)) + assert.Equal(t, "b7d2a666860f3c6b8f5ef96f86c7ec5562e97fd04c2e10f3755ff3a0456f9feb", fmt.Sprintf("%x", r)) + assert.Equal(t, "246df95217bf9082f84f9e40adb0049c6664a5bb4c9cbe34ab1a73e77bab26ed", fmt.Sprintf("%x", s)) + assert.Equal(t, uint64(24931), txs[0].Gas()) + assert.Equal(t, "64fbb77c", hex.EncodeToString(txs[0].Data())) + assert.Equal(t, uint64(0), txs[0].Nonce()) + assert.Equal(t, new(big.Int).SetUint64(1000000000), txs[0].GasPrice()) + + pre155, err = hex.DecodeString("e580843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae988084159278193d7bcd98c00060650f12c381cc2d4f4cc8abf54059aecd2c7aabcfcdd191ba6827b1e72f0eb0b8d5daae64962f4aafde7853e1c102de053edbedf066e6e3c2dc1b") + require.NoError(t, err) + txs, _, _, err = state.DecodeTxs(pre155, forkID4) + require.NoError(t, err) + t.Log("Txs decoded: ", txs) + assert.Equal(t, 1, len(txs)) + assert.Equal(t, "0x1275fbb540c8efC58b812ba83B0D0B8b9917AE98", txs[0].To().String()) + assert.Equal(t, uint64(0), txs[0].Nonce()) + assert.Equal(t, big.NewInt(0), txs[0].Value()) + assert.Equal(t, "15927819", hex.EncodeToString(txs[0].Data())) + assert.Equal(t, uint64(100000), txs[0].Gas()) + assert.Equal(t, new(big.Int).SetUint64(1000000000), txs[0].GasPrice()) +} + +func TestDecodePre155BatchL2DataForkID5(t *testing.T) { pre155, err := hex.DecodeString("e480843b9aca00826163941275fbb540c8efc58b812ba83b0d0b8b9917ae98808464fbb77cb7d2a666860f3c6b8f5ef96f86c7ec5562e97fd04c2e10f3755ff3a0456f9feb246df95217bf9082f84f9e40adb0049c6664a5bb4c9cbe34ab1a73e77bab26ed1bff") require.NoError(t, err) - txs, _, _, err := state.DecodeTxs(pre155) + txs, _, _, err := state.DecodeTxs(pre155, forkID5) require.NoError(t, err) t.Log("Txs decoded: ", txs, len(txs)) assert.Equal(t, 1, len(txs)) @@ -57,9 +93,9 @@ func TestDecodePre155BatchL2Data(t *testing.T) { assert.Equal(t, uint64(0), txs[0].Nonce()) assert.Equal(t, new(big.Int).SetUint64(1000000000), txs[0].GasPrice()) - pre155, err = hex.DecodeString("e580843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae988084159278193d7bcd98c00060650f12c381cc2d4f4cc8abf54059aecd2c7aabcfcdd191ba6827b1e72f0eb0b8d5daae64962f4aafde7853e1c102de053edbedf066e6e3c2dc1bff") + pre155, err = hex.DecodeString("e580843b9aca00830186a0941275fbb540c8efc58b812ba83b0d0b8b9917ae988084159278193d7bcd98c00060650f12c381cc2d4f4cc8abf54059aecd2c7aabcfcdd191ba6827b1e72f0eb0b8d5daae64962f4aafde7853e1c102de053edbedf066e6e3c2dc1b") require.NoError(t, err) - txs, _, _, err = state.DecodeTxs(pre155) + txs, _, _, err = state.DecodeTxs(pre155, forkID4) require.NoError(t, err) t.Log("Txs decoded: ", txs) assert.Equal(t, 1, len(txs)) @@ -87,12 +123,23 @@ func TestDecodePre155Tx(t *testing.T) { assert.Equal(t, new(big.Int).SetUint64(1000000000), tx.GasPrice()) } -func TestEncodePre155BatchL2Data(t *testing.T) { +func TestEncodePre155BatchL2DataPreForkID5(t *testing.T) { + pre155, err := hex.DecodeString("e480843b9aca00826163941275fbb540c8efc58b812ba83b0d0b8b9917ae98808464fbb77cb7d2a666860f3c6b8f5ef96f86c7ec5562e97fd04c2e10f3755ff3a0456f9feb246df95217bf9082f84f9e40adb0049c6664a5bb4c9cbe34ab1a73e77bab26ed1b") + require.NoError(t, err) + txs, _, effectivePercentages, err := state.DecodeTxs(pre155, forkID4) + require.NoError(t, err) + rawtxs, err := state.EncodeTransactions(txs, effectivePercentages, forkID4) + require.NoError(t, err) + t.Log("Txs decoded: ", txs, len(txs)) + assert.Equal(t, pre155, rawtxs) +} + +func TestEncodePre155BatchL2DataForkID5(t *testing.T) { pre155, err := hex.DecodeString("e480843b9aca00826163941275fbb540c8efc58b812ba83b0d0b8b9917ae98808464fbb77cb7d2a666860f3c6b8f5ef96f86c7ec5562e97fd04c2e10f3755ff3a0456f9feb246df95217bf9082f84f9e40adb0049c6664a5bb4c9cbe34ab1a73e77bab26ed1bff") require.NoError(t, err) - txs, _, effectivePercentages, err := state.DecodeTxs(pre155) + txs, _, effectivePercentages, err := state.DecodeTxs(pre155, forkID5) require.NoError(t, err) - rawtxs, err := state.EncodeTransactions(txs, effectivePercentages) + rawtxs, err := state.EncodeTransactions(txs, effectivePercentages, forkID5) require.NoError(t, err) t.Log("Txs decoded: ", txs, len(txs)) assert.Equal(t, pre155, rawtxs) @@ -158,7 +205,7 @@ func TestMaliciousTransaction(t *testing.T) { 0xd2, 0x05, 0xf0, 0xa3, 0x6f, 0xdc, 0x6e, 0x4e, 0x4c, 0x5a, 0x7b, 0x88, 0xd4, 0x5b, 0x1b} - _, _, _, err = state.DecodeTxs(b) + _, _, _, err = state.DecodeTxs(b, forkID4) require.Error(t, err) require.Equal(t, err, state.ErrInvalidData) } diff --git a/state/state_test.go b/state/state_test.go index 1f2a3887fb..45ae8025ca 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -242,7 +242,7 @@ func TestOpenCloseBatch(t *testing.T) { }, } - data, err := state.EncodeTransactions([]types.Transaction{tx1, tx2}, constants.TwoEffectivePercentages) + data, err := state.EncodeTransactions([]types.Transaction{tx1, tx2}, constants.TwoEffectivePercentages, forkID) require.NoError(t, err) receipt1.BatchL2Data = data @@ -277,7 +277,7 @@ func TestOpenCloseBatch(t *testing.T) { // Get batch #1 from DB and compare with on memory batch actualBatch, err := testState.GetBatchByNumber(ctx, 1, dbTx) require.NoError(t, err) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{tx1, tx2}, constants.TwoEffectivePercentages) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{tx1, tx2}, constants.TwoEffectivePercentages, forkID) require.NoError(t, err) assertBatch(t, state.Batch{ BatchNumber: 1, @@ -820,7 +820,7 @@ func TestExecutorRevert(t *testing.T) { signedTx1, err := auth.Signer(auth.From, tx1) require.NoError(t, err) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx0, *signedTx1}, constants.TwoEffectivePercentages) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx0, *signedTx1}, constants.TwoEffectivePercentages, forkID) require.NoError(t, err) // Create Batch @@ -1024,7 +1024,7 @@ func TestExecutorTransfer(t *testing.T) { signedTx, err := auth.Signer(auth.From, tx) require.NoError(t, err) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage, forkID) require.NoError(t, err) // Create Batch @@ -1171,7 +1171,7 @@ func TestExecutorTxHashAndRLP(t *testing.T) { require.Equal(t, testCase.Hash, tx.Hash().String()) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx}, constants.EffectivePercentage) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx}, constants.EffectivePercentage, forkID) require.NoError(t, err) // Create Batch @@ -1280,7 +1280,7 @@ func TestExecutorInvalidNonce(t *testing.T) { require.NoError(t, err) // encode txs - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage, forkID) require.NoError(t, err) // Create Batch @@ -1615,7 +1615,7 @@ func TestExecutorUnsignedTransactions(t *testing.T) { *signedTxFirstRetrieve, } threeEffectivePercentages := []uint8{state.MaxEffectivePercentage, state.MaxEffectivePercentage, state.MaxEffectivePercentage} - batchL2Data, err := state.EncodeTransactions(signedTxs, threeEffectivePercentages) + batchL2Data, err := state.EncodeTransactions(signedTxs, threeEffectivePercentages, forkID) require.NoError(t, err) processBatchResponse, err := testState.ProcessSequencerBatch(context.Background(), 1, batchL2Data, metrics.SequencerCallerLabel, dbTx) @@ -2017,7 +2017,7 @@ func TestExecutorEstimateGas(t *testing.T) { signedTx1, err := auth.Signer(auth.From, tx1) require.NoError(t, err) - batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx0, *signedTx1}, constants.TwoEffectivePercentages) + batchL2Data, err := state.EncodeTransactions([]types.Transaction{*signedTx0, *signedTx1}, constants.TwoEffectivePercentages, forkID) require.NoError(t, err) // Create Batch @@ -2371,7 +2371,7 @@ func TestExecutorGasEstimationMultisig(t *testing.T) { for range transactions { effectivePercentages = append(effectivePercentages, state.MaxEffectivePercentage) } - batchL2Data, err := state.EncodeTransactions(transactions, effectivePercentages) + batchL2Data, err := state.EncodeTransactions(transactions, effectivePercentages, forkID) require.NoError(t, err) // Create Batch @@ -2459,7 +2459,7 @@ func TestExecutorGasEstimationMultisig(t *testing.T) { signedTx6, err = auth.Signer(auth.From, tx6) require.NoError(t, err) - batchL2Data, err = state.EncodeTransactions([]types.Transaction{*signedTx6}, constants.EffectivePercentage) + batchL2Data, err = state.EncodeTransactions([]types.Transaction{*signedTx6}, constants.EffectivePercentage, forkID) require.NoError(t, err) processBatchRequest = &executorclientpb.ProcessBatchRequest{ @@ -2515,7 +2515,7 @@ func TestExecuteWithoutUpdatingMT(t *testing.T) { *signedTxDeploy, } - batchL2Data, err := state.EncodeTransactions(signedTxs, constants.EffectivePercentage) + batchL2Data, err := state.EncodeTransactions(signedTxs, constants.EffectivePercentage, forkID) require.NoError(t, err) // Create Batch @@ -2574,7 +2574,7 @@ func TestExecuteWithoutUpdatingMT(t *testing.T) { *signedTxFirstRetrieve, } - batchL2Data2, err := state.EncodeTransactions(signedTxs2, constants.TwoEffectivePercentages) + batchL2Data2, err := state.EncodeTransactions(signedTxs2, constants.TwoEffectivePercentages, forkID) require.NoError(t, err) // Create Batch 2 @@ -2665,7 +2665,7 @@ func TestExecutorUnsignedTransactionsWithCorrectL2BlockStateRoot(t *testing.T) { effectivePercentages = append(effectivePercentages, state.MaxEffectivePercentage) } - batchL2Data, err := state.EncodeTransactions(signedTxs, effectivePercentages) + batchL2Data, err := state.EncodeTransactions(signedTxs, effectivePercentages, forkID) require.NoError(t, err) processBatchResponse, err := testState.ProcessSequencerBatch(context.Background(), 1, batchL2Data, metrics.SequencerCallerLabel, dbTx) diff --git a/state/transaction.go b/state/transaction.go index 59ea6344ae..1dcca5ef2f 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -220,25 +220,25 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has return nil, err } - // generate batch l2 data for the transaction - batchL2Data, err := EncodeTransactions([]types.Transaction{*tx}, []uint8{MaxEffectivePercentage}) - if err != nil { - return nil, err - } - // gets batch that including the l2 block batch, err := s.GetBatchByL2BlockNumber(ctx, block.NumberU64(), dbTx) if err != nil { return nil, err } + forkId := s.GetForkIDByBatchNumber(batch.BatchNumber) + // gets batch that including the previous l2 block previousBatch, err := s.GetBatchByL2BlockNumber(ctx, previousBlock.NumberU64(), dbTx) if err != nil { return nil, err } - forkId := s.GetForkIDByBatchNumber(batch.BatchNumber) + // generate batch l2 data for the transaction + batchL2Data, err := EncodeTransactions([]types.Transaction{*tx}, []uint8{MaxEffectivePercentage}, forkId) + if err != nil { + return nil, err + } // Create Batch traceConfigRequest := &pb.TraceConfig{ @@ -297,7 +297,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has return nil, err } - txs, _, _, err := DecodeTxs(batchL2Data) + txs, _, _, err := DecodeTxs(batchL2Data, forkId) if err != nil && !errors.Is(err, ErrInvalidData) { return nil, err } diff --git a/test/e2e/forced_batches_test.go b/test/e2e/forced_batches_test.go index c1cd49dbda..88808db20c 100644 --- a/test/e2e/forced_batches_test.go +++ b/test/e2e/forced_batches_test.go @@ -56,7 +56,7 @@ func TestForcedBatches(t *testing.T) { unsignedTx := types.NewTransaction(nonce, toAddress, amount, gasLimit, gasPrice, nil) signedTx, err := auth.Signer(auth.From, unsignedTx) require.NoError(t, err) - encodedTxs, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage) + encodedTxs, err := state.EncodeTransactions([]types.Transaction{*signedTx}, constants.EffectivePercentage, forkID) require.NoError(t, err) forcedBatch, err := sendForcedBatch(t, encodedTxs, opsman) require.NoError(t, err) diff --git a/test/e2e/forced_batches_vector_test.go b/test/e2e/forced_batches_vector_test.go index cb2d2e62d9..05b0eab7f3 100644 --- a/test/e2e/forced_batches_vector_test.go +++ b/test/e2e/forced_batches_vector_test.go @@ -23,6 +23,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + forkID = 5 +) + func TestForcedBatchesVectorFiles(t *testing.T) { if testing.Short() { @@ -71,7 +75,7 @@ func TestForcedBatchesVectorFiles(t *testing.T) { require.Equal(t, testCase.ExpectedOldStateRoot, actualOldStateRoot.Hex()) decodedData, err := hex.DecodeHex(testCase.BatchL2Data) require.NoError(t, err) - _, txBytes, _, err := state.DecodeTxs(decodedData) + _, txBytes, _, err := state.DecodeTxs(decodedData, forkID) forcedBatch, err := sendForcedBatchForVector(t, txBytes, opsman) require.NoError(t, err) actualNewStateRoot := forcedBatch.StateRoot diff --git a/tools/executor/main.go b/tools/executor/main.go index a2d98f3b0f..47f5de6ae2 100644 --- a/tools/executor/main.go +++ b/tools/executor/main.go @@ -18,6 +18,7 @@ import ( ) const ( + forkID = 4 waitForDBSeconds = 3 vectorDir = "./vectors/" genesisDir = "./genesis/" @@ -117,7 +118,7 @@ func runTestCase(ctx context.Context, genesis []genesisItem, tc testCase) error return err } log.Infof("********** BATCH %d **********", tc.Requests[i].OldBatchNum) - txs, _, _, err := state.DecodeTxs(tc.Requests[i].BatchL2Data) + txs, _, _, err := state.DecodeTxs(tc.Requests[i].BatchL2Data, forkID) if err != nil { log.Warnf("Txs are not correctly encoded") } diff --git a/tools/rlp/README.md b/tools/rlp/README.md index a20c988ac4..0c612fbb0e 100644 --- a/tools/rlp/README.md +++ b/tools/rlp/README.md @@ -1,16 +1,16 @@ # Commands: ## Decode full call data: ``` -go run main.go decodeFull 0x06d6490f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000e1ee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a00008082019180806e209c61ca92c2b980d6197e7ac9ccc3f547bf13be6455dfe682aa5dda9655ef16819a7edcc3fefec81ca97c7a6f3d10ec774440e409adbba693ce8b698d41f11cef80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff89056bc75e2d63100000808203e98080fe1e96b35c836fbebac887681150c5fc9fdae862d747aaaf8c30373c0becf7691ff0c900aaaac6d1565a603f69b5a45f222ed205f0a36fdc6e4e4c5a7b88d45b1b00000000000000000000000000000000000000000000000000000000000000 +go run main.go --forkID 4 decodeFull 0x06d6490f00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000e1ee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a00008082019180806e209c61ca92c2b980d6197e7ac9ccc3f547bf13be6455dfe682aa5dda9655ef16819a7edcc3fefec81ca97c7a6f3d10ec774440e409adbba693ce8b698d41f11cef80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff89056bc75e2d63100000808203e98080fe1e96b35c836fbebac887681150c5fc9fdae862d747aaaf8c30373c0becf7691ff0c900aaaac6d1565a603f69b5a45f222ed205f0a36fdc6e4e4c5a7b88d45b1b00000000000000000000000000000000000000000000000000000000000000 ``` ## Decode raw txs: ``` -go run main.go decode 0xee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a00008082019180806e209c61ca92c2b980d6197e7ac9ccc3f547bf13be6455dfe682aa5dda9655ef16819a7edcc3fefec81ca97c7a6f3d10ec774440e409adbba693ce8b698d41f11cef80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff89056bc75e2d63100000808203e98080fe1e96b35c836fbebac887681150c5fc9fdae862d747aaaf8c30373c0becf7691ff0c900aaaac6d1565a603f69b5a45f222ed205f0a36fdc6e4e4c5a7b88d45b1b +go run main.go --forkID 4 decode 0xee80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff88016345785d8a00008082019180806e209c61ca92c2b980d6197e7ac9ccc3f547bf13be6455dfe682aa5dda9655ef16819a7edcc3fefec81ca97c7a6f3d10ec774440e409adbba693ce8b698d41f11cef80843b9aca00830186a0944d5cf5032b2a844602278b01199ed191a86c93ff89056bc75e2d63100000808203e98080fe1e96b35c836fbebac887681150c5fc9fdae862d747aaaf8c30373c0becf7691ff0c900aaaac6d1565a603f69b5a45f222ed205f0a36fdc6e4e4c5a7b88d45b1b ``` ## Encode tx: ``` -go run main.go encode +go run main.go encode --forkID 4 ``` #### Decoded parameters: Nonce: 0 diff --git a/tools/rlp/main.go b/tools/rlp/main.go index 423b91dc02..a952afe793 100644 --- a/tools/rlp/main.go +++ b/tools/rlp/main.go @@ -19,6 +19,10 @@ import ( "github.com/urfave/cli/v2" ) +const ( + forkID4 = 4 +) + func main() { app := cli.NewApp() app.Name = "RlpTool" @@ -43,6 +47,14 @@ func main() { Action: encode, }, } + app.Flags = []cli.Flag{ + &cli.Uint64Flag{ + Name: "forkID", + Aliases: []string{"forkid"}, + Usage: "forkID number", + Value: forkID4, + }, + } err := app.Run(os.Args) if err != nil { log.Errorf("\nError: %v\n", err) @@ -57,7 +69,7 @@ func decodeFull(ctx *cli.Context) error { log.Error("error decoding callData: ", err) return err } - txs, rawTxs, err := decodeFullCallDataToTxs(bytesCallData) + txs, rawTxs, err := decodeFullCallDataToTxs(bytesCallData, ctx.Uint64("forkID")) if err != nil { return err } @@ -72,7 +84,7 @@ func decode(ctx *cli.Context) error { log.Error("error decoding rawTxs: ", err) return err } - txs, _, _, err := state.DecodeTxs(bytesRawTxs) + txs, _, _, err := state.DecodeTxs(bytesRawTxs, ctx.Uint64("forkID")) if err != nil { log.Error("error decoding tx callData: ", err) return err @@ -82,7 +94,7 @@ func decode(ctx *cli.Context) error { } func encode(ctx *cli.Context) error { - fmt.Print("Nonce : ") + fmt.Println("Nonce : ") var nonceS string if _, err := fmt.Scanln(&nonceS); err != nil { return err @@ -92,17 +104,17 @@ func encode(ctx *cli.Context) error { log.Error("error decoding nonce: ", err) return err } - log.Info("Nonce: ", nonce) + fmt.Println("Nonce: ", nonce) - fmt.Print("GasPrice : ") + fmt.Println("GasPrice : ") var gasPriceS string if _, err := fmt.Scanln(&gasPriceS); err != nil { return err } gasPrice, _ := new(big.Int).SetString(gasPriceS, encoding.Base10) - log.Info("GasPrice: ", gasPrice) + fmt.Println("GasPrice: ", gasPrice) - fmt.Print("Gas : ") + fmt.Println("Gas : ") var gasS string if _, err := fmt.Scanln(&gasS); err != nil { return err @@ -112,25 +124,25 @@ func encode(ctx *cli.Context) error { log.Error("error decoding gas: ", err) return err } - log.Info("Gas: ", gas) + fmt.Println("Gas: ", gas) - fmt.Print("To : ") + fmt.Println("To : ") var toS string if _, err := fmt.Scanln(&toS); err != nil { return err } to := common.HexToAddress(toS) - log.Info("To: ", to) + fmt.Println("To: ", to) - fmt.Print("Value : ") + fmt.Println("Value : ") var valueS string if _, err := fmt.Scanln(&valueS); err != nil { return err } value, _ := new(big.Int).SetString(valueS, encoding.Base10) - log.Info("Value: ", value) + fmt.Println("Value: ", value) - fmt.Print("Data : ") + fmt.Println("Data : ") var dataS string if _, err := fmt.Scanln(&dataS); err != nil { if err.Error() != "unexpected newline" { @@ -145,31 +157,31 @@ func encode(ctx *cli.Context) error { return err } } - log.Info("Data: ", data) + fmt.Println("Data: ", data) - fmt.Print("V: ") + fmt.Println("V: ") var vS string if _, err := fmt.Scanln(&vS); err != nil { return err } v, _ := new(big.Int).SetString(vS, encoding.Base10) - log.Info("V: ", v) + fmt.Println("V: ", v) - fmt.Print("R: ") + fmt.Println("R: ") var rS string if _, err := fmt.Scanln(&rS); err != nil { return err } r, _ := new(big.Int).SetString(rS, encoding.Base10) - log.Info("R: ", r) + fmt.Println("R: ", r) - fmt.Print("S: ") + fmt.Println("S: ") var sS string if _, err := fmt.Scanln(&sS); err != nil { return err } s, _ := new(big.Int).SetString(sS, encoding.Base10) - log.Info("S: ", s) + fmt.Println("S: ", s) var txLegacy = types.LegacyTx{ Nonce: nonce, @@ -184,41 +196,41 @@ func encode(ctx *cli.Context) error { } tx := types.NewTx(&txLegacy) - rawBytes, err := state.EncodeTransactions([]types.Transaction{*tx}, constants.EffectivePercentage) + rawBytes, err := state.EncodeTransactions([]types.Transaction{*tx}, constants.EffectivePercentage, ctx.Uint64("forkID")) if err != nil { log.Error("error encoding txs: ", err) return err } - log.Info("encoded tx with signature using RLP in []byte: ", rawBytes) - log.Info("rawtx with signature using RLP in hex: ", hex.EncodeToString(rawBytes)) + fmt.Println("encoded tx with signature using RLP in []byte: ", rawBytes) + fmt.Println("rawtx with signature using RLP in hex: ", hex.EncodeToString(rawBytes)) return nil } func printTxs(txs []types.Transaction, rawTxs []byte) { - log.Info("RawTxs: ", hex.EncodeToHex(rawTxs)) + fmt.Println("RawTxs: ", hex.EncodeToHex(rawTxs)) for _, tx := range txs { - log.Info("#######################################################################") - log.Info("#######################################################################") - log.Infof("Decoded tx: %+v", tx) - log.Info("ChainID: ", tx.ChainId()) - log.Info("Cost: ", tx.Cost()) - log.Info("Data: ", hex.EncodeToString(tx.Data())) - log.Info("Gas: ", tx.Gas()) - log.Info("GasPrice: ", tx.GasPrice()) - log.Info("Hash: ", tx.Hash()) - log.Info("Nonce: ", tx.Nonce()) + fmt.Println("#######################################################################") + fmt.Println("#######################################################################") + fmt.Printf("Decoded tx: %+v\n", tx) + fmt.Println("ChainID: ", tx.ChainId()) + fmt.Println("Cost: ", tx.Cost()) + fmt.Println("Data: ", hex.EncodeToString(tx.Data())) + fmt.Println("Gas: ", tx.Gas()) + fmt.Println("GasPrice: ", tx.GasPrice()) + fmt.Println("Hash: ", tx.Hash()) + fmt.Println("Nonce: ", tx.Nonce()) v, r, s := tx.RawSignatureValues() - log.Info("V: ", v) - log.Info("R: ", r) - log.Info("S: ", s) - log.Info("To: ", tx.To()) - log.Info("Type: ", tx.Type()) - log.Info("Value: ", tx.Value()) + fmt.Println("V: ", v) + fmt.Println("R: ", r) + fmt.Println("S: ", s) + fmt.Println("To: ", tx.To()) + fmt.Println("Type: ", tx.Type()) + fmt.Println("Value: ", tx.Value()) } } -func decodeFullCallDataToTxs(txsData []byte) ([]types.Transaction, []byte, error) { +func decodeFullCallDataToTxs(txsData []byte, forkID uint64) ([]types.Transaction, []byte, error) { // The first 4 bytes are the function hash bytes. These bytes has to be ripped. // After that, the unpack method is used to read the call data. // The txs data is a chunk of concatenated rawTx. This rawTx is the encoded tx information in rlp + the signature information (v, r, s). @@ -245,6 +257,6 @@ func decodeFullCallDataToTxs(txsData []byte) ([]types.Transaction, []byte, error txsData = data[0].([]byte) - txs, _, _, err := state.DecodeTxs(txsData) + txs, _, _, err := state.DecodeTxs(txsData, forkID) return txs, txsData, err }