forked from 0xPolygonHermez/zkevm-node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fork-etrog: synchronizer: update L1InfoTree (0xPolygonHermez#2818)
* update LxLy changes --------- Co-authored-by: Alonso Rodriguez <[email protected]>
- Loading branch information
1 parent
511b41f
commit f755f8f
Showing
31 changed files
with
764 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
-- +migrate Up | ||
ALTER TABLE state.exit_root | ||
ADD COLUMN prev_block_hash BYTEA DEFAULT NULL, | ||
ADD COLUMN l1_info_root BYTEA DEFAULT NULL, | ||
ADD COLUMN l1_info_tree_index BIGINT DEFAULT NULL UNIQUE; | ||
CREATE INDEX IF NOT EXISTS exit_root_l1_info_tree_index ON state.exit_root (l1_info_tree_index); | ||
|
||
-- +migrate Down | ||
ALTER TABLE state.exit_root | ||
DROP COLUMN prev_block_hash, | ||
DROP COLUMN l1_info_root, | ||
DROP COLUMN l1_info_tree_index; | ||
DROP INDEX IF EXISTS state.exit_root_l1_info_tree_index; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package migrations_test | ||
|
||
import ( | ||
"database/sql" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
blockHashValue = "0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1" | ||
mainExitRootValue = "0x83fc198de31e1b2b1a8212d2430fbb7766c13d9ad305637dea3759065606475d" | ||
rollupExitRootValue = "0xadb91a6a1fce56eaea561002bc9a993f4e65a7710bd72f4eee3067cbd73a743c" | ||
globalExitRootValue = "0x5bf4af1a651a2a74b36e6eb208481f94c69fc959f756223dfa49608061937585" | ||
previousBlockHashValue = "0xe865e912b504572a4d80ad018e29797e3c11f00bf9ae2549548a25779c9d7e57" | ||
l1InfoRootValue = "0x2b9484b83c6398033241865b015fb9430eb3e159182a6075d00c924845cc393e" | ||
) | ||
|
||
// this migration changes length of the token name | ||
type migrationTest0013 struct{} | ||
|
||
func (m migrationTest0013) insertBlock(blockNumber uint64, db *sql.DB) error { | ||
const addBlock = "INSERT INTO state.block (block_num, received_at, block_hash) VALUES ($1, $2, $3)" | ||
if _, err := db.Exec(addBlock, blockNumber, time.Now(), blockHashValue); err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (m migrationTest0013) insertRowInOldTable(db *sql.DB, args []interface{}) error { | ||
insert := ` | ||
INSERT INTO state.exit_root (block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root) | ||
VALUES ($1, $2, $3, $4, $5 );` | ||
|
||
_, err := db.Exec(insert, args...) | ||
return err | ||
} | ||
|
||
func (m migrationTest0013) InsertData(db *sql.DB) error { | ||
var err error | ||
if err = m.insertBlock(uint64(123), db); err != nil { | ||
return err | ||
} | ||
if err = m.insertBlock(uint64(124), db); err != nil { | ||
return err | ||
} | ||
if err = m.insertRowInOldTable(db, []interface{}{123, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue}); err != nil { | ||
return err | ||
} | ||
if err = m.insertRowInOldTable(db, []interface{}{124, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue}); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
func (m migrationTest0013) insertRowInMigratedTable(db *sql.DB, args []interface{}) error { | ||
insert := ` | ||
INSERT INTO state.exit_root (block_num, timestamp, mainnet_exit_root, rollup_exit_root, global_exit_root, prev_block_hash, l1_info_root, l1_info_tree_index) | ||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8);` | ||
|
||
_, err := db.Exec(insert, args...) | ||
return err | ||
} | ||
|
||
func (m migrationTest0013) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) { | ||
err := m.insertBlock(uint64(125), db) | ||
assert.NoError(t, err) | ||
err = m.insertBlock(uint64(126), db) | ||
assert.NoError(t, err) | ||
err = m.insertBlock(uint64(127), db) | ||
assert.NoError(t, err) | ||
prevBlockHash := previousBlockHashValue | ||
l1InfoRoot := l1InfoRootValue | ||
err = m.insertRowInMigratedTable(db, []interface{}{125, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue, prevBlockHash, l1InfoRoot, 1}) | ||
assert.NoError(t, err) | ||
// insert duplicated l1_info_root | ||
err = m.insertRowInMigratedTable(db, []interface{}{126, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue, prevBlockHash, l1InfoRoot, 1}) | ||
assert.Error(t, err) | ||
|
||
// insert in the old way must work | ||
err = m.insertRowInOldTable(db, []interface{}{127, time.Now(), mainExitRootValue, rollupExitRootValue, globalExitRootValue}) | ||
assert.NoError(t, err) | ||
|
||
sqlSelect := `SELECT prev_block_hash, l1_info_root FROM state.exit_root WHERE l1_info_tree_index = $1` | ||
currentPrevBlockHash := "" | ||
currentL1InfoRoot := "" | ||
err = db.QueryRow(sqlSelect, 1).Scan(¤tPrevBlockHash, ¤tL1InfoRoot) | ||
assert.NoError(t, err) | ||
assert.Equal(t, prevBlockHash, currentPrevBlockHash) | ||
assert.Equal(t, l1InfoRoot, currentL1InfoRoot) | ||
} | ||
|
||
func (m migrationTest0013) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) { | ||
sqlSelect := `SELECT count(id) FROM state.exit_root` | ||
count := 0 | ||
err := db.QueryRow(sqlSelect).Scan(&count) | ||
assert.NoError(t, err) | ||
assert.Equal(t, 4, count) | ||
} | ||
|
||
func TestMigration0013(t *testing.T) { | ||
runMigrationTest(t, 13, migrationTest0013{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package state | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/0xPolygonHermez/zkevm-node/l1infotree" | ||
"github.com/0xPolygonHermez/zkevm-node/log" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/jackc/pgx/v4" | ||
) | ||
|
||
// L1InfoTreeLeaf leaf of the L1InfoTree | ||
type L1InfoTreeLeaf struct { | ||
GlobalExitRoot | ||
PreviousBlockHash common.Hash | ||
} | ||
|
||
// L1InfoTreeExitRootStorageEntry entry of the Database | ||
type L1InfoTreeExitRootStorageEntry struct { | ||
L1InfoTreeLeaf | ||
L1InfoTreeRoot common.Hash | ||
L1InfoTreeIndex uint64 | ||
} | ||
|
||
var ( | ||
// TODO: Put the real hash of Leaf 0, pending of deploying contracts | ||
leaf0Hash = [32]byte{} //nolint:gomnd | ||
) | ||
|
||
// Hash returns the hash of the leaf | ||
func (l *L1InfoTreeLeaf) Hash() common.Hash { | ||
timestamp := uint64(l.Timestamp.Unix()) | ||
return l1infotree.HashLeafData(l.GlobalExitRoot.GlobalExitRoot, l.PreviousBlockHash, timestamp) | ||
} | ||
|
||
// AddL1InfoTreeLeaf adds a new leaf to the L1InfoTree and returns the entry and error | ||
func (s *State) AddL1InfoTreeLeaf(ctx context.Context, L1InfoTreeLeaf *L1InfoTreeLeaf, dbTx pgx.Tx) (*L1InfoTreeExitRootStorageEntry, error) { | ||
allLeaves, err := s.GetAllL1InfoRootEntries(ctx, dbTx) | ||
if err != nil { | ||
log.Error("error getting all leaves. Error: ", err) | ||
return nil, err | ||
} | ||
root, err := buildL1InfoTree(allLeaves) | ||
if err != nil { | ||
log.Error("error building L1InfoTree. Error: ", err) | ||
return nil, err | ||
} | ||
entry := L1InfoTreeExitRootStorageEntry{ | ||
L1InfoTreeLeaf: *L1InfoTreeLeaf, | ||
L1InfoTreeRoot: root, | ||
} | ||
index, err := s.AddL1InfoRootToExitRoot(ctx, &entry, dbTx) | ||
if err != nil { | ||
log.Error("error adding L1InfoRoot to ExitRoot. Error: ", err) | ||
return nil, err | ||
} | ||
entry.L1InfoTreeIndex = index | ||
return &entry, nil | ||
} | ||
|
||
func buildL1InfoTree(allLeaves []L1InfoTreeExitRootStorageEntry) (common.Hash, error) { | ||
mt := l1infotree.NewL1InfoTree(uint8(32)) //nolint:gomnd | ||
var leaves [][32]byte | ||
// Insert the Leaf0 that is not used but compute for the Merkle Tree | ||
leaves = append(leaves, leaf0Hash) | ||
for _, leaf := range allLeaves { | ||
leaves = append(leaves, leaf.Hash()) | ||
} | ||
root, err := mt.BuildL1InfoRoot(leaves) | ||
return root, err | ||
} |
Oops, something went wrong.