Skip to content

Commit

Permalink
Add test executor unsigned txs (0xPolygonHermez#1017)
Browse files Browse the repository at this point in the history
* add executor test for unsigned txs

* fix error check

* Use ProcessUnsignedTransaction

* small fixes to test

* WIP

* Fix lint

* Fix lint

* Hardcode chainID for unsigned txs

* Fix lint

* Fix lint

Co-authored-by: Arnau <[email protected]>
  • Loading branch information
tclemos and arnaubennassar authored Aug 10, 2022
1 parent e43b777 commit 85d5165
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 15 deletions.
2 changes: 1 addition & 1 deletion state/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func EncodeUnsignedTransaction(tx types.Transaction) ([]byte, error) {
tx.To(),
tx.Value(),
tx.Data(),
tx.ChainId(), uint(0), uint(0),
big.NewInt(1000), uint(0), uint(0), //nolint:gomnd
})

if err != nil {
Expand Down
15 changes: 10 additions & 5 deletions state/pgstatestorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const (
getVerifiedBatchSQL = "SELECT block_num, batch_num, tx_hash, aggregator FROM state.verified_batch WHERE batch_num = $1"
getLastBatchNumberSQL = "SELECT batch_num FROM state.batch ORDER BY batch_num DESC LIMIT 1"
getLastNBatchesSQL = "SELECT batch_num, global_exit_root, local_exit_root, state_root, timestamp, coinbase, raw_txs_data from state.batch ORDER BY batch_num DESC LIMIT $1"
getLastNBatchesByBlockNumberSQL = "SELECT b.batch_num, b.global_exit_root, b.local_exit_root, b.state_root, b.timestamp, b.coinbase, b.raw_txs_data, l.header->>'stateRoot' as l2_block_state_root from state.batch b, state.l2block l where l.block_num = $1 and b.batch_num <= l.batch_num order by b.batch_num DESC LIMIT $2"
getLastBatchTimeSQL = "SELECT timestamp FROM state.batch ORDER BY batch_num DESC LIMIT 1"
getLastVirtualBatchNumSQL = "SELECT COALESCE(MAX(batch_num), 0) FROM state.virtual_batch"
getLastVirtualBatchBlockNumSQL = "SELECT block_num FROM state.virtual_batch ORDER BY batch_num DESC LIMIT 1"
Expand Down Expand Up @@ -408,11 +407,16 @@ func (p *PostgresStorage) GetLastNBatches(ctx context.Context, numBatches uint,
return batches, nil
}

// GetLastNBatchesByBlockNumber returns the last numBatches batches along with the block state root by blockNumber
func (p *PostgresStorage) GetLastNBatchesByBlockNumber(ctx context.Context, blockNumber uint64, numBatches uint, dbTx pgx.Tx) ([]*Batch, common.Hash, error) {
// GetLastNBatchesByL2BlockNumber returns the last numBatches batches along with the l2 block state root by l2BlockNumber
func (p *PostgresStorage) GetLastNBatchesByL2BlockNumber(ctx context.Context, l2BlockNumber uint64, numBatches uint, dbTx pgx.Tx) ([]*Batch, common.Hash, error) {
const getLastNBatchesByBlockNumberSQL = `
SELECT b.batch_num, b.global_exit_root, b.local_exit_root, b.state_root, b.timestamp, b.coinbase, b.raw_txs_data, l2.header->>'stateRoot' as l2_block_state_root
FROM state.batch b, state.l2block l2
WHERE l2.block_num = $1 AND b.batch_num <= l2.batch_num
ORDER BY b.batch_num DESC LIMIT $2`
var l2BlockStateRoot common.Hash
e := p.getExecQuerier(dbTx)
rows, err := e.Query(ctx, getLastNBatchesByBlockNumberSQL, blockNumber, numBatches)
rows, err := e.Query(ctx, getLastNBatchesByBlockNumberSQL, l2BlockNumber, numBatches)
if errors.Is(err, pgx.ErrNoRows) {
return nil, l2BlockStateRoot, ErrStateNotSynchronized
} else if err != nil {
Expand All @@ -423,11 +427,12 @@ func (p *PostgresStorage) GetLastNBatchesByBlockNumber(ctx context.Context, bloc
batches := make([]*Batch, 0, len(rows.RawValues()))

for rows.Next() {
batch, l2BlockStateRoot, err := scanBatchWithL2BlockStateRoot(rows)
batch, _l2BlockStateRoot, err := scanBatchWithL2BlockStateRoot(rows)
if err != nil {
return nil, l2BlockStateRoot, err
}
batches = append(batches, &batch)
l2BlockStateRoot = _l2BlockStateRoot
}

return batches, l2BlockStateRoot, nil
Expand Down
12 changes: 8 additions & 4 deletions state/runtime/executor/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
type ExecutorError int32

const (
// NO_ERROR indicates the execution ended successfully
NO_ERROR ExecutorError = iota
// ERROR_UNSPECIFIED indicates the execution ended successfully
ERROR_UNSPECIFIED ExecutorError = iota
// ERROR_NO_ERROR indicates the execution ended successfully
ERROR_NO_ERROR
// ERROR_OUT_OF_GAS indicates there is not enough balance to continue the execution
ERROR_OUT_OF_GAS
// ERROR_STACK_OVERFLOW indicates a stack overflow has happened
Expand All @@ -36,11 +38,13 @@ const (
ERROR_OUT_OF_COUNTERS
// ERROR_INVALID_TX indicates the transaction is invalid
ERROR_INVALID_TX
// ERROR_INTRINSIC_INVALID_TX indicates the transaction is failing at the intrinsic checks
ERROR_INTRINSIC_INVALID_TX
)

func (e ExecutorError) Error() string {
switch e {
case NO_ERROR:
case ERROR_NO_ERROR:
return ""
case ERROR_OUT_OF_GAS:
return runtime.ErrOutOfGas.Error()
Expand All @@ -66,7 +70,7 @@ func (e ExecutorError) Error() string {
return runtime.ErrCodeStoreOutOfGas.Error()
case ERROR_OUT_OF_COUNTERS:
return runtime.ErrOutOfCounters.Error()
case ERROR_INVALID_TX:
case ERROR_INVALID_TX, ERROR_INTRINSIC_INVALID_TX:
return runtime.ErrInvalidTransaction.Error()
}
return "unknown error"
Expand Down
8 changes: 5 additions & 3 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common
}

// Check if an out of gas error happened during EVM execution
if processBatchResponse.Responses[0].Error != pb.Error(executor.NO_ERROR) {
if processBatchResponse.Responses[0].Error != pb.Error(executor.ERROR_NO_ERROR) {
error := fmt.Errorf(executor.ExecutorError(processBatchResponse.Responses[0].Error).Error())

if (isGasEVMError(error) || isGasApplyError(error)) && shouldOmitErr {
Expand Down Expand Up @@ -727,10 +727,10 @@ func (s *State) ParseTheTraceUsingTheTracer(env *fakevm.FakeEVM, trace instrumen
}

// ProcessUnsignedTransaction processes the given unsigned transaction.
func (s *State) ProcessUnsignedTransaction(ctx context.Context, tx *types.Transaction, senderAddress common.Address, blockNumber uint64, dbTx pgx.Tx) *runtime.ExecutionResult {
func (s *State) ProcessUnsignedTransaction(ctx context.Context, tx *types.Transaction, senderAddress common.Address, l2BlockNumber uint64, dbTx pgx.Tx) *runtime.ExecutionResult {
result := new(runtime.ExecutionResult)

lastBatches, l2BlockStateRoot, err := s.PostgresStorage.GetLastNBatchesByBlockNumber(ctx, blockNumber, two, dbTx)
lastBatches, l2BlockStateRoot, err := s.PostgresStorage.GetLastNBatchesByL2BlockNumber(ctx, l2BlockNumber, two, dbTx)
if err != nil {
result.Err = err
return result
Expand All @@ -750,12 +750,14 @@ func (s *State) ProcessUnsignedTransaction(ctx context.Context, tx *types.Transa

// Create Batch
processBatchRequest := &pb.ProcessBatchRequest{
BatchNum: lastBatch.BatchNumber,
BatchL2Data: batchL2Data,
From: senderAddress.String(),
OldStateRoot: l2BlockStateRoot.Bytes(),
GlobalExitRoot: lastBatch.GlobalExitRoot.Bytes(),
OldLocalExitRoot: previousBatch.LocalExitRoot.Bytes(),
EthTimestamp: uint64(lastBatch.Timestamp.Unix()),
Coinbase: lastBatch.Coinbase.String(),
UpdateMerkleTree: cFalse,
}

Expand Down
125 changes: 125 additions & 0 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1514,3 +1514,128 @@ func TestGenesisFromMock(t *testing.T) {
}
}
}

func TestExecutorUnsignedTransactions(t *testing.T) {
// Init database instance
err := dbutils.InitOrReset(cfg)
require.NoError(t, err)
var chainIDSequencer = new(big.Int).SetInt64(1000)
var sequencerAddress = common.HexToAddress("0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D")
var sequencerPvtKey = "0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e"
var gasLimit = uint64(4000000)
var scAddress = common.HexToAddress("0x1275fbb540c8efC58b812ba83B0D0B8b9917AE98")
scByteCode, err := testutils.ReadBytecode("Counter/Counter.bin")
require.NoError(t, err)

// auth
privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(sequencerPvtKey, "0x"))
require.NoError(t, err)
auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainIDSequencer)
require.NoError(t, err)

// signed tx to deploy SC
unsignedTxDeploy := types.NewTx(&types.LegacyTx{
Nonce: 0,
To: nil,
Value: new(big.Int),
Gas: gasLimit,
GasPrice: new(big.Int),
Data: common.Hex2Bytes(scByteCode),
})
signedTxDeploy, err := auth.Signer(auth.From, unsignedTxDeploy)
require.NoError(t, err)

incrementFnSignature := crypto.Keccak256Hash([]byte("increment()")).Bytes()[:4]
retrieveFnSignature := crypto.Keccak256Hash([]byte("getCount()")).Bytes()[:4]

// signed tx to call SC
unsignedTxFirstIncrement := types.NewTx(&types.LegacyTx{
Nonce: 1,
To: &scAddress,
Value: new(big.Int),
Gas: gasLimit,
GasPrice: new(big.Int),
Data: incrementFnSignature,
})
signedTxFirstIncrement, err := auth.Signer(auth.From, unsignedTxFirstIncrement)
require.NoError(t, err)

unsignedTxFirstRetrieve := types.NewTx(&types.LegacyTx{
Nonce: 2,
To: &scAddress,
Value: new(big.Int),
Gas: gasLimit,
GasPrice: new(big.Int),
Data: retrieveFnSignature,
})
signedTxFirstRetrieve, err := auth.Signer(auth.From, unsignedTxFirstRetrieve)
require.NoError(t, err)

dbTx, err := testState.BeginStateTransaction(context.Background())
require.NoError(t, err)
// Set genesis
genesis := state.Genesis{Actions: []*state.GenesisAction{
{
Address: sequencerAddress.Hex(),
Type: int(merkletree.LeafTypeBalance),
Value: "100000000000000000000000",
},
}}
_, err = testState.SetGenesis(ctx, state.Block{}, genesis, dbTx)
require.NoError(t, err)
batchCtx := state.ProcessingContext{
BatchNumber: 1,
Coinbase: sequencerAddress,
Timestamp: time.Now(),
}
err = testState.OpenBatch(context.Background(), batchCtx, dbTx)
require.NoError(t, err)
signedTxs := []types.Transaction{
*signedTxDeploy,
*signedTxFirstIncrement,
*signedTxFirstRetrieve,
}
processBatchResponse, err := testState.ProcessSequencerBatch(context.Background(), 1, signedTxs, dbTx)
require.NoError(t, err)
// assert signed tx do deploy sc
assert.Equal(t, "", processBatchResponse.Responses[0].Error)
assert.Equal(t, scAddress, processBatchResponse.Responses[0].CreateAddress)

// assert signed tx to increment counter
assert.Equal(t, "", processBatchResponse.Responses[1].Error)

// assert signed tx to increment counter
assert.Equal(t, "", processBatchResponse.Responses[2].Error)
assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000001", hex.EncodeToString(processBatchResponse.Responses[2].ReturnValue))

// Add txs to DB
err = testState.StoreTransactions(context.Background(), 1, processBatchResponse.Responses, dbTx)
require.NoError(t, err)
// Close batch
err = testState.CloseBatch(
context.Background(),
state.ProcessingReceipt{
BatchNumber: 1,
StateRoot: processBatchResponse.NewStateRoot,
LocalExitRoot: processBatchResponse.NewLocalExitRoot,
}, dbTx,
)
require.NoError(t, err)

require.NoError(t, dbTx.Commit(context.Background()))
dbTx, err = testState.BeginStateTransaction(context.Background())
require.NoError(t, err)
// TODO: uncoment once it's working
unsignedTxSecondRetrieve := types.NewTx(&types.LegacyTx{
Nonce: 0,
To: &scAddress,
Value: new(big.Int),
Gas: gasLimit,
GasPrice: new(big.Int),
Data: retrieveFnSignature,
})
result := testState.ProcessUnsignedTransaction(context.Background(), unsignedTxSecondRetrieve, common.HexToAddress("0x1000000000000000000000000000000000000000"), 3, dbTx)
// assert unsigned tx
assert.Equal(t, "", result.Err.Error())
assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000001", hex.EncodeToString(result.ReturnValue))
}
4 changes: 4 additions & 0 deletions test/contracts/auto/Counter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@ contract Counter {
function increment() external {
count += 1;
}

function getCount() public view returns (uint) {
return count;
}
}
35 changes: 33 additions & 2 deletions test/contracts/bin/Counter/Counter.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 85d5165

Please sign in to comment.