Skip to content

Commit

Permalink
Merge pull request #50 from 0xPolygon/feature/etrog
Browse files Browse the repository at this point in the history
Feature/etrog
  • Loading branch information
christophercampbell authored Jan 30, 2024
2 parents 845d86b + 509c645 commit f2ae2dd
Show file tree
Hide file tree
Showing 55 changed files with 6,413 additions and 8,784 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
dist

.idea

test/gethData
test/coverage.out
8 changes: 4 additions & 4 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func start(cliCtx *cli.Context) error {
}

// Load EtherMan
etherman, err := etherman.New(c.L1)
etm, err := etherman.New(c.L1)
if err != nil {
log.Fatal(err)
}
Expand All @@ -92,14 +92,14 @@ func start(cliCtx *cli.Context) error {
selfAddr := crypto.PubkeyToAddress(pk.PublicKey)

// ensure synchro/reorg start block is set
err = synchronizer.InitStartBlock(storage, &types.EthClientFactoryImpl{}, c.L1)
err = synchronizer.InitStartBlock(storage, types.NewEthClientFactory(), c.L1)
if err != nil {
log.Fatal(err)
}

var cancelFuncs []context.CancelFunc

sequencerTracker, err := sequencer.NewTracker(c.L1, etherman)
sequencerTracker, err := sequencer.NewTracker(c.L1, etm)
if err != nil {
log.Fatal(err)
}
Expand All @@ -119,7 +119,7 @@ func start(cliCtx *cli.Context) error {
cancelFuncs = append(cancelFuncs, detector.Stop)

batchSynchronizer, err := synchronizer.NewBatchSynchronizer(c.L1, selfAddr,
storage, detector.Subscribe(), etherman, sequencerTracker, client.NewFactory())
storage, detector.Subscribe(), etm, sequencerTracker, client.NewFactory())
if err != nil {
log.Fatal(err)
}
Expand Down
34 changes: 15 additions & 19 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ type Config struct {

// L1Config is a struct that defines L1 contract and service settings
type L1Config struct {
WsURL string `mapstructure:"WsURL"`
RpcURL string `mapstructure:"RpcURL"`
CDKValidiumAddress string `mapstructure:"CDKValidiumAddress"`
DataCommitteeAddress string `mapstructure:"DataCommitteeAddress"`
Timeout types.Duration `mapstructure:"Timeout"`
RetryPeriod types.Duration `mapstructure:"RetryPeriod"`
BlockBatchSize uint `mapstructure:"BlockBatchSize"`
WsURL string `mapstructure:"WsURL"`
RpcURL string `mapstructure:"RpcURL"`
PolygonValidiumAddress string `mapstructure:"PolygonValidiumAddress"`
DataCommitteeAddress string `mapstructure:"DataCommitteeAddress"`
Timeout types.Duration `mapstructure:"Timeout"`
RetryPeriod types.Duration `mapstructure:"RetryPeriod"`
BlockBatchSize uint `mapstructure:"BlockBatchSize"`
}

// Load loads the configuration baseed on the cli context
Expand All @@ -47,6 +47,12 @@ func Load(ctx *cli.Context) (*Config, error) {
if err != nil {
return nil, err
}

viper.AutomaticEnv()
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
viper.SetEnvPrefix("DATA_NODE")

configFilePath := ctx.String(FlagCfg)
if configFilePath != "" {
dirName, fileName := filepath.Split(configFilePath)
Expand All @@ -57,18 +63,8 @@ func Load(ctx *cli.Context) (*Config, error) {
viper.AddConfigPath(dirName)
viper.SetConfigName(fileNameWithoutExtension)
viper.SetConfigType(fileExtension)
}
viper.AutomaticEnv()
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
viper.SetEnvPrefix("DATA_NODE")
err = viper.ReadInConfig()
if err != nil {
_, ok := err.(viper.ConfigFileNotFoundError)
if ok {
log.Infof("config file not found")
} else {
log.Infof("error reading config file: ", err)
err = viper.ReadInConfig()
if err != nil {
return nil, err
}
}
Expand Down
33 changes: 31 additions & 2 deletions config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package config

import (
"flag"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
Expand All @@ -25,8 +28,8 @@ func Test_Defaults(t *testing.T) {
expectedValue: "http://127.0.0.1:8545",
},
{
path: "L1.CDKValidiumAddress",
expectedValue: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
path: "L1.PolygonValidiumAddress",
expectedValue: "0x8dAF17A20c9DBA35f005b6324F493785D239719d",
},
{
path: "L1.Timeout",
Expand Down Expand Up @@ -56,6 +59,32 @@ func Test_Defaults(t *testing.T) {
}
}

func Test_ConfigFileNotFound(t *testing.T) {
flags := flag.FlagSet{}
flags.String("cfg", "/fictitious-file/foo.cfg", "")

ctx := cli.NewContext(cli.NewApp(), &flags, nil)
_, err := Load(ctx)
require.Error(t, err)
}

func Test_ConfigFileOverride(t *testing.T) {
tempDir := t.TempDir()
overrides := filepath.Join(tempDir, "overrides.toml")
f, err := os.Create(overrides)
require.NoError(t, err)
_, err = f.WriteString("[L1]\n")
require.NoError(t, err)
_, err = f.WriteString("PolygonValidiumAddress = \"0xDEADBEEF\"")
require.NoError(t, err)
flags := flag.FlagSet{}
flags.String("cfg", overrides, "")
ctx := cli.NewContext(cli.NewApp(), &flags, nil)
cfg, err := Load(ctx)
require.NoError(t, err)
require.Equal(t, "0xDEADBEEF", cfg.L1.PolygonValidiumAddress)
}

func getValueFromStruct(path string, object interface{}) interface{} {
keySlice := strings.Split(path, ".")
v := reflect.ValueOf(object)
Expand Down
4 changes: 2 additions & 2 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ PrivateKey = {Path = "/pk/test-member.keystore", Password = "testonly"}
[L1]
WsURL = "ws://127.0.0.1:8546"
RpcURL = "http://127.0.0.1:8545"
CDKValidiumAddress = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82"
DataCommitteeAddress = "0x0"
PolygonValidiumAddress = "0x8dAF17A20c9DBA35f005b6324F493785D239719d"
DataCommitteeAddress = "0x68B1D87F95878fE05B998F19b66F4baba5De1aed"
Timeout = "1m"
RetryPeriod = "5s"
BlockBatchSize = "64"
Expand Down
13 changes: 13 additions & 0 deletions config/default_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package config

import (
"testing"

"github.com/stretchr/testify/require"
)

func Test_DefaultsConstructor(t *testing.T) {
dflt, err := Default()
require.NoError(t, err)
require.Equal(t, "committee_user", dflt.DB.User)
}
4 changes: 2 additions & 2 deletions docs/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ PrivateKey = {Path = "/pk/test-member.keystore", Password = "testonly"} # CHANGE
[L1]
WsURL = "ws://URLofYourL1Node:8546" # CHANGE THIS: use the URL of your L1 node
RpcURL = "http://URLofYourL1Node:8545" # CHANGE THIS: use the URL of your L1 node
CDKValidiumAddress = "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82" # CHANGE THIS: Address of the Validium smart contract
DataCommitteeAddress = "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6" # CHANGE THIS: Address of the data availability committee smart contract
PolygonValidiumAddress = "0x8dAF17A20c9DBA35f005b6324F493785D239719d" # CHANGE THIS: Address of the Validium smart contract
DataCommitteeAddress = "0x68B1D87F95878fE05B998F19b66F4baba5De1aed" # CHANGE THIS: Address of the data availability committee smart contract
Timeout = "3m"
RetryPeriod = "5s"
BlockBatchSize = 32
Expand Down
84 changes: 44 additions & 40 deletions etherman/etherman.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"math/big"

"github.com/0xPolygon/cdk-data-availability/config"
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/cdkdatacommittee"
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/cdkvalidium"
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/polygondatacommittee"
"github.com/0xPolygon/cdk-data-availability/etherman/smartcontracts/polygonvalidium"
"github.com/0xPolygon/cdk-data-availability/log"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -16,6 +16,19 @@ import (
"github.com/ethereum/go-ethereum/event"
)

// DataCommitteeMember represents a member of the Data Committee
type DataCommitteeMember struct {
Addr common.Address
URL string
}

// DataCommittee represents a specific committee
type DataCommittee struct {
AddressesHash common.Hash
Members []DataCommitteeMember
RequiredSignatures uint64
}

// Etherman defines functions that should be implemented by Etherman
type Etherman interface {
GetCurrentDataCommittee() (*DataCommittee, error)
Expand All @@ -24,31 +37,29 @@ type Etherman interface {
TrustedSequencer() (common.Address, error)
WatchSetTrustedSequencer(
ctx context.Context,
events chan *cdkvalidium.CdkvalidiumSetTrustedSequencer,
events chan *polygonvalidium.PolygonvalidiumSetTrustedSequencer,
) (event.Subscription, error)
TrustedSequencerURL() (string, error)
WatchSetTrustedSequencerURL(
ctx context.Context,
events chan *cdkvalidium.CdkvalidiumSetTrustedSequencerURL,
events chan *polygonvalidium.PolygonvalidiumSetTrustedSequencerURL,
) (event.Subscription, error)
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
FilterSequenceBatches(
opts *bind.FilterOpts,
numBatch []uint64,
) (*cdkvalidium.CdkvalidiumSequenceBatchesIterator, error)
) (*polygonvalidium.PolygonvalidiumSequenceBatchesIterator, error)
}

var _ Etherman = (*EthermanImpl)(nil)

// EthermanImpl is the implementation of EtherMan.
type EthermanImpl struct {
// etherman is the implementation of EtherMan.
type etherman struct {
EthClient *ethclient.Client
CDKValidium *cdkvalidium.Cdkvalidium
DataCommittee *cdkdatacommittee.Cdkdatacommittee
CDKValidium *polygonvalidium.Polygonvalidium
DataCommittee *polygondatacommittee.Polygondatacommittee
}

// New creates a new etherman
func New(cfg config.L1Config) (*EthermanImpl, error) {
func New(cfg config.L1Config) (Etherman, error) {
ctx, cancel := context.WithTimeout(context.Background(), cfg.Timeout.Duration)
defer cancel()

Expand All @@ -58,89 +69,78 @@ func New(cfg config.L1Config) (*EthermanImpl, error) {
return nil, err
}

cdkValidium, err := cdkvalidium.NewCdkvalidium(common.HexToAddress(cfg.CDKValidiumAddress), ethClient)
cdkValidium, err := polygonvalidium.NewPolygonvalidium(common.HexToAddress(cfg.PolygonValidiumAddress), ethClient)
if err != nil {
return nil, err
}

dataCommittee, err :=
cdkdatacommittee.NewCdkdatacommittee(common.HexToAddress(cfg.DataCommitteeAddress), ethClient)
polygondatacommittee.NewPolygondatacommittee(common.HexToAddress(cfg.DataCommitteeAddress), ethClient)
if err != nil {
return nil, err
}

return &EthermanImpl{
return &etherman{
EthClient: ethClient,
CDKValidium: cdkValidium,
DataCommittee: dataCommittee,
}, nil
}

// GetTx function get ethereum tx
func (e *EthermanImpl) GetTx(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
func (e *etherman) GetTx(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
return e.EthClient.TransactionByHash(ctx, txHash)
}

// TrustedSequencer gets trusted sequencer address
func (e *EthermanImpl) TrustedSequencer() (common.Address, error) {
func (e *etherman) TrustedSequencer() (common.Address, error) {
return e.CDKValidium.TrustedSequencer(&bind.CallOpts{Pending: false})
}

// WatchSetTrustedSequencer watches trusted sequencer address
func (e *EthermanImpl) WatchSetTrustedSequencer(
func (e *etherman) WatchSetTrustedSequencer(
ctx context.Context,
events chan *cdkvalidium.CdkvalidiumSetTrustedSequencer,
events chan *polygonvalidium.PolygonvalidiumSetTrustedSequencer,
) (event.Subscription, error) {
return e.CDKValidium.WatchSetTrustedSequencer(&bind.WatchOpts{Context: ctx}, events)
}

// TrustedSequencerURL gets trusted sequencer's RPC url
func (e *EthermanImpl) TrustedSequencerURL() (string, error) {
func (e *etherman) TrustedSequencerURL() (string, error) {
return e.CDKValidium.TrustedSequencerURL(&bind.CallOpts{Pending: false})
}

// WatchSetTrustedSequencerURL watches trusted sequencer's RPC url
func (e *EthermanImpl) WatchSetTrustedSequencerURL(
func (e *etherman) WatchSetTrustedSequencerURL(
ctx context.Context,
events chan *cdkvalidium.CdkvalidiumSetTrustedSequencerURL,
events chan *polygonvalidium.PolygonvalidiumSetTrustedSequencerURL,
) (event.Subscription, error) {
return e.CDKValidium.WatchSetTrustedSequencerURL(&bind.WatchOpts{Context: ctx}, events)
}

// HeaderByNumber returns header by number from the eth client
func (e *EthermanImpl) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
func (e *etherman) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
return e.EthClient.HeaderByNumber(ctx, number)
}

// FilterSequenceBatches retrieves filtered batches on CDK validium
func (e *EthermanImpl) FilterSequenceBatches(opts *bind.FilterOpts,
numBatch []uint64) (*cdkvalidium.CdkvalidiumSequenceBatchesIterator, error) {
func (e *etherman) FilterSequenceBatches(opts *bind.FilterOpts,
numBatch []uint64) (*polygonvalidium.PolygonvalidiumSequenceBatchesIterator, error) {
return e.CDKValidium.FilterSequenceBatches(opts, numBatch)
}

// DataCommitteeMember represents a member of the Data Committee
type DataCommitteeMember struct {
Addr common.Address
URL string
}

// DataCommittee represents a specific committee
type DataCommittee struct {
AddressesHash common.Hash
Members []DataCommitteeMember
RequiredSignatures uint64
}

// GetCurrentDataCommittee return the currently registered data committee
func (e *EthermanImpl) GetCurrentDataCommittee() (*DataCommittee, error) {
func (e *etherman) GetCurrentDataCommittee() (*DataCommittee, error) {
addrsHash, err := e.DataCommittee.CommitteeHash(&bind.CallOpts{Pending: false})
if err != nil {
return nil, fmt.Errorf("error getting CommitteeHash from L1 SC: %w", err)
}

reqSign, err := e.DataCommittee.RequiredAmountOfSignatures(&bind.CallOpts{Pending: false})
if err != nil {
return nil, fmt.Errorf("error getting RequiredAmountOfSignatures from L1 SC: %w", err)
}

members, err := e.GetCurrentDataCommitteeMembers()
if err != nil {
return nil, err
Expand All @@ -154,21 +154,25 @@ func (e *EthermanImpl) GetCurrentDataCommittee() (*DataCommittee, error) {
}

// GetCurrentDataCommitteeMembers return the currently registered data committee members
func (e *EthermanImpl) GetCurrentDataCommitteeMembers() ([]DataCommitteeMember, error) {
func (e *etherman) GetCurrentDataCommitteeMembers() ([]DataCommitteeMember, error) {
members := []DataCommitteeMember{}

nMembers, err := e.DataCommittee.GetAmountOfMembers(&bind.CallOpts{Pending: false})
if err != nil {
return nil, fmt.Errorf("error getting GetAmountOfMembers from L1 SC: %w", err)
}

for i := int64(0); i < nMembers.Int64(); i++ {
member, err := e.DataCommittee.Members(&bind.CallOpts{Pending: false}, big.NewInt(i))
if err != nil {
return nil, fmt.Errorf("error getting Members %d from L1 SC: %w", i, err)
}

members = append(members, DataCommitteeMember{
Addr: member.Addr,
URL: member.Url,
})
}

return members, nil
}
Loading

0 comments on commit f2ae2dd

Please sign in to comment.