Skip to content

Commit

Permalink
Add coments
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaubennassar committed Aug 2, 2024
1 parent f2f2fda commit da78344
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 11 deletions.
3 changes: 3 additions & 0 deletions bridgesync/bridgesync.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type LocalBridgeSync struct {
driver *sync.EVMDriver
}

// NewL1 creates a bridge syncer that synchronizes the mainnet exit tree
func NewL1(
ctx context.Context,
dbPath string,
Expand All @@ -51,6 +52,7 @@ func NewL1(
)
}

// NewL2 creates a bridge syncer that synchronizes the local exit tree
func NewL2(
ctx context.Context,
dbPath string,
Expand Down Expand Up @@ -134,6 +136,7 @@ func new(
}, nil
}

// Start starts the synchronization process
func (s *LocalBridgeSync) Start(ctx context.Context) {
s.driver.Sync(ctx)
}
Expand Down
12 changes: 11 additions & 1 deletion bridgesync/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var (
lastBlokcKey = []byte("lb")
)

// Bridge is the representation of a bridge event
type Bridge struct {
LeafType uint8
OriginNetwork uint32
Expand All @@ -38,6 +39,7 @@ type Bridge struct {
DepositCount uint32
}

// Hash returns the hash of the bridge event as expected by the exit tree
func (b *Bridge) Hash() common.Hash {
origNet := make([]byte, 4) //nolint:gomnd
binary.BigEndian.PutUint32(origNet, uint32(b.OriginNetwork))
Expand Down Expand Up @@ -65,6 +67,7 @@ func (b *Bridge) Hash() common.Hash {
return hash
}

// Claim representation of a claim event
type Claim struct {
GlobalIndex *big.Int
OriginNetwork uint32
Expand All @@ -73,6 +76,7 @@ type Claim struct {
Amount *big.Int
}

// Event combination of bridge and claim events
type Event struct {
Bridge *Bridge
Claim *Claim
Expand Down Expand Up @@ -103,7 +107,7 @@ func newProcessor(ctx context.Context, dbPath, dbPrefix string) (*processor, err
if err != nil {
return nil, err
}
exitTree, err := tree.NewAppendOnly(ctx, db, dbPrefix)
exitTree, err := tree.NewAppendOnlyTree(ctx, db, dbPrefix)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -158,6 +162,8 @@ func (p *processor) GetClaimsAndBridges(
return events, nil
}

// GetLastProcessedBlock returns the last processed block oby the processor, including blocks
// that don't have events
func (p *processor) GetLastProcessedBlock(ctx context.Context) (uint64, error) {
tx, err := p.db.BeginRo(ctx)
if err != nil {
Expand All @@ -177,6 +183,8 @@ func (p *processor) getLastProcessedBlockWithTx(tx kv.Tx) (uint64, error) {
}
}

// Reorg triggers a purge and reset process on the processot to leave it on a state
// as if the last block processed was firstReorgedBlock-1
func (p *processor) Reorg(ctx context.Context, firstReorgedBlock uint64) error {
tx, err := p.db.BeginRw(ctx)
if err != nil {
Expand Down Expand Up @@ -231,6 +239,8 @@ func (p *processor) Reorg(ctx context.Context, firstReorgedBlock uint64) error {
return nil
}

// ProcessBlock procees the events of the block to build the exit tree
// and updates the last processed block (can be called without events for that purpose)
func (p *processor) ProcessBlock(ctx context.Context, block sync.Block) error {
tx, err := p.db.BeginRw(ctx)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions l1infotreesync/l1infotreesync.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ type L1InfoTreeSync struct {
driver *sync.EVMDriver
}

// New creates a L1 Info tree syncer that syncs the L1 info tree
// and the rollup exit tree
func New(
ctx context.Context,
dbPath string,
Expand Down Expand Up @@ -96,22 +98,28 @@ func New(
}, nil
}

// Start starts the synchronization process
func (s *L1InfoTreeSync) Start(ctx context.Context) {
s.driver.Sync(ctx)
}

// GetL1InfoTreeMerkleProof creates a merkle proof for the L1 Info tree
func (s *L1InfoTreeSync) GetL1InfoTreeMerkleProof(ctx context.Context, index uint32) ([]common.Hash, common.Hash, error) {
return s.processor.GetL1InfoTreeMerkleProof(ctx, index)
}

// GetLatestInfoUntilBlock returns the most recent L1InfoTreeLeaf that occurred before or at blockNum.
// If the blockNum has not been processed yet the error ErrBlockNotProcessed will be returned
func (s *L1InfoTreeSync) GetLatestInfoUntilBlock(ctx context.Context, blockNum uint64) (*L1InfoTreeLeaf, error) {
return s.processor.GetLatestInfoUntilBlock(ctx, blockNum)
}

// GetInfoByIndex returns the value of a leave (not the hash) of the L1 info tree
func (s *L1InfoTreeSync) GetInfoByIndex(ctx context.Context, index uint32) (*L1InfoTreeLeaf, error) {
return s.processor.GetInfoByIndex(ctx, index)
}

// GetL1InfoTreeRootByIndex returns the root of the L1 info tree at the moment the leaf with the given index was added
func (s *L1InfoTreeSync) GetL1InfoTreeRootByIndex(ctx context.Context, index uint32) (common.Hash, error) {
tx, err := s.processor.db.BeginRo(ctx)
if err != nil {
Expand All @@ -122,14 +130,17 @@ func (s *L1InfoTreeSync) GetL1InfoTreeRootByIndex(ctx context.Context, index uin
return s.processor.l1InfoTree.GetRootByIndex(tx, index)
}

// GetLastRollupExitRoot return the last rollup exit root processed
func (s *L1InfoTreeSync) GetLastRollupExitRoot(ctx context.Context) (common.Hash, error) {
return s.processor.rollupExitTree.GetLastRoot(ctx)
}

// GetLastL1InfoTreeRootAndIndex return the last root and index processed from the L1 Info tree
func (s *L1InfoTreeSync) GetLastL1InfoTreeRootAndIndex(ctx context.Context) (uint32, common.Hash, error) {
return s.processor.l1InfoTree.GetLastIndexAndRoot(ctx)
}

// GetLastProcessedBlock return the last processed block
func (s *L1InfoTreeSync) GetLastProcessedBlock(ctx context.Context) (uint64, error) {
return s.processor.GetLastProcessedBlock(ctx)
}
18 changes: 14 additions & 4 deletions l1infotreesync/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ type processor struct {
rollupExitTree *tree.UpdatableTree
}

// UpdateL1InfoTree representation of the UpdateL1InfoTree event
type UpdateL1InfoTree struct {
MainnetExitRoot ethCommon.Hash
RollupExitRoot ethCommon.Hash
ParentHash ethCommon.Hash
Timestamp uint64
}

// VerifyBatches representation of the VerifyBatches and VerifyBatchesTrustedAggregator events
type VerifyBatches struct {
RollupID uint32
NumBatch uint64
Expand All @@ -69,6 +71,7 @@ type Event struct {
VerifyBatches *VerifyBatches
}

// L1InfoTreeLeaf representation of a leaf of the L1 Info tree
type L1InfoTreeLeaf struct {
L1InfoTreeIndex uint32
PreviousBlockHash ethCommon.Hash
Expand All @@ -88,6 +91,7 @@ type storeLeaf struct {
Timestamp uint64
}

// Hash as expected by the tree
func (l *storeLeaf) Hash() ethCommon.Hash {
var res [32]byte
t := make([]byte, 8) //nolint:gomnd
Expand All @@ -103,6 +107,7 @@ type blockWithLeafs struct {
LastIndex uint32
}

// GlobalExitRoot returns the GER
func (l *storeLeaf) GlobalExitRoot() ethCommon.Hash {
var gerBytes [32]byte
hasher := sha3.NewLegacyKeccak256()
Expand Down Expand Up @@ -134,19 +139,20 @@ func newProcessor(ctx context.Context, dbPath string) (*processor, error) {
db: db,
}

l1InfoTree, err := tree.NewAppendOnly(ctx, db, dbPrefix+l1InfoTreeSuffix)
l1InfoTree, err := tree.NewAppendOnlyTree(ctx, db, dbPrefix+l1InfoTreeSuffix)
if err != nil {
return nil, err
}
p.l1InfoTree = l1InfoTree
rollupExitTree, err := tree.NewUpdatable(ctx, db, dbPrefix+rollupExitTreeSuffix)
rollupExitTree, err := tree.NewUpdatableTree(ctx, db, dbPrefix+rollupExitTreeSuffix)
if err != nil {
return nil, err
}
p.rollupExitTree = rollupExitTree
return p, nil
}

// GetL1InfoTreeMerkleProof creates a merkle proof for the L1 Info tree
func (p *processor) GetL1InfoTreeMerkleProof(ctx context.Context, index uint32) ([]ethCommon.Hash, ethCommon.Hash, error) {
tx, err := p.db.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -206,6 +212,7 @@ func (p *processor) GetLatestInfoUntilBlock(ctx context.Context, blockNum uint64
return p.getInfoByIndexWithTx(tx, blk.LastIndex-1)
}

// GetInfoByIndex returns the value of a leave (not the hash) of the L1 info tree
func (p *processor) GetInfoByIndex(ctx context.Context, index uint32) (*L1InfoTreeLeaf, error) {
tx, err := p.db.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -238,6 +245,7 @@ func (p *processor) getInfoByIndexWithTx(tx kv.Tx, index uint32) (*L1InfoTreeLea
}, nil
}

// GetLastProcessedBlock returns the last processed block
func (p *processor) GetLastProcessedBlock(ctx context.Context) (uint64, error) {
tx, err := p.db.BeginRo(ctx)
if err != nil {
Expand All @@ -257,6 +265,8 @@ func (p *processor) getLastProcessedBlockWithTx(tx kv.Tx) (uint64, error) {
return common.BytesToUint64(blockNumBytes), nil
}

// Reorg triggers a purge and reset process on the processot to leave it on a state
// as if the last block processed was firstReorgedBlock-1
func (p *processor) Reorg(ctx context.Context, firstReorgedBlock uint64) error {
tx, err := p.db.BeginRw(ctx)
if err != nil {
Expand Down Expand Up @@ -320,8 +330,8 @@ func (p *processor) deleteLeaf(tx kv.RwTx, index uint32) error {
return nil
}

// ProcessBlock process the leafs of the L1 info tree found on a block
// this function can be called without leafs with the intention to track the last processed block
// ProcessBlock procees the events of the block to build the rollup exit tree and the l1 info tree
// and updates the last processed block (can be called without events for that purpose)
func (p *processor) ProcessBlock(ctx context.Context, b sync.Block) error {
tx, err := p.db.BeginRw(ctx)
if err != nil {
Expand Down
11 changes: 9 additions & 2 deletions tree/appendonlytree.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (
"github.com/ledgerwatch/erigon-lib/kv"
)

// AppendOnlyTree is a tree where leaves are added sequentially (by index)
type AppendOnlyTree struct {
*Tree
lastLeftCache []common.Hash
lastIndex int64
}

func NewAppendOnly(ctx context.Context, db kv.RwDB, dbPrefix string) (*AppendOnlyTree, error) {
// NewAppendOnlyTree creates a AppendOnlyTree
func NewAppendOnlyTree(ctx context.Context, db kv.RwDB, dbPrefix string) (*AppendOnlyTree, error) {
t := newTree(db, dbPrefix)
at := &AppendOnlyTree{Tree: t}
if err := at.initLastLeftCacheAndLastDepositCount(ctx); err != nil {
Expand All @@ -24,7 +26,9 @@ func NewAppendOnly(ctx context.Context, db kv.RwDB, dbPrefix string) (*AppendOnl
return at, nil
}

// AddLeaves adds a list leaves into the tree
// AddLeaves adds a list leaves into the tree. The indexes of the leaves must be consecutive,
// starting by the index of the last leave added +1
// It returns a function that must be called to rollback the changes done by this interaction
func (t *AppendOnlyTree) AddLeaves(tx kv.RwTx, leaves []Leaf) (func(), error) {
// Sanity check
if len(leaves) == 0 {
Expand Down Expand Up @@ -95,10 +99,12 @@ func (t *AppendOnlyTree) addLeaf(tx kv.RwTx, leaf Leaf) error {
return nil
}

// GetRootByIndex returns the root of the tree as it was right after adding the leaf with index
func (t *AppendOnlyTree) GetRootByIndex(tx kv.Tx, index uint32) (common.Hash, error) {
return t.getRootByIndex(tx, uint64(index))
}

// GetLastIndexAndRoot returns the last index and root added to the tree
func (t *AppendOnlyTree) GetLastIndexAndRoot(ctx context.Context) (uint32, common.Hash, error) {
tx, err := t.db.BeginRo(ctx)
if err != nil {
Expand Down Expand Up @@ -176,6 +182,7 @@ func (t *AppendOnlyTree) initLastLeftCache(tx kv.Tx, lastIndex int64, lastRoot c

// Reorg deletes all the data relevant from firstReorgedIndex (includded) and onwards
// and prepares the tree tfor being used as it was at firstReorgedIndex-1
// It returns a function that must be called to rollback the changes done by this interaction
func (t *AppendOnlyTree) Reorg(tx kv.RwTx, firstReorgedIndex uint32) (func(), error) {
if t.lastIndex == -1 {
return func() {}, nil
Expand Down
2 changes: 2 additions & 0 deletions tree/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func (n *treeNode) UnmarshalBinary(data []byte) error {
return nil
}

// AddTables add the needed tables for the tree to work in a tableCfg
func AddTables(tableCfg map[string]kv.TableCfgItem, dbPrefix string) {
rootTable := dbPrefix + rootTableSufix
rhtTable := dbPrefix + rhtTableSufix
Expand Down Expand Up @@ -222,6 +223,7 @@ func (t *Tree) storeRoot(tx kv.RwTx, rootIndex uint64, root common.Hash) error {
return tx.Put(t.rootTable, dbCommon.Uint64ToBytes(rootIndex), root[:])
}

// GetLastRoot returns the last processed root
func (t *Tree) GetLastRoot(ctx context.Context) (common.Hash, error) {
tx, err := t.db.BeginRo(ctx)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions tree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestMTAddLeaf(t *testing.T) {
WithTableCfg(tableCfgFunc).
Open()
require.NoError(t, err)
tree, err := NewAppendOnly(context.Background(), db, dbPrefix)
tree, err := NewAppendOnlyTree(context.Background(), db, dbPrefix)
require.NoError(t, err)

// Add exisiting leaves
Expand Down Expand Up @@ -105,7 +105,7 @@ func TestMTGetProof(t *testing.T) {
WithTableCfg(tableCfgFunc).
Open()
require.NoError(t, err)
tree, err := NewAppendOnly(context.Background(), db, dbPrefix)
tree, err := NewAppendOnlyTree(context.Background(), db, dbPrefix)
require.NoError(t, err)

leaves := []Leaf{}
Expand Down
14 changes: 12 additions & 2 deletions tree/updatabletree.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import (
"github.com/ledgerwatch/erigon-lib/kv"
)

// UpdatableTree is a tree that have updatable leaves, and doesn't need to have sequential inserts
type UpdatableTree struct {
*Tree
lastRoot common.Hash
}

func NewUpdatable(ctx context.Context, db kv.RwDB, dbPrefix string) (*UpdatableTree, error) {
// NewUpdatableTree returns an UpdatableTree
func NewUpdatableTree(ctx context.Context, db kv.RwDB, dbPrefix string) (*UpdatableTree, error) {
// TODO: Load last root
t := newTree(db, dbPrefix)
tx, err := t.db.BeginRw(ctx)
Expand All @@ -36,6 +38,10 @@ func NewUpdatable(ctx context.Context, db kv.RwDB, dbPrefix string) (*UpdatableT
return ut, nil
}

// UpseartLeaves inserts or updates a list of leaves. The root index will be used to index the resulting
// root after performing all the operations. Root index must be greater than the last used root index,
// but doesn't need to be sequential. Great for relating block nums and roots :)
// It returns a function that must be called to rollback the changes done by this interaction
func (t *UpdatableTree) UpseartLeaves(tx kv.RwTx, leaves []Leaf, rootIndex uint64) (func(), error) {
if len(leaves) == 0 {
return func() {}, nil
Expand Down Expand Up @@ -90,6 +96,9 @@ func (t *UpdatableTree) upsertLeaf(tx kv.RwTx, leaf Leaf) error {
return nil
}

// Reorg deletes all the data relevant from firstReorgedIndex (includded) and onwards
// and prepares the tree tfor being used as it was at firstReorgedIndex-1.
// It returns a function that must be called to rollback the changes done by this interaction
func (t *UpdatableTree) Reorg(tx kv.RwTx, firstReorgedIndex uint64) (func(), error) {
iter, err := tx.RangeDescend(
t.rootTable,
Expand Down Expand Up @@ -125,6 +134,7 @@ func (t *UpdatableTree) Reorg(tx kv.RwTx, firstReorgedIndex uint64) (func(), err
return rollback, nil
}

func (t *UpdatableTree) GetRootByIndex(tx kv.Tx, rootIndex uint64) (common.Hash, error) {
// GetRootByRootIndex returns the root of the tree as it was right after adding the leaf with index
func (t *UpdatableTree) GetRootByRootIndex(tx kv.Tx, rootIndex uint64) (common.Hash, error) {
return t.getRootByIndex(tx, rootIndex)
}

0 comments on commit da78344

Please sign in to comment.