From db81a2644ffd06aa461fa5a39c61fd46c501f943 Mon Sep 17 00:00:00 2001 From: Arnau Bennassar Date: Wed, 18 Sep 2024 18:22:58 +0200 Subject: [PATCH] feat: add missing methods needed to generate PP certificate (#82) * wip * wip * WIP * decoding direct and indeirecr assets and messages works * connect everything * fix building contract scripts * fix building contract scripts * wip * WIP * tree migrated to SQLite * wip * wip * bridgesync working with sqlite * pass tests * minor cleaning * add GetBlockByLER func * handle err not found * merge develop * use memory for sqlite on the tests * increase timestamp to pass UT * review * finished implementation * replace l1bridge2infosync for rpc logic * ut wip * unit tests for new rpc funcs * add UTs for new methods in the l1infotreesync processor * fix UTs * pass linter * add PR requests * add missing processor calls * fixx linter * feat: add missing methods needed to generate PP certificate * fix linter --- l1infotreesync/l1infotreesync.go | 11 ++++ .../migrations/l1infotreesync0001.sql | 2 +- l1infotreesync/processor.go | 60 +++++++++++-------- l1infotreesync/processor_test.go | 10 +++- 4 files changed, 56 insertions(+), 27 deletions(-) diff --git a/l1infotreesync/l1infotreesync.go b/l1infotreesync/l1infotreesync.go index c414e42b..4c4b796e 100644 --- a/l1infotreesync/l1infotreesync.go +++ b/l1infotreesync/l1infotreesync.go @@ -179,3 +179,14 @@ func (s *L1InfoTreeSync) GetFirstInfo() (*L1InfoTreeLeaf, error) { func (s *L1InfoTreeSync) GetFirstInfoAfterBlock(blockNum uint64) (*L1InfoTreeLeaf, error) { return s.processor.GetFirstInfoAfterBlock(blockNum) } + +func (s *L1InfoTreeSync) GetInfoByGlobalExitRoot(ger common.Hash) (*L1InfoTreeLeaf, error) { + return s.processor.GetInfoByGlobalExitRoot(ger) +} + +// GetL1InfoTreeMerkleProofFromIndexToRoot creates a merkle proof for the L1 Info tree +func (s *L1InfoTreeSync) GetL1InfoTreeMerkleProofFromIndexToRoot( + ctx context.Context, index uint32, root common.Hash, +) (types.Proof, error) { + return s.processor.l1InfoTree.GetProof(ctx, index, root) +} diff --git a/l1infotreesync/migrations/l1infotreesync0001.sql b/l1infotreesync/migrations/l1infotreesync0001.sql index f22408cd..7a689281 100644 --- a/l1infotreesync/migrations/l1infotreesync0001.sql +++ b/l1infotreesync/migrations/l1infotreesync0001.sql @@ -16,7 +16,7 @@ CREATE TABLE l1info_leaf ( timestamp INTEGER NOT NULL, mainnet_exit_root VARCHAR NOT NULL, rollup_exit_root VARCHAR NOT NULL, - global_exit_root VARCHAR NOT NULL, + global_exit_root VARCHAR NOT NULL UNIQUE, hash VARCHAR NOT NULL, PRIMARY KEY (block_num, block_pos) ); diff --git a/l1infotreesync/processor.go b/l1infotreesync/processor.go index 7b762b55..a672c5ef 100644 --- a/l1infotreesync/processor.go +++ b/l1infotreesync/processor.go @@ -13,7 +13,7 @@ import ( "github.com/0xPolygon/cdk/sync" "github.com/0xPolygon/cdk/tree" treeTypes "github.com/0xPolygon/cdk/tree/types" - ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/iden3/go-iden3-crypto/keccak256" "github.com/russross/meddler" "golang.org/x/crypto/sha3" @@ -33,29 +33,29 @@ type processor struct { // UpdateL1InfoTree representation of the UpdateL1InfoTree event type UpdateL1InfoTree struct { BlockPosition uint64 - MainnetExitRoot ethCommon.Hash - RollupExitRoot ethCommon.Hash - ParentHash ethCommon.Hash + MainnetExitRoot common.Hash + RollupExitRoot common.Hash + ParentHash common.Hash Timestamp uint64 } // VerifyBatches representation of the VerifyBatches and VerifyBatchesTrustedAggregator events type VerifyBatches struct { - BlockNumber uint64 `meddler:"block_num"` - BlockPosition uint64 `meddler:"block_pos"` - RollupID uint32 `meddler:"rollup_id"` - NumBatch uint64 `meddler:"batch_num"` - StateRoot ethCommon.Hash `meddler:"state_root,hash"` - ExitRoot ethCommon.Hash `meddler:"exit_root,hash"` - Aggregator ethCommon.Address `meddler:"aggregator,address"` + BlockNumber uint64 `meddler:"block_num"` + BlockPosition uint64 `meddler:"block_pos"` + RollupID uint32 `meddler:"rollup_id"` + NumBatch uint64 `meddler:"batch_num"` + StateRoot common.Hash `meddler:"state_root,hash"` + ExitRoot common.Hash `meddler:"exit_root,hash"` + Aggregator common.Address `meddler:"aggregator,address"` // Not provided by downloader - RollupExitRoot ethCommon.Hash `meddler:"rollup_exit_root,hash"` + RollupExitRoot common.Hash `meddler:"rollup_exit_root,hash"` } type InitL1InfoRootMap struct { LeafCount uint32 - CurrentL1InfoRoot ethCommon.Hash + CurrentL1InfoRoot common.Hash } type Event struct { @@ -66,19 +66,19 @@ type Event struct { // L1InfoTreeLeaf representation of a leaf of the L1 Info tree type L1InfoTreeLeaf struct { - BlockNumber uint64 `meddler:"block_num"` - BlockPosition uint64 `meddler:"block_pos"` - L1InfoTreeIndex uint32 `meddler:"position"` - PreviousBlockHash ethCommon.Hash `meddler:"previous_block_hash,hash"` - Timestamp uint64 `meddler:"timestamp"` - MainnetExitRoot ethCommon.Hash `meddler:"mainnet_exit_root,hash"` - RollupExitRoot ethCommon.Hash `meddler:"rollup_exit_root,hash"` - GlobalExitRoot ethCommon.Hash `meddler:"global_exit_root,hash"` - Hash ethCommon.Hash `meddler:"hash,hash"` + BlockNumber uint64 `meddler:"block_num"` + BlockPosition uint64 `meddler:"block_pos"` + L1InfoTreeIndex uint32 `meddler:"position"` + PreviousBlockHash common.Hash `meddler:"previous_block_hash,hash"` + Timestamp uint64 `meddler:"timestamp"` + MainnetExitRoot common.Hash `meddler:"mainnet_exit_root,hash"` + RollupExitRoot common.Hash `meddler:"rollup_exit_root,hash"` + GlobalExitRoot common.Hash `meddler:"global_exit_root,hash"` + Hash common.Hash `meddler:"hash,hash"` } // Hash as expected by the tree -func (l *L1InfoTreeLeaf) hash() ethCommon.Hash { +func (l *L1InfoTreeLeaf) hash() common.Hash { var res [treeTypes.DefaultHeight]byte t := make([]byte, 8) //nolint:mnd binary.BigEndian.PutUint64(t, l.Timestamp) @@ -87,7 +87,7 @@ func (l *L1InfoTreeLeaf) hash() ethCommon.Hash { } // GlobalExitRoot returns the GER -func (l *L1InfoTreeLeaf) globalExitRoot() ethCommon.Hash { +func (l *L1InfoTreeLeaf) globalExitRoot() common.Hash { var gerBytes [treeTypes.DefaultHeight]byte hasher := sha3.NewLegacyKeccak256() hasher.Write(l.MainnetExitRoot[:]) @@ -362,7 +362,7 @@ func (p *processor) GetFirstVerifiedBatchesAfterBlock(rollupID uint32, blockNum return verified, db.ReturnErrNotFound(err) } -func (p *processor) GetFirstL1InfoWithRollupExitRoot(rollupExitRoot ethCommon.Hash) (*L1InfoTreeLeaf, error) { +func (p *processor) GetFirstL1InfoWithRollupExitRoot(rollupExitRoot common.Hash) (*L1InfoTreeLeaf, error) { info := &L1InfoTreeLeaf{} err := meddler.QueryRow(p.db, info, ` SELECT * FROM l1info_leaf @@ -403,3 +403,13 @@ func (p *processor) GetFirstInfoAfterBlock(blockNum uint64) (*L1InfoTreeLeaf, er `, blockNum) return info, db.ReturnErrNotFound(err) } + +func (p *processor) GetInfoByGlobalExitRoot(ger common.Hash) (*L1InfoTreeLeaf, error) { + info := &L1InfoTreeLeaf{} + err := meddler.QueryRow(p.db, info, ` + SELECT * FROM l1info_leaf + WHERE global_exit_root = $1 + LIMIT 1; + `, ger.Hex()) + return info, db.ReturnErrNotFound(err) +} diff --git a/l1infotreesync/processor_test.go b/l1infotreesync/processor_test.go index 5853e90e..3da02998 100644 --- a/l1infotreesync/processor_test.go +++ b/l1infotreesync/processor_test.go @@ -91,6 +91,8 @@ func TestGetInfo(t *testing.T) { require.Equal(t, db.ErrNotFound, err) _, err = p.GetFirstInfoAfterBlock(0) require.Equal(t, db.ErrNotFound, err) + _, err = p.GetInfoByGlobalExitRoot(common.Hash{}) + require.Equal(t, db.ErrNotFound, err) // First insert info1 := &UpdateL1InfoTree{ @@ -128,10 +130,13 @@ func TestGetInfo(t *testing.T) { actual, err = p.GetFirstInfoAfterBlock(0) require.NoError(t, err) require.Equal(t, expected1, *actual) + actual, err = p.GetInfoByGlobalExitRoot(expected1.GlobalExitRoot) + require.NoError(t, err) + require.Equal(t, expected1, *actual) // Second insert info2 := &UpdateL1InfoTree{ - MainnetExitRoot: common.HexToHash("beef"), + MainnetExitRoot: common.HexToHash("b055"), RollupExitRoot: common.HexToHash("5ca1e"), ParentHash: common.HexToHash("1010101"), Timestamp: 420, @@ -165,4 +170,7 @@ func TestGetInfo(t *testing.T) { actual, err = p.GetFirstInfoAfterBlock(2) require.NoError(t, err) require.Equal(t, expected2, *actual) + actual, err = p.GetInfoByGlobalExitRoot(expected2.GlobalExitRoot) + require.NoError(t, err) + require.Equal(t, expected2, *actual) }