Skip to content

Commit

Permalink
Feature/mt test vectors (0xPolygonHermez#1076)
Browse files Browse the repository at this point in the history
* Pass smt-genesis.json test vector

* Update genesis.go

* Improve genesis gen tool
  • Loading branch information
arnaubennassar authored Aug 23, 2022
1 parent 02b8330 commit 9e0e4e8
Show file tree
Hide file tree
Showing 11 changed files with 506 additions and 383 deletions.
136 changes: 68 additions & 68 deletions config/genesis.go

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions encoding/encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/0xPolygonHermez/zkevm-node/hex"
"github.com/ethereum/go-ethereum/common"
)

const (
Expand Down Expand Up @@ -88,3 +89,22 @@ func EncodeBigInt(b *big.Int) *string {
res := "0x" + b.Text(hex.Base)
return &res
}

// DecodeBigIntHexOrDecimal parses a string that can be decimal or hexa (starts with 0x)
// into a *big.Int
func DecodeBigIntHexOrDecimal(s string) (*big.Int, error) {
var r *big.Int
if strings.HasPrefix(s, "0x") { // nolint
// Value in hex format
s = s[2:]
r = new(big.Int).SetBytes(common.Hex2Bytes(s))
} else {
// Value in decimal format
value, ok := new(big.Int).SetString(s, Base10)
if !ok {
return nil, fmt.Errorf("Could not set base10 %q to big.Int", s)
}
r = value
}
return r, nil
}
1 change: 0 additions & 1 deletion state/converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func isProcessed(oldRoot common.Hash, newRoot common.Hash, err pb.Error) bool {

func convertToProcessTransactionResponse(oldRoot common.Hash, txs []types.Transaction, responses []*pb.ProcessTransactionResponse) ([]*ProcessTransactionResponse, error) {
results := make([]*ProcessTransactionResponse, 0, len(responses))

for i, response := range responses {
trace, err := convertToStrucLogArray(response.ExecutionTrace)
if err != nil {
Expand Down
102 changes: 102 additions & 0 deletions state/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package state_test

import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"math/big"
"os"
"path"
"runtime"
"testing"

"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/0xPolygonHermez/zkevm-node/test/dbutils"
"github.com/0xPolygonHermez/zkevm-node/tools/genesis/genesisparser"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// genesisAccountReader struct
type genesisAccountReader struct {
Balance string `json:"balance"`
Nonce string `json:"nonce"`
Address string `json:"address"`
Bytecode string `json:"bytecode"`
Storage map[string]string `json:"storage"`
}

// genesisTestVectorReader struct
type genesisTestVectorReader struct {
Root string `json:"expectedRoot"`
Accounts []genesisAccountReader `json:"addresses"`
}

func (gr genesisTestVectorReader) GenesisAccountTest() []genesisparser.GenesisAccountTest {
accs := []genesisparser.GenesisAccountTest{}
for i := 0; i < len(gr.Accounts); i++ {
accs = append(accs, genesisparser.GenesisAccountTest{
Balance: gr.Accounts[i].Balance,
Nonce: gr.Accounts[i].Nonce,
Address: gr.Accounts[i].Address,
Bytecode: gr.Accounts[i].Bytecode,
Storage: gr.Accounts[i].Storage,
})
}
return accs
}

func init() {
// Change dir to project root
// This is important because we have relative paths to files containing test vectors
_, filename, _, _ := runtime.Caller(0)
dir := path.Join(path.Dir(filename), "../")
err := os.Chdir(dir)
if err != nil {
panic(err)
}
}

func TestGenesisVectors(t *testing.T) {
// Load test vectors
var testVectors []genesisTestVectorReader
files := []string{
"test/vectors/src/merkle-tree/smt-full-genesis.json",
"test/vectors/src/merkle-tree/smt-genesis.json",
}
for _, f := range files {
var tv []genesisTestVectorReader
data, err := os.ReadFile(f)
require.NoError(t, err)
err = json.Unmarshal(data, &tv)
require.NoError(t, err)
testVectors = append(testVectors, tv...)
}
// Run vectors
for ti, testVector := range testVectors {
t.Run(fmt.Sprintf("Test vector %d", ti), func(t *testing.T) {
genesisCase(t, testVector)
})
}
}

func genesisCase(t *testing.T, tv genesisTestVectorReader) {
// Init database instance
err := dbutils.InitOrReset(cfg)
require.NoError(t, err)
actions := genesisparser.GenesisTest2Actions(tv.GenesisAccountTest())
genesis := state.Genesis{
Actions: actions,
}
ctx := context.Background()
dbTx, err := testState.BeginStateTransaction(ctx)
require.NoError(t, err)
root, err := testState.SetGenesis(ctx, state.Block{}, genesis, dbTx)
require.NoError(t, err)
err = dbTx.Commit(ctx)
require.NoError(t, err)
expectedRoot, _ := big.NewInt(0).SetString(tv.Root, 10)
actualRoot, _ := big.NewInt(0).SetString(hex.EncodeToString(root), 16)
assert.Equal(t, expectedRoot, actualRoot)
}
27 changes: 14 additions & 13 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,18 +852,18 @@ func (s *State) SetGenesis(ctx context.Context, block Block, genesis Genesis, db
address := common.HexToAddress(action.Address)
switch action.Type {
case int(merkletree.LeafTypeBalance):
balance, ok := new(big.Int).SetString(action.Value, encoding.Base10)
if !ok {
return newRoot, fmt.Errorf("Could not set base10 balance %q to big.Int", action.Value)
balance, err := encoding.DecodeBigIntHexOrDecimal(action.Value)
if err != nil {
return newRoot, err
}
newRoot, _, err = s.tree.SetBalance(ctx, address, balance, newRoot)
if err != nil {
return newRoot, err
}
case int(merkletree.LeafTypeNonce):
nonce, ok := new(big.Int).SetString(action.Value, encoding.Base10)
if !ok {
return newRoot, fmt.Errorf("Could not set base10 nonce %q to big.Int", action.Value)
nonce, err := encoding.DecodeBigIntHexOrDecimal(action.Value)
if err != nil {
return newRoot, err
}
newRoot, _, err = s.tree.SetNonce(ctx, address, nonce, newRoot)
if err != nil {
Expand All @@ -879,15 +879,16 @@ func (s *State) SetGenesis(ctx context.Context, block Block, genesis Genesis, db
return newRoot, err
}
case int(merkletree.LeafTypeStorage):
if strings.HasPrefix(action.StoragePosition, "0x") { // nolint
action.StoragePosition = action.StoragePosition[2:]
// Parse position and value
positionBI, err := encoding.DecodeBigIntHexOrDecimal(action.StoragePosition)
if err != nil {
return newRoot, err
}
positionBI := new(big.Int).SetBytes(common.Hex2Bytes(action.StoragePosition))
if strings.HasPrefix(action.Value, "0x") { // nolint
action.StoragePosition = action.Value[2:]
valueBI, err := encoding.DecodeBigIntHexOrDecimal(action.Value)
if err != nil {
return newRoot, err
}
valueBI := new(big.Int).SetBytes(common.Hex2Bytes(action.Value))

// Store
newRoot, _, err = s.tree.SetStorageAt(ctx, address, positionBI, valueBI, newRoot)
if err != nil {
return newRoot, err
Expand Down
Loading

0 comments on commit 9e0e4e8

Please sign in to comment.