Skip to content

Commit

Permalink
Feature/lastgersync (#33)
Browse files Browse the repository at this point in the history
* wip

* wip

* implementation done

* separated setup logic from aggoracle e2e

* pass e2e

* Fix sync UTs

* Feature/claim sponsor (#35)

* implementation done, missing finish e2e test

* pass E2E
  • Loading branch information
arnaubennassar authored Aug 13, 2024
1 parent 27aa35c commit bd0036f
Show file tree
Hide file tree
Showing 27 changed files with 1,772 additions and 277 deletions.
179 changes: 3 additions & 176 deletions aggoracle/e2e_test.go
Original file line number Diff line number Diff line change
@@ -1,196 +1,23 @@
package aggoracle_test

import (
"context"
"errors"
"fmt"
"math/big"
"strconv"
"testing"
"time"

gerContractL1 "github.com/0xPolygon/cdk-contracts-tooling/contracts/manual/globalexitrootnopush0"
gerContractEVMChain "github.com/0xPolygon/cdk-contracts-tooling/contracts/manual/pessimisticglobalexitrootnopush0"
"github.com/0xPolygon/cdk/aggoracle"
"github.com/0xPolygon/cdk/aggoracle/chaingersender"
"github.com/0xPolygon/cdk/etherman"
"github.com/0xPolygon/cdk/l1infotreesync"
"github.com/0xPolygon/cdk/log"
"github.com/0xPolygon/cdk/reorgdetector"
ethtxmanager "github.com/0xPolygonHermez/zkevm-ethtx-manager/ethtxmanager"
"github.com/ethereum/go-ethereum"
"github.com/0xPolygon/cdk/test/helpers"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient/simulated"
mock "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
)

func TestEVM(t *testing.T) {
ctx := context.Background()
l1Client, syncer, gerL1Contract, authL1 := commonSetup(t)
sender := evmSetup(t)
oracle, err := aggoracle.New(sender, l1Client.Client(), syncer, etherman.LatestBlock, time.Millisecond)
require.NoError(t, err)
go oracle.Start(ctx)

runTest(t, gerL1Contract, sender, l1Client, authL1)
}

func commonSetup(t *testing.T) (
*simulated.Backend,
*l1infotreesync.L1InfoTreeSync,
*gerContractL1.Globalexitrootnopush0,
*bind.TransactOpts,
) {
// Config and spin up
ctx := context.Background()
// Simulated L1
privateKeyL1, err := crypto.GenerateKey()
require.NoError(t, err)
authL1, err := bind.NewKeyedTransactorWithChainID(privateKeyL1, big.NewInt(1337))
require.NoError(t, err)
l1Client, gerL1Addr, gerL1Contract, err := newSimulatedL1(authL1)
require.NoError(t, err)
// Reorg detector
dbPathReorgDetector := t.TempDir()
reorg, err := reorgdetector.New(ctx, l1Client.Client(), dbPathReorgDetector)
require.NoError(t, err)
// Syncer
dbPathSyncer := t.TempDir()
syncer, err := l1infotreesync.New(ctx, dbPathSyncer, gerL1Addr, common.Address{}, 10, etherman.LatestBlock, reorg, l1Client.Client(), time.Millisecond, 0, 100*time.Millisecond, 3)
require.NoError(t, err)
go syncer.Start(ctx)

return l1Client, syncer, gerL1Contract, authL1
}

func evmSetup(t *testing.T) aggoracle.ChainSender {
privateKeyL2, err := crypto.GenerateKey()
require.NoError(t, err)
authL2, err := bind.NewKeyedTransactorWithChainID(privateKeyL2, big.NewInt(1337))
require.NoError(t, err)
l2Client, gerL2Addr, _, err := newSimulatedEVMAggSovereignChain(authL2)
require.NoError(t, err)
ethTxManMock := aggoracle.NewEthTxManagerMock(t)
// id, err := c.ethTxMan.Add(ctx, &c.gerAddr, nil, big.NewInt(0), tx.Data(), c.gasOffset, nil)
ethTxManMock.On("Add", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Run(func(args mock.Arguments) {
ctx := context.Background()
nonce, err := l2Client.Client().PendingNonceAt(ctx, authL2.From)
if err != nil {
log.Error(err)
return
}
gas, err := l2Client.Client().EstimateGas(ctx, ethereum.CallMsg{
From: authL2.From,
To: args.Get(1).(*common.Address),
Value: big.NewInt(0),
Data: args.Get(4).([]byte),
})
if err != nil {
log.Error(err)
res, err := l2Client.Client().CallContract(ctx, ethereum.CallMsg{
From: authL2.From,
To: args.Get(1).(*common.Address),
Value: big.NewInt(0),
Data: args.Get(4).([]byte),
}, nil)
log.Debugf("contract call: %s", res)
if err != nil {
log.Error(err)
}
return
}
price, err := l2Client.Client().SuggestGasPrice(ctx)
if err != nil {
log.Error(err)
}
tx := types.NewTx(&types.LegacyTx{
To: args.Get(1).(*common.Address),
Nonce: nonce,
Value: big.NewInt(0),
Data: args.Get(4).([]byte),
Gas: gas,
GasPrice: price,
})
tx.Gas()
signedTx, err := authL2.Signer(authL2.From, tx)
if err != nil {
log.Error(err)
return
}
err = l2Client.Client().SendTransaction(ctx, signedTx)
if err != nil {
log.Error(err)
return
}
l2Client.Commit()
}).
Return(common.Hash{}, nil)
// res, err := c.ethTxMan.Result(ctx, id)
ethTxManMock.On("Result", mock.Anything, mock.Anything).
Return(ethtxmanager.MonitoredTxResult{Status: ethtxmanager.MonitoredTxStatusMined}, nil)
sender, err := chaingersender.NewEVMChainGERSender(gerL2Addr, authL2.From, l2Client.Client(), ethTxManMock, 0, time.Millisecond*50)
require.NoError(t, err)

return sender
}

func newSimulatedL1(auth *bind.TransactOpts) (
client *simulated.Backend,
gerAddr common.Address,
gerContract *gerContractL1.Globalexitrootnopush0,
err error,
) {
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
address := auth.From
genesisAlloc := map[common.Address]types.Account{
address: {
Balance: balance,
},
}
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))

gerAddr, _, gerContract, err = gerContractL1.DeployGlobalexitrootnopush0(auth, client.Client(), auth.From, auth.From)

client.Commit()
return
}

func newSimulatedEVMAggSovereignChain(auth *bind.TransactOpts) (
client *simulated.Backend,
gerAddr common.Address,
gerContract *gerContractEVMChain.Pessimisticglobalexitrootnopush0,
err error,
) {
balance, _ := new(big.Int).SetString("10000000000000000000000000", 10) //nolint:gomnd
address := auth.From
genesisAlloc := map[common.Address]types.Account{
address: {
Balance: balance,
},
}
blockGasLimit := uint64(999999999999999999) //nolint:gomnd
client = simulated.NewBackend(genesisAlloc, simulated.WithBlockGasLimit(blockGasLimit))

gerAddr, _, gerContract, err = gerContractEVMChain.DeployPessimisticglobalexitrootnopush0(auth, client.Client(), auth.From)
if err != nil {
return
}
client.Commit()

_GLOBAL_EXIT_ROOT_SETTER_ROLE := common.HexToHash("0x7b95520991dfda409891be0afa2635b63540f92ee996fda0bf695a166e5c5176")
_, err = gerContract.GrantRole(auth, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From)
client.Commit()
hasRole, _ := gerContract.HasRole(&bind.CallOpts{Pending: false}, _GLOBAL_EXIT_ROOT_SETTER_ROLE, auth.From)
if !hasRole {
err = errors.New("failed to set role")
}
return
env := helpers.SetupAggoracleWithEVMChain(t)
runTest(t, env.GERL1Contract, env.AggOracleSender, env.L1Client, env.AuthL1)
}

func runTest(
Expand Down
9 changes: 9 additions & 0 deletions bridgesync/bridgesync.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func NewL1(
rd sync.ReorgDetector,
ethClient EthClienter,
initialBlock uint64,
waitForNewBlocksPeriod time.Duration,
) (*BridgeSync, error) {
return new(
ctx,
Expand All @@ -49,6 +50,7 @@ func NewL1(
initialBlock,
dbPrefixL1,
reorgDetectorIDL1,
waitForNewBlocksPeriod,
)
}

Expand All @@ -62,6 +64,7 @@ func NewL2(
rd sync.ReorgDetector,
ethClient EthClienter,
initialBlock uint64,
waitForNewBlocksPeriod time.Duration,
) (*BridgeSync, error) {
return new(
ctx,
Expand All @@ -74,6 +77,7 @@ func NewL2(
initialBlock,
dbPrefixL1,
reorgDetectorIDL1,
waitForNewBlocksPeriod,
)
}

Expand All @@ -87,6 +91,7 @@ func new(
ethClient EthClienter,
initialBlock uint64,
dbPrefix, reorgDetectorID string,
waitForNewBlocksPeriod time.Duration,
) (*BridgeSync, error) {
processor, err := newProcessor(ctx, dbPath, dbPrefix)
if err != nil {
Expand Down Expand Up @@ -152,3 +157,7 @@ func (s *BridgeSync) GetBridgeIndexByRoot(ctx context.Context, root common.Hash)
func (s *BridgeSync) GetClaimsAndBridges(ctx context.Context, fromBlock, toBlock uint64) ([]Event, error) {
return s.processor.GetClaimsAndBridges(ctx, fromBlock, toBlock)
}

func (s *BridgeSync) GetProof(ctx context.Context, depositCount uint32, localExitRoot common.Hash) ([32]common.Hash, error) {
return s.processor.exitTree.GetProof(ctx, depositCount, localExitRoot)
}
5 changes: 0 additions & 5 deletions bridgesync/downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package bridgesync
import (
"fmt"
"math/big"
"time"

"github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridge"
"github.com/0xPolygon/cdk-contracts-tooling/contracts/etrog/polygonzkevmbridgev2"
Expand All @@ -15,10 +14,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

const (
waitForNewBlocksPeriod = time.Millisecond * 100
)

var (
bridgeEventSignature = crypto.Keccak256Hash([]byte("BridgeEvent(uint8,uint32,address,uint32,address,uint256,bytes,uint32)"))
claimEventSignature = crypto.Keccak256Hash([]byte("ClaimEvent(uint256,uint32,address,address,uint256)"))
Expand Down
2 changes: 1 addition & 1 deletion bridgesync/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestBridgeEventE2E(t *testing.T) {
rd, err := reorgdetector.New(ctx, client.Client(), dbPathReorg)
go rd.Start(ctx)

syncer, err := bridgesync.NewL1(ctx, dbPathSyncer, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0)
syncer, err := bridgesync.NewL1(ctx, dbPathSyncer, bridgeAddr, 10, etherman.LatestBlock, rd, client.Client(), 0, time.Millisecond*10)
require.NoError(t, err)
go syncer.Start(ctx)

Expand Down
18 changes: 18 additions & 0 deletions bridgesync/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,21 @@ func (p *processor) updateLastProcessedBlock(tx kv.RwTx, blockNum uint64) error
blockNumBytes := dbCommon.Uint64ToBytes(blockNum)
return tx.Put(p.lastBlockTable, lastBlokcKey, blockNumBytes)
}

func GenerateGlobalIndex(mainnetFlag bool, rollupIndex uint, localExitRootIndex uint32) *big.Int {
var (
globalIndexBytes []byte
buf [4]byte
)
if mainnetFlag {
globalIndexBytes = append(globalIndexBytes, big.NewInt(1).Bytes()...)
ri := big.NewInt(0).FillBytes(buf[:])
globalIndexBytes = append(globalIndexBytes, ri...)
} else {
ri := big.NewInt(0).SetUint64(uint64(rollupIndex)).FillBytes(buf[:])
globalIndexBytes = append(globalIndexBytes, ri...)
}
leri := big.NewInt(0).SetUint64(uint64(localExitRootIndex)).FillBytes(buf[:])
globalIndexBytes = append(globalIndexBytes, leri...)
return big.NewInt(0).SetBytes(globalIndexBytes)
}
Loading

0 comments on commit bd0036f

Please sign in to comment.