Merge pull request #383 from hermeznetwork/feature/initvars

Use init SC vars and start block from events
This commit is contained in:
arnau
2020-12-18 20:26:41 +01:00
committed by GitHub
15 changed files with 219 additions and 171 deletions

View File

@@ -24,11 +24,6 @@ URL = "http://localhost:8545"
SyncLoopInterval = "1s" SyncLoopInterval = "1s"
StatsRefreshPeriod = "1s" StatsRefreshPeriod = "1s"
[Synchronizer.StartBlockNum]
Rollup = 19
Auction = 17
WDelayer = 15
[SmartContracts] [SmartContracts]
Rollup = "0x8EEaea23686c319133a7cC110b840d1591d9AeE0" Rollup = "0x8EEaea23686c319133a7cC110b840d1591d9AeE0"
Auction = "0x317113D2593e3efF1FfAE0ba2fF7A61861Df7ae5" Auction = "0x317113D2593e3efF1FfAE0ba2fF7A61861Df7ae5"
@@ -36,65 +31,6 @@ WDelayer = "0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F"
TokenHEZ = "0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77" TokenHEZ = "0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77"
TokenHEZName = "Hermez Network Token" TokenHEZName = "Hermez Network Token"
[Synchronizer.InitialVariables.Auction]
DonationAddress = "0x0000000000000000000000000000000000000001"
BootCoordinator = "0xb4124cEB3451635DAcedd11767f004d8a28c6eE7"
BootCoordinatorURL = "https://boot.coordinator.io"
DefaultSlotSetBid = [
"10000000000000000000",
"10000000000000000000",
"10000000000000000000",
"10000000000000000000",
"10000000000000000000",
"10000000000000000000",
]
DefaultSlotSetBidSlotNum = 0
ClosedAuctionSlots = 2
OpenAuctionSlots = 4320
AllocationRatio = [4000, 4000, 2000]
Outbidding = 1000
SlotDeadline = 20
[Synchronizer.InitialVariables.WDelayer]
# HermezRollupAddress =
HermezGovernanceAddress = "0x0000000000000000000000000000000000000001"
EmergencyCouncilAddress = "0x0000000000000000000000000000000000000001"
WithdrawalDelay = 60
EmergencyModeStartingTime = 0
EmergencyMode = false
[Synchronizer.InitialVariables.Rollup]
FeeAddToken = "10"
ForgeL1L2BatchTimeout = 10
WithdrawalDelay = 1209600 # 60 * 60 * 24 * 7 * 2
SafeMode = false
[[Synchronizer.InitialVariables.Rollup.Buckets]]
CeilUSD = 0
Withdrawals = 0
BlockWithdrawalRate = 0
MaxWithdrawals = 0
[[Synchronizer.InitialVariables.Rollup.Buckets]]
CeilUSD = 0
Withdrawals = 0
BlockWithdrawalRate = 0
MaxWithdrawals = 0
[[Synchronizer.InitialVariables.Rollup.Buckets]]
CeilUSD = 0
Withdrawals = 0
BlockWithdrawalRate = 0
MaxWithdrawals = 0
[[Synchronizer.InitialVariables.Rollup.Buckets]]
CeilUSD = 0
Withdrawals = 0
BlockWithdrawalRate = 0
MaxWithdrawals = 0
[[Synchronizer.InitialVariables.Rollup.Buckets]]
CeilUSD = 0
Withdrawals = 0
BlockWithdrawalRate = 0
MaxWithdrawals = 0
[Coordinator] [Coordinator]
ForgerAddress = "0x6BB84Cc84D4A34467aD12a2039A312f7029e2071" ForgerAddress = "0x6BB84Cc84D4A34467aD12a2039A312f7029e2071"
ConfirmBlocks = 10 ConfirmBlocks = 10

View File

@@ -53,7 +53,7 @@ type L1Tx struct {
func NewL1Tx(tx *L1Tx) (*L1Tx, error) { func NewL1Tx(tx *L1Tx) (*L1Tx, error) {
txTypeOld := tx.Type txTypeOld := tx.Type
if err := tx.SetType(); err != nil { if err := tx.SetType(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original Type doesn't match the correct one, return error // If original Type doesn't match the correct one, return error
if txTypeOld != "" && txTypeOld != tx.Type { if txTypeOld != "" && txTypeOld != tx.Type {
@@ -63,7 +63,7 @@ func NewL1Tx(tx *L1Tx) (*L1Tx, error) {
txIDOld := tx.TxID txIDOld := tx.TxID
if err := tx.SetID(); err != nil { if err := tx.SetID(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original TxID doesn't match the correct one, return error // If original TxID doesn't match the correct one, return error
if txIDOld != (TxID{}) && txIDOld != tx.TxID { if txIDOld != (TxID{}) && txIDOld != tx.TxID {

View File

@@ -27,7 +27,7 @@ type L2Tx struct {
func NewL2Tx(tx *L2Tx) (*L2Tx, error) { func NewL2Tx(tx *L2Tx) (*L2Tx, error) {
txTypeOld := tx.Type txTypeOld := tx.Type
if err := tx.SetType(); err != nil { if err := tx.SetType(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original Type doesn't match the correct one, return error // If original Type doesn't match the correct one, return error
if txTypeOld != "" && txTypeOld != tx.Type { if txTypeOld != "" && txTypeOld != tx.Type {
@@ -37,7 +37,7 @@ func NewL2Tx(tx *L2Tx) (*L2Tx, error) {
txIDOld := tx.TxID txIDOld := tx.TxID
if err := tx.SetID(); err != nil { if err := tx.SetID(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original TxID doesn't match the correct one, return error // If original TxID doesn't match the correct one, return error
if txIDOld != (TxID{}) && txIDOld != tx.TxID { if txIDOld != (TxID{}) && txIDOld != tx.TxID {

View File

@@ -53,7 +53,7 @@ type PoolL2Tx struct {
func NewPoolL2Tx(tx *PoolL2Tx) (*PoolL2Tx, error) { func NewPoolL2Tx(tx *PoolL2Tx) (*PoolL2Tx, error) {
txTypeOld := tx.Type txTypeOld := tx.Type
if err := tx.SetType(); err != nil { if err := tx.SetType(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original Type doesn't match the correct one, return error // If original Type doesn't match the correct one, return error
if txTypeOld != "" && txTypeOld != tx.Type { if txTypeOld != "" && txTypeOld != tx.Type {
@@ -63,7 +63,7 @@ func NewPoolL2Tx(tx *PoolL2Tx) (*PoolL2Tx, error) {
txIDOld := tx.TxID txIDOld := tx.TxID
if err := tx.SetID(); err != nil { if err := tx.SetID(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
// If original TxID doesn't match the correct one, return error // If original TxID doesn't match the correct one, return error
if txIDOld != (TxID{}) && txIDOld != tx.TxID { if txIDOld != (TxID{}) && txIDOld != tx.TxID {

View File

@@ -8,7 +8,6 @@ import (
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
ethCommon "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/synchronizer"
"github.com/hermeznetwork/tracerr" "github.com/hermeznetwork/tracerr"
"gopkg.in/go-playground/validator.v9" "gopkg.in/go-playground/validator.v9"
) )
@@ -111,10 +110,8 @@ type Node struct {
URL string `validate:"required"` URL string `validate:"required"`
} `validate:"required"` } `validate:"required"`
Synchronizer struct { Synchronizer struct {
SyncLoopInterval Duration `validate:"required"` SyncLoopInterval Duration `validate:"required"`
StatsRefreshPeriod Duration `validate:"required"` StatsRefreshPeriod Duration `validate:"required"`
StartBlockNum synchronizer.ConfigStartBlockNum `validate:"required"`
InitialVariables synchronizer.SCVariables `validate:"required"`
} `validate:"required"` } `validate:"required"`
SmartContracts struct { SmartContracts struct {
Rollup ethCommon.Address `validate:"required"` Rollup ethCommon.Address `validate:"required"`

View File

@@ -185,16 +185,7 @@ func newTestSynchronizer(t *testing.T, ethClient *test.Client, ethClientSetup *t
modules modules) *synchronizer.Synchronizer { modules modules) *synchronizer.Synchronizer {
sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.stateDB, sync, err := synchronizer.NewSynchronizer(ethClient, modules.historyDB, modules.stateDB,
synchronizer.Config{ synchronizer.Config{
StartBlockNum: synchronizer.ConfigStartBlockNum{ StatsRefreshPeriod: 0 * time.Second,
Rollup: 1,
Auction: 1,
WDelayer: 1,
},
InitialVariables: synchronizer.SCVariables{
Rollup: *ethClientSetup.RollupVariables,
Auction: *ethClientSetup.AuctionVariables,
WDelayer: *ethClientSetup.WDelayerVariables,
},
}) })
require.NoError(t, err) require.NoError(t, err)
return sync return sync
@@ -311,7 +302,11 @@ func TestCoordCanForge(t *testing.T) {
coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules) coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules)
_, err := ethClient.AuctionSetCoordinator(forger, "https://foo.bar") _, err := ethClient.AuctionSetCoordinator(forger, "https://foo.bar")
require.NoError(t, err) require.NoError(t, err)
_, err = ethClient.AuctionBidSimple(2, big.NewInt(9999)) bid, ok := new(big.Int).SetString("12000000000000000000", 10)
if !ok {
panic("bad bid")
}
_, err = ethClient.AuctionBidSimple(2, bid)
require.NoError(t, err) require.NoError(t, err)
modules2 := newTestModules(t) modules2 := newTestModules(t)
@@ -359,7 +354,11 @@ func TestCoordHandleMsgSyncBlock(t *testing.T) {
coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules) coord := newTestCoordinator(t, forger, ethClient, ethClientSetup, modules)
_, err := ethClient.AuctionSetCoordinator(forger, "https://foo.bar") _, err := ethClient.AuctionSetCoordinator(forger, "https://foo.bar")
require.NoError(t, err) require.NoError(t, err)
_, err = ethClient.AuctionBidSimple(2, big.NewInt(9999)) bid, ok := new(big.Int).SetString("11000000000000000000", 10)
if !ok {
panic("bad bid")
}
_, err = ethClient.AuctionBidSimple(2, bid)
require.NoError(t, err) require.NoError(t, err)
var msg MsgSyncBlock var msg MsgSyncBlock

View File

@@ -69,6 +69,26 @@ type AuctionEventInitialize struct {
AllocationRatio [3]uint16 AllocationRatio [3]uint16
} }
// AuctionVariables returns the AuctionVariables from the initialize event
func (ei *AuctionEventInitialize) AuctionVariables(InitialMinimalBidding *big.Int) *common.AuctionVariables {
return &common.AuctionVariables{
EthBlockNum: 0,
DonationAddress: ei.DonationAddress,
BootCoordinator: ei.BootCoordinatorAddress,
BootCoordinatorURL: ei.BootCoordinatorURL,
DefaultSlotSetBid: [6]*big.Int{
InitialMinimalBidding, InitialMinimalBidding, InitialMinimalBidding,
InitialMinimalBidding, InitialMinimalBidding, InitialMinimalBidding,
},
DefaultSlotSetBidSlotNum: 0,
ClosedAuctionSlots: ei.ClosedAuctionSlots,
OpenAuctionSlots: ei.OpenAuctionSlots,
AllocationRatio: ei.AllocationRatio,
Outbidding: ei.Outbidding,
SlotDeadline: ei.SlotDeadline,
}
}
// AuctionEventNewBid is an event of the Auction Smart Contract // AuctionEventNewBid is an event of the Auction Smart Contract
type AuctionEventNewBid struct { type AuctionEventNewBid struct {
Slot int64 Slot int64
@@ -235,6 +255,7 @@ type AuctionInterface interface {
AuctionConstants() (*common.AuctionConstants, error) AuctionConstants() (*common.AuctionConstants, error)
AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error)
AuctionEventInit() (*AuctionEventInitialize, int64, error)
} }
// //
@@ -756,11 +777,11 @@ func (c *AuctionClient) AuctionEventInit() (*AuctionEventInitialize, int64, erro
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
if len(logs) != 1 { if len(logs) != 1 {
return nil, 0, fmt.Errorf("no event of type InitializeHermezAuctionProtocolEvent found") return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeHermezAuctionProtocolEvent found"))
} }
vLog := logs[0] vLog := logs[0]
if vLog.Topics[0] != logAuctionInitialize { if vLog.Topics[0] != logAuctionInitialize {
return nil, 0, fmt.Errorf("event is not InitializeHermezAuctionProtocolEvent") return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeHermezAuctionProtocolEvent"))
} }
var auctionInit AuctionEventInitialize var auctionInit AuctionEventInitialize
@@ -768,7 +789,7 @@ func (c *AuctionClient) AuctionEventInit() (*AuctionEventInitialize, int64, erro
"InitializeHermezAuctionProtocolEvent", vLog.Data); err != nil { "InitializeHermezAuctionProtocolEvent", vLog.Data); err != nil {
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
return &auctionInit, int64(vLog.BlockNumber), err return &auctionInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
} }
// AuctionEventsByBlock returns the events in a block that happened in the // AuctionEventsByBlock returns the events in a block that happened in the

View File

@@ -59,6 +59,27 @@ type RollupEventInitialize struct {
WithdrawalDelay uint64 WithdrawalDelay uint64
} }
// RollupVariables returns the RollupVariables from the initialize event
func (ei *RollupEventInitialize) RollupVariables() *common.RollupVariables {
var buckets [common.RollupConstNumBuckets]common.BucketParams
for i := range buckets {
buckets[i] = common.BucketParams{
CeilUSD: big.NewInt(0),
Withdrawals: big.NewInt(0),
BlockWithdrawalRate: big.NewInt(0),
MaxWithdrawals: big.NewInt(0),
}
}
return &common.RollupVariables{
EthBlockNum: 0,
FeeAddToken: ei.FeeAddToken,
ForgeL1L2BatchTimeout: int64(ei.ForgeL1L2BatchTimeout),
WithdrawalDelay: ei.WithdrawalDelay,
Buckets: buckets,
SafeMode: false,
}
}
// RollupEventL1UserTx is an event of the Rollup Smart Contract // RollupEventL1UserTx is an event of the Rollup Smart Contract
type RollupEventL1UserTx struct { type RollupEventL1UserTx struct {
// ToForgeL1TxsNum int64 // QueueIndex *big.Int // ToForgeL1TxsNum int64 // QueueIndex *big.Int
@@ -245,6 +266,7 @@ type RollupInterface interface {
RollupConstants() (*common.RollupConstants, error) RollupConstants() (*common.RollupConstants, error)
RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
RollupForgeBatchArgs(ethCommon.Hash, uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) RollupForgeBatchArgs(ethCommon.Hash, uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error)
RollupEventInit() (*RollupEventInitialize, int64, error)
} }
// //
@@ -688,18 +710,18 @@ func (c *RollupClient) RollupEventInit() (*RollupEventInitialize, int64, error)
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
if len(logs) != 1 { if len(logs) != 1 {
return nil, 0, fmt.Errorf("no event of type InitializeHermezEvent found") return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeHermezEvent found"))
} }
vLog := logs[0] vLog := logs[0]
if vLog.Topics[0] != logHermezInitialize { if vLog.Topics[0] != logHermezInitialize {
return nil, 0, fmt.Errorf("event is not InitializeHermezEvent") return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeHermezEvent"))
} }
var rollupInit RollupEventInitialize var rollupInit RollupEventInitialize
if err := c.contractAbi.UnpackIntoInterface(&rollupInit, "InitializeHermezEvent", vLog.Data); err != nil { if err := c.contractAbi.UnpackIntoInterface(&rollupInit, "InitializeHermezEvent", vLog.Data); err != nil {
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
return &rollupInit, int64(vLog.BlockNumber), err return &rollupInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
} }
// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract

View File

@@ -33,6 +33,18 @@ type WDelayerEventInitialize struct {
InitialEmergencyCouncil ethCommon.Address InitialEmergencyCouncil ethCommon.Address
} }
// WDelayerVariables returns the WDelayerVariables from the initialize event
func (ei *WDelayerEventInitialize) WDelayerVariables() *common.WDelayerVariables {
return &common.WDelayerVariables{
EthBlockNum: 0,
HermezGovernanceAddress: ei.InitialHermezGovernanceAddress,
EmergencyCouncilAddress: ei.InitialEmergencyCouncil,
WithdrawalDelay: ei.InitialWithdrawalDelay,
EmergencyModeStartingBlock: 0,
EmergencyMode: false,
}
}
// WDelayerEventDeposit is an event of the WithdrawalDelayer Smart Contract // WDelayerEventDeposit is an event of the WithdrawalDelayer Smart Contract
type WDelayerEventDeposit struct { type WDelayerEventDeposit struct {
Owner ethCommon.Address Owner ethCommon.Address
@@ -124,6 +136,7 @@ type WDelayerInterface interface {
WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error)
WDelayerConstants() (*common.WDelayerConstants, error) WDelayerConstants() (*common.WDelayerConstants, error)
WDelayerEventInit() (*WDelayerEventInitialize, int64, error)
} }
// //
@@ -395,11 +408,11 @@ func (c *WDelayerClient) WDelayerEventInit() (*WDelayerEventInitialize, int64, e
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
if len(logs) != 1 { if len(logs) != 1 {
return nil, 0, fmt.Errorf("no event of type InitializeWithdrawalDelayerEvent found") return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeWithdrawalDelayerEvent found"))
} }
vLog := logs[0] vLog := logs[0]
if vLog.Topics[0] != logWDelayerInitialize { if vLog.Topics[0] != logWDelayerInitialize {
return nil, 0, fmt.Errorf("event is not InitializeWithdrawalDelayerEvent") return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeWithdrawalDelayerEvent"))
} }
var wDelayerInit WDelayerEventInitialize var wDelayerInit WDelayerEventInitialize
@@ -407,7 +420,7 @@ func (c *WDelayerClient) WDelayerEventInit() (*WDelayerEventInitialize, int64, e
vLog.Data); err != nil { vLog.Data); err != nil {
return nil, 0, tracerr.Wrap(err) return nil, 0, tracerr.Wrap(err)
} }
return &wDelayerInit, int64(vLog.BlockNumber), err return &wDelayerInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
} }
// WDelayerEventsByBlock returns the events in a block that happened in the // WDelayerEventsByBlock returns the events in a block that happened in the

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
@@ -120,8 +121,6 @@ func NewNode(mode Mode, cfg *config.Node) (*Node, error) {
} }
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{ sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
StartBlockNum: cfg.Synchronizer.StartBlockNum,
InitialVariables: cfg.Synchronizer.InitialVariables,
StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration, StatsRefreshPeriod: cfg.Synchronizer.StatsRefreshPeriod.Duration,
}) })
if err != nil { if err != nil {
@@ -390,7 +389,11 @@ func (n *Node) syncLoopFn(lastBlock *common.Block) (*common.Block, time.Duration
stats := n.sync.Stats() stats := n.sync.Stats()
if err != nil { if err != nil {
// case: error // case: error
log.Errorw("Synchronizer.Sync", "err", err) if strings.Contains(err.Error(), "context canceled") {
log.Warnw("Synchronizer.Sync", "err", err)
} else {
log.Errorw("Synchronizer.Sync", "err", err)
}
return nil, n.cfg.Synchronizer.SyncLoopInterval.Duration return nil, n.cfg.Synchronizer.SyncLoopInterval.Duration
} else if discarded != nil { } else if discarded != nil {
// case: reorg // case: reorg

View File

@@ -27,7 +27,7 @@ type bigInt big.Int
func (b *bigInt) UnmarshalText(text []byte) error { func (b *bigInt) UnmarshalText(text []byte) error {
_, ok := (*big.Int)(b).SetString(string(text), 10) _, ok := (*big.Int)(b).SetString(string(text), 10)
if !ok { if !ok {
return fmt.Errorf("invalid big int: \"%v\"", string(text)) return tracerr.Wrap(fmt.Errorf("invalid big int: \"%v\"", string(text)))
} }
return nil return nil
} }
@@ -42,7 +42,7 @@ func (p *Proof) UnmarshalJSON(data []byte) error {
Protocol string `json:"protocol"` Protocol string `json:"protocol"`
}{} }{}
if err := json.Unmarshal(data, &proof); err != nil { if err := json.Unmarshal(data, &proof); err != nil {
return err return tracerr.Wrap(err)
} }
p.PiA[0] = (*big.Int)(proof.PiA[0]) p.PiA[0] = (*big.Int)(proof.PiA[0])
p.PiA[1] = (*big.Int)(proof.PiA[1]) p.PiA[1] = (*big.Int)(proof.PiA[1])
@@ -66,7 +66,7 @@ type PublicInputs []*big.Int
func (p *PublicInputs) UnmarshalJSON(data []byte) error { func (p *PublicInputs) UnmarshalJSON(data []byte) error {
pubInputs := []*bigInt{} pubInputs := []*bigInt{}
if err := json.Unmarshal(data, &pubInputs); err != nil { if err := json.Unmarshal(data, &pubInputs); err != nil {
return err return tracerr.Wrap(err)
} }
*p = make([]*big.Int, len(pubInputs)) *p = make([]*big.Int, len(pubInputs))
for i, v := range pubInputs { for i, v := range pubInputs {
@@ -245,7 +245,7 @@ func (p *ProofServerClient) GetProof(ctx context.Context) (*Proof, []*big.Int, e
} }
return &proof, pubInputs, nil return &proof, pubInputs, nil
} }
return nil, nil, fmt.Errorf("status != StatusCodeSuccess, status = %v", status.Status) return nil, nil, tracerr.Wrap(fmt.Errorf("status != StatusCodeSuccess, status = %v", status.Status))
} }
// Cancel cancels any current proof computation // Cancel cancels any current proof computation
@@ -261,7 +261,7 @@ func (p *ProofServerClient) WaitReady(ctx context.Context) error {
return tracerr.Wrap(err) return tracerr.Wrap(err)
} }
if !status.Status.IsInitialized() { if !status.Status.IsInitialized() {
return fmt.Errorf("Proof Server is not initialized") return tracerr.Wrap(fmt.Errorf("Proof Server is not initialized"))
} }
if status.Status.IsReady() { if status.Status.IsReady() {
return nil return nil

View File

@@ -17,31 +17,6 @@ import (
"github.com/hermeznetwork/tracerr" "github.com/hermeznetwork/tracerr"
) )
var (
// ErrNotAbleToSync is used when there is not possible to find a valid block to sync
// ErrNotAbleToSync = errors.New("it has not been possible to synchronize any block")
)
// // SyncronizerState describes the synchronization progress of the smart contracts
// type SyncronizerState struct {
// LastUpdate time.Time // last time this information was updated
// CurrentBatchNum BatchNum // Last batch that was forged on the blockchain
// CurrentBlockNum uint64 // Last block that was mined on Ethereum
// CurrentToForgeL1TxsNum uint32
// LastSyncedBatchNum BatchNum // last batch synchronized by the coordinator
// LastSyncedBlockNum uint64 // last Ethereum block synchronized by the coordinator
// LastSyncedToForgeL1TxsNum uint32
// }
// // SyncStatus is returned by the Status method of the Synchronizer
// type SyncStatus struct {
// CurrentBlock int64
// CurrentBatch BatchNum
// CurrentForgerAddr ethCommon.Address
// NextForgerAddr ethCommon.Address
// Synchronized bool
// }
// Stats of the syncrhonizer // Stats of the syncrhonizer
type Stats struct { type Stats struct {
Eth struct { Eth struct {
@@ -170,12 +145,12 @@ func (s *StatsHolder) batchesPerc(batchNum int64) float64 {
float64(s.Eth.LastBatch) float64(s.Eth.LastBatch)
} }
// ConfigStartBlockNum sets the first block used to start tracking the smart // StartBlockNums sets the first block used to start tracking the smart
// contracts // contracts
type ConfigStartBlockNum struct { type StartBlockNums struct {
Rollup int64 `validate:"required"` Rollup int64
Auction int64 `validate:"required"` Auction int64
WDelayer int64 `validate:"required"` WDelayer int64
} }
// SCVariables joins all the smart contract variables in a single struct // SCVariables joins all the smart contract variables in a single struct
@@ -202,8 +177,8 @@ type SCConsts struct {
// Config is the Synchronizer configuration // Config is the Synchronizer configuration
type Config struct { type Config struct {
StartBlockNum ConfigStartBlockNum // StartBlockNum StartBlockNum
InitialVariables SCVariables // InitialVariables SCVariables
StatsRefreshPeriod time.Duration StatsRefreshPeriod time.Duration
} }
@@ -217,6 +192,7 @@ type Synchronizer struct {
historyDB *historydb.HistoryDB historyDB *historydb.HistoryDB
stateDB *statedb.StateDB stateDB *statedb.StateDB
cfg Config cfg Config
initVars SCVariables
startBlockNum int64 startBlockNum int64
vars SCVariables vars SCVariables
stats *StatsHolder stats *StatsHolder
@@ -242,27 +218,38 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
return nil, tracerr.Wrap(fmt.Errorf("NewSynchronizer ethClient.WDelayerConstants(): %w", return nil, tracerr.Wrap(fmt.Errorf("NewSynchronizer ethClient.WDelayerConstants(): %w",
err)) err))
} }
consts := SCConsts{
Rollup: *rollupConstants,
Auction: *auctionConstants,
WDelayer: *wDelayerConstants,
}
initVars, startBlockNums, err := getInitialVariables(ethClient, &consts)
if err != nil {
return nil, tracerr.Wrap(err)
}
log.Infow("Synchronizer syncing from smart contract blocks",
"rollup", startBlockNums.Rollup,
"auction", startBlockNums.Auction,
"wdelayer", startBlockNums.WDelayer,
)
// Set startBlockNum to the minimum between Auction, Rollup and // Set startBlockNum to the minimum between Auction, Rollup and
// WDelayer StartBlockNum // WDelayer StartBlockNum
startBlockNum := cfg.StartBlockNum.Auction startBlockNum := startBlockNums.Auction
if cfg.StartBlockNum.Rollup < startBlockNum { if startBlockNums.Rollup < startBlockNum {
startBlockNum = cfg.StartBlockNum.Rollup startBlockNum = startBlockNums.Rollup
} }
if cfg.StartBlockNum.WDelayer < startBlockNum { if startBlockNums.WDelayer < startBlockNum {
startBlockNum = cfg.StartBlockNum.WDelayer startBlockNum = startBlockNums.WDelayer
} }
stats := NewStatsHolder(startBlockNum, cfg.StatsRefreshPeriod) stats := NewStatsHolder(startBlockNum, cfg.StatsRefreshPeriod)
s := &Synchronizer{ s := &Synchronizer{
ethClient: ethClient, ethClient: ethClient,
consts: SCConsts{ consts: consts,
Rollup: *rollupConstants,
Auction: *auctionConstants,
WDelayer: *wDelayerConstants,
},
historyDB: historyDB, historyDB: historyDB,
stateDB: stateDB, stateDB: stateDB,
cfg: cfg, cfg: cfg,
initVars: *initVars,
startBlockNum: startBlockNum, startBlockNum: startBlockNum,
stats: stats, stats: stats,
} }
@@ -596,22 +583,54 @@ func (s *Synchronizer) reorg(uncleBlock *common.Block) (int64, error) {
return block.Num, nil return block.Num, nil
} }
func getInitialVariables(ethClient eth.ClientInterface,
consts *SCConsts) (*SCVariables, *StartBlockNums, error) {
rollupInit, rollupInitBlock, err := ethClient.RollupEventInit()
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
auctionInit, auctionInitBlock, err := ethClient.AuctionEventInit()
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
wDelayerInit, wDelayerInitBlock, err := ethClient.WDelayerEventInit()
if err != nil {
return nil, nil, tracerr.Wrap(err)
}
rollupVars := rollupInit.RollupVariables()
auctionVars := auctionInit.AuctionVariables(consts.Auction.InitialMinimalBidding)
wDelayerVars := wDelayerInit.WDelayerVariables()
return &SCVariables{
Rollup: *rollupVars,
Auction: *auctionVars,
WDelayer: *wDelayerVars,
}, &StartBlockNums{
Rollup: rollupInitBlock,
Auction: auctionInitBlock,
WDelayer: wDelayerInitBlock,
}, nil
}
func (s *Synchronizer) resetState(block *common.Block) error { func (s *Synchronizer) resetState(block *common.Block) error {
rollup, auction, wDelayer, err := s.historyDB.GetSCVars() rollup, auction, wDelayer, err := s.historyDB.GetSCVars()
// If SCVars are not in the HistoryDB, this is probably the first run // If SCVars are not in the HistoryDB, this is probably the first run
// of the Synchronizer: store the initial vars taken from config // of the Synchronizer: store the initial vars taken from config
if tracerr.Unwrap(err) == sql.ErrNoRows { if tracerr.Unwrap(err) == sql.ErrNoRows {
rollup = &s.cfg.InitialVariables.Rollup vars := s.initVars
auction = &s.cfg.InitialVariables.Auction
wDelayer = &s.cfg.InitialVariables.WDelayer
log.Info("Setting initial SCVars in HistoryDB") log.Info("Setting initial SCVars in HistoryDB")
if err = s.historyDB.SetInitialSCVars(rollup, auction, wDelayer); err != nil { if err = s.historyDB.SetInitialSCVars(&vars.Rollup, &vars.Auction, &vars.WDelayer); err != nil {
return tracerr.Wrap(fmt.Errorf("historyDB.SetInitialSCVars: %w", err)) return tracerr.Wrap(fmt.Errorf("historyDB.SetInitialSCVars: %w", err))
} }
s.vars.Rollup = *vars.Rollup.Copy()
s.vars.Auction = *vars.Auction.Copy()
s.vars.WDelayer = *vars.WDelayer.Copy()
} else if err != nil {
return tracerr.Wrap(err)
} else {
s.vars.Rollup = *rollup
s.vars.Auction = *auction
s.vars.WDelayer = *wDelayer
} }
s.vars.Rollup = *rollup
s.vars.Auction = *auction
s.vars.WDelayer = *wDelayer
batchNum, err := s.historyDB.GetLastBatchNum() batchNum, err := s.historyDB.GetLastBatchNum()
if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows { if err != nil && tracerr.Unwrap(err) != sql.ErrNoRows {
@@ -786,7 +805,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
// Set TxID, BlockNum, BatchNum and Position to the forged L2Txs // Set TxID, BlockNum, BatchNum and Position to the forged L2Txs
for i := range l2Txs { for i := range l2Txs {
if err := l2Txs[i].SetID(); err != nil { if err := l2Txs[i].SetID(); err != nil {
return nil, err return nil, tracerr.Wrap(err)
} }
l2Txs[i].EthBlockNum = blockNum l2Txs[i].EthBlockNum = blockNum
l2Txs[i].BatchNum = batchNum l2Txs[i].BatchNum = batchNum

View File

@@ -9,6 +9,7 @@ import (
"os" "os"
"sort" "sort"
"testing" "testing"
"time"
ethCommon "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/common"
@@ -300,16 +301,7 @@ func TestSync(t *testing.T) {
// Create Synchronizer // Create Synchronizer
s, err := NewSynchronizer(client, historyDB, stateDB, Config{ s, err := NewSynchronizer(client, historyDB, stateDB, Config{
StartBlockNum: ConfigStartBlockNum{ StatsRefreshPeriod: 0 * time.Second,
Rollup: 1,
Auction: 1,
WDelayer: 1,
},
InitialVariables: SCVariables{
Rollup: *clientSetup.RollupVariables,
Auction: *clientSetup.AuctionVariables,
WDelayer: *clientSetup.WDelayerVariables,
},
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@@ -301,10 +301,20 @@ func NewClientSetupExample() *ClientSetup {
HermezAuctionContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"), HermezAuctionContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
WithdrawDelayerContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"), WithdrawDelayerContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
} }
var buckets [common.RollupConstNumBuckets]common.BucketParams
for i := range buckets {
buckets[i] = common.BucketParams{
CeilUSD: big.NewInt(0),
Withdrawals: big.NewInt(0),
BlockWithdrawalRate: big.NewInt(0),
MaxWithdrawals: big.NewInt(0),
}
}
rollupVariables := &common.RollupVariables{ rollupVariables := &common.RollupVariables{
FeeAddToken: big.NewInt(11), FeeAddToken: big.NewInt(11),
ForgeL1L2BatchTimeout: 9, ForgeL1L2BatchTimeout: 9,
WithdrawalDelay: 80, WithdrawalDelay: 80,
Buckets: buckets,
} }
auctionConstants := &common.AuctionConstants{ auctionConstants := &common.AuctionConstants{
BlocksPerSlot: 40, BlocksPerSlot: 40,
@@ -319,8 +329,9 @@ func NewClientSetupExample() *ClientSetup {
BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"), BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
BootCoordinatorURL: "https://boot.coordinator.com", BootCoordinatorURL: "https://boot.coordinator.com",
DefaultSlotSetBid: [6]*big.Int{ DefaultSlotSetBid: [6]*big.Int{
big.NewInt(1000), big.NewInt(1100), big.NewInt(1200), initialMinimalBidding, initialMinimalBidding, initialMinimalBidding,
big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)}, initialMinimalBidding, initialMinimalBidding, initialMinimalBidding,
},
ClosedAuctionSlots: 2, ClosedAuctionSlots: 2,
OpenAuctionSlots: 4320, OpenAuctionSlots: 4320,
AllocationRatio: [3]uint16{4000, 4000, 2000}, AllocationRatio: [3]uint16{4000, 4000, 2000},
@@ -1064,6 +1075,16 @@ func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCom
return &block.Rollup.Events, &block.Eth.Hash, nil return &block.Rollup.Events, &block.Eth.Hash, nil
} }
// RollupEventInit returns the initialize event with its corresponding block number
func (c *Client) RollupEventInit() (*eth.RollupEventInitialize, int64, error) {
vars := c.blocks[0].Rollup.Vars
return &eth.RollupEventInitialize{
ForgeL1L2BatchTimeout: uint8(vars.ForgeL1L2BatchTimeout),
FeeAddToken: vars.FeeAddToken,
WithdrawalDelay: vars.WithdrawalDelay,
}, 1, nil
}
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) { func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) {
c.rw.RLock() c.rw.RLock()
@@ -1511,6 +1532,21 @@ func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethC
return &block.Auction.Events, &block.Eth.Hash, nil return &block.Auction.Events, &block.Eth.Hash, nil
} }
// AuctionEventInit returns the initialize event with its corresponding block number
func (c *Client) AuctionEventInit() (*eth.AuctionEventInitialize, int64, error) {
vars := c.blocks[0].Auction.Vars
return &eth.AuctionEventInitialize{
DonationAddress: vars.DonationAddress,
BootCoordinatorAddress: vars.BootCoordinator,
BootCoordinatorURL: vars.BootCoordinatorURL,
Outbidding: vars.Outbidding,
SlotDeadline: vars.SlotDeadline,
ClosedAuctionSlots: vars.ClosedAuctionSlots,
OpenAuctionSlots: vars.OpenAuctionSlots,
AllocationRatio: vars.AllocationRatio,
}, 1, nil
}
// //
// WDelayer // WDelayer
// //
@@ -1720,6 +1756,16 @@ func (c *Client) WDelayerConstants() (*common.WDelayerConstants, error) {
return c.wDelayerConstants, nil return c.wDelayerConstants, nil
} }
// WDelayerEventInit returns the initialize event with its corresponding block number
func (c *Client) WDelayerEventInit() (*eth.WDelayerEventInitialize, int64, error) {
vars := c.blocks[0].WDelayer.Vars
return &eth.WDelayerEventInitialize{
InitialWithdrawalDelay: vars.WithdrawalDelay,
InitialHermezGovernanceAddress: vars.HermezGovernanceAddress,
InitialEmergencyCouncil: vars.EmergencyCouncilAddress,
}, 1, nil
}
// CtlAddBlocks adds block data to the smarts contracts. The added blocks will // CtlAddBlocks adds block data to the smarts contracts. The added blocks will
// appear as mined. Not thread safe. // appear as mined. Not thread safe.
func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) { func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
@@ -1731,14 +1777,14 @@ func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
auction := nextBlock.Auction auction := nextBlock.Auction
for _, token := range block.Rollup.AddedTokens { for _, token := range block.Rollup.AddedTokens {
if _, err := c.RollupAddTokenSimple(token.EthAddr, rollup.Vars.FeeAddToken); err != nil { if _, err := c.RollupAddTokenSimple(token.EthAddr, rollup.Vars.FeeAddToken); err != nil {
return err return tracerr.Wrap(err)
} }
} }
for _, tx := range block.Rollup.L1UserTxs { for _, tx := range block.Rollup.L1UserTxs {
c.CtlSetAddr(tx.FromEthAddr) c.CtlSetAddr(tx.FromEthAddr)
if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.DepositAmount, tx.Amount, if _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.DepositAmount, tx.Amount,
uint32(tx.TokenID), int64(tx.ToIdx)); err != nil { uint32(tx.TokenID), int64(tx.ToIdx)); err != nil {
return err return tracerr.Wrap(err)
} }
} }
c.CtlSetAddr(auction.Vars.BootCoordinator) c.CtlSetAddr(auction.Vars.BootCoordinator)
@@ -1758,7 +1804,7 @@ func (c *Client) CtlAddBlocks(blocks []common.BlockData) (err error) {
ProofB: [2][2]*big.Int{}, // Intentionally empty ProofB: [2][2]*big.Int{}, // Intentionally empty
ProofC: [2]*big.Int{}, // Intentionally empty ProofC: [2]*big.Int{}, // Intentionally empty
}); err != nil { }); err != nil {
return err return tracerr.Wrap(err)
} }
} }
// Mine block and sync // Mine block and sync

View File

@@ -883,7 +883,7 @@ func (tc *Context) FillBlocksExtra(blocks []common.BlockData, cfg *ConfigExtra)
tc.extra.nonces[tx.FromIdx]++ tc.extra.nonces[tx.FromIdx]++
tx.Nonce = tc.extra.nonces[tx.FromIdx] tx.Nonce = tc.extra.nonces[tx.FromIdx]
if err := tx.SetID(); err != nil { if err := tx.SetID(); err != nil {
return err return tracerr.Wrap(err)
} }
nTx, err := common.NewL2Tx(tx) nTx, err := common.NewL2Tx(tx)
if err != nil { if err != nil {