mirror of
https://github.com/arnaucube/hermez-node.git
synced 2026-02-07 03:16:45 +01:00
Update Synchronizer (node) implementation
- node:
- Extend config to add initial variables of the smart contracts used as
defaults before they are changed via events.
- In stopped channels, set size 1 so that panics are not witheld until the
node stops completely.
- common:
- In Smart Contract variables, comment:
- `WDelayerVariables.HermezRollupAddress` because it's not needed.
- `RollupVariables.Buckets` because there are no events for it, and for
now it's not used.
- historydb:
- Add functions to get and set smart contract variables.
- db:
- Add `Rollback` function in `utils.go` to reduce boilerplate in sql
transaction rollbacks in defers in db functions.
- Update `rollup_vars` and `auction_vars` (renamed from `consensus_vars`)
table, and add `wdelayer_vars` table.
- synchronizer:
- Synchronize WDelayer
- Handle SC variables properly
- test/ethclient:
- Add essential implementation of WDelayer
This commit is contained in:
@@ -18,15 +18,17 @@ URL = "http://localhost:8545"
|
|||||||
|
|
||||||
[Synchronizer]
|
[Synchronizer]
|
||||||
SyncLoopInterval = "1s"
|
SyncLoopInterval = "1s"
|
||||||
|
|
||||||
[Synchronizer.StartBlockNum]
|
[Synchronizer.StartBlockNum]
|
||||||
Rollup = 1
|
Rollup = 1
|
||||||
Auction = 1
|
Auction = 1
|
||||||
WDelayer = 1
|
WDelayer = 1
|
||||||
|
|
||||||
[SmartContracts]
|
[SmartContracts]
|
||||||
Rollup = "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe"
|
Rollup = "0x6F4e99522F4eB37e0B73D0C0373147893EF12fD5"
|
||||||
Auction = "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8"
|
Auction = "0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F"
|
||||||
TokenHEZ = "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c"
|
WDelayer = "0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77"
|
||||||
|
TokenHEZ = "0x2b7dEe2CF60484325716A1c6A193519c8c3b19F3"
|
||||||
TokenHEZName = "Hermez Network Token"
|
TokenHEZName = "Hermez Network Token"
|
||||||
|
|
||||||
[EthClient]
|
[EthClient]
|
||||||
@@ -35,3 +37,64 @@ DeployGasLimit = 1000000
|
|||||||
GasPriceDiv = 100
|
GasPriceDiv = 100
|
||||||
ReceiptTimeout = "60s"
|
ReceiptTimeout = "60s"
|
||||||
IntervalReceiptLoop = "200ms"
|
IntervalReceiptLoop = "200ms"
|
||||||
|
|
||||||
|
[Synchronizer.InitialVariables.Auction]
|
||||||
|
DonationAddress = "0x0000000000000000000000000000000000000001"
|
||||||
|
BootCoordinator = "0x0000000000000000000000000000000000000001"
|
||||||
|
DefaultSlotSetBid = [
|
||||||
|
"10000000000000000000",
|
||||||
|
"10000000000000000000",
|
||||||
|
"10000000000000000000",
|
||||||
|
"10000000000000000000",
|
||||||
|
"10000000000000000000",
|
||||||
|
"10000000000000000000",
|
||||||
|
]
|
||||||
|
ClosedAuctionSlots = 2
|
||||||
|
OpenAuctionSlots = 4320
|
||||||
|
AllocationRatio = [4000, 4000, 2000]
|
||||||
|
Outbidding = 1000
|
||||||
|
SlotDeadline = 20
|
||||||
|
|
||||||
|
[Synchronizer.InitialVariables.WDelayer]
|
||||||
|
# HermezRollupAddress =
|
||||||
|
HermezGovernanceDAOAddress = "0x0000000000000000000000000000000000000001"
|
||||||
|
WhiteHackGroupAddress = "0x0000000000000000000000000000000000000001"
|
||||||
|
HermezKeeperAddress = "0x0000000000000000000000000000000000000001"
|
||||||
|
WithdrawalDelay = 60
|
||||||
|
EmergencyModeStartingTime = 0
|
||||||
|
EmergencyMode = false
|
||||||
|
|
||||||
|
[Synchronizer.InitialVariables.Rollup]
|
||||||
|
FeeAddToken = "10"
|
||||||
|
ForgeL1L2BatchTimeout = 10
|
||||||
|
WithdrawalDelay = 1209600 # 60 * 60 * 24 * 7 * 2
|
||||||
|
# [[Synchronizer.InitialVariables.Rollup.Buckets]]
|
||||||
|
# CeilUSD = 0
|
||||||
|
# BlockStamp = 0
|
||||||
|
# Withdrawals = 0
|
||||||
|
# BlockWithdrawalRate = 0
|
||||||
|
# MaxWithdrawals = 0
|
||||||
|
# [[Synchronizer.InitialVariables.Rollup.Buckets]]
|
||||||
|
# CeilUSD = 0
|
||||||
|
# BlockStamp = 0
|
||||||
|
# Withdrawals = 0
|
||||||
|
# BlockWithdrawalRate = 0
|
||||||
|
# MaxWithdrawals = 0
|
||||||
|
# [[Synchronizer.InitialVariables.Rollup.Buckets]]
|
||||||
|
# CeilUSD = 0
|
||||||
|
# BlockStamp = 0
|
||||||
|
# Withdrawals = 0
|
||||||
|
# BlockWithdrawalRate = 0
|
||||||
|
# MaxWithdrawals = 0
|
||||||
|
# [[Synchronizer.InitialVariables.Rollup.Buckets]]
|
||||||
|
# CeilUSD = 0
|
||||||
|
# BlockStamp = 0
|
||||||
|
# Withdrawals = 0
|
||||||
|
# BlockWithdrawalRate = 0
|
||||||
|
# MaxWithdrawals = 0
|
||||||
|
# [[Synchronizer.InitialVariables.Rollup.Buckets]]
|
||||||
|
# CeilUSD = 0
|
||||||
|
# BlockStamp = 0
|
||||||
|
# Withdrawals = 0
|
||||||
|
# BlockWithdrawalRate = 0
|
||||||
|
# MaxWithdrawals = 0
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ func getConfig(c *cli.Context) (*Config, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// nodeCfg.Synchronizer.InitialVariables.WDelayer.HermezRollupAddress = nodeCfg.SmartContracts.Rollup
|
||||||
cfg.node = nodeCfg
|
cfg.node = nodeCfg
|
||||||
|
|
||||||
return &cfg, nil
|
return &cfg, nil
|
||||||
|
|||||||
@@ -25,20 +25,21 @@ type AuctionConstants struct {
|
|||||||
|
|
||||||
// AuctionVariables are the variables of the Auction Smart Contract
|
// AuctionVariables are the variables of the Auction Smart Contract
|
||||||
type AuctionVariables struct {
|
type AuctionVariables struct {
|
||||||
|
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
|
||||||
// Boot Coordinator Address
|
// Boot Coordinator Address
|
||||||
DonationAddress ethCommon.Address `json:"donationAddress" meddler:"donation_address"`
|
DonationAddress ethCommon.Address `json:"donationAddress" meddler:"donation_address" validate:"required"`
|
||||||
// Boot Coordinator Address
|
// Boot Coordinator Address
|
||||||
BootCoordinator ethCommon.Address `json:"bootCoordinator" meddler:"boot_coordinator"`
|
BootCoordinator ethCommon.Address `json:"bootCoordinator" meddler:"boot_coordinator" validate:"required"`
|
||||||
// The minimum bid value in a series of 6 slots
|
// The minimum bid value in a series of 6 slots
|
||||||
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json"`
|
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json" validate:"required"`
|
||||||
// Distance (#slots) to the closest slot to which you can bid ( 2 Slots = 2 * 40 Blocks = 20 min )
|
// Distance (#slots) to the closest slot to which you can bid ( 2 Slots = 2 * 40 Blocks = 20 min )
|
||||||
ClosedAuctionSlots uint16 `json:"closedAuctionSlots" meddler:"closed_auction_slots"`
|
ClosedAuctionSlots uint16 `json:"closedAuctionSlots" meddler:"closed_auction_slots" validate:"required"`
|
||||||
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
|
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
|
||||||
OpenAuctionSlots uint16 `json:"openAuctionSlots" meddler:"open_auction_slots"`
|
OpenAuctionSlots uint16 `json:"openAuctionSlots" meddler:"open_auction_slots" validate:"required"`
|
||||||
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation: 40% - HGT: 20%)
|
// How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation: 40% - HGT: 20%)
|
||||||
AllocationRatio [3]uint16 `json:"allocationRatio" meddler:"allocation_ratio,json"`
|
AllocationRatio [3]uint16 `json:"allocationRatio" meddler:"allocation_ratio,json" validate:"required"`
|
||||||
// Minimum outbid (percentage) over the previous one to consider it valid
|
// Minimum outbid (percentage) over the previous one to consider it valid
|
||||||
Outbidding uint16 `json:"outbidding" meddler:"outbidding"`
|
Outbidding uint16 `json:"outbidding" meddler:"outbidding" validate:"required"`
|
||||||
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
|
// Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
|
||||||
SlotDeadline uint8 `json:"slotDeadline" meddler:"slot_deadline"`
|
SlotDeadline uint8 `json:"slotDeadline" meddler:"slot_deadline" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,8 +157,9 @@ type Bucket struct {
|
|||||||
|
|
||||||
// RollupVariables are the variables of the Rollup Smart Contract
|
// RollupVariables are the variables of the Rollup Smart Contract
|
||||||
type RollupVariables struct {
|
type RollupVariables struct {
|
||||||
FeeAddToken *big.Int `json:"feeAddToken" meddler:"fee_addtoken"`
|
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
|
||||||
ForgeL1L2BatchTimeout int64 `json:"forgeL1L2BatchTimeout" meddler:"forge_l1l2_timeout"`
|
FeeAddToken *big.Int `json:"feeAddToken" meddler:"fee_add_token,bigint" validate:"required"`
|
||||||
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
|
ForgeL1L2BatchTimeout int64 `json:"forgeL1L2BatchTimeout" meddler:"forge_l1_timeout" validate:"required"`
|
||||||
Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
|
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay" validate:"required"`
|
||||||
|
// Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ type WDelayerConstants struct {
|
|||||||
|
|
||||||
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
|
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
|
||||||
type WDelayerVariables struct {
|
type WDelayerVariables struct {
|
||||||
HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`
|
EthBlockNum int64 `json:"ethereumBlockNum" meddler:"eth_block_num"`
|
||||||
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress" meddler:"govdao_address"`
|
// HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`
|
||||||
WhiteHackGroupAddress ethCommon.Address `json:"whiteHackGroupAddress" meddler:"whg_address"`
|
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress" meddler:"govdao_address" validate:"required"`
|
||||||
HermezKeeperAddress ethCommon.Address `json:"hermezKeeperAddress" meddler:"keeper_address"`
|
WhiteHackGroupAddress ethCommon.Address `json:"whiteHackGroupAddress" meddler:"whg_address" validate:"required"`
|
||||||
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
|
HermezKeeperAddress ethCommon.Address `json:"hermezKeeperAddress" meddler:"keeper_address" validate:"required"`
|
||||||
|
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay" validate:"required"`
|
||||||
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
|
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
|
||||||
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
|
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,5 +282,7 @@ func L1CoordinatorTxFromBytes(b []byte) (*L1Tx, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tx.FromEthAddr = crypto.PubkeyToAddress(*pubKey)
|
tx.FromEthAddr = crypto.PubkeyToAddress(*pubKey)
|
||||||
|
tx.Amount = big.NewInt(0)
|
||||||
|
tx.LoadAmount = big.NewInt(0)
|
||||||
return tx, nil
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,6 +158,8 @@ func TestL1CoordinatorTxByteParsers(t *testing.T) {
|
|||||||
TokenID: 231,
|
TokenID: 231,
|
||||||
FromBJJ: pk,
|
FromBJJ: pk,
|
||||||
FromEthAddr: fromEthAddr,
|
FromEthAddr: fromEthAddr,
|
||||||
|
Amount: big.NewInt(0),
|
||||||
|
LoadAmount: big.NewInt(0),
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesCoordinatorL1, err := l1Tx.BytesCoordinatorTx(signature)
|
bytesCoordinatorL1, err := l1Tx.BytesCoordinatorTx(signature)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ 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"
|
||||||
"gopkg.in/go-playground/validator.v9"
|
"gopkg.in/go-playground/validator.v9"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -65,16 +66,14 @@ 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"`
|
||||||
StartBlockNum struct {
|
StartBlockNum synchronizer.ConfigStartBlockNum `validate:"required"`
|
||||||
Rollup int64 `validate:"required"`
|
InitialVariables synchronizer.SCVariables `validate:"required"`
|
||||||
Auction int64 `validate:"required"`
|
|
||||||
WDelayer int64 `validate:"required"`
|
|
||||||
} `validate:"required"`
|
|
||||||
} `validate:"required"`
|
} `validate:"required"`
|
||||||
SmartContracts struct {
|
SmartContracts struct {
|
||||||
Rollup ethCommon.Address `validate:"required"`
|
Rollup ethCommon.Address `validate:"required"`
|
||||||
Auction ethCommon.Address `validate:"required"`
|
Auction ethCommon.Address `validate:"required"`
|
||||||
|
WDelayer ethCommon.Address `validate:"required"`
|
||||||
TokenHEZ ethCommon.Address `validate:"required"`
|
TokenHEZ ethCommon.Address `validate:"required"`
|
||||||
TokenHEZName string `validate:"required"`
|
TokenHEZName string `validate:"required"`
|
||||||
} `validate:"required"`
|
} `validate:"required"`
|
||||||
|
|||||||
@@ -1097,6 +1097,72 @@ func (hdb *HistoryDB) GetLastTxsPosition(toForgeL1TxsNum int64) (int, error) {
|
|||||||
return lastL1TxsPosition, row.Scan(&lastL1TxsPosition)
|
return lastL1TxsPosition, row.Scan(&lastL1TxsPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSCVars returns the rollup, auction and wdelayer smart contracts variables at their last update.
|
||||||
|
func (hdb *HistoryDB) GetSCVars() (*common.RollupVariables, *common.AuctionVariables,
|
||||||
|
*common.WDelayerVariables, error) {
|
||||||
|
var rollup common.RollupVariables
|
||||||
|
var auction common.AuctionVariables
|
||||||
|
var wDelayer common.WDelayerVariables
|
||||||
|
if err := meddler.QueryRow(hdb.db, &rollup,
|
||||||
|
"SELECT * FROM rollup_vars ORDER BY eth_block_num DESC LIMIT 1;"); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
if err := meddler.QueryRow(hdb.db, &auction,
|
||||||
|
"SELECT * FROM auction_vars ORDER BY eth_block_num DESC LIMIT 1;"); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
if err := meddler.QueryRow(hdb.db, &wDelayer,
|
||||||
|
"SELECT * FROM wdelayer_vars ORDER BY eth_block_num DESC LIMIT 1;"); err != nil {
|
||||||
|
return nil, nil, nil, err
|
||||||
|
}
|
||||||
|
return &rollup, &auction, &wDelayer, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hdb *HistoryDB) setRollupVars(d meddler.DB, rollup *common.RollupVariables) error {
|
||||||
|
return meddler.Insert(d, "rollup_vars", rollup)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hdb *HistoryDB) setAuctionVars(d meddler.DB, auction *common.AuctionVariables) error {
|
||||||
|
return meddler.Insert(d, "auction_vars", auction)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hdb *HistoryDB) setWDelayerVars(d meddler.DB, wDelayer *common.WDelayerVariables) error {
|
||||||
|
return meddler.Insert(d, "wdelayer_vars", wDelayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetInitialSCVars sets the initial state of rollup, auction, wdelayer smart
|
||||||
|
// contract variables. This initial state is stored linked to block 0, which
|
||||||
|
// always exist in the DB and is used to store initialization data that always
|
||||||
|
// exist in the smart contracts.
|
||||||
|
func (hdb *HistoryDB) SetInitialSCVars(rollup *common.RollupVariables,
|
||||||
|
auction *common.AuctionVariables, wDelayer *common.WDelayerVariables) error {
|
||||||
|
txn, err := hdb.db.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
db.Rollback(txn)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
// Force EthBlockNum to be 0 because it's the block used to link data
|
||||||
|
// that belongs to the creation of the smart contracts
|
||||||
|
rollup.EthBlockNum = 0
|
||||||
|
auction.EthBlockNum = 0
|
||||||
|
wDelayer.EthBlockNum = 0
|
||||||
|
if err := hdb.setRollupVars(txn, rollup); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := hdb.setAuctionVars(txn, auction); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := hdb.setWDelayerVars(txn, wDelayer); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return txn.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
// AddBlockSCData stores all the information of a block retrieved by the
|
// AddBlockSCData stores all the information of a block retrieved by the
|
||||||
// Synchronizer. Blocks should be inserted in order, leaving no gaps because
|
// Synchronizer. Blocks should be inserted in order, leaving no gaps because
|
||||||
// the pagination system of the API/DB depends on this. Within blocks, all
|
// the pagination system of the API/DB depends on this. Within blocks, all
|
||||||
@@ -1108,47 +1174,39 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errRollback := txn.Rollback()
|
db.Rollback(txn)
|
||||||
if errRollback != nil {
|
|
||||||
log.Errorw("Rollback", "err", errRollback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Add block
|
// Add block
|
||||||
err = hdb.addBlock(txn, &blockData.Block)
|
if err := hdb.addBlock(txn, &blockData.Block); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Coordinators
|
// Add Coordinators
|
||||||
if len(blockData.Auction.Coordinators) > 0 {
|
if len(blockData.Auction.Coordinators) > 0 {
|
||||||
err = hdb.addCoordinators(txn, blockData.Auction.Coordinators)
|
if err := hdb.addCoordinators(txn, blockData.Auction.Coordinators); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Bids
|
// Add Bids
|
||||||
if len(blockData.Auction.Bids) > 0 {
|
if len(blockData.Auction.Bids) > 0 {
|
||||||
err = hdb.addBids(txn, blockData.Auction.Bids)
|
if err := hdb.addBids(txn, blockData.Auction.Bids); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Tokens
|
// Add Tokens
|
||||||
if len(blockData.Rollup.AddedTokens) > 0 {
|
if len(blockData.Rollup.AddedTokens) > 0 {
|
||||||
err = hdb.addTokens(txn, blockData.Rollup.AddedTokens)
|
if err := hdb.addTokens(txn, blockData.Rollup.AddedTokens); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add l1 Txs
|
// Add l1 Txs
|
||||||
if len(blockData.Rollup.L1UserTxs) > 0 {
|
if len(blockData.Rollup.L1UserTxs) > 0 {
|
||||||
err = hdb.addL1Txs(txn, blockData.Rollup.L1UserTxs)
|
if err := hdb.addL1Txs(txn, blockData.Rollup.L1UserTxs); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1158,16 +1216,14 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
batch := &blockData.Rollup.Batches[i]
|
batch := &blockData.Rollup.Batches[i]
|
||||||
// Add Batch: this will trigger an update on the DB
|
// Add Batch: this will trigger an update on the DB
|
||||||
// that will set the batch num of forged L1 txs in this batch
|
// that will set the batch num of forged L1 txs in this batch
|
||||||
err = hdb.addBatch(txn, &batch.Batch)
|
if err = hdb.addBatch(txn, &batch.Batch); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add unforged l1 Txs
|
// Add unforged l1 Txs
|
||||||
if batch.L1Batch {
|
if batch.L1Batch {
|
||||||
if len(batch.L1CoordinatorTxs) > 0 {
|
if len(batch.L1CoordinatorTxs) > 0 {
|
||||||
err = hdb.addL1Txs(txn, batch.L1CoordinatorTxs)
|
if err := hdb.addL1Txs(txn, batch.L1CoordinatorTxs); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1175,29 +1231,39 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
|
|||||||
|
|
||||||
// Add l2 Txs
|
// Add l2 Txs
|
||||||
if len(batch.L2Txs) > 0 {
|
if len(batch.L2Txs) > 0 {
|
||||||
err = hdb.addL2Txs(txn, batch.L2Txs)
|
if err := hdb.addL2Txs(txn, batch.L2Txs); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add accounts
|
// Add accounts
|
||||||
if len(batch.CreatedAccounts) > 0 {
|
if len(batch.CreatedAccounts) > 0 {
|
||||||
err = hdb.addAccounts(txn, batch.CreatedAccounts)
|
if err := hdb.addAccounts(txn, batch.CreatedAccounts); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add exit tree
|
// Add exit tree
|
||||||
if len(batch.ExitTree) > 0 {
|
if len(batch.ExitTree) > 0 {
|
||||||
err = hdb.addExitTree(txn, batch.ExitTree)
|
if err := hdb.addExitTree(txn, batch.ExitTree); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// TODO: INSERT CONTRACTS VARS
|
if blockData.Rollup.Vars != nil {
|
||||||
|
if err := hdb.setRollupVars(txn, blockData.Rollup.Vars); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if blockData.Auction.Vars != nil {
|
||||||
|
if err := hdb.setAuctionVars(txn, blockData.Auction.Vars); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if blockData.WDelayer.Vars != nil {
|
||||||
|
if err := hdb.setWDelayerVars(txn, blockData.WDelayer.Vars); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Process withdrawals
|
// TODO: Process withdrawals
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package historydb
|
package historydb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
ethCommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/hermeznetwork/hermez-node/common"
|
"github.com/hermeznetwork/hermez-node/common"
|
||||||
dbUtils "github.com/hermeznetwork/hermez-node/db"
|
dbUtils "github.com/hermeznetwork/hermez-node/db"
|
||||||
"github.com/hermeznetwork/hermez-node/log"
|
"github.com/hermeznetwork/hermez-node/log"
|
||||||
@@ -429,6 +431,52 @@ func TestGetL1UserTxs(t *testing.T) {
|
|||||||
assert.Equal(t, 0, len(l1UserTxs))
|
assert.Equal(t, 0, len(l1UserTxs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSetInitialSCVars(t *testing.T) {
|
||||||
|
test.WipeDB(historyDB.DB())
|
||||||
|
_, _, _, err := historyDB.GetSCVars()
|
||||||
|
assert.Equal(t, sql.ErrNoRows, err)
|
||||||
|
|
||||||
|
//nolint:govet
|
||||||
|
rollup := &common.RollupVariables{
|
||||||
|
0,
|
||||||
|
big.NewInt(10),
|
||||||
|
12,
|
||||||
|
13,
|
||||||
|
}
|
||||||
|
//nolint:govet
|
||||||
|
auction := &common.AuctionVariables{
|
||||||
|
0,
|
||||||
|
ethCommon.BigToAddress(big.NewInt(2)),
|
||||||
|
ethCommon.BigToAddress(big.NewInt(3)),
|
||||||
|
[6]*big.Int{
|
||||||
|
big.NewInt(1), big.NewInt(2), big.NewInt(3),
|
||||||
|
big.NewInt(4), big.NewInt(5), big.NewInt(6),
|
||||||
|
},
|
||||||
|
2,
|
||||||
|
4320,
|
||||||
|
[3]uint16{10, 11, 12},
|
||||||
|
1000,
|
||||||
|
20,
|
||||||
|
}
|
||||||
|
//nolint:govet
|
||||||
|
wDelayer := &common.WDelayerVariables{
|
||||||
|
0,
|
||||||
|
ethCommon.BigToAddress(big.NewInt(2)),
|
||||||
|
ethCommon.BigToAddress(big.NewInt(3)),
|
||||||
|
ethCommon.BigToAddress(big.NewInt(4)),
|
||||||
|
13,
|
||||||
|
14,
|
||||||
|
false,
|
||||||
|
}
|
||||||
|
err = historyDB.SetInitialSCVars(rollup, auction, wDelayer)
|
||||||
|
require.Nil(t, err)
|
||||||
|
dbRollup, dbAuction, dbWDelayer, err := historyDB.GetSCVars()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
require.Equal(t, rollup, dbRollup)
|
||||||
|
require.Equal(t, auction, dbAuction)
|
||||||
|
require.Equal(t, wDelayer, dbWDelayer)
|
||||||
|
}
|
||||||
|
|
||||||
// setTestBlocks WARNING: this will delete the blocks and recreate them
|
// setTestBlocks WARNING: this will delete the blocks and recreate them
|
||||||
func setTestBlocks(from, to int64) []common.Block {
|
func setTestBlocks(from, to int64) []common.Block {
|
||||||
test.WipeDB(historyDB.DB())
|
test.WipeDB(historyDB.DB())
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
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/db"
|
"github.com/hermeznetwork/hermez-node/db"
|
||||||
"github.com/hermeznetwork/hermez-node/log"
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
//nolint:errcheck // driver for postgres DB
|
//nolint:errcheck // driver for postgres DB
|
||||||
@@ -243,10 +242,7 @@ func (l2db *L2DB) CheckNonces(updatedAccounts []common.Account, batchNum common.
|
|||||||
defer func() {
|
defer func() {
|
||||||
// Rollback the transaction if there was an error.
|
// Rollback the transaction if there was an error.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errRollback := txn.Rollback()
|
db.Rollback(txn)
|
||||||
if errRollback != nil {
|
|
||||||
log.Errorw("Rollback", "err", errRollback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
for i := 0; i < len(updatedAccounts); i++ {
|
for i := 0; i < len(updatedAccounts); i++ {
|
||||||
@@ -291,10 +287,7 @@ func (l2db *L2DB) Purge(currentBatchNum common.BatchNum) (err error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
// Rollback the transaction if there was an error.
|
// Rollback the transaction if there was an error.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errRollback := txn.Rollback()
|
db.Rollback(txn)
|
||||||
if errRollback != nil {
|
|
||||||
log.Errorw("Rollback", "err", errRollback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// Delete pending txs that have been in the pool after the TTL if maxTxs is reached
|
// Delete pending txs that have been in the pool after the TTL if maxTxs is reached
|
||||||
|
|||||||
@@ -516,23 +516,31 @@ FOR EACH ROW EXECUTE PROCEDURE forge_l1_user_txs();
|
|||||||
|
|
||||||
CREATE TABLE rollup_vars (
|
CREATE TABLE rollup_vars (
|
||||||
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
forge_l1_timeout BYTEA NOT NULL,
|
|
||||||
fee_l1_user_tx BYTEA NOT NULL,
|
|
||||||
fee_add_token BYTEA NOT NULL,
|
fee_add_token BYTEA NOT NULL,
|
||||||
tokens_hez BYTEA NOT NULL,
|
forge_l1_timeout BYTEA NOT NULL,
|
||||||
governance BYTEA NOT NULL
|
withdrawal_delay BIGINT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE consensus_vars (
|
CREATE TABLE auction_vars (
|
||||||
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
slot_deadline INT NOT NULL,
|
|
||||||
close_auction_slots INT NOT NULL,
|
|
||||||
open_auction_slots INT NOT NULL,
|
|
||||||
min_bid_slots VARCHAR(200) NOT NULL,
|
|
||||||
outbidding INT NOT NULL,
|
|
||||||
donation_address BYTEA NOT NULL,
|
donation_address BYTEA NOT NULL,
|
||||||
governance_address BYTEA NOT NULL,
|
boot_coordinator BYTEA NOT NULL,
|
||||||
allocation_ratio VARCHAR(200)
|
default_slot_set_bid BYTEA NOT NULL,
|
||||||
|
closed_auction_slots INT NOT NULL,
|
||||||
|
open_auction_slots INT NOT NULL,
|
||||||
|
allocation_ratio VARCHAR(200),
|
||||||
|
outbidding INT NOT NULL,
|
||||||
|
slot_deadline INT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE wdelayer_vars (
|
||||||
|
eth_block_num BIGINT PRIMARY KEY REFERENCES block (eth_block_num) ON DELETE CASCADE,
|
||||||
|
govdao_address BYTEA NOT NULL,
|
||||||
|
whg_address BYTEA NOT NULL,
|
||||||
|
keeper_address BYTEA NOT NULL,
|
||||||
|
withdrawal_delay BIGINT NOT NULL,
|
||||||
|
emergency_start_time BIGINT NOT NULL,
|
||||||
|
emergency_mode BOOLEAN NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- L2
|
-- L2
|
||||||
@@ -606,8 +614,9 @@ DROP FUNCTION set_pool_tx;
|
|||||||
-- drop tables
|
-- drop tables
|
||||||
DROP TABLE account_creation_auth;
|
DROP TABLE account_creation_auth;
|
||||||
DROP TABLE tx_pool;
|
DROP TABLE tx_pool;
|
||||||
DROP TABLE consensus_vars;
|
DROP TABLE auction_vars;
|
||||||
DROP TABLE rollup_vars;
|
DROP TABLE rollup_vars;
|
||||||
|
DROP TABLE wdelayer_vars;
|
||||||
DROP TABLE tx;
|
DROP TABLE tx;
|
||||||
DROP TABLE exit_tree;
|
DROP TABLE exit_tree;
|
||||||
DROP TABLE account;
|
DROP TABLE account;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
@@ -192,3 +193,11 @@ type Paginationer interface {
|
|||||||
GetPagination() *Pagination
|
GetPagination() *Pagination
|
||||||
Len() int
|
Len() int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rollback an sql transaction, and log the error if it's not nil
|
||||||
|
func Rollback(txn *sql.Tx) {
|
||||||
|
err := txn.Rollback()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorw("Rollback", "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type ClientInterface interface {
|
|||||||
EthereumInterface
|
EthereumInterface
|
||||||
RollupInterface
|
RollupInterface
|
||||||
AuctionInterface
|
AuctionInterface
|
||||||
|
WDelayerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -28,6 +29,7 @@ type Client struct {
|
|||||||
EthereumClient
|
EthereumClient
|
||||||
AuctionClient
|
AuctionClient
|
||||||
RollupClient
|
RollupClient
|
||||||
|
WDelayerClient
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenConfig is used to define the information about token
|
// TokenConfig is used to define the information about token
|
||||||
@@ -47,11 +49,17 @@ type AuctionConfig struct {
|
|||||||
TokenHEZ TokenConfig
|
TokenHEZ TokenConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WDelayerConfig is the configuration for the WDelayer smart contract interface
|
||||||
|
type WDelayerConfig struct {
|
||||||
|
Address ethCommon.Address
|
||||||
|
}
|
||||||
|
|
||||||
// ClientConfig is the configuration of the Client
|
// ClientConfig is the configuration of the Client
|
||||||
type ClientConfig struct {
|
type ClientConfig struct {
|
||||||
Ethereum EthereumConfig
|
Ethereum EthereumConfig
|
||||||
Rollup RollupConfig
|
Rollup RollupConfig
|
||||||
Auction AuctionConfig
|
Auction AuctionConfig
|
||||||
|
WDelayer WDelayerConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClient creates a new Client to interact with Ethereum and the Hermez smart contracts.
|
// NewClient creates a new Client to interact with Ethereum and the Hermez smart contracts.
|
||||||
@@ -61,13 +69,18 @@ func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeyst
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rollupCient, err := NewRollupClient(ethereumClient, cfg.Rollup.Address, cfg.Auction.TokenHEZ)
|
rollupClient, err := NewRollupClient(ethereumClient, cfg.Rollup.Address, cfg.Auction.TokenHEZ)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
wDelayerClient, err := NewWDelayerClient(ethereumClient, cfg.WDelayer.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Client{
|
return &Client{
|
||||||
EthereumClient: *ethereumClient,
|
EthereumClient: *ethereumClient,
|
||||||
AuctionClient: *auctionClient,
|
AuctionClient: *auctionClient,
|
||||||
RollupClient: *rollupCient,
|
RollupClient: *rollupClient,
|
||||||
|
WDelayerClient: *wDelayerClient,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -510,9 +510,6 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if len(logs) > 0 {
|
if len(logs) > 0 {
|
||||||
for i := range logs {
|
|
||||||
log.Debugw("log", "i", i, "blockHash", logs[i].BlockHash)
|
|
||||||
}
|
|
||||||
blockHash = &logs[0].BlockHash
|
blockHash = &logs[0].BlockHash
|
||||||
}
|
}
|
||||||
for _, vLog := range logs {
|
for _, vLog := range logs {
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ type WDelayerInterface interface {
|
|||||||
WDelayerGetEmergencyModeStartingTime() (*big.Int, error)
|
WDelayerGetEmergencyModeStartingTime() (*big.Int, error)
|
||||||
WDelayerEnableEmergencyMode() (*types.Transaction, error)
|
WDelayerEnableEmergencyMode() (*types.Transaction, error)
|
||||||
WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*types.Transaction, error)
|
WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*types.Transaction, error)
|
||||||
WDelayerDepositInfo(owner, token ethCommon.Address) (*big.Int, uint64)
|
WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error)
|
||||||
WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
|
WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
|
||||||
WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error)
|
WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error)
|
||||||
WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
|
WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
|
||||||
@@ -340,7 +340,8 @@ func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Addre
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WDelayerConstants returns the Constants of the WDelayer Smart Contract
|
// WDelayerConstants returns the Constants of the WDelayer Smart Contract
|
||||||
func (c *WDelayerClient) WDelayerConstants() (constants common.WDelayerConstants, err error) {
|
func (c *WDelayerClient) WDelayerConstants() (constants *common.WDelayerConstants, err error) {
|
||||||
|
constants = new(common.WDelayerConstants)
|
||||||
if err := c.client.Call(func(ec *ethclient.Client) error {
|
if err := c.client.Call(func(ec *ethclient.Client) error {
|
||||||
constants.MaxWithdrawalDelay, err = c.wdelayer.MAXWITHDRAWALDELAY(nil)
|
constants.MaxWithdrawalDelay, err = c.wdelayer.MAXWITHDRAWALDELAY(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -377,7 +378,7 @@ var (
|
|||||||
// there are no events in that block, blockHash is nil.
|
// there are no events in that block, blockHash is nil.
|
||||||
func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) {
|
func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) {
|
||||||
var wdelayerEvents WDelayerEvents
|
var wdelayerEvents WDelayerEvents
|
||||||
var blockHash ethCommon.Hash
|
var blockHash *ethCommon.Hash
|
||||||
|
|
||||||
query := ethereum.FilterQuery{
|
query := ethereum.FilterQuery{
|
||||||
FromBlock: big.NewInt(blockNum),
|
FromBlock: big.NewInt(blockNum),
|
||||||
@@ -394,10 +395,10 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents,
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
if len(logs) > 0 {
|
if len(logs) > 0 {
|
||||||
blockHash = logs[0].BlockHash
|
blockHash = &logs[0].BlockHash
|
||||||
}
|
}
|
||||||
for _, vLog := range logs {
|
for _, vLog := range logs {
|
||||||
if vLog.BlockHash != blockHash {
|
if vLog.BlockHash != *blockHash {
|
||||||
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
|
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
|
||||||
return nil, nil, ErrBlockHashMismatchEvent
|
return nil, nil, ErrBlockHashMismatchEvent
|
||||||
}
|
}
|
||||||
@@ -470,5 +471,5 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents,
|
|||||||
wdelayerEvents.NewHermezGovernanceDAOAddress = append(wdelayerEvents.NewHermezGovernanceDAOAddress, governanceDAOAddress)
|
wdelayerEvents.NewHermezGovernanceDAOAddress = append(wdelayerEvents.NewHermezGovernanceDAOAddress, governanceDAOAddress)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &wdelayerEvents, &blockHash, nil
|
return &wdelayerEvents, blockHash, nil
|
||||||
}
|
}
|
||||||
|
|||||||
25
node/node.go
25
node/node.go
@@ -102,17 +102,17 @@ func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node,
|
|||||||
Name: cfg.SmartContracts.TokenHEZName,
|
Name: cfg.SmartContracts.TokenHEZName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
WDelayer: eth.WDelayerConfig{
|
||||||
|
Address: cfg.SmartContracts.WDelayer,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
|
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
|
||||||
StartBlockNum: synchronizer.ConfigStartBlockNum{
|
StartBlockNum: cfg.Synchronizer.StartBlockNum,
|
||||||
Rollup: cfg.Synchronizer.StartBlockNum.Rollup,
|
InitialVariables: cfg.Synchronizer.InitialVariables,
|
||||||
Auction: cfg.Synchronizer.StartBlockNum.Auction,
|
|
||||||
WDelayer: cfg.Synchronizer.StartBlockNum.WDelayer,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -176,9 +176,9 @@ func (n *Node) StartCoordinator() {
|
|||||||
n.stopGetProofCallForge = make(chan bool)
|
n.stopGetProofCallForge = make(chan bool)
|
||||||
n.stopForgeCallConfirm = make(chan bool)
|
n.stopForgeCallConfirm = make(chan bool)
|
||||||
|
|
||||||
n.stoppedForge = make(chan bool)
|
n.stoppedForge = make(chan bool, 1)
|
||||||
n.stoppedGetProofCallForge = make(chan bool)
|
n.stoppedGetProofCallForge = make(chan bool, 1)
|
||||||
n.stoppedForgeCallConfirm = make(chan bool)
|
n.stoppedForgeCallConfirm = make(chan bool, 1)
|
||||||
|
|
||||||
queueSize := 1
|
queueSize := 1
|
||||||
batchCh0 := make(chan *coordinator.BatchInfo, queueSize)
|
batchCh0 := make(chan *coordinator.BatchInfo, queueSize)
|
||||||
@@ -249,15 +249,18 @@ func (n *Node) StopCoordinator() {
|
|||||||
// StartSynchronizer starts the synchronizer
|
// StartSynchronizer starts the synchronizer
|
||||||
func (n *Node) StartSynchronizer() {
|
func (n *Node) StartSynchronizer() {
|
||||||
log.Info("Starting Synchronizer...")
|
log.Info("Starting Synchronizer...")
|
||||||
n.stoppedSync = make(chan bool)
|
// stopped channel is size 1 so that the defer doesn't block
|
||||||
|
n.stoppedSync = make(chan bool, 1)
|
||||||
go func() {
|
go func() {
|
||||||
defer func() { n.stoppedSync <- true }()
|
defer func() {
|
||||||
|
n.stoppedSync <- true
|
||||||
|
}()
|
||||||
var lastBlock *common.Block
|
var lastBlock *common.Block
|
||||||
d := time.Duration(0)
|
d := time.Duration(0)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-n.ctx.Done():
|
case <-n.ctx.Done():
|
||||||
log.Info("Coordinator stopped")
|
log.Info("Synchronizer stopped")
|
||||||
return
|
return
|
||||||
case <-time.After(d):
|
case <-time.After(d):
|
||||||
if blockData, discarded, err := n.sync.Sync2(n.ctx, lastBlock); err != nil {
|
if blockData, discarded, err := n.sync.Sync2(n.ctx, lastBlock); err != nil {
|
||||||
|
|||||||
@@ -41,14 +41,22 @@ var (
|
|||||||
// ConfigStartBlockNum sets the first block used to start tracking the smart
|
// ConfigStartBlockNum sets the first block used to start tracking the smart
|
||||||
// contracts
|
// contracts
|
||||||
type ConfigStartBlockNum struct {
|
type ConfigStartBlockNum struct {
|
||||||
Rollup int64
|
Rollup int64 `validate:"required"`
|
||||||
Auction int64
|
Auction int64 `validate:"required"`
|
||||||
WDelayer int64
|
WDelayer int64 `validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SCVariables joins all the smart contract variables in a single struct
|
||||||
|
type SCVariables struct {
|
||||||
|
Rollup common.RollupVariables `validate:"required"`
|
||||||
|
Auction common.AuctionVariables `validate:"required"`
|
||||||
|
WDelayer common.WDelayerVariables `validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the Synchronizer configuration
|
// Config is the Synchronizer configuration
|
||||||
type Config struct {
|
type Config struct {
|
||||||
StartBlockNum ConfigStartBlockNum
|
StartBlockNum ConfigStartBlockNum
|
||||||
|
InitialVariables SCVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronizer implements the Synchronizer type
|
// Synchronizer implements the Synchronizer type
|
||||||
@@ -61,6 +69,7 @@ type Synchronizer struct {
|
|||||||
stateDB *statedb.StateDB
|
stateDB *statedb.StateDB
|
||||||
cfg Config
|
cfg Config
|
||||||
startBlockNum int64
|
startBlockNum int64
|
||||||
|
vars SCVariables
|
||||||
// firstSavedBlock *common.Block
|
// firstSavedBlock *common.Block
|
||||||
// mux sync.Mutex
|
// mux sync.Mutex
|
||||||
}
|
}
|
||||||
@@ -78,12 +87,11 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
|
|||||||
log.Errorw("NewSynchronizer ethClient.RollupConstants()", "err", err)
|
log.Errorw("NewSynchronizer ethClient.RollupConstants()", "err", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// TODO: Uncomment once ethClient.WDelayerConstants() is implemented
|
wDelayerConstants, err := ethClient.WDelayerConstants()
|
||||||
// wDelayerConstants, err := ethClient.WDelayerConstants()
|
if err != nil {
|
||||||
// if err != nil {
|
log.Errorw("NewSynchronizer ethClient.WDelayerConstants()", "err", err)
|
||||||
// log.Errorw("NewSynchronizer ethClient.WDelayerConstants()", "err", err)
|
return nil, err
|
||||||
// return nil, err
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// Set startBlockNum to the minimum between Auction, Rollup and
|
// Set startBlockNum to the minimum between Auction, Rollup and
|
||||||
// WDelayer StartBlockNum
|
// WDelayer StartBlockNum
|
||||||
@@ -94,19 +102,17 @@ func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.History
|
|||||||
if startBlockNum < cfg.StartBlockNum.WDelayer {
|
if startBlockNum < cfg.StartBlockNum.WDelayer {
|
||||||
startBlockNum = cfg.StartBlockNum.WDelayer
|
startBlockNum = cfg.StartBlockNum.WDelayer
|
||||||
}
|
}
|
||||||
return &Synchronizer{
|
s := &Synchronizer{
|
||||||
ethClient: ethClient,
|
ethClient: ethClient,
|
||||||
auctionConstants: *auctionConstants,
|
auctionConstants: *auctionConstants,
|
||||||
// auctionConstants: common.AuctionConstants{},
|
rollupConstants: *rollupConstants,
|
||||||
rollupConstants: *rollupConstants,
|
wDelayerConstants: *wDelayerConstants,
|
||||||
// rollupConstants: common.RollupConstants{},
|
|
||||||
// wDelayerConstants: *wDelayerConstants,
|
|
||||||
wDelayerConstants: common.WDelayerConstants{},
|
|
||||||
historyDB: historyDB,
|
historyDB: historyDB,
|
||||||
stateDB: stateDB,
|
stateDB: stateDB,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
startBlockNum: startBlockNum,
|
startBlockNum: startBlockNum,
|
||||||
}, nil
|
}
|
||||||
|
return s, s.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuctionConstants returns the AuctionConstants read from the smart contract
|
// AuctionConstants returns the AuctionConstants read from the smart contract
|
||||||
@@ -124,6 +130,23 @@ func (s *Synchronizer) WDelayerConstants() *common.WDelayerConstants {
|
|||||||
return &s.wDelayerConstants
|
return &s.wDelayerConstants
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Synchronizer) init() error {
|
||||||
|
rollup, auction, wDelayer, err := s.historyDB.GetSCVars()
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
rollup = &s.cfg.InitialVariables.Rollup
|
||||||
|
auction = &s.cfg.InitialVariables.Auction
|
||||||
|
wDelayer = &s.cfg.InitialVariables.WDelayer
|
||||||
|
log.Debug("Setting initial SCVars in HistoryDB")
|
||||||
|
if err = s.historyDB.SetInitialSCVars(rollup, auction, wDelayer); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.vars.Rollup = *rollup
|
||||||
|
s.vars.Auction = *auction
|
||||||
|
s.vars.WDelayer = *wDelayer
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Sync2 attems to synchronize an ethereum block starting from lastSavedBlock.
|
// Sync2 attems to synchronize an ethereum block starting from lastSavedBlock.
|
||||||
// If lastSavedBlock is nil, the lastSavedBlock value is obtained from de DB.
|
// If lastSavedBlock is nil, the lastSavedBlock value is obtained from de DB.
|
||||||
// If a block is synched, it will be returned and also stored in the DB. If a
|
// If a block is synched, it will be returned and also stored in the DB. If a
|
||||||
@@ -325,7 +348,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
return &rollupData, nil
|
return &rollupData, nil
|
||||||
}
|
}
|
||||||
if *blockHash != ethBlock.Hash {
|
if *blockHash != ethBlock.Hash {
|
||||||
log.Errorw("Block hash mismatch", "expectd", ethBlock.Hash.String(),
|
log.Errorw("Block hash mismatch in Rollup events", "expected", ethBlock.Hash.String(),
|
||||||
"got", blockHash.String())
|
"got", blockHash.String())
|
||||||
return nil, eth.ErrBlockHashMismatchEvent
|
return nil, eth.ErrBlockHashMismatchEvent
|
||||||
}
|
}
|
||||||
@@ -498,16 +521,15 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
rollupData.AddedTokens = append(rollupData.AddedTokens, token)
|
rollupData.AddedTokens = append(rollupData.AddedTokens, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars common.RollupVariables
|
|
||||||
varsUpdate := false
|
varsUpdate := false
|
||||||
|
|
||||||
for _, evtUpdateForgeL1L2BatchTimeout := range rollupEvents.UpdateForgeL1L2BatchTimeout {
|
for _, evtUpdateForgeL1L2BatchTimeout := range rollupEvents.UpdateForgeL1L2BatchTimeout {
|
||||||
vars.ForgeL1L2BatchTimeout = evtUpdateForgeL1L2BatchTimeout.NewForgeL1L2BatchTimeout
|
s.vars.Rollup.ForgeL1L2BatchTimeout = evtUpdateForgeL1L2BatchTimeout.NewForgeL1L2BatchTimeout
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, evtUpdateFeeAddToken := range rollupEvents.UpdateFeeAddToken {
|
for _, evtUpdateFeeAddToken := range rollupEvents.UpdateFeeAddToken {
|
||||||
vars.FeeAddToken = evtUpdateFeeAddToken.NewFeeAddToken
|
s.vars.Rollup.FeeAddToken = evtUpdateFeeAddToken.NewFeeAddToken
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -524,7 +546,8 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if varsUpdate {
|
if varsUpdate {
|
||||||
rollupData.Vars = &vars
|
s.vars.Rollup.EthBlockNum = blockNum
|
||||||
|
rollupData.Vars = &s.vars.Rollup
|
||||||
}
|
}
|
||||||
|
|
||||||
return &rollupData, nil
|
return &rollupData, nil
|
||||||
@@ -552,7 +575,7 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
return &auctionData, nil
|
return &auctionData, nil
|
||||||
}
|
}
|
||||||
if *blockHash != ethBlock.Hash {
|
if *blockHash != ethBlock.Hash {
|
||||||
log.Errorw("Block hash mismatch", "expectd", ethBlock.Hash.String(),
|
log.Errorw("Block hash mismatch in Auction events", "expected", ethBlock.Hash.String(),
|
||||||
"got", blockHash.String())
|
"got", blockHash.String())
|
||||||
return nil, eth.ErrBlockHashMismatchEvent
|
return nil, eth.ErrBlockHashMismatchEvent
|
||||||
}
|
}
|
||||||
@@ -578,35 +601,34 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
auctionData.Coordinators = append(auctionData.Coordinators, coordinator)
|
auctionData.Coordinators = append(auctionData.Coordinators, coordinator)
|
||||||
}
|
}
|
||||||
|
|
||||||
var vars common.AuctionVariables
|
|
||||||
varsUpdate := false
|
varsUpdate := false
|
||||||
|
|
||||||
for _, evt := range auctionEvents.NewSlotDeadline {
|
for _, evt := range auctionEvents.NewSlotDeadline {
|
||||||
vars.SlotDeadline = evt.NewSlotDeadline
|
s.vars.Auction.SlotDeadline = evt.NewSlotDeadline
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewClosedAuctionSlots {
|
for _, evt := range auctionEvents.NewClosedAuctionSlots {
|
||||||
vars.ClosedAuctionSlots = evt.NewClosedAuctionSlots
|
s.vars.Auction.ClosedAuctionSlots = evt.NewClosedAuctionSlots
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewOutbidding {
|
for _, evt := range auctionEvents.NewOutbidding {
|
||||||
vars.Outbidding = evt.NewOutbidding
|
s.vars.Auction.Outbidding = evt.NewOutbidding
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewDonationAddress {
|
for _, evt := range auctionEvents.NewDonationAddress {
|
||||||
vars.DonationAddress = evt.NewDonationAddress
|
s.vars.Auction.DonationAddress = evt.NewDonationAddress
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewBootCoordinator {
|
for _, evt := range auctionEvents.NewBootCoordinator {
|
||||||
vars.BootCoordinator = evt.NewBootCoordinator
|
s.vars.Auction.BootCoordinator = evt.NewBootCoordinator
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewOpenAuctionSlots {
|
for _, evt := range auctionEvents.NewOpenAuctionSlots {
|
||||||
vars.OpenAuctionSlots = evt.NewOpenAuctionSlots
|
s.vars.Auction.OpenAuctionSlots = evt.NewOpenAuctionSlots
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewAllocationRatio {
|
for _, evt := range auctionEvents.NewAllocationRatio {
|
||||||
vars.AllocationRatio = evt.NewAllocationRatio
|
s.vars.Auction.AllocationRatio = evt.NewAllocationRatio
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
for _, evt := range auctionEvents.NewDefaultSlotSetBid {
|
for _, evt := range auctionEvents.NewDefaultSlotSetBid {
|
||||||
@@ -614,7 +636,7 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
return nil, fmt.Errorf("unexpected SlotSet in "+
|
return nil, fmt.Errorf("unexpected SlotSet in "+
|
||||||
"auctionEvents.NewDefaultSlotSetBid: %v", evt.SlotSet)
|
"auctionEvents.NewDefaultSlotSetBid: %v", evt.SlotSet)
|
||||||
}
|
}
|
||||||
vars.DefaultSlotSetBid[evt.SlotSet] = evt.NewInitialMinBid
|
s.vars.Auction.DefaultSlotSetBid[evt.SlotSet] = evt.NewInitialMinBid
|
||||||
varsUpdate = true
|
varsUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +645,8 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
// NOTE: We ignore HEZClaimed
|
// NOTE: We ignore HEZClaimed
|
||||||
|
|
||||||
if varsUpdate {
|
if varsUpdate {
|
||||||
auctionData.Vars = &vars
|
s.vars.Auction.EthBlockNum = blockNum
|
||||||
|
auctionData.Vars = &s.vars.Auction
|
||||||
}
|
}
|
||||||
|
|
||||||
return &auctionData, nil
|
return &auctionData, nil
|
||||||
@@ -631,12 +654,55 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData,
|
|||||||
|
|
||||||
// wdelayerSync gets information from the Withdrawal Delayer Contract
|
// wdelayerSync gets information from the Withdrawal Delayer Contract
|
||||||
func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*common.WDelayerData, error) {
|
func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*common.WDelayerData, error) {
|
||||||
// blockNum := ethBlock.EthBlockNum
|
blockNum := ethBlock.EthBlockNum
|
||||||
|
|
||||||
// TODO: Parse events to generate varialbes once ethClient.WDelayerEventsByBlock is implemented
|
|
||||||
|
|
||||||
wDelayerData := common.NewWDelayerData()
|
wDelayerData := common.NewWDelayerData()
|
||||||
|
|
||||||
|
// Get wDelayer events in the block
|
||||||
|
wDelayerEvents, blockHash, err := s.ethClient.WDelayerEventsByBlock(blockNum)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// No events in this block
|
||||||
|
if blockHash == nil {
|
||||||
|
return &wDelayerData, nil
|
||||||
|
}
|
||||||
|
if *blockHash != ethBlock.Hash {
|
||||||
|
log.Errorw("Block hash mismatch in WDelayer events", "expected", ethBlock.Hash.String(),
|
||||||
|
"got", blockHash.String())
|
||||||
|
return nil, eth.ErrBlockHashMismatchEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
varsUpdate := false
|
||||||
|
|
||||||
|
// TODO Deposit
|
||||||
|
// TODO Withdraw
|
||||||
|
// TODO EscapeHatchWithdrawal
|
||||||
|
for range wDelayerEvents.EmergencyModeEnabled {
|
||||||
|
s.vars.WDelayer.EmergencyMode = true
|
||||||
|
varsUpdate = true
|
||||||
|
}
|
||||||
|
for _, evt := range wDelayerEvents.NewWithdrawalDelay {
|
||||||
|
s.vars.WDelayer.WithdrawalDelay = evt.WithdrawalDelay
|
||||||
|
varsUpdate = true
|
||||||
|
}
|
||||||
|
for _, evt := range wDelayerEvents.NewHermezKeeperAddress {
|
||||||
|
s.vars.WDelayer.HermezKeeperAddress = evt.NewHermezKeeperAddress
|
||||||
|
varsUpdate = true
|
||||||
|
}
|
||||||
|
for _, evt := range wDelayerEvents.NewWhiteHackGroupAddress {
|
||||||
|
s.vars.WDelayer.WhiteHackGroupAddress = evt.NewWhiteHackGroupAddress
|
||||||
|
varsUpdate = true
|
||||||
|
}
|
||||||
|
for _, evt := range wDelayerEvents.NewHermezGovernanceDAOAddress {
|
||||||
|
s.vars.WDelayer.HermezGovernanceDAOAddress = evt.NewHermezGovernanceDAOAddress
|
||||||
|
varsUpdate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if varsUpdate {
|
||||||
|
s.vars.WDelayer.EthBlockNum = blockNum
|
||||||
|
wDelayerData.Vars = &s.vars.WDelayer
|
||||||
|
}
|
||||||
|
|
||||||
return &wDelayerData, nil
|
return &wDelayerData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -241,6 +241,11 @@ func TestSync(t *testing.T) {
|
|||||||
Auction: 1,
|
Auction: 1,
|
||||||
WDelayer: 1,
|
WDelayer: 1,
|
||||||
},
|
},
|
||||||
|
InitialVariables: SCVariables{
|
||||||
|
Rollup: *clientSetup.RollupVariables,
|
||||||
|
Auction: *clientSetup.AuctionVariables,
|
||||||
|
WDelayer: *clientSetup.WDelayerVariables,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WDelayerBlock stores all the data related to the WDelayer SC from an ethereum block
|
||||||
|
type WDelayerBlock struct {
|
||||||
|
// State eth.WDelayerState // TODO
|
||||||
|
Vars common.WDelayerVariables
|
||||||
|
Events eth.WDelayerEvents
|
||||||
|
Txs map[ethCommon.Hash]*types.Transaction
|
||||||
|
Constants *common.WDelayerConstants
|
||||||
|
Eth *EthereumBlock
|
||||||
|
}
|
||||||
|
|
||||||
// RollupBlock stores all the data related to the Rollup SC from an ethereum block
|
// RollupBlock stores all the data related to the Rollup SC from an ethereum block
|
||||||
type RollupBlock struct {
|
type RollupBlock struct {
|
||||||
State eth.RollupState
|
State eth.RollupState
|
||||||
@@ -185,9 +195,10 @@ type EthereumBlock struct {
|
|||||||
|
|
||||||
// Block represents a ethereum block
|
// Block represents a ethereum block
|
||||||
type Block struct {
|
type Block struct {
|
||||||
Rollup *RollupBlock
|
Rollup *RollupBlock
|
||||||
Auction *AuctionBlock
|
Auction *AuctionBlock
|
||||||
Eth *EthereumBlock
|
WDelayer *WDelayerBlock
|
||||||
|
Eth *EthereumBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Block) copy() *Block {
|
func (b *Block) copy() *Block {
|
||||||
@@ -210,8 +221,10 @@ func (b *Block) Next() *Block {
|
|||||||
|
|
||||||
blockNext.Rollup.Constants = b.Rollup.Constants
|
blockNext.Rollup.Constants = b.Rollup.Constants
|
||||||
blockNext.Auction.Constants = b.Auction.Constants
|
blockNext.Auction.Constants = b.Auction.Constants
|
||||||
|
blockNext.WDelayer.Constants = b.WDelayer.Constants
|
||||||
blockNext.Rollup.Eth = blockNext.Eth
|
blockNext.Rollup.Eth = blockNext.Eth
|
||||||
blockNext.Auction.Eth = blockNext.Eth
|
blockNext.Auction.Eth = blockNext.Eth
|
||||||
|
blockNext.WDelayer.Eth = blockNext.Eth
|
||||||
|
|
||||||
return blockNext
|
return blockNext
|
||||||
}
|
}
|
||||||
@@ -219,11 +232,13 @@ func (b *Block) Next() *Block {
|
|||||||
// ClientSetup is used to initialize the constants of the Smart Contracts and
|
// ClientSetup is used to initialize the constants of the Smart Contracts and
|
||||||
// other details of the test Client
|
// other details of the test Client
|
||||||
type ClientSetup struct {
|
type ClientSetup struct {
|
||||||
RollupConstants *common.RollupConstants
|
RollupConstants *common.RollupConstants
|
||||||
RollupVariables *common.RollupVariables
|
RollupVariables *common.RollupVariables
|
||||||
AuctionConstants *common.AuctionConstants
|
AuctionConstants *common.AuctionConstants
|
||||||
AuctionVariables *common.AuctionVariables
|
AuctionVariables *common.AuctionVariables
|
||||||
VerifyProof bool
|
WDelayerConstants *common.WDelayerConstants
|
||||||
|
WDelayerVariables *common.WDelayerVariables
|
||||||
|
VerifyProof bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClientSetupExample returns a ClientSetup example with hardcoded realistic
|
// NewClientSetupExample returns a ClientSetup example with hardcoded realistic
|
||||||
@@ -279,11 +294,26 @@ func NewClientSetupExample() *ClientSetup {
|
|||||||
Outbidding: 1000,
|
Outbidding: 1000,
|
||||||
SlotDeadline: 20,
|
SlotDeadline: 20,
|
||||||
}
|
}
|
||||||
|
wDelayerConstants := &common.WDelayerConstants{
|
||||||
|
MaxWithdrawalDelay: 60 * 60 * 24 * 7 * 2, // 2 weeks
|
||||||
|
MaxEmergencyModeTime: 60 * 60 * 24 * 7 * 26, // 26 weeks
|
||||||
|
HermezRollup: auctionConstants.HermezRollup,
|
||||||
|
}
|
||||||
|
wDelayerVariables := &common.WDelayerVariables{
|
||||||
|
HermezGovernanceDAOAddress: ethCommon.HexToAddress("0xcfD0d163AE6432a72682323E2C3A5a69e6B37D12"),
|
||||||
|
WhiteHackGroupAddress: ethCommon.HexToAddress("0x2730700932a4FDB97B9268A3Ca29f97Ea5fd7EA0"),
|
||||||
|
HermezKeeperAddress: ethCommon.HexToAddress("0x92aAD86176dC0f0046FE85Ed5dA008a828bE3868"),
|
||||||
|
WithdrawalDelay: 60,
|
||||||
|
EmergencyModeStartingTime: 0,
|
||||||
|
EmergencyMode: false,
|
||||||
|
}
|
||||||
return &ClientSetup{
|
return &ClientSetup{
|
||||||
RollupConstants: rollupConstants,
|
RollupConstants: rollupConstants,
|
||||||
RollupVariables: rollupVariables,
|
RollupVariables: rollupVariables,
|
||||||
AuctionConstants: auctionConstants,
|
AuctionConstants: auctionConstants,
|
||||||
AuctionVariables: auctionVariables,
|
AuctionVariables: auctionVariables,
|
||||||
|
WDelayerConstants: wDelayerConstants,
|
||||||
|
WDelayerVariables: wDelayerVariables,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,12 +337,13 @@ type batch struct {
|
|||||||
// Client implements the eth.ClientInterface interface, allowing to manipulate the
|
// Client implements the eth.ClientInterface interface, allowing to manipulate the
|
||||||
// values for testing, working with deterministic results.
|
// values for testing, working with deterministic results.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
rw *sync.RWMutex
|
rw *sync.RWMutex
|
||||||
log bool
|
log bool
|
||||||
addr *ethCommon.Address
|
addr *ethCommon.Address
|
||||||
rollupConstants *common.RollupConstants
|
rollupConstants *common.RollupConstants
|
||||||
auctionConstants *common.AuctionConstants
|
auctionConstants *common.AuctionConstants
|
||||||
blocks map[int64]*Block
|
wDelayerConstants *common.WDelayerConstants
|
||||||
|
blocks map[int64]*Block
|
||||||
// state state
|
// state state
|
||||||
blockNum int64 // last mined block num
|
blockNum int64 // last mined block num
|
||||||
maxBlockNum int64 // highest block num calculated
|
maxBlockNum int64 // highest block num calculated
|
||||||
@@ -365,6 +396,13 @@ func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup)
|
|||||||
Events: eth.NewAuctionEvents(),
|
Events: eth.NewAuctionEvents(),
|
||||||
Constants: setup.AuctionConstants,
|
Constants: setup.AuctionConstants,
|
||||||
},
|
},
|
||||||
|
WDelayer: &WDelayerBlock{
|
||||||
|
// State: TODO
|
||||||
|
Vars: *setup.WDelayerVariables,
|
||||||
|
Txs: make(map[ethCommon.Hash]*types.Transaction),
|
||||||
|
Events: eth.NewWDelayerEvents(),
|
||||||
|
Constants: setup.WDelayerConstants,
|
||||||
|
},
|
||||||
Eth: &EthereumBlock{
|
Eth: &EthereumBlock{
|
||||||
BlockNum: blockNum,
|
BlockNum: blockNum,
|
||||||
Time: timer.Time(),
|
Time: timer.Time(),
|
||||||
@@ -385,6 +423,7 @@ func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup)
|
|||||||
addr: addr,
|
addr: addr,
|
||||||
rollupConstants: setup.RollupConstants,
|
rollupConstants: setup.RollupConstants,
|
||||||
auctionConstants: setup.AuctionConstants,
|
auctionConstants: setup.AuctionConstants,
|
||||||
|
wDelayerConstants: setup.WDelayerConstants,
|
||||||
blocks: blocks,
|
blocks: blocks,
|
||||||
timer: timer,
|
timer: timer,
|
||||||
hasher: hasher,
|
hasher: hasher,
|
||||||
@@ -1343,3 +1382,202 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WDelayer
|
||||||
|
//
|
||||||
|
|
||||||
|
// WDelayerGetHermezGovernanceDAOAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerGetHermezGovernanceDAOAddress() (*ethCommon.Address, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerSetHermezGovernanceDAOAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerSetHermezGovernanceDAOAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerGetHermezKeeperAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerGetHermezKeeperAddress() (*ethCommon.Address, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerSetHermezKeeperAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerSetHermezKeeperAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerGetWhiteHackGroupAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerGetWhiteHackGroupAddress() (*ethCommon.Address, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerSetWhiteHackGroupAddress is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerSetWhiteHackGroupAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerIsEmergencyMode is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerIsEmergencyMode() (bool, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return false, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerGetWithdrawalDelay is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerGetWithdrawalDelay() (*big.Int, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerGetEmergencyModeStartingTime() (*big.Int, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerEnableEmergencyMode is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerDepositInfo is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerDepositInfo(owner, token ethCommon.Address) (eth.DepositState, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return eth.DepositState{}, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerDeposit is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerWithdrawal is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
|
||||||
|
func (c *Client) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
|
||||||
|
c.rw.Lock()
|
||||||
|
defer c.rw.Unlock()
|
||||||
|
cpy := c.nextBlock().copy()
|
||||||
|
defer func() { c.revertIfErr(err, cpy) }()
|
||||||
|
if c.addr == nil {
|
||||||
|
return nil, eth.ErrAccountNil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Error("TODO")
|
||||||
|
return nil, errTODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerEventsByBlock returns the events in a block that happened in the WDelayer Contract
|
||||||
|
func (c *Client) WDelayerEventsByBlock(blockNum int64) (*eth.WDelayerEvents, *ethCommon.Hash, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
block, ok := c.blocks[blockNum]
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum)
|
||||||
|
}
|
||||||
|
return &block.WDelayer.Events, &block.Eth.Hash, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WDelayerConstants returns the Constants of the WDelayer Contract
|
||||||
|
func (c *Client) WDelayerConstants() (*common.WDelayerConstants, error) {
|
||||||
|
c.rw.RLock()
|
||||||
|
defer c.rw.RUnlock()
|
||||||
|
|
||||||
|
return c.wDelayerConstants, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user