Browse Source

Reorganize smart contract types, udate eth tests, etc.

- Move smart contract constants and structs for variables to
  common/{ethrollup.go, ethauction.go, ethwdelayer.go}:
    - This removes repeated code of the structs for variables
    - Allows reusing the constants and variables from all modules without
      import cycles
- Remove unused common/scvars.go
- In common.BlockData, split data from each smart contract into a sepparate
  field (Rollup, Auction, WDelayer).  This affects the structures that til uses
  as output, and HistoryDB in the AddBlockSCData.
- In Synchronizer:
    - Pass starting block of each smart contract as config, instead of
      incorrectly using the genesis block found in the acution constant (which
      has a very different meaning)
    - Use variable structs from common instead of an internal copy
    - Synchronize more stuff (resolve some TODOs)
    - Fix some issues found after initial testing with ganache
- In eth:
    - In auction.go: Add method to get constants
    - Update README to use ganache instead of buidlerevm as local blockchain
      for testing
    - Update env variables and test vectors to pass the tests with the
      deployment in the ganache testnet.
    - Use ethereum keys derived from paths (hdwallet) in testing to avoid
      hardcoding private keys and generate the same keys from a mnemonic used
      in the ganache tesnet.
feature/sql-semaphore1
Eduard S 3 years ago
parent
commit
e6fb0a03de
36 changed files with 1006 additions and 722 deletions
  1. +15
    -16
      api/api_test.go
  2. +18
    -19
      api/dbtoapistructs.go
  3. +6
    -7
      api/state.go
  4. +37
    -0
      cli/node/cfg.buidler.toml
  5. +51
    -10
      common/block.go
  6. +44
    -0
      common/ethauction.go
  7. +164
    -0
      common/ethrollup.go
  8. +24
    -0
      common/ethwdelayer.go
  9. +7
    -0
      common/exittree.go
  10. +0
    -52
      common/scvars.go
  11. +5
    -0
      config/config.go
  12. +13
    -11
      db/historydb/historydb.go
  13. +2
    -2
      db/historydb/historydb_test.go
  14. +62
    -61
      db/statedb/txprocessors_test.go
  15. +6
    -6
      eth/.env.example
  16. +1
    -0
      eth/.gitignore
  17. +16
    -16
      eth/README.md
  18. +12
    -46
      eth/auction.go
  19. +1
    -1
      eth/auction_test.go
  20. +1
    -0
      eth/ethereum.go
  21. +1
    -1
      eth/ethereum_test.go
  22. +81
    -76
      eth/main_test.go
  23. +22
    -130
      eth/rollup.go
  24. +16
    -15
      eth/rollup_test.go
  25. +28
    -21
      eth/wdelayer.go
  26. +11
    -1
      eth/wdelayer_test.go
  27. +2
    -1
      go.mod
  28. +58
    -0
      go.sum
  29. +7
    -1
      node/node.go
  30. +185
    -124
      synchronizer/synchronizer.go
  31. +40
    -34
      synchronizer/synchronizer_test.go
  32. +19
    -20
      test/ethclient.go
  33. +3
    -3
      test/til/sets_test.go
  34. +6
    -4
      test/til/txs.go
  35. +38
    -39
      test/til/txs_test.go
  36. +4
    -5
      txselector/txselector_test.go

+ 15
- 16
api/api_test.go

@ -23,7 +23,6 @@ import (
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/db/statedb"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/hermez-node/test"
"github.com/iden3/go-iden3-crypto/babyjub"
@ -91,32 +90,32 @@ func TestMain(m *testing.M) {
l2DB := l2db.NewL2DB(database, 10, 100, 24*time.Hour)
test.WipeDB(l2DB.DB()) // this will clean HistoryDB and L2DB
// Config (smart contract constants)
config.RollupConstants.ExchangeMultiplier = eth.RollupConstExchangeMultiplier
config.RollupConstants.ExitIdx = eth.RollupConstExitIDx
config.RollupConstants.ReservedIdx = eth.RollupConstReservedIDx
config.RollupConstants.ExchangeMultiplier = common.RollupConstExchangeMultiplier
config.RollupConstants.ExitIdx = common.RollupConstExitIDx
config.RollupConstants.ReservedIdx = common.RollupConstReservedIDx
config.RollupConstants.LimitLoadAmount, _ = new(big.Int).SetString("340282366920938463463374607431768211456", 10)
config.RollupConstants.LimitL2TransferAmount, _ = new(big.Int).SetString("6277101735386680763835789423207666416102355444464034512896", 10)
config.RollupConstants.LimitTokens = eth.RollupConstLimitTokens
config.RollupConstants.L1CoordinatorTotalBytes = eth.RollupConstL1CoordinatorTotalBytes
config.RollupConstants.L1UserTotalBytes = eth.RollupConstL1UserTotalBytes
config.RollupConstants.MaxL1UserTx = eth.RollupConstMaxL1UserTx
config.RollupConstants.MaxL1Tx = eth.RollupConstMaxL1Tx
config.RollupConstants.InputSHAConstantBytes = eth.RollupConstInputSHAConstantBytes
config.RollupConstants.NumBuckets = eth.RollupConstNumBuckets
config.RollupConstants.MaxWithdrawalDelay = eth.RollupConstMaxWithdrawalDelay
var rollupPublicConstants eth.RollupPublicConstants
config.RollupConstants.LimitTokens = common.RollupConstLimitTokens
config.RollupConstants.L1CoordinatorTotalBytes = common.RollupConstL1CoordinatorTotalBytes
config.RollupConstants.L1UserTotalBytes = common.RollupConstL1UserTotalBytes
config.RollupConstants.MaxL1UserTx = common.RollupConstMaxL1UserTx
config.RollupConstants.MaxL1Tx = common.RollupConstMaxL1Tx
config.RollupConstants.InputSHAConstantBytes = common.RollupConstInputSHAConstantBytes
config.RollupConstants.NumBuckets = common.RollupConstNumBuckets
config.RollupConstants.MaxWithdrawalDelay = common.RollupConstMaxWithdrawalDelay
var rollupPublicConstants common.RollupConstants
rollupPublicConstants.AbsoluteMaxL1L2BatchTimeout = 240
rollupPublicConstants.HermezAuctionContract = ethCommon.HexToAddress("0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e")
rollupPublicConstants.HermezGovernanceDAOAddress = ethCommon.HexToAddress("0xeAD9C93b79Ae7C1591b1FB5323BD777E86e150d4")
rollupPublicConstants.SafetyAddress = ethCommon.HexToAddress("0xE5904695748fe4A84b40b3fc79De2277660BD1D3")
rollupPublicConstants.TokenHEZ = ethCommon.HexToAddress("0xf784709d2317D872237C4bC22f867d1BAe2913AB")
rollupPublicConstants.WithdrawDelayerContract = ethCommon.HexToAddress("0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe")
var verifier eth.RollupVerifierStruct
var verifier common.RollupVerifierStruct
verifier.MaxTx = 512
verifier.NLevels = 32
rollupPublicConstants.Verifiers = append(rollupPublicConstants.Verifiers, verifier)
var auctionConstants eth.AuctionConstants
var auctionConstants common.AuctionConstants
auctionConstants.BlocksPerSlot = 40
auctionConstants.GenesisBlockNum = 100
auctionConstants.GovernanceAddress = ethCommon.HexToAddress("0xeAD9C93b79Ae7C1591b1FB5323BD777E86e150d4")
@ -124,7 +123,7 @@ func TestMain(m *testing.M) {
auctionConstants.HermezRollup = ethCommon.HexToAddress("0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0")
auctionConstants.TokenHEZ = ethCommon.HexToAddress("0xf784709d2317D872237C4bC22f867d1BAe2913AB")
var wdelayerConstants eth.WDelayerConstants
var wdelayerConstants common.WDelayerConstants
wdelayerConstants.HermezRollup = ethCommon.HexToAddress("0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0")
wdelayerConstants.MaxEmergencyModeTime = uint64(1000000)
wdelayerConstants.MaxWithdrawalDelay = uint64(10000000)

+ 18
- 19
api/dbtoapistructs.go

@ -7,7 +7,6 @@ import (
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/iden3/go-iden3-crypto/babyjub"
)
@ -41,25 +40,25 @@ func idxToHez(idx common.Idx, tokenSymbol string) string {
// Config
type rollupConstants struct {
PublicConstants eth.RollupPublicConstants `json:"publicConstants"`
MaxFeeIdxCoordinator int `json:"maxFeeIdxCoordinator"`
ReservedIdx int `json:"reservedIdx"`
ExitIdx int `json:"exitIdx"`
LimitLoadAmount *big.Int `json:"limitLoadAmount"`
LimitL2TransferAmount *big.Int `json:"limitL2TransferAmount"`
LimitTokens int `json:"limitTokens"`
L1CoordinatorTotalBytes int `json:"l1CoordinatorTotalBytes"`
L1UserTotalBytes int `json:"l1UserTotalBytes"`
MaxL1UserTx int `json:"maxL1UserTx"`
MaxL1Tx int `json:"maxL1Tx"`
InputSHAConstantBytes int `json:"inputSHAConstantBytes"`
NumBuckets int `json:"numBuckets"`
MaxWithdrawalDelay int `json:"maxWithdrawalDelay"`
ExchangeMultiplier int `json:"exchangeMultiplier"`
PublicConstants common.RollupConstants `json:"publicConstants"`
MaxFeeIdxCoordinator int `json:"maxFeeIdxCoordinator"`
ReservedIdx int `json:"reservedIdx"`
ExitIdx int `json:"exitIdx"`
LimitLoadAmount *big.Int `json:"limitLoadAmount"`
LimitL2TransferAmount *big.Int `json:"limitL2TransferAmount"`
LimitTokens int `json:"limitTokens"`
L1CoordinatorTotalBytes int `json:"l1CoordinatorTotalBytes"`
L1UserTotalBytes int `json:"l1UserTotalBytes"`
MaxL1UserTx int `json:"maxL1UserTx"`
MaxL1Tx int `json:"maxL1Tx"`
InputSHAConstantBytes int `json:"inputSHAConstantBytes"`
NumBuckets int `json:"numBuckets"`
MaxWithdrawalDelay int `json:"maxWithdrawalDelay"`
ExchangeMultiplier int `json:"exchangeMultiplier"`
}
type configAPI struct {
RollupConstants rollupConstants `json:"hermez"`
AuctionConstants eth.AuctionConstants `json:"auction"`
WDelayerConstants eth.WDelayerConstants `json:"withdrawalDelayer"`
RollupConstants rollupConstants `json:"hermez"`
AuctionConstants common.AuctionConstants `json:"auction"`
WDelayerConstants common.WDelayerConstants `json:"withdrawalDelayer"`
}

+ 6
- 7
api/state.go

@ -3,15 +3,14 @@ package api
import (
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/eth"
)
// Status define status of the network
type Status struct {
Network historydb.Network `json:"network"`
Metrics historydb.Metrics `json:"metrics"`
Rollup eth.RollupVariables `json:"rollup"`
Auction eth.AuctionVariables `json:"auction"`
WithdrawalDelayer eth.WDelayerVariables `json:"withdrawalDelayer"`
RecommendedFee common.RecommendedFee `json:"recommendedFee"`
Network historydb.Network `json:"network"`
Metrics historydb.Metrics `json:"metrics"`
Rollup common.RollupVariables `json:"rollup"`
Auction common.AuctionVariables `json:"auction"`
WithdrawalDelayer common.WDelayerVariables `json:"withdrawalDelayer"`
RecommendedFee common.RecommendedFee `json:"recommendedFee"`
}

+ 37
- 0
cli/node/cfg.buidler.toml

@ -0,0 +1,37 @@
[StateDB]
Path = "/tmp/iden3-test/hermez/statedb"
[PostgreSQL]
Port = 5432
Host = "localhost"
User = "hermez"
Password = "yourpasswordhere"
Name = "hermez"
[L2DB]
SafetyPeriod = 10
MaxTxs = 512
TTL = "24h"
[Web3]
URL = "http://localhost:8545"
[Synchronizer]
SyncLoopInterval = "1s"
[Synchronizer.StartBlockNum]
Rollup = 1
Auction = 1
WDelayer = 1
[SmartContracts]
Rollup = "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe"
Auction = "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8"
TokenHEZ = "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c"
TokenHEZName = "Hermez Network Token"
[EthClient]
CallGasLimit = 300000
DeployGasLimit = 1000000
GasPriceDiv = 100
ReceiptTimeout = "60s"
IntervalReceiptLoop = "200ms"

+ 51
- 10
common/block.go

@ -14,20 +14,61 @@ type Block struct {
ParentHash ethCommon.Hash `meddler:"-"`
}
// BlockData contains the information of a Block
type BlockData struct {
Block Block
// Rollup
// RollupData contains information returned by the Rollup smart contract
type RollupData struct {
// L1UserTxs that were submitted in the block
L1UserTxs []L1Tx
Batches []BatchData
AddedTokens []Token
RollupVars *RollupVars
// Auction
Bids []Bid
Coordinators []Coordinator
AuctionVars *AuctionVars
WithdrawDelayerVars *WithdrawDelayerVars
Withdrawals []WithdrawInfo
Vars *RollupVariables
}
// NewRollupData creates an empty RollupData with the slices initialized.
func NewRollupData() RollupData {
return RollupData{
L1UserTxs: make([]L1Tx, 0),
Batches: make([]BatchData, 0),
AddedTokens: make([]Token, 0),
Withdrawals: make([]WithdrawInfo, 0),
Vars: nil,
}
}
// AuctionData contains information returned by the Action smart contract
type AuctionData struct {
Bids []Bid
Coordinators []Coordinator
Vars *AuctionVariables
}
// NewAuctionData creates an empty AuctionData with the slices initialized.
func NewAuctionData() AuctionData {
return AuctionData{
Bids: make([]Bid, 0),
Coordinators: make([]Coordinator, 0),
Vars: nil,
}
}
// WDelayerData contains information returned by the WDelayer smart contract
type WDelayerData struct {
Vars *WDelayerVariables
}
// NewWDelayerData creates an empty WDelayerData.
func NewWDelayerData() WDelayerData {
return WDelayerData{
Vars: nil,
}
}
// BlockData contains the information of a Block
type BlockData struct {
Block Block
Rollup RollupData
Auction AuctionData
WDelayer WDelayerData
// TODO: enable when common.WithdrawalDelayerVars is Merged from Synchronizer PR
// WithdrawalDelayerVars *common.WithdrawalDelayerVars
}

+ 44
- 0
common/ethauction.go

@ -0,0 +1,44 @@
package common
import (
"math/big"
ethCommon "github.com/ethereum/go-ethereum/common"
)
// AuctionConstants are the constants of the Rollup Smart Contract
type AuctionConstants struct {
// Blocks per slot
BlocksPerSlot uint8 `json:"blocksPerSlot"`
// Minimum bid when no one has bid yet
InitialMinimalBidding *big.Int `json:"initialMinimalBidding"`
// First block where the first slot begins
GenesisBlockNum int64 `json:"genesisBlockNum"`
// ERC777 token with which the bids will be made
TokenHEZ ethCommon.Address `json:"tokenHEZ"`
// HermezRollup smartcontract address
HermezRollup ethCommon.Address `json:"hermezRollup"`
// Hermez Governanze Token smartcontract address who controls some parameters and collects HEZ fee
// Only for test
GovernanceAddress ethCommon.Address `json:"governanceAddress"`
}
// AuctionVariables are the variables of the Auction Smart Contract
type AuctionVariables struct {
// Boot Coordinator Address
DonationAddress ethCommon.Address `json:"donationAddress" meddler:"donation_address"`
// Boot Coordinator Address
BootCoordinator ethCommon.Address `json:"bootCoordinator" meddler:"boot_coordinator"`
// The minimum bid value in a series of 6 slots
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json"`
// 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"`
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
OpenAuctionSlots uint16 `json:"openAuctionSlots" meddler:"open_auction_slots"`
// 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"`
// Minimum outbid (percentage) over the previous one to consider it valid
Outbidding uint16 `json:"outbidding" meddler:"outbidding"`
// 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"`
}

+ 164
- 0
common/ethrollup.go

@ -0,0 +1,164 @@
package common
import (
"math/big"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
)
// RollupVars contain the Rollup smart contract variables
// type RollupVars struct {
// EthBlockNum uint64
// ForgeL1Timeout *big.Int
// FeeL1UserTx *big.Int
// FeeAddToken *big.Int
// TokensHEZ eth.Address
// Governance eth.Address
// }
// AuctionVars contain the Auction smart contract variables
// type AuctionVars struct {
// EthBlockNum uint64
// SlotDeadline uint
// CloseAuctionSlots uint
// OpenAuctionSlots uint
// Governance eth.Address
// MinBidSlots MinBidSlots
// Outbidding int
// DonationAddress eth.Address
// GovernanceAddress eth.Address
// AllocationRatio AllocationRatio
// }
// WithdrawDelayerVars contains the Withdrawal Delayer smart contract variables
// type WithdrawDelayerVars struct {
// HermezRollupAddress eth.Address
// HermezGovernanceDAOAddress eth.Address
// WhiteHackGroupAddress eth.Address
// WithdrawalDelay uint
// EmergencyModeStartingTime time.Time
// EmergencyModeEnabled bool
// }
// MinBidSlots TODO
// type MinBidSlots [6]uint
//
// // AllocationRatio TODO
// type AllocationRatio struct {
// Donation uint
// Burn uint
// Forger uint
// }
const (
// RollupConstMaxFeeIdxCoordinator is the maximum number of tokens the
// coordinator can use to collect fees (determines the number of tokens
// that the coordinator can collect fees from). This value is
// determined by the circuit.
RollupConstMaxFeeIdxCoordinator = 64
// RollupConstReservedIDx First 256 indexes reserved, first user index will be the 256
RollupConstReservedIDx = 255
// RollupConstExitIDx IDX 1 is reserved for exits
RollupConstExitIDx = 1
// RollupConstLimitLoadAmount Max load amount allowed (loadAmount: L1 --> L2)
RollupConstLimitLoadAmount = (1 << 128)
// RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
RollupConstLimitL2TransferAmount = (1 << 192)
// RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
RollupConstLimitTokens = (1 << 32)
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
RollupConstL1CoordinatorTotalBytes = 101
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
// [2 bytes] loadAmountFloat16 + [2 bytes] amountFloat16 + [4 bytes] tokenId + [6 bytes] toIdx
RollupConstL1UserTotalBytes = 72
// RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
RollupConstMaxL1UserTx = 128
// RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
RollupConstMaxL1Tx = 256
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
// [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
// 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
RollupConstInputSHAConstantBytes = 18542
// RollupConstNumBuckets Number of buckets
RollupConstNumBuckets = 5
// RollupConstMaxWithdrawalDelay max withdrawal delay in seconds
RollupConstMaxWithdrawalDelay = 2 * 7 * 24 * 60 * 60
// RollupConstExchangeMultiplier exchange multiplier
RollupConstExchangeMultiplier = 1e14
// LenVerifiers number of Rollup Smart Contract Verifiers
LenVerifiers = 1
)
var (
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
// This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
// account without needing an ethereum address
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
// RollupConstRfield Modulus zkSNARK
RollupConstRfield, _ = new(big.Int).SetString(
"21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
// RollupConstERC1820 ERC1820Registry address
RollupConstERC1820 = ethCommon.HexToAddress("0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24")
// ERC777 tokens signatures
// RollupConstRecipientInterfaceHash ERC777 recipient interface hash
RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
// RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
// RollupConstSendSignature ERC777 Signature
RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
// RollupConstERC777Granularity ERC777 Signature
RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
// ERC20 signature
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
// RollupConstERC20Signature ERC20 decimals signature
RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
)
// RollupVerifierStruct is the information about verifiers of the Rollup Smart Contract
type RollupVerifierStruct struct {
MaxTx int64 `json:"maxTx"`
NLevels int64 `json:"nlevels"`
}
// RollupConstants are the constants of the Rollup Smart Contract
type RollupConstants struct {
AbsoluteMaxL1L2BatchTimeout int64 `json:"absoluteMaxL1L2BatchTimeout"`
TokenHEZ ethCommon.Address `json:"tokenHEZ"`
Verifiers []RollupVerifierStruct `json:"verifiers"`
HermezAuctionContract ethCommon.Address `json:"hermezAuctionContract"`
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress"`
SafetyAddress ethCommon.Address `json:"safetyAddress"`
WithdrawDelayerContract ethCommon.Address `json:"withdrawDelayerContract"`
}
// Bucket are the variables of each Bucket of Rollup Smart Contract
type Bucket struct {
CeilUSD uint64 `json:"ceilUSD"`
BlockStamp uint64 `json:"blockStamp"`
Withdrawals uint64 `json:"withdrawals"`
BlockWithdrawalRate uint64 `json:"blockWithdrawalRate"`
MaxWithdrawals uint64 `json:"maxWithdrawals"`
}
// RollupVariables are the variables of the Rollup Smart Contract
type RollupVariables struct {
FeeAddToken *big.Int `json:"feeAddToken" meddler:"fee_addtoken"`
ForgeL1L2BatchTimeout int64 `json:"forgeL1L2BatchTimeout" meddler:"forge_l1l2_timeout"`
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
}

+ 24
- 0
common/ethwdelayer.go

@ -0,0 +1,24 @@
package common
import ethCommon "github.com/ethereum/go-ethereum/common"
// WDelayerConstants are the constants of the Withdrawal Delayer Smart Contract
type WDelayerConstants struct {
// Max Withdrawal Delay
MaxWithdrawalDelay uint64 `json:"maxWithdrawalDelay"`
// Max Emergency mode time
MaxEmergencyModeTime uint64 `json:"maxEmergencyModeTime"`
// HermezRollup smartcontract address
HermezRollup ethCommon.Address `json:"hermezRollup"`
}
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
type WDelayerVariables struct {
HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress" meddler:"govdao_address"`
WhiteHackGroupAddress ethCommon.Address `json:"whiteHackGroupAddress" meddler:"whg_address"`
HermezKeeperAddress ethCommon.Address `json:"hermezKeeperAddress" meddler:"keeper_address"`
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
}

+ 7
- 0
common/exittree.go

@ -24,3 +24,10 @@ type ExitInfo struct {
// happened.
DelayedWithdrawn *int64 `meddler:"delayed_withdrawn"`
}
// WithdrawInfo represents a withdraw action to the rollup
type WithdrawInfo struct {
Idx Idx
NumExitRoot BatchNum
InstantWithdraw bool
}

+ 0
- 52
common/scvars.go

@ -1,52 +0,0 @@
package common
import (
"math/big"
"time"
eth "github.com/ethereum/go-ethereum/common"
)
// RollupVars contain the Rollup smart contract variables
type RollupVars struct {
EthBlockNum uint64
ForgeL1Timeout *big.Int
FeeL1UserTx *big.Int
FeeAddToken *big.Int
TokensHEZ eth.Address
Governance eth.Address
}
// AuctionVars contain the Auction smart contract variables
type AuctionVars struct {
EthBlockNum uint64
SlotDeadline uint
CloseAuctionSlots uint
OpenAuctionSlots uint
Governance eth.Address
MinBidSlots MinBidSlots
Outbidding int
DonationAddress eth.Address
GovernanceAddress eth.Address
AllocationRatio AllocationRatio
}
// WithdrawDelayerVars contains the Withdrawal Delayer smart contract variables
type WithdrawDelayerVars struct {
HermezRollupAddress eth.Address
HermezGovernanceDAOAddress eth.Address
WhiteHackGroupAddress eth.Address
WithdrawalDelay uint
EmergencyModeStartingTime time.Time
EmergencyModeEnabled bool
}
// MinBidSlots TODO
type MinBidSlots [6]uint
// AllocationRatio TODO
type AllocationRatio struct {
Donation uint
Burn uint
Forger uint
}

+ 5
- 0
config/config.go

@ -66,6 +66,11 @@ type Node struct {
} `validate:"required"`
Synchronizer struct {
SyncLoopInterval Duration `validate:"required"`
StartBlockNum struct {
Rollup int64 `validate:"required"`
Auction int64 `validate:"required"`
WDelayer int64 `validate:"required"`
} `validate:"required"`
} `validate:"required"`
SmartContracts struct {
Rollup ethCommon.Address `validate:"required"`

+ 13
- 11
db/historydb/historydb.go

@ -329,7 +329,7 @@ func (hdb *HistoryDB) SyncPoD(
blockNum uint64,
bids []common.Bid,
coordinators []common.Coordinator,
vars *common.AuctionVars,
vars *common.AuctionVariables,
) error {
return nil
}
@ -1110,40 +1110,40 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
}
// Add Coordinators
if len(blockData.Coordinators) > 0 {
err = hdb.addCoordinators(txn, blockData.Coordinators)
if len(blockData.Auction.Coordinators) > 0 {
err = hdb.addCoordinators(txn, blockData.Auction.Coordinators)
if err != nil {
return err
}
}
// Add Bids
if len(blockData.Bids) > 0 {
err = hdb.addBids(txn, blockData.Bids)
if len(blockData.Auction.Bids) > 0 {
err = hdb.addBids(txn, blockData.Auction.Bids)
if err != nil {
return err
}
}
// Add Tokens
if len(blockData.AddedTokens) > 0 {
err = hdb.addTokens(txn, blockData.AddedTokens)
if len(blockData.Rollup.AddedTokens) > 0 {
err = hdb.addTokens(txn, blockData.Rollup.AddedTokens)
if err != nil {
return err
}
}
// Add l1 Txs
if len(blockData.L1UserTxs) > 0 {
err = hdb.addL1Txs(txn, blockData.L1UserTxs)
if len(blockData.Rollup.L1UserTxs) > 0 {
err = hdb.addL1Txs(txn, blockData.Rollup.L1UserTxs)
if err != nil {
return err
}
}
// Add Batches
for i := range blockData.Batches {
batch := &blockData.Batches[i]
for i := range blockData.Rollup.Batches {
batch := &blockData.Rollup.Batches[i]
// Add Batch: this will trigger an update on the DB
// that will set the batch num of forged L1 txs in this batch
err = hdb.addBatch(txn, &batch.Batch)
@ -1188,6 +1188,8 @@ func (hdb *HistoryDB) AddBlockSCData(blockData *common.BlockData) (err error) {
// TODO: INSERT CONTRACTS VARS
}
// TODO: Process withdrawals
return txn.Commit()
}

+ 2
- 2
db/historydb/historydb_test.go

@ -408,7 +408,7 @@ func TestGetL1UserTxs(t *testing.T) {
require.Nil(t, err)
// Sanity check
require.Equal(t, 1, len(blocks))
require.Equal(t, 5, len(blocks[0].L1UserTxs))
require.Equal(t, 5, len(blocks[0].Rollup.L1UserTxs))
// fmt.Printf("DBG Blocks: %+v\n", blocks)
toForgeL1TxsNum := int64(1)
@ -421,7 +421,7 @@ func TestGetL1UserTxs(t *testing.T) {
l1UserTxs, err := historyDB.GetL1UserTxs(toForgeL1TxsNum)
require.Nil(t, err)
assert.Equal(t, 5, len(l1UserTxs))
assert.Equal(t, blocks[0].L1UserTxs, l1UserTxs)
assert.Equal(t, blocks[0].Rollup.L1UserTxs, l1UserTxs)
// No l1UserTxs for this toForgeL1TxsNum
l1UserTxs, err = historyDB.GetL1UserTxs(2)

+ 62
- 61
db/statedb/txprocessors_test.go

@ -8,7 +8,6 @@ import (
"testing"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/hermez-node/test/til"
"github.com/stretchr/testify/assert"
@ -31,7 +30,7 @@ func TestProcessTxsBalances(t *testing.T) {
assert.Nil(t, err)
// generate test transactions from test.SetBlockchain0 code
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(til.SetBlockchainMinimumFlow0)
require.Nil(t, err)
@ -39,51 +38,51 @@ func TestProcessTxsBalances(t *testing.T) {
coordIdxs := []common.Idx{256, 257}
log.Debug("block:0 batch:0, only L1CoordinatorTxs")
_, err = sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
_, err = sdb.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
require.Nil(t, err)
log.Debug("block:0 batch:1")
l1UserTxs := []common.L1Tx{}
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
log.Debug("block:0 batch:2")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[2].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[2].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
log.Debug("block:0 batch:3")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[3].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[3].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[3].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[3].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[3].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[3].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
checkBalance(t, tc, sdb, "A", 1, "500")
log.Debug("block:0 batch:4")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[4].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[4].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[4].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[4].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[4].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[4].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "A", 0, "500")
checkBalance(t, tc, sdb, "A", 1, "500")
log.Debug("block:0 batch:5")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[5].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[5].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[5].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[5].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[5].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[5].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "A", 0, "600")
checkBalance(t, tc, sdb, "A", 1, "500")
checkBalance(t, tc, sdb, "B", 0, "400")
log.Debug("block:0 batch:6")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[6].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[6].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[6].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[6].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[6].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[6].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "Coord", 0, "10")
checkBalance(t, tc, sdb, "Coord", 1, "20")
@ -95,9 +94,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "D", 0, "800")
log.Debug("block:0 batch:7")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Batches[7].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[7].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Batches[7].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[0].Rollup.Batches[7].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[7].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[0].Rollup.Batches[7].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "Coord", 0, "35")
checkBalance(t, tc, sdb, "Coord", 1, "30")
@ -110,9 +109,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "D", 0, "800")
log.Debug("block:1 batch:0")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[0].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[0].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
checkBalance(t, tc, sdb, "Coord", 0, "75")
checkBalance(t, tc, sdb, "Coord", 1, "30")
@ -125,9 +124,9 @@ func TestProcessTxsBalances(t *testing.T) {
checkBalance(t, tc, sdb, "D", 0, "470")
log.Debug("block:1 batch:1")
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Batches[1].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
l1UserTxs = til.L1TxsToCommonL1Txs(tc.Queues[*blocks[1].Rollup.Batches[1].Batch.ForgeL1TxsNum])
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, l1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
// use Set of PoolL2 txs
@ -157,18 +156,18 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Nil(t, err)
// generate test transactions from test.SetBlockchain0 code
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
require.Nil(t, err)
assert.Equal(t, 31, len(blocks[0].L1UserTxs))
assert.Equal(t, 4, len(blocks[0].Batches[0].L1CoordinatorTxs))
assert.Equal(t, 0, len(blocks[0].Batches[1].L1CoordinatorTxs))
assert.Equal(t, 22, len(blocks[0].Batches[2].L2Txs))
assert.Equal(t, 1, len(blocks[1].Batches[0].L1CoordinatorTxs))
assert.Equal(t, 62, len(blocks[1].Batches[0].L2Txs))
assert.Equal(t, 1, len(blocks[1].Batches[1].L1CoordinatorTxs))
assert.Equal(t, 8, len(blocks[1].Batches[1].L2Txs))
assert.Equal(t, 31, len(blocks[0].Rollup.L1UserTxs))
assert.Equal(t, 4, len(blocks[0].Rollup.Batches[0].L1CoordinatorTxs))
assert.Equal(t, 0, len(blocks[0].Rollup.Batches[1].L1CoordinatorTxs))
assert.Equal(t, 22, len(blocks[0].Rollup.Batches[2].L2Txs))
assert.Equal(t, 1, len(blocks[1].Rollup.Batches[0].L1CoordinatorTxs))
assert.Equal(t, 62, len(blocks[1].Rollup.Batches[0].L2Txs))
assert.Equal(t, 1, len(blocks[1].Rollup.Batches[1].L1CoordinatorTxs))
assert.Equal(t, 8, len(blocks[1].Rollup.Batches[1].L2Txs))
// Coordinator Idx where to send the fees
coordIdxs := []common.Idx{256, 257, 258, 259}
@ -179,14 +178,15 @@ func TestProcessTxsSynchronizer(t *testing.T) {
// Process the 1st batch, which contains the L1CoordinatorTxs necessary
// to create the Coordinator accounts to receive the fees
log.Debug("block:0 batch:0, only L1CoordinatorTxs")
ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
require.Nil(t, err)
assert.Equal(t, 4, len(ptOut.CreatedAccounts))
assert.Equal(t, 0, len(ptOut.CollectedFees))
log.Debug("block:0 batch:1")
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs,
blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
assert.Equal(t, 0, len(ptOut.ExitInfos))
assert.Equal(t, 31, len(ptOut.CreatedAccounts))
@ -200,8 +200,8 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Equal(t, "50", acc.Balance.String())
log.Debug("block:0 batch:2")
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
assert.Equal(t, 0, len(ptOut.ExitInfos))
assert.Equal(t, 0, len(ptOut.CreatedAccounts))
@ -215,13 +215,13 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Equal(t, "35", acc.Balance.String())
log.Debug("block:1 batch:0")
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
// before processing expect l2Txs[0:2].Nonce==0
assert.Equal(t, common.Nonce(0), l2Txs[0].Nonce)
assert.Equal(t, common.Nonce(0), l2Txs[1].Nonce)
assert.Equal(t, common.Nonce(0), l2Txs[2].Nonce)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
// after processing expect l2Txs[0:2].Nonce!=0 and has expected value
@ -241,8 +241,9 @@ func TestProcessTxsSynchronizer(t *testing.T) {
assert.Equal(t, "57", acc.Balance.String())
log.Debug("block:1 batch:1")
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[1].L1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs,
blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
assert.Equal(t, 2, len(ptOut.ExitInfos)) // 2, as previous batch was without L1UserTxs, and has pending the 'ForceExit(1) A: 5'
@ -276,7 +277,7 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
assert.Nil(t, err)
// generate test transactions from test.SetBlockchain0 code
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
require.Nil(t, err)
@ -289,14 +290,14 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
// Process the 1st batch, which contains the L1CoordinatorTxs necessary
// to create the Coordinator accounts to receive the fees
log.Debug("block:0 batch:0, only L1CoordinatorTxs")
ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
ptOut, err := sdb.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
require.Nil(t, err)
// expect 0 at CreatedAccount, as is only computed when StateDB.Type==TypeSynchronizer
assert.Equal(t, 0, len(ptOut.CreatedAccounts))
log.Debug("block:0 batch:1")
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
assert.Equal(t, 0, len(ptOut.ExitInfos))
assert.Equal(t, 0, len(ptOut.CreatedAccounts))
@ -305,8 +306,8 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
assert.Equal(t, "50", acc.Balance.String())
log.Debug("block:0 batch:2")
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Batches[2].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Batches[2].L1CoordinatorTxs, l2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[2].L2Txs)
ptOut, err = sdb.ProcessTxs(coordIdxs, nil, blocks[0].Rollup.Batches[2].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
assert.Equal(t, 0, len(ptOut.ExitInfos))
assert.Equal(t, 0, len(ptOut.CreatedAccounts))
@ -315,16 +316,16 @@ func TestProcessTxsBatchBuilder(t *testing.T) {
assert.Equal(t, "35", acc.Balance.String())
log.Debug("block:1 batch:0")
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[0].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Batches[0].L1CoordinatorTxs, l2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[0].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, nil, blocks[1].Rollup.Batches[0].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
acc, err = sdb.GetAccount(idxA1)
require.Nil(t, err)
assert.Equal(t, "57", acc.Balance.String())
log.Debug("block:1 batch:1")
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, blocks[1].L1UserTxs, blocks[1].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs = common.L2TxsToPoolL2Txs(blocks[1].Rollup.Batches[1].L2Txs)
_, err = sdb.ProcessTxs(coordIdxs, blocks[1].Rollup.L1UserTxs, blocks[1].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
acc, err = sdb.GetAccount(idxA1)
assert.Nil(t, err)
@ -355,7 +356,7 @@ func TestZKInputsGeneration(t *testing.T) {
assert.Nil(t, err)
// generate test transactions from test.SetBlockchain0 code
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
require.Nil(t, err)
@ -363,11 +364,11 @@ func TestZKInputsGeneration(t *testing.T) {
coordIdxs := []common.Idx{256, 257, 258, 259}
log.Debug("block:0 batch:0, only L1CoordinatorTxs")
_, err = sdb.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
_, err = sdb.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
require.Nil(t, err)
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Batches[1].L2Txs)
ptOut, err := sdb.ProcessTxs(coordIdxs, blocks[0].L1UserTxs, blocks[0].Batches[1].L1CoordinatorTxs, l2Txs)
l2Txs := common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[1].L2Txs)
ptOut, err := sdb.ProcessTxs(coordIdxs, blocks[0].Rollup.L1UserTxs, blocks[0].Rollup.Batches[1].L1CoordinatorTxs, l2Txs)
require.Nil(t, err)
s, err := json.Marshal(ptOut.ZKInputs)

+ 6
- 6
eth/.env.example

@ -1,7 +1,7 @@
GENESIS_BLOCK=97
AUCTION="0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8"
AUCTION_TEST="0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0"
TOKENHEZ="0xf4e77E5Da47AC3125140c470c71cBca77B5c638c"
HERMEZ="0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe"
WDELAYER="0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e"
WDELAYER_TEST="0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160"
AUCTION="0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F"
AUCTION_TEST="0x56D4563E85477AC8Aa6a3b980b831DDb18a826ec"
TOKENHEZ="0x2b7dEe2CF60484325716A1c6A193519c8c3b19F3"
HERMEZ="0x6F4e99522F4eB37e0B73D0C0373147893EF12fD5"
WDELAYER="0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77"
WDELAYER_TEST="0xdc05EFc3029024068FCc86f05323411f14D69280"

+ 1
- 0
eth/.gitignore

@ -0,0 +1 @@
.env

+ 16
- 16
eth/README.md

@ -8,7 +8,7 @@ The first step is to clone the github repository where the contracts are located
While the prepared deployment is not found to master, branch in repository must be changed:
`git checkout feature/ethclient-test-deployment`
`git checkout feature/ethclient-test-deployment-ganache` (tested with commit `f62c768bd4817921872666b3644403a119e28248`)
Now, install the dependencies:
@ -21,14 +21,14 @@ Go to where the deployment scripts for the test are found:
`cd scripts/ethclient-deployment/`
Now, a bash script (which uses gnome-terminal) has to be run to do the deployment:
`./test-deploy.sh`
This bash file follows these steps:
- `npx builder node`: a local blockchain to do our tests
- `npx buidler run --network localhost test-deployment.js`: run the deployment on the local blockchain
Alternatively you can run the two previous commands manually in different terminals.
Now, in a terminal start a local blockchain with ganache:
```
../../node_modules/.bin/ganache-cli -d -m "explain tackle mirror kit van hammer degree position ginger unfair soup bonus" -p 8545 -l 12500000 -a 20 -e 10000 --allowUnlimitedContractSize --chainId 31337
```
Once ganache is ready, in another terminal run the deployment in the local ganache network:
```
npx buidler run --network ganache test-deployment.js
```
An output file necessary for the next step is obtained: `deploy-output`.
@ -43,12 +43,12 @@ They can be provided by file called `.env`:
```
GENESIS_BLOCK=97
AUCTION="0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8"
AUCTION_TEST="0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0"
TOKENHEZ="0xf4e77E5Da47AC3125140c470c71cBca77B5c638c"
HERMEZ="0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe"
WDELAYER="0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e"
WDELAYER_TEST="0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160"
AUCTION="0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F"
AUCTION_TEST="0x56D4563E85477AC8Aa6a3b980b831DDb18a826ec"
TOKENHEZ="0x2b7dEe2CF60484325716A1c6A193519c8c3b19F3"
HERMEZ="0x6F4e99522F4eB37e0B73D0C0373147893EF12fD5"
WDELAYER="0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77"
WDELAYER_TEST="0xdc05EFc3029024068FCc86f05323411f14D69280"
```
> An example is found in `hermez-node/eth/.env.example`
@ -59,4 +59,4 @@ And then run test from `hermez-node/eth/`:
Or they can be provided as a parameter in the command that runs the test:
`INTEGRATION=1 GENESIS_BLOCK=97 AUCTION="0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8" AUCTION_TEST="0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0" TOKENHEZ="0xf4e77E5Da47AC3125140c470c71cBca77B5c638c" HERMEZ="0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe" WDELAYER="0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e" WDELAYER_TEST="0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160" go test`
`INTEGRATION=1 GENESIS_BLOCK=97 AUCTION="0x5E0816F0f8bC560cB2B9e9C87187BeCac8c2021F" AUCTION_TEST="0x56D4563E85477AC8Aa6a3b980b831DDb18a826ec" TOKENHEZ="0x2b7dEe2CF60484325716A1c6A193519c8c3b19F3" HERMEZ="0x6F4e99522F4eB37e0B73D0C0373147893EF12fD5" WDELAYER="0x5D94e3e7aeC542aB0F9129B9a7BAdeb5B3Ca0f77" WDELAYER_TEST="0xdc05EFc3029024068FCc86f05323411f14D69280" go test`

+ 12
- 46
eth/auction.go

@ -13,27 +13,12 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/hermeznetwork/hermez-node/common"
HermezAuctionProtocol "github.com/hermeznetwork/hermez-node/eth/contracts/auction"
HEZ "github.com/hermeznetwork/hermez-node/eth/contracts/tokenHEZ"
"github.com/hermeznetwork/hermez-node/log"
)
// AuctionConstants are the constants of the Rollup Smart Contract
type AuctionConstants struct {
// Blocks per slot
BlocksPerSlot uint8 `json:"blocksPerSlot"`
// Minimum bid when no one has bid yet
InitialMinimalBidding *big.Int `json:"initialMinimalBidding"`
// First block where the first slot begins
GenesisBlockNum int64 `json:"genesisBlockNum"`
// ERC777 token with which the bids will be made
TokenHEZ ethCommon.Address `json:"tokenHEZ"`
// HermezRollup smartcontract address
HermezRollup ethCommon.Address `json:"hermezRollup"`
// Hermez Governanze Token smartcontract address who controls some parameters and collects HEZ fee
// Only for test
GovernanceAddress ethCommon.Address `json:"governanceAddress"`
}
// SlotState is the state of a slot
type SlotState struct {
Bidder ethCommon.Address
@ -58,26 +43,6 @@ type Coordinator struct {
URL string
}
// AuctionVariables are the variables of the Auction Smart Contract
type AuctionVariables struct {
// Boot Coordinator Address
DonationAddress ethCommon.Address `json:"donationAddress" meddler:"donation_address"`
// Boot Coordinator Address
BootCoordinator ethCommon.Address `json:"bootCoordinator" meddler:"boot_coordinator"`
// The minimum bid value in a series of 6 slots
DefaultSlotSetBid [6]*big.Int `json:"defaultSlotSetBid" meddler:"default_slot_set_bid,json"`
// 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"`
// Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
OpenAuctionSlots uint16 `json:"openAuctionSlots" meddler:"open_auction_slots"`
// 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"`
// Minimum outbid (percentage) over the previous one to consider it valid
Outbidding uint16 `json:"outbidding" meddler:"outbidding"`
// 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"`
}
// AuctionState represents the state of the Rollup in the Smart Contract
type AuctionState struct {
// Mapping to control slot state
@ -251,7 +216,7 @@ type AuctionInterface interface {
// Smart Contract Status
//
AuctionConstants() (*AuctionConstants, error)
AuctionConstants() (*common.AuctionConstants, error)
AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error)
}
@ -655,8 +620,8 @@ func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (tx *types.Transa
}
// AuctionConstants returns the Constants of the Auction Smart Contract
func (c *AuctionClient) AuctionConstants() (auctionConstants *AuctionConstants, err error) {
auctionConstants = new(AuctionConstants)
func (c *AuctionClient) AuctionConstants() (auctionConstants *common.AuctionConstants, err error) {
auctionConstants = new(common.AuctionConstants)
if err := c.client.Call(func(ec *ethclient.Client) error {
auctionConstants.BlocksPerSlot, err = c.auction.BLOCKSPERSLOT(nil)
if err != nil {
@ -684,8 +649,8 @@ func (c *AuctionClient) AuctionConstants() (auctionConstants *AuctionConstants,
}
// AuctionVariables returns the variables of the Auction Smart Contract
func (c *AuctionClient) AuctionVariables() (auctionVariables *AuctionVariables, err error) {
auctionVariables = new(AuctionVariables)
func (c *AuctionClient) AuctionVariables() (auctionVariables *common.AuctionVariables, err error) {
auctionVariables = new(common.AuctionVariables)
if err := c.client.Call(func(ec *ethclient.Client) error {
auctionVariables.AllocationRatio, err = c.AuctionGetAllocationRatio()
if err != nil {
@ -751,7 +716,7 @@ var (
// are no events in that block, blockHash is nil.
func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) {
var auctionEvents AuctionEvents
var blockHash ethCommon.Hash
var blockHash *ethCommon.Hash
query := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNum),
@ -767,10 +732,11 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e
return nil, nil, err
}
if len(logs) > 0 {
blockHash = logs[0].BlockHash
blockHash = &logs[0].BlockHash
}
for _, vLog := range logs {
if vLog.BlockHash != blockHash {
if vLog.BlockHash != *blockHash {
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
return nil, nil, ErrBlockHashMismatchEvent
}
switch vLog.Topics[0] {
@ -869,5 +835,5 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e
auctionEvents.HEZClaimed = append(auctionEvents.HEZClaimed, HEZClaimed)
}
}
return &auctionEvents, &blockHash, nil
return &auctionEvents, blockHash, nil
}

+ 1
- 1
eth/auction_test.go

@ -35,7 +35,7 @@ func TestAuctionConstants(t *testing.T) {
require.Nil(t, err)
assert.Equal(t, auctionConstants.BlocksPerSlot, blocksPerSlot)
assert.Equal(t, auctionConstants.GenesisBlockNum, genesisBlock)
assert.Equal(t, auctionConstants.HermezRollup, hermezRollupAddressTestConst)
assert.Equal(t, auctionConstants.HermezRollup, hermezRollupTestAddressConst)
assert.Equal(t, auctionConstants.InitialMinimalBidding, INITMINBID)
assert.Equal(t, auctionConstants.TokenHEZ, tokenHEZAddressConst)
}

+ 1
- 0
eth/ethereum.go

@ -270,6 +270,7 @@ func (c *EthereumClient) EthBlockByNumber(ctx context.Context, number int64) (*c
b := &common.Block{
EthBlockNum: block.Number().Int64(),
Timestamp: time.Unix(int64(block.Time()), 0),
ParentHash: block.ParentHash(),
Hash: block.Hash(),
}
return b, nil

+ 1
- 1
eth/ethereum_test.go

@ -11,7 +11,7 @@ import (
func TestEthERC20(t *testing.T) {
ethClient, err := ethclient.Dial(ethClientDialURL)
require.Nil(t, err)
client := NewEthereumClient(ethClient, accountAux, ks, nil)
client := NewEthereumClient(ethClient, auxAccount, ks, nil)
consts, err := client.EthERC20Consts(tokenHEZAddressConst)
require.Nil(t, err)

+ 81
- 76
eth/main_test.go

@ -3,6 +3,7 @@ package eth
import (
"fmt"
"io/ioutil"
"log"
"math/big"
"os"
"strconv"
@ -11,9 +12,9 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/joho/godotenv"
hdwallet "github.com/miguelmota/go-ethereum-hdwallet"
)
var errEnvVar = fmt.Errorf("Some environment variable is missing")
@ -22,8 +23,31 @@ var (
ethClientDialURL = "http://localhost:8545"
password = "pass"
deadline, _ = new(big.Int).SetString("ffffffffffffffffffffffffffffffff", 16)
mnemonic = "explain tackle mirror kit van hammer degree position ginger unfair soup bonus"
)
func genAcc(w *hdwallet.Wallet, ks *keystore.KeyStore, i int) (*accounts.Account, ethCommon.Address) {
path := hdwallet.MustParseDerivationPath(fmt.Sprintf("m/44'/60'/0'/0/%d", i))
account, err := w.Derive(path, false)
if err != nil {
log.Fatal(err)
}
key, err := w.PrivateKey(account)
if err != nil {
log.Fatal(err)
}
_, err = ks.ImportECDSA(key, password)
if err != nil {
log.Fatal(err)
}
if err := ks.Unlock(account, password); err != nil {
log.Fatal(err)
}
return &account, account.Address
}
// Smart Contract Addresses
var (
genesisBlock int64
@ -35,53 +59,41 @@ var (
wdelayerTestAddressConst ethCommon.Address
tokenHEZ TokenConfig
donationAddressStr = "0x6c365935CA8710200C7595F0a72EB6023A7706Cd"
donationAddressConst = ethCommon.HexToAddress(donationAddressStr)
bootCoordinatorAddressStr = "0xc783df8a850f42e7f7e57013759c285caa701eb6"
bootCoordinatorAddressConst = ethCommon.HexToAddress(bootCoordinatorAddressStr)
safetyAddressStr = "0xE5904695748fe4A84b40b3fc79De2277660BD1D3"
safetyAddressConst = ethCommon.HexToAddress(safetyAddressStr)
donationAccount *accounts.Account
donationAddressConst ethCommon.Address
bootCoordinatorAccount *accounts.Account
bootCoordinatorAddressConst ethCommon.Address
safetyAccount *accounts.Account
safetyAddressConst ethCommon.Address
)
// Ethereum Accounts
var (
hermezGovernanceDAOAddressSK = "2a8aede924268f84156a00761de73998dac7bf703408754b776ff3f873bcec60"
hermezGovernanceDAOAddressStr = "0x84Fae3d3Cba24A97817b2a18c2421d462dbBCe9f"
hermezGovernanceDAOAddressConst = ethCommon.HexToAddress(hermezGovernanceDAOAddressStr)
hermezGovernanceDAOAccount *accounts.Account
hermezGovernanceDAOAddressConst ethCommon.Address
whiteHackGroupAddressSK = "8b24fd94f1ce869d81a34b95351e7f97b2cd88a891d5c00abc33d0ec9501902e"
whiteHackGroupAddressStr = "0xfa3BdC8709226Da0dA13A4d904c8b66f16c3c8BA"
whiteHackGroupAddressConst = ethCommon.HexToAddress(whiteHackGroupAddressStr)
whiteHackGroupAccount *accounts.Account
whiteHackGroupAddressConst ethCommon.Address
hermezKeeperAddressSK = "7f307c41137d1ed409f0a7b028f6c7596f12734b1d289b58099b99d60a96efff"
hermezKeeperAddressStr = "0xFbC51a9582D031f2ceaaD3959256596C5D3a5468"
hermezKeeperAddressConst = ethCommon.HexToAddress(hermezKeeperAddressStr)
hermezKeeperAccount *accounts.Account
hermezKeeperAddressConst ethCommon.Address
governanceAddressSK = "d49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb"
governanceAddressStr = "0xead9c93b79ae7c1591b1fb5323bd777e86e150d4"
governanceAddressConst = ethCommon.HexToAddress(governanceAddressStr)
governanceAccount *accounts.Account
governanceAddressConst ethCommon.Address
auxAddressSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29089"
auxAddressStr = "0x3d91185a02774C70287F6c74Dd26d13DFB58ff16"
auxAddressConst = ethCommon.HexToAddress(auxAddressStr)
auxAccount *accounts.Account
auxAddressConst ethCommon.Address
aux2AddressSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29087"
// aux2AddressStr = "0x532792b73c0c6e7565912e7039c59986f7e1dd1f"
// aux2AddressConst = ethCommon.HexToAddress(aux2AddressStr)
aux2Account *accounts.Account
aux2AddressConst ethCommon.Address
hermezRollupTestSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29088"
hermezRollupTestAddressStr = "0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0"
hermezRollupAddressTestConst = ethCommon.HexToAddress(hermezRollupTestAddressStr)
hermezRollupTestAccount *accounts.Account
hermezRollupTestAddressConst ethCommon.Address
)
var (
accountGov *accounts.Account
accountKep *accounts.Account
accountWhite *accounts.Account
accountGovDAO *accounts.Account
accountAux *accounts.Account
accountAux2 *accounts.Account
accountHermez *accounts.Account
ks *keystore.KeyStore
ethClient *ethclient.Client
ethereumClientWhite *EthereumClient
@ -92,22 +104,6 @@ var (
ethereumClientHermez *EthereumClient
)
func addKey(ks *keystore.KeyStore, skHex string) *accounts.Account {
key, err := crypto.HexToECDSA(skHex)
if err != nil {
panic(err)
}
account, err := ks.ImportECDSA(key, password)
if err != nil {
panic(err)
}
err = ks.Unlock(account, password)
if err != nil {
panic(err)
}
return &account
}
func getEnvVariables() {
err := godotenv.Load()
if err != nil {
@ -124,10 +120,10 @@ func getEnvVariables() {
genesisBlockEnv := os.Getenv("GENESIS_BLOCK")
genesisBlock, err = strconv.ParseInt(genesisBlockEnv, 10, 64)
if err != nil {
panic(errEnvVar)
log.Fatal(errEnvVar)
}
if auctionAddressStr == "" || auctionTestAddressStr == "" || tokenHEZAddressStr == "" || hermezRollupAddressStr == "" || wdelayerAddressStr == "" || wdelayerTestAddressStr == "" || genesisBlockEnv == "" {
panic(errEnvVar)
log.Fatal(errEnvVar)
}
auctionAddressConst = ethCommon.HexToAddress(auctionAddressStr)
@ -149,58 +145,67 @@ func TestMain(m *testing.M) {
getEnvVariables()
dir, err := ioutil.TempDir("", "tmpks")
if err != nil {
panic(err)
log.Fatal(err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
panic(err)
log.Fatal(err)
}
}()
ks = keystore.NewKeyStore(dir, keystore.LightScryptN, keystore.LightScryptP)
// Load ethereum accounts from private keys
accountGov = addKey(ks, governanceAddressSK)
accountKep = addKey(ks, hermezKeeperAddressSK)
accountWhite = addKey(ks, whiteHackGroupAddressSK)
accountGovDAO = addKey(ks, hermezGovernanceDAOAddressSK)
accountAux = addKey(ks, auxAddressSK)
accountAux2 = addKey(ks, aux2AddressSK)
accountHermez = addKey(ks, hermezRollupTestSK)
w, err := hdwallet.NewFromMnemonic(mnemonic)
if err != nil {
log.Fatal(err)
}
// Create ethereum accounts from mnemonic and load private keys
// into the keystore
bootCoordinatorAccount, bootCoordinatorAddressConst = genAcc(w, ks, 0)
governanceAccount, governanceAddressConst = genAcc(w, ks, 1)
safetyAccount, safetyAddressConst = genAcc(w, ks, 2)
hermezKeeperAccount, hermezKeeperAddressConst = genAcc(w, ks, 6)
hermezGovernanceDAOAccount, hermezGovernanceDAOAddressConst = genAcc(w, ks, 7)
whiteHackGroupAccount, whiteHackGroupAddressConst = genAcc(w, ks, 8)
donationAccount, donationAddressConst = genAcc(w, ks, 9)
aux2Account, aux2AddressConst = genAcc(w, ks, 11)
hermezRollupTestAccount, hermezRollupTestAddressConst = genAcc(w, ks, 12)
auxAccount, auxAddressConst = genAcc(w, ks, 13)
ethClient, err = ethclient.Dial(ethClientDialURL)
if err != nil {
panic(err)
log.Fatal(err)
}
// Controllable Governance Address
ethereumClientGov := NewEthereumClient(ethClient, accountGov, ks, nil)
ethereumClientGov := NewEthereumClient(ethClient, governanceAccount, ks, nil)
auctionClient, err = NewAuctionClient(ethereumClientGov, auctionAddressConst, tokenHEZ)
if err != nil {
panic(err)
log.Fatal(err)
}
auctionClientTest, err = NewAuctionClient(ethereumClientGov, auctionTestAddressConst, tokenHEZ)
if err != nil {
panic(err)
log.Fatal(err)
}
rollupClient, err = NewRollupClient(ethereumClientGov, hermezRollupAddressConst, tokenHEZ)
if err != nil {
panic(err)
log.Fatal(err)
}
wdelayerClient, err = NewWDelayerClient(ethereumClientGov, wdelayerAddressConst)
if err != nil {
panic(err)
log.Fatal(err)
}
wdelayerClientTest, err = NewWDelayerClient(ethereumClientGov, wdelayerTestAddressConst)
if err != nil {
panic(err)
log.Fatal(err)
}
ethereumClientKep = NewEthereumClient(ethClient, accountKep, ks, nil)
ethereumClientWhite = NewEthereumClient(ethClient, accountWhite, ks, nil)
ethereumClientGovDAO = NewEthereumClient(ethClient, accountGovDAO, ks, nil)
ethereumClientAux = NewEthereumClient(ethClient, accountAux, ks, nil)
ethereumClientAux2 = NewEthereumClient(ethClient, accountAux2, ks, nil)
ethereumClientHermez = NewEthereumClient(ethClient, accountHermez, ks, nil)
ethereumClientKep = NewEthereumClient(ethClient, hermezKeeperAccount, ks, nil)
ethereumClientWhite = NewEthereumClient(ethClient, whiteHackGroupAccount, ks, nil)
ethereumClientGovDAO = NewEthereumClient(ethClient, hermezGovernanceDAOAccount, ks, nil)
ethereumClientAux = NewEthereumClient(ethClient, auxAccount, ks, nil)
ethereumClientAux2 = NewEthereumClient(ethClient, aux2Account, ks, nil)
ethereumClientHermez = NewEthereumClient(ethClient, hermezRollupTestAccount, ks, nil)
exitVal = m.Run()
}

+ 22
- 130
eth/rollup.go

@ -20,112 +20,6 @@ import (
"github.com/iden3/go-iden3-crypto/babyjub"
)
const (
// RollupConstMaxFeeIdxCoordinator is the maximum number of tokens the
// coordinator can use to collect fees (determines the number of tokens
// that the coordinator can collect fees from). This value is
// determined by the circuit.
RollupConstMaxFeeIdxCoordinator = 64
// RollupConstReservedIDx First 256 indexes reserved, first user index will be the 256
RollupConstReservedIDx = 255
// RollupConstExitIDx IDX 1 is reserved for exits
RollupConstExitIDx = 1
// RollupConstLimitLoadAmount Max load amount allowed (loadAmount: L1 --> L2)
RollupConstLimitLoadAmount = (1 << 128)
// RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
RollupConstLimitL2TransferAmount = (1 << 192)
// RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
RollupConstLimitTokens = (1 << 32)
// RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
RollupConstL1CoordinatorTotalBytes = 101
// RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
// [2 bytes] loadAmountFloat16 + [2 bytes] amountFloat16 + [4 bytes] tokenId + [6 bytes] toIdx
RollupConstL1UserTotalBytes = 72
// RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
RollupConstMaxL1UserTx = 128
// RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
RollupConstMaxL1Tx = 256
// RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
// [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
// 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
RollupConstInputSHAConstantBytes = 18542
// RollupConstNumBuckets Number of buckets
RollupConstNumBuckets = 5
// RollupConstMaxWithdrawalDelay max withdrawal delay in seconds
RollupConstMaxWithdrawalDelay = 2 * 7 * 24 * 60 * 60
// RollupConstExchangeMultiplier exchange multiplier
RollupConstExchangeMultiplier = 1e14
// LenVerifiers number of Rollup Smart Contract Verifiers
LenVerifiers = 1
)
var (
// RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
// This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
// account without needing an ethereum address
RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
// RollupConstRfield Modulus zkSNARK
RollupConstRfield, _ = new(big.Int).SetString(
"21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
// RollupConstERC1820 ERC1820Registry address
RollupConstERC1820 = ethCommon.HexToAddress("0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24")
// ERC777 tokens signatures
// RollupConstRecipientInterfaceHash ERC777 recipient interface hash
RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
// RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
// RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
// RollupConstSendSignature ERC777 Signature
RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
// RollupConstERC777Granularity ERC777 Signature
RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
// RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
// ERC20 signature
// RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
// RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
// RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
// RollupConstERC20Signature ERC20 decimals signature
RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
)
// RollupPublicConstants are the constants of the Rollup Smart Contract
type RollupPublicConstants struct {
AbsoluteMaxL1L2BatchTimeout int64 `json:"absoluteMaxL1L2BatchTimeout"`
TokenHEZ ethCommon.Address `json:"tokenHEZ"`
Verifiers []RollupVerifierStruct `json:"verifiers"`
HermezAuctionContract ethCommon.Address `json:"hermezAuctionContract"`
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress"`
SafetyAddress ethCommon.Address `json:"safetyAddress"`
WithdrawDelayerContract ethCommon.Address `json:"withdrawDelayerContract"`
}
// Bucket are the variables of each Bucket of Rollup Smart Contract
type Bucket struct {
CeilUSD uint64 `json:"ceilUSD"`
BlockStamp uint64 `json:"blockStamp"`
Withdrawals uint64 `json:"withdrawals"`
BlockWithdrawalRate uint64 `json:"blockWithdrawalRate"`
MaxWithdrawals uint64 `json:"maxWithdrawals"`
}
// RollupVariables are the variables of the Rollup Smart Contract
type RollupVariables struct {
FeeAddToken *big.Int `json:"feeAddToken" meddler:"fee_addtoken"`
ForgeL1L2BatchTimeout int64 `json:"forgeL1L2BatchTimeout" meddler:"forge_l1l2_timeout"`
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
Buckets [RollupConstNumBuckets]Bucket `json:"buckets" meddler:"buckets,json"`
}
// QueueStruct is the queue of L1Txs for a batch
type QueueStruct struct {
L1TxQueue []common.L1Tx
@ -140,12 +34,6 @@ func NewQueueStruct() *QueueStruct {
}
}
// RollupVerifierStruct is the information about verifiers of the Rollup Smart Contract
type RollupVerifierStruct struct {
MaxTx int64 `json:"maxTx"`
NLevels int64 `json:"nlevels"`
}
// RollupState represents the state of the Rollup in the Smart Contract
type RollupState struct {
StateRoot *big.Int
@ -197,8 +85,8 @@ type RollupEventUpdateFeeAddToken struct {
NewFeeAddToken *big.Int
}
// RollupEventWithdrawEvent is an event of the Rollup Smart Contract
type RollupEventWithdrawEvent struct {
// RollupEventWithdraw is an event of the Rollup Smart Contract
type RollupEventWithdraw struct {
Idx uint64
NumExitRoot uint64
InstantWithdraw bool
@ -211,7 +99,7 @@ type RollupEvents struct {
ForgeBatch []RollupEventForgeBatch
UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
UpdateFeeAddToken []RollupEventUpdateFeeAddToken
WithdrawEvent []RollupEventWithdrawEvent
Withdraw []RollupEventWithdraw
}
// NewRollupEvents creates an empty RollupEvents with the slices initialized.
@ -222,7 +110,7 @@ func NewRollupEvents() RollupEvents {
ForgeBatch: make([]RollupEventForgeBatch, 0),
UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
WithdrawEvent: make([]RollupEventWithdrawEvent, 0),
Withdraw: make([]RollupEventWithdraw, 0),
}
}
@ -287,7 +175,7 @@ type RollupInterface interface {
// Smart Contract Status
//
RollupConstants() (*RollupPublicConstants, error)
RollupConstants() (*common.RollupConstants, error)
RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, *ethCommon.Address, error)
}
@ -361,11 +249,11 @@ func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (tx *types.T
l2DataBytes = append(l2DataBytes, bytesl2[:]...)
}
var feeIdxCoordinator []byte
if len(args.FeeIdxCoordinator) > RollupConstMaxFeeIdxCoordinator {
if len(args.FeeIdxCoordinator) > common.RollupConstMaxFeeIdxCoordinator {
return nil, fmt.Errorf("len(args.FeeIdxCoordinator) > %v",
RollupConstMaxFeeIdxCoordinator)
common.RollupConstMaxFeeIdxCoordinator)
}
for i := 0; i < RollupConstMaxFeeIdxCoordinator; i++ {
for i := 0; i < common.RollupConstMaxFeeIdxCoordinator; i++ {
feeIdx := common.Idx(0)
if i < len(args.FeeIdxCoordinator) {
feeIdx = args.FeeIdxCoordinator[i]
@ -552,8 +440,8 @@ func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *typ
}
// RollupConstants returns the Constants of the Rollup Smart Contract
func (c *RollupClient) RollupConstants() (rollupConstants *RollupPublicConstants, err error) {
rollupConstants = new(RollupPublicConstants)
func (c *RollupClient) RollupConstants() (rollupConstants *common.RollupConstants, err error) {
rollupConstants = new(common.RollupConstants)
if err := c.client.Call(func(ec *ethclient.Client) error {
absoluteMaxL1L2BatchTimeout, err := c.hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil)
if err != nil {
@ -564,8 +452,8 @@ func (c *RollupClient) RollupConstants() (rollupConstants *RollupPublicConstants
if err != nil {
return err
}
for i := int64(0); i < int64(LenVerifiers); i++ {
var newRollupVerifier RollupVerifierStruct
for i := int64(0); i < int64(common.LenVerifiers); i++ {
var newRollupVerifier common.RollupVerifierStruct
rollupVerifier, err := c.hermez.RollupVerifiers(nil, big.NewInt(i))
if err != nil {
return err
@ -606,7 +494,7 @@ var (
// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) {
var rollupEvents RollupEvents
var blockHash ethCommon.Hash
var blockHash *ethCommon.Hash
query := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNum),
@ -622,10 +510,14 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC
return nil, nil, err
}
if len(logs) > 0 {
blockHash = logs[0].BlockHash
for i := range logs {
log.Debugw("log", "i", i, "blockHash", logs[i].BlockHash)
}
blockHash = &logs[0].BlockHash
}
for _, vLog := range logs {
if vLog.BlockHash != blockHash {
if vLog.BlockHash != *blockHash {
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
return nil, nil, ErrBlockHashMismatchEvent
}
switch vLog.Topics[0] {
@ -680,17 +572,17 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC
}
rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken)
case logHermezWithdrawEvent:
var withdraw RollupEventWithdrawEvent
var withdraw RollupEventWithdraw
withdraw.Idx = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
withdraw.NumExitRoot = new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64()
instantWithdraw := new(big.Int).SetBytes(vLog.Topics[3][:]).Uint64()
if instantWithdraw == 1 {
withdraw.InstantWithdraw = true
}
rollupEvents.WithdrawEvent = append(rollupEvents.WithdrawEvent, withdraw)
rollupEvents.Withdraw = append(rollupEvents.Withdraw, withdraw)
}
}
return &rollupEvents, &blockHash, nil
return &rollupEvents, blockHash, nil
}
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the

+ 16
- 15
eth/rollup_test.go

@ -70,7 +70,7 @@ func TestRollupRegisterTokensCount(t *testing.T) {
assert.Equal(t, big.NewInt(1), registerTokensCount)
}
func TestAddToken(t *testing.T) {
func TestRollupAddToken(t *testing.T) {
feeAddToken := big.NewInt(10)
// Addtoken ERC20Permit
registerTokensCount, err := rollupClient.RollupRegisterTokensCount()
@ -731,7 +731,7 @@ func TestRollupForgeBatch2(t *testing.T) {
newStateRoot := new(big.Int)
newStateRoot.SetString("0", 10)
newExitRoot := new(big.Int)
newExitRoot.SetString("6442511778188868333499919207091562876207840300369859025739972956758642594045", 10)
newExitRoot.SetString("4694629460381124336935185586347620040847956843554725549791403956105308092690", 10)
args.NewLastIdx = int64(1000)
args.NewStRoot = newStateRoot
args.NewExitRoot = newExitRoot
@ -760,11 +760,12 @@ func TestRollupWithdrawMerkleProof(t *testing.T) {
require.Nil(t, err)
var pkComp babyjub.PublicKeyComp
pkCompB, err := hex.DecodeString("9a0c13552c3a0b7b2b63ec4ab8a906b4af471ef3aa4463491ff08a0b489ac50f")
require.Nil(t, err)
pkCompL := common.SwapEndianness(pkCompB)
err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
pkCompBE, err := hex.DecodeString("adc3b754f8da621967b073a787bef8eec7052f2ba712b23af57d98f65beea8b2")
require.Nil(t, err)
pkCompLE := common.SwapEndianness(pkCompBE)
copy(pkComp[:], pkCompLE)
// err = pkComp.UnmarshalText([]byte(hex.EncodeToString(pkCompL)))
// require.Nil(t, err)
pk, err := pkComp.Decompress()
require.Nil(t, err)
@ -774,13 +775,13 @@ func TestRollupWithdrawMerkleProof(t *testing.T) {
numExitRoot := int64(2)
fromIdx := int64(256)
amount := big.NewInt(10)
siblingBytes0, _ := new(big.Int).SetString("19508838618377323910556678335932426220272947530531646682154552299216398748115", 10)
require.Nil(t, err)
siblingBytes1, _ := new(big.Int).SetString("15198806719713909654457742294233381653226080862567104272457668857208564789571", 10)
require.Nil(t, err)
// siblingBytes0, _ := new(big.Int).SetString("19508838618377323910556678335932426220272947530531646682154552299216398748115", 10)
// require.Nil(t, err)
// siblingBytes1, _ := new(big.Int).SetString("15198806719713909654457742294233381653226080862567104272457668857208564789571", 10)
// require.Nil(t, err)
var siblings []*big.Int
siblings = append(siblings, siblingBytes0)
siblings = append(siblings, siblingBytes1)
// siblings = append(siblings, siblingBytes0)
// siblings = append(siblings, siblingBytes1)
instantWithdraw := true
_, err = rollupClientAux.RollupWithdrawMerkleProof(pk, tokenID, numExitRoot, fromIdx, amount, siblings, instantWithdraw)
@ -789,7 +790,7 @@ func TestRollupWithdrawMerkleProof(t *testing.T) {
currentBlockNum, _ := rollupClient.client.EthCurrentBlock()
rollupEvents, _, _ := rollupClient.RollupEventsByBlock(currentBlockNum)
assert.Equal(t, uint64(fromIdx), rollupEvents.WithdrawEvent[0].Idx)
assert.Equal(t, instantWithdraw, rollupEvents.WithdrawEvent[0].InstantWithdraw)
assert.Equal(t, uint64(numExitRoot), rollupEvents.WithdrawEvent[0].NumExitRoot)
assert.Equal(t, uint64(fromIdx), rollupEvents.Withdraw[0].Idx)
assert.Equal(t, instantWithdraw, rollupEvents.Withdraw[0].InstantWithdraw)
assert.Equal(t, uint64(numExitRoot), rollupEvents.Withdraw[0].NumExitRoot)
}

+ 28
- 21
eth/wdelayer.go

@ -13,30 +13,11 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/hermeznetwork/hermez-node/common"
WithdrawalDelayer "github.com/hermeznetwork/hermez-node/eth/contracts/withdrawdelayer"
"github.com/hermeznetwork/hermez-node/log"
)
// WDelayerConstants are the constants of the Withdrawal Delayer Smart Contract
type WDelayerConstants struct {
// Max Withdrawal Delay
MaxWithdrawalDelay uint64 `json:"maxWithdrawalDelay"`
// Max Emergency mode time
MaxEmergencyModeTime uint64 `json:"maxEmergencyModeTime"`
// HermezRollup smartcontract address
HermezRollup ethCommon.Address `json:"hermezRollup"`
}
// WDelayerVariables are the variables of the Withdrawal Delayer Smart Contract
type WDelayerVariables struct {
HermezRollupAddress ethCommon.Address `json:"hermezRollupAddress" meddler:"rollup_address"`
HermezGovernanceDAOAddress ethCommon.Address `json:"hermezGovernanceDAOAddress" meddler:"govdao_address"`
WhiteHackGroupAddress ethCommon.Address `json:"whiteHackGroupAddress" meddler:"whg_address"`
HermezKeeperAddress ethCommon.Address `json:"hermezKeeperAddress" meddler:"keeper_address"`
WithdrawalDelay uint64 `json:"withdrawalDelay" meddler:"withdrawal_delay"`
EmergencyModeStartingTime uint64 `json:"emergencyModeStartingTime" meddler:"emergency_start_time"`
EmergencyMode bool `json:"emergencyMode" meddler:"emergency_mode"`
}
// DepositState is the state of Deposit
type DepositState struct {
Amount *big.Int
@ -137,6 +118,9 @@ type WDelayerInterface interface {
WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error)
WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error)
WDelayerConstants() (*common.WDelayerConstants, error)
}
//
@ -355,6 +339,28 @@ func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Addre
return tx, nil
}
// WDelayerConstants returns the Constants of the WDelayer Smart Contract
func (c *WDelayerClient) WDelayerConstants() (constants common.WDelayerConstants, err error) {
if err := c.client.Call(func(ec *ethclient.Client) error {
constants.MaxWithdrawalDelay, err = c.wdelayer.MAXWITHDRAWALDELAY(nil)
if err != nil {
return err
}
constants.MaxEmergencyModeTime, err = c.wdelayer.MAXEMERGENCYMODETIME(nil)
if err != nil {
return err
}
constants.HermezRollup, err = c.wdelayer.HermezRollupAddress(nil)
if err != nil {
return err
}
return err
}); err != nil {
return constants, err
}
return constants, nil
}
var (
logWDelayerDeposit = crypto.Keccak256Hash([]byte("Deposit(address,address,uint192,uint64)"))
logWDelayerWithdraw = crypto.Keccak256Hash([]byte("Withdraw(address,address,uint192)"))
@ -392,6 +398,7 @@ func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents,
}
for _, vLog := range logs {
if vLog.BlockHash != blockHash {
log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
return nil, nil, ErrBlockHashMismatchEvent
}
switch vLog.Topics[0] {

+ 11
- 1
eth/wdelayer_test.go

@ -17,6 +17,15 @@ var wdelayerClientTest *WDelayerClient
var initWithdrawalDelay = big.NewInt(60)
var newWithdrawalDelay = big.NewInt(79)
var maxEmergencyModeTime = time.Hour * 24 * 7 * 26
var maxWithdrawalDelay = time.Hour * 24 * 7 * 2
func TestWDelayerConstants(t *testing.T) {
wDelayerConstants, err := wdelayerClientTest.WDelayerConstants()
require.Nil(t, err)
assert.Equal(t, uint64(maxWithdrawalDelay.Seconds()), wDelayerConstants.MaxWithdrawalDelay)
assert.Equal(t, uint64(maxEmergencyModeTime.Seconds()), wDelayerConstants.MaxEmergencyModeTime)
assert.Equal(t, hermezRollupTestAddressConst, wDelayerConstants.HermezRollup)
}
func TestWDelayerGetHermezGovernanceDAOAddress(t *testing.T) {
governanceAddress, err := wdelayerClientTest.WDelayerGetHermezGovernanceDAOAddress()
@ -139,7 +148,8 @@ func TestWDelayerWithdrawal(t *testing.T) {
amount.SetString("1100000000000000000", 10)
_, err := wdelayerClientTest.WDelayerWithdrawal(auxAddressConst, tokenHEZAddressConst)
require.Contains(t, err.Error(), "WITHDRAWAL_NOT_ALLOWED")
addBlocks(newWithdrawalDelay.Int64(), ethClientDialURL)
addTime(float64(newWithdrawalDelay.Int64()), ethClientDialURL)
addBlock(ethClientDialURL)
_, err = wdelayerClientTest.WDelayerWithdrawal(auxAddressConst, tokenHEZAddressConst)
require.Nil(t, err)
currentBlockNum, _ := wdelayerClientTest.client.EthCurrentBlock()

+ 2
- 1
go.mod

@ -4,7 +4,7 @@ go 1.14
require (
github.com/BurntSushi/toml v0.3.1
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015
github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6
github.com/dghubble/sling v1.3.0
github.com/ethereum/go-ethereum v1.9.17
github.com/getkin/kin-openapi v0.22.0
@ -19,6 +19,7 @@ require (
github.com/joho/godotenv v1.3.0
github.com/lib/pq v1.8.0
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c
github.com/mitchellh/copystructure v1.0.0
github.com/rogpeppe/go-internal v1.6.1 // indirect
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351

+ 58
- 0
go.sum

@ -17,10 +17,12 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
@ -42,9 +44,14 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apilayer/freegeoip v3.5.0+incompatible/go.mod h1:CUfFqErhFhXneJendyQ/rRcuA8kH8JxHvYnbOozmlCU=
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
github.com/aristanetworks/glog v0.0.0-20180419172825-c15b03b3054f/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015 h1:7ABPr1+uJdqESAdlVevnc/2FJGiC/K3uMg1JiELeF+0=
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6 h1:6bZNnQcA2fkzH9AhZXbp2nDqbWa4bBqFeUb70Zq1HBM=
github.com/aristanetworks/goarista v0.0.0-20190912214011-b54698eaaca6/go.mod h1:Z4RTxGAuYhPzcq8+EdRM+R8M48Ssle2TsWtwRKa+vns=
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
@ -62,8 +69,11 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78=
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
@ -138,10 +148,12 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum/go-ethereum v1.9.5/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo=
github.com/ethereum/go-ethereum v1.9.13/go.mod h1:qwN9d1GLyDh0N7Ab8bMGd0H9knaji2jOBm2RrMGjXls=
github.com/ethereum/go-ethereum v1.9.17 h1:2D02O8KcoyQHxfizvMi0vGXXzFIkQTMeKXwt0+4SYEA=
@ -156,6 +168,7 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
github.com/getkin/kin-openapi v0.22.0 h1:J5IFyKd/5yuB6AZAgwK0CMBKnabWcmkowtsl6bRkz4s=
@ -313,11 +326,14 @@ github.com/iden3/go-wasm3 v0.0.1/go.mod h1:j+TcAB94Dfrjlu5kJt83h2OqAU+oyNUTwNZnQ
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/influxdata/influxdb v1.7.8/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/ipfsconsortium/go-ipfsc v0.0.0-20190116161836-3629ecc1f76f/go.mod h1:4MbfcV8YX3CWjkWgUIH4vEVk002kMJlOEmhoSJP8SeE=
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a h1:zPPuIq2jAWWPTrGt70eK/BSch+gFAGrNzecsoENgu2o=
@ -336,6 +352,7 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/hid v1.0.0/go.mod h1:Vr51f8rUOLYrfrWDFlV12GGQgM5AT8sVh+2fY4MPeu8=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/karrick/godirwalk v1.15.3 h1:0a2pXOgtB16CqIqXTiT7+K9L73f74n/aNQUnH6Ortew=
@ -345,6 +362,8 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -397,6 +416,8 @@ github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJK
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c h1:cbhK2JT4nl7k8frmCN98ttRdSGP75x9mDxDhlQ1kHQQ=
github.com/miguelmota/go-ethereum-hdwallet v0.0.0-20200123000308-a60dcd172b4c/go.mod h1:Z4zI+CdJB1fyrZ1jfevFH6flNV9izrLZnQAeuD6Wkjk=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
@ -438,9 +459,13 @@ github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2f
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@ -460,6 +485,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM=
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -474,6 +500,7 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -484,11 +511,13 @@ github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7q
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA=
@ -509,6 +538,7 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 h1:HXr/qUllAWv9riaI4zh2eXWKmCSDqVS/XH1MRHLKRwk=
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg=
@ -520,6 +550,7 @@ github.com/russross/meddler v1.0.0 h1:3HgwIot/NsCrLrmorjSO7JhzoshoSVfuqgFgZ0VTbr
github.com/russross/meddler v1.0.0/go.mod h1:j75NzzcOL4CGy+pPKykxZoT/At5Qj4ZnRRs1PXxweZI=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.20.5+incompatible h1:tYH07UPoQt0OCQdgWWMgYHy3/a9bcxNpBIysykNIP7I=
@ -568,10 +599,15 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v0.0.0-20180621010148-0d5a0ceb10cf/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tyler-smith/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
@ -593,8 +629,12 @@ github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
@ -632,9 +672,11 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -685,6 +727,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
@ -716,13 +760,17 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -750,6 +798,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190912185636-87d9f09c5d89/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@ -788,6 +837,7 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -795,6 +845,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
@ -806,6 +857,12 @@ gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvR
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
gopkg.in/karalabe/cookiejar.v2 v2.0.0-20150724131613-8dcd6a7f4951/go.mod h1:owOxCRGGeAx1uugABik6K9oeNu1cgxP/R9ItzLDxNWA=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
@ -813,6 +870,7 @@ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJ
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=

+ 7
- 1
node/node.go

@ -107,7 +107,13 @@ func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node,
return nil, err
}
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB)
sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB, synchronizer.Config{
StartBlockNum: synchronizer.ConfigStartBlockNum{
Rollup: cfg.Synchronizer.StartBlockNum.Rollup,
Auction: cfg.Synchronizer.StartBlockNum.Auction,
WDelayer: cfg.Synchronizer.StartBlockNum.WDelayer,
},
})
if err != nil {
return nil, err
}

+ 185
- 124
synchronizer/synchronizer.go

@ -3,6 +3,7 @@ package synchronizer
import (
"context"
"database/sql"
"fmt"
"github.com/ethereum/go-ethereum"
"github.com/hermeznetwork/hermez-node/common"
@ -37,69 +38,92 @@ var (
// Synchronized bool
// }
// rollupData contains information returned by the Rollup SC
type rollupData struct {
l1UserTxs []common.L1Tx
batches []common.BatchData
// withdrawals []*common.ExitInfo
addTokens []common.Token
vars *common.RollupVars
// ConfigStartBlockNum sets the first block used to start tracking the smart
// contracts
type ConfigStartBlockNum struct {
Rollup int64
Auction int64
WDelayer int64
}
// NewRollupData creates an empty rollupData with the slices initialized.
func newRollupData() rollupData {
return rollupData{
l1UserTxs: make([]common.L1Tx, 0),
batches: make([]common.BatchData, 0),
// withdrawals: make([]*common.ExitInfo, 0),
addTokens: make([]common.Token, 0),
}
}
// auctionData contains information returned by the Action SC
type auctionData struct {
bids []common.Bid
coordinators []common.Coordinator
vars *common.AuctionVars
}
// newAuctionData creates an empty auctionData with the slices initialized.
func newAuctionData() *auctionData {
return &auctionData{
bids: make([]common.Bid, 0),
coordinators: make([]common.Coordinator, 0),
}
}
type wdelayerData struct {
vars *common.WithdrawDelayerVars
// Config is the Synchronizer configuration
type Config struct {
StartBlockNum ConfigStartBlockNum
}
// Synchronizer implements the Synchronizer type
type Synchronizer struct {
ethClient eth.ClientInterface
auctionConstants eth.AuctionConstants
historyDB *historydb.HistoryDB
stateDB *statedb.StateDB
ethClient eth.ClientInterface
auctionConstants common.AuctionConstants
rollupConstants common.RollupConstants
wDelayerConstants common.WDelayerConstants
historyDB *historydb.HistoryDB
stateDB *statedb.StateDB
cfg Config
startBlockNum int64
// firstSavedBlock *common.Block
// mux sync.Mutex
}
// NewSynchronizer creates a new Synchronizer
func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.HistoryDB, stateDB *statedb.StateDB) (*Synchronizer, error) {
func NewSynchronizer(ethClient eth.ClientInterface, historyDB *historydb.HistoryDB,
stateDB *statedb.StateDB, cfg Config) (*Synchronizer, error) {
auctionConstants, err := ethClient.AuctionConstants()
if err != nil {
log.Errorw("NewSynchronizer", "err", err)
log.Errorw("NewSynchronizer ethClient.AuctionConstants()", "err", err)
return nil, err
}
rollupConstants, err := ethClient.RollupConstants()
if err != nil {
log.Errorw("NewSynchronizer ethClient.RollupConstants()", "err", err)
return nil, err
}
// TODO: Uncomment once ethClient.WDelayerConstants() is implemented
// wDelayerConstants, err := ethClient.WDelayerConstants()
// if err != nil {
// log.Errorw("NewSynchronizer ethClient.WDelayerConstants()", "err", err)
// return nil, err
// }
// Set startBlockNum to the minimum between Auction, Rollup and
// WDelayer StartBlockNum
startBlockNum := cfg.StartBlockNum.Auction
if startBlockNum < cfg.StartBlockNum.Rollup {
startBlockNum = cfg.StartBlockNum.Rollup
}
if startBlockNum < cfg.StartBlockNum.WDelayer {
startBlockNum = cfg.StartBlockNum.WDelayer
}
return &Synchronizer{
ethClient: ethClient,
auctionConstants: *auctionConstants,
historyDB: historyDB,
stateDB: stateDB,
// auctionConstants: common.AuctionConstants{},
rollupConstants: *rollupConstants,
// rollupConstants: common.RollupConstants{},
// wDelayerConstants: *wDelayerConstants,
wDelayerConstants: common.WDelayerConstants{},
historyDB: historyDB,
stateDB: stateDB,
cfg: cfg,
startBlockNum: startBlockNum,
}, nil
}
// AuctionConstants returns the AuctionConstants read from the smart contract
func (s *Synchronizer) AuctionConstants() *common.AuctionConstants {
return &s.auctionConstants
}
// RollupConstants returns the RollupConstants read from the smart contract
func (s *Synchronizer) RollupConstants() *common.RollupConstants {
return &s.rollupConstants
}
// WDelayerConstants returns the WDelayerConstants read from the smart contract
func (s *Synchronizer) WDelayerConstants() *common.WDelayerConstants {
return &s.wDelayerConstants
}
// Sync2 attems to synchronize an ethereum block starting from lastSavedBlock.
// 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
@ -115,9 +139,10 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
if err != nil && err != sql.ErrNoRows {
return nil, nil, err
}
// If we don't have any stored block, we must do a full sync starting from the rollup genesis block
// If we don't have any stored block, we must do a full sync
// starting from the startBlockNum
if err == sql.ErrNoRows || lastSavedBlock.EthBlockNum == 0 {
nextBlockNum = s.auctionConstants.GenesisBlockNum
nextBlockNum = s.startBlockNum
lastSavedBlock = nil
}
}
@ -131,6 +156,7 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
} else if err != nil {
return nil, nil, err
}
log.Debugf("ethBlock: num: %v, parent: %v, hash: %v", ethBlock.EthBlockNum, ethBlock.ParentHash.String(), ethBlock.Hash.String())
log.Debugw("Syncing...", "block", nextBlockNum)
@ -140,7 +166,7 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
// Reorg detected
log.Debugw("Reorg Detected",
"blockNum", ethBlock.EthBlockNum,
"block.parent", ethBlock.ParentHash, "parent.hash", lastSavedBlock.Hash)
"block.parent(got)", ethBlock.ParentHash, "parent.hash(exp)", lastSavedBlock.Hash)
lastDBBlockNum, err := s.reorg(lastSavedBlock)
if err != nil {
return nil, nil, err
@ -169,21 +195,12 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
}
// Group all the block data into the structs to save into HistoryDB
var blockData common.BlockData
blockData.Block = *ethBlock
blockData.L1UserTxs = rollupData.l1UserTxs
blockData.Batches = rollupData.batches
// blockData.withdrawals = rollupData.withdrawals // TODO
blockData.AddedTokens = rollupData.addTokens
blockData.RollupVars = rollupData.vars
blockData.Bids = auctionData.bids
blockData.Coordinators = auctionData.coordinators
blockData.AuctionVars = auctionData.vars
blockData.WithdrawDelayerVars = wdelayerData.vars
blockData := common.BlockData{
Block: *ethBlock,
Rollup: *rollupData,
Auction: *auctionData,
WDelayer: *wdelayerData,
}
// log.Debugw("Sync()", "block", blockData)
// err = s.historyDB.AddBlock(blockData.Block)
@ -204,16 +221,15 @@ func (s *Synchronizer) Sync2(ctx context.Context, lastSavedBlock *common.Block)
// corresponding batches in StateBD are discarded. Returns the last valid
// blockNum from the HistoryDB.
func (s *Synchronizer) reorg(uncleBlock *common.Block) (int64, error) {
var block *common.Block
blockNum := uncleBlock.EthBlockNum
for blockNum >= s.auctionConstants.GenesisBlockNum {
for blockNum >= s.startBlockNum {
ethBlock, err := s.ethClient.EthBlockByNumber(context.Background(), blockNum)
if err != nil {
return 0, err
}
block, err = s.historyDB.GetBlock(blockNum)
block, err := s.historyDB.GetBlock(blockNum)
if err != nil {
return 0, err
}
@ -227,7 +243,7 @@ func (s *Synchronizer) reorg(uncleBlock *common.Block) (int64, error) {
log.Debugw("Discarding blocks", "total", total, "from", uncleBlock.EthBlockNum, "to", blockNum+1)
// Set History DB and State DB to the correct state
err := s.historyDB.Reorg(block.EthBlockNum)
err := s.historyDB.Reorg(blockNum)
if err != nil {
return 0, err
}
@ -243,7 +259,7 @@ func (s *Synchronizer) reorg(uncleBlock *common.Block) (int64, error) {
}
}
return block.EthBlockNum, nil
return blockNum, nil
}
// TODO: Figure out who will use the Status output, and only return what's strictly need
@ -293,9 +309,9 @@ func (s *Synchronizer) Status() (*common.SyncStatus, error) {
// rollupSync retreives all the Rollup Smart Contract Data that happened at
// ethBlock.blockNum with ethBlock.Hash.
func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*common.RollupData, error) {
blockNum := ethBlock.EthBlockNum
var rollupData = newRollupData()
var rollupData = common.NewRollupData()
// var forgeL1TxsNum int64
// Get rollup events in the block, and make sure the block hash matches
@ -304,7 +320,13 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
if err != nil {
return nil, err
}
// No events in this block
if blockHash == nil {
return &rollupData, nil
}
if *blockHash != ethBlock.Hash {
log.Errorw("Block hash mismatch", "expectd", ethBlock.Hash.String(),
"got", blockHash.String())
return nil, eth.ErrBlockHashMismatchEvent
}
@ -319,14 +341,8 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
nextForgeL1TxsNum = 0
}
// Get newLastIdx that will be used to complete the accounts
// idx, err := s.getIdx(rollupEvents)
// if err != nil {
// return nil, err
// }
// Get L1UserTX
rollupData.l1UserTxs, err = getL1UserTx(rollupEvents.L1UserTx, blockNum)
rollupData.L1UserTxs, err = getL1UserTx(rollupEvents.L1UserTx, blockNum)
if err != nil {
return nil, err
}
@ -362,7 +378,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
// block doesn't contain the l1UserTxs, it means that
// the L1UserTxs queue with toForgeL1TxsNum was closed
// empty, so we leave `l1UserTxs` as an empty slice.
for _, l1UserTx := range rollupData.l1UserTxs {
for _, l1UserTx := range rollupData.L1UserTxs {
if *l1UserTx.ToForgeL1TxsNum == nextForgeL1TxsNum {
l1UserTxs = append(l1UserTxs, l1UserTx)
}
@ -391,7 +407,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
// Insert all the txs forged in this batch (l1UserTxs,
// L1CoordinatorTxs, PoolL2Txs) into stateDB so that they are
// processed.
poolL2Txs := common.L2TxsToPoolL2Txs(forgeBatchArgs.L2TxsData) // TODO: This is a big ugly, find a better way
poolL2Txs := common.L2TxsToPoolL2Txs(forgeBatchArgs.L2TxsData) // NOTE: This is a big ugly, find a better way
// ProcessTxs updates poolL2Txs adding: Nonce (and also TokenID, but we don't use it).
processTxsOut, err := s.stateDB.ProcessTxs(forgeBatchArgs.FeeIdxCoordinator, l1UserTxs,
@ -407,7 +423,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
}
batchData.ExitTree = processTxsOut.ExitInfos
l2Txs, err := common.PoolL2TxsToL2Txs(poolL2Txs) // TODO: This is a big uggly, find a better way
l2Txs, err := common.PoolL2TxsToL2Txs(poolL2Txs) // NOTE: This is a big uggly, find a better way
if err != nil {
return nil, err
}
@ -457,7 +473,7 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
nextForgeL1TxsNum++
}
batchData.Batch = batch
rollupData.batches = append(rollupData.batches, *batchData)
rollupData.Batches = append(rollupData.Batches, *batchData)
}
// Get Registered Tokens
@ -479,16 +495,37 @@ func (s *Synchronizer) rollupSync(ethBlock *common.Block) (*rollupData, error) {
token.Decimals = consts.Decimals
}
rollupData.addTokens = append(rollupData.addTokens, token)
rollupData.AddedTokens = append(rollupData.AddedTokens, token)
}
var vars common.RollupVariables
varsUpdate := false
for _, evtUpdateForgeL1L2BatchTimeout := range rollupEvents.UpdateForgeL1L2BatchTimeout {
vars.ForgeL1L2BatchTimeout = evtUpdateForgeL1L2BatchTimeout.NewForgeL1L2BatchTimeout
varsUpdate = true
}
for _, evtUpdateFeeAddToken := range rollupEvents.UpdateFeeAddToken {
vars.FeeAddToken = evtUpdateFeeAddToken.NewFeeAddToken
varsUpdate = true
}
// TODO: rollupEvents.UpdateForgeL1L2BatchTimeout
// TODO: rollupEvents.UpdateFeeAddToken
// TODO: rollupEvents.WithdrawEvent
// NOTE: WithdrawDelay update doesn't have event, so we can't track changes
// TODO: Emergency Mechanism
// TODO: Variables
// TODO: Constants
// NOTE: Buckets update dones't have event, so we can't track changes
for _, evtWithdraw := range rollupEvents.Withdraw {
rollupData.Withdrawals = append(rollupData.Withdrawals, common.WithdrawInfo{
Idx: common.Idx(evtWithdraw.Idx),
NumExitRoot: common.BatchNum(evtWithdraw.NumExitRoot),
InstantWithdraw: evtWithdraw.InstantWithdraw,
})
}
if varsUpdate {
rollupData.Vars = &vars
}
return &rollupData, nil
}
@ -501,16 +538,22 @@ func cutStringMax(s string, max int) string {
}
// auctionSync gets information from the Auction Contract
func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*auctionData, error) {
func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*common.AuctionData, error) {
blockNum := ethBlock.EthBlockNum
var auctionData = newAuctionData()
var auctionData = common.NewAuctionData()
// Get auction events in the block
auctionEvents, blockHash, err := s.ethClient.AuctionEventsByBlock(blockNum)
if err != nil {
return nil, err
}
// No events in this block
if blockHash == nil {
return &auctionData, nil
}
if *blockHash != ethBlock.Hash {
log.Errorw("Block hash mismatch", "expectd", ethBlock.Hash.String(),
"got", blockHash.String())
return nil, eth.ErrBlockHashMismatchEvent
}
@ -522,7 +565,7 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*auctionData, error)
Bidder: evtNewBid.Bidder,
EthBlockNum: blockNum,
}
auctionData.bids = append(auctionData.bids, bid)
auctionData.Bids = append(auctionData.Bids, bid)
}
// Get Coordinators
@ -532,52 +575,70 @@ func (s *Synchronizer) auctionSync(ethBlock *common.Block) (*auctionData, error)
Forger: evtSetCoordinator.ForgerAddress,
URL: evtSetCoordinator.CoordinatorURL,
}
auctionData.coordinators = append(auctionData.coordinators, coordinator)
auctionData.Coordinators = append(auctionData.Coordinators, coordinator)
}
var vars common.AuctionVariables
varsUpdate := false
for _, evt := range auctionEvents.NewSlotDeadline {
vars.SlotDeadline = evt.NewSlotDeadline
varsUpdate = true
}
for _, evt := range auctionEvents.NewClosedAuctionSlots {
vars.ClosedAuctionSlots = evt.NewClosedAuctionSlots
varsUpdate = true
}
for _, evt := range auctionEvents.NewOutbidding {
vars.Outbidding = evt.NewOutbidding
varsUpdate = true
}
for _, evt := range auctionEvents.NewDonationAddress {
vars.DonationAddress = evt.NewDonationAddress
varsUpdate = true
}
for _, evt := range auctionEvents.NewBootCoordinator {
vars.BootCoordinator = evt.NewBootCoordinator
varsUpdate = true
}
for _, evt := range auctionEvents.NewOpenAuctionSlots {
vars.OpenAuctionSlots = evt.NewOpenAuctionSlots
varsUpdate = true
}
for _, evt := range auctionEvents.NewAllocationRatio {
vars.AllocationRatio = evt.NewAllocationRatio
varsUpdate = true
}
for _, evt := range auctionEvents.NewDefaultSlotSetBid {
if evt.SlotSet > 6 { //nolint:gomnd
return nil, fmt.Errorf("unexpected SlotSet in "+
"auctionEvents.NewDefaultSlotSetBid: %v", evt.SlotSet)
}
vars.DefaultSlotSetBid[evt.SlotSet] = evt.NewInitialMinBid
varsUpdate = true
}
// TODO: NewSlotDeadline
// TODO: NewClosedAuctionSlots
// TODO: NewOutbidding
// TODO: NewDonationAddress
// TODO: NewBootCoordinator
// TODO: NewOpenAuctionSlots
// TODO: NewAllocationRatio
// TODO: NewForgeAllocated
// TODO: NewDefaultSlotSetBid
// TODO: NewForge
// TODO: HEZClaimed
// NOTE: We ignore NewForgeAllocated
// NOTE: We ignore NewForge because we're already tracking ForgeBatch event from Rollup
// NOTE: We ignore HEZClaimed
// TODO: VARS
// TODO: CONSTANTS
if varsUpdate {
auctionData.Vars = &vars
}
return auctionData, nil
return &auctionData, nil
}
// wdelayerSync gets information from the Withdrawal Delayer Contract
func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*wdelayerData, error) {
func (s *Synchronizer) wdelayerSync(ethBlock *common.Block) (*common.WDelayerData, error) {
// blockNum := ethBlock.EthBlockNum
// TODO: VARS
// TODO: CONSTANTS
return &wdelayerData{
vars: nil,
}, nil
}
// TODO: Parse events to generate varialbes once ethClient.WDelayerEventsByBlock is implemented
// func (s *Synchronizer) getIdx(rollupEvents *eth.RollupEvents) (int64, error) {
// // TODO: FIXME: There will be an error here when `len(rollupEvents.ForgeBatch) == 0`
// lastForgeBatch := rollupEvents.ForgeBatch[len(rollupEvents.ForgeBatch)-1]
//
// // TODO: RollupForgeBatchArgs is already called in `rollupSync`.
// // Ideally it should not need to be called twice for the same batch.
// // Get the input for forgeBatch
// forgeBatchArgs, err := s.ethClient.RollupForgeBatchArgs(lastForgeBatch.EthTxHash)
// if err != nil {
// return 0, err
// }
//
// return forgeBatchArgs.NewLastIdx + 1, nil
// }
wDelayerData := common.NewWDelayerData()
return &wDelayerData, nil
}
func getL1UserTx(eventsL1UserTx []eth.RollupEventL1UserTx, blockNum int64) ([]common.L1Tx, error) {
l1Txs := make([]common.L1Tx, len(eventsL1UserTx))

+ 40
- 34
synchronizer/synchronizer_test.go

@ -49,13 +49,13 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
assert.Greater(t, dbBlocks[blockNum-1].Timestamp.Unix(), dbBlocks[blockNum-2].Timestamp.Unix())
// Check Tokens
assert.Equal(t, len(block.AddedTokens), len(syncBlock.AddedTokens))
assert.Equal(t, len(block.Rollup.AddedTokens), len(syncBlock.Rollup.AddedTokens))
dbTokens, err := s.historyDB.GetAllTokens()
require.Nil(t, err)
dbTokens = dbTokens[1:] // ignore token 0, added by default in the DB
for i, token := range block.AddedTokens {
for i, token := range block.Rollup.AddedTokens {
dbToken := dbTokens[i]
syncToken := syncBlock.AddedTokens[i]
syncToken := syncBlock.Rollup.AddedTokens[i]
assert.Equal(t, block.Block.EthBlockNum, syncToken.EthBlockNum)
assert.Equal(t, token.TokenID, syncToken.TokenID)
@ -74,15 +74,15 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
}
// Check L1UserTxs
assert.Equal(t, len(block.L1UserTxs), len(syncBlock.L1UserTxs))
assert.Equal(t, len(block.Rollup.L1UserTxs), len(syncBlock.Rollup.L1UserTxs))
dbL1UserTxs, err := s.historyDB.GetAllL1UserTxs()
require.Nil(t, err)
// Ignore BatchNum in syncBlock.L1UserTxs because this value is set by the HistoryDB
for i := range syncBlock.L1UserTxs {
syncBlock.L1UserTxs[i].BatchNum = block.L1UserTxs[i].BatchNum
for i := range syncBlock.Rollup.L1UserTxs {
syncBlock.Rollup.L1UserTxs[i].BatchNum = block.Rollup.L1UserTxs[i].BatchNum
}
assert.Equal(t, block.L1UserTxs, syncBlock.L1UserTxs)
for _, tx := range block.L1UserTxs {
assert.Equal(t, block.Rollup.L1UserTxs, syncBlock.Rollup.L1UserTxs)
for _, tx := range block.Rollup.L1UserTxs {
var dbTx *common.L1Tx
// Find tx in DB output
for _, _dbTx := range dbL1UserTxs {
@ -97,7 +97,7 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
}
// Check Batches
assert.Equal(t, len(block.Batches), len(syncBlock.Batches))
assert.Equal(t, len(block.Rollup.Batches), len(syncBlock.Rollup.Batches))
dbBatches, err := s.historyDB.GetAllBatches()
require.Nil(t, err)
@ -110,7 +110,7 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
dbExits, err := s.historyDB.GetAllExits()
require.Nil(t, err)
// dbL1CoordinatorTxs := []common.L1Tx{}
for i, batch := range block.Batches {
for i, batch := range block.Rollup.Batches {
var dbBatch *common.Batch
// Find batch in DB output
for _, _dbBatch := range dbBatches {
@ -120,7 +120,7 @@ func checkSyncBlock(t *testing.T, s *Synchronizer, blockNum int, block, syncBloc
break
}
}
syncBatch := syncBlock.Batches[i]
syncBatch := syncBlock.Rollup.Batches[i]
// We don't care about TotalFeesUSD. Use the syncBatch that
// has a TotalFeesUSD inserted by the HistoryDB
@ -235,7 +235,13 @@ func TestSync(t *testing.T) {
client := test.NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
// Create Synchronizer
s, err := NewSynchronizer(client, historyDB, stateDB)
s, err := NewSynchronizer(client, historyDB, stateDB, Config{
StartBlockNum: ConfigStartBlockNum{
Rollup: 1,
Auction: 1,
WDelayer: 1,
},
})
require.Nil(t, err)
//
@ -296,7 +302,7 @@ func TestSync(t *testing.T) {
> block // blockNum=3
`
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(set1)
require.Nil(t, err)
// Sanity check
@ -304,20 +310,20 @@ func TestSync(t *testing.T) {
// blocks 0 (blockNum=2)
i := 0
require.Equal(t, 2, int(blocks[i].Block.EthBlockNum))
require.Equal(t, 3, len(blocks[i].AddedTokens))
require.Equal(t, 5, len(blocks[i].L1UserTxs))
require.Equal(t, 2, len(blocks[i].Batches))
require.Equal(t, 2, len(blocks[i].Batches[0].L1CoordinatorTxs))
require.Equal(t, 3, len(blocks[i].Rollup.AddedTokens))
require.Equal(t, 5, len(blocks[i].Rollup.L1UserTxs))
require.Equal(t, 2, len(blocks[i].Rollup.Batches))
require.Equal(t, 2, len(blocks[i].Rollup.Batches[0].L1CoordinatorTxs))
// blocks 1 (blockNum=3)
i = 1
require.Equal(t, 3, int(blocks[i].Block.EthBlockNum))
require.Equal(t, 3, len(blocks[i].L1UserTxs))
require.Equal(t, 2, len(blocks[i].Batches))
require.Equal(t, 2, len(blocks[i].Batches[0].L2Txs))
require.Equal(t, 3, len(blocks[i].Rollup.L1UserTxs))
require.Equal(t, 2, len(blocks[i].Rollup.Batches))
require.Equal(t, 2, len(blocks[i].Rollup.Batches[0].L2Txs))
// Generate extra required data
for _, block := range blocks {
for _, token := range block.AddedTokens {
for _, token := range block.Rollup.AddedTokens {
consts := eth.ERC20Consts{
Name: fmt.Sprintf("Token %d", token.TokenID),
Symbol: fmt.Sprintf("TK%d", token.TokenID),
@ -330,11 +336,11 @@ func TestSync(t *testing.T) {
// Add block data to the smart contracts
for _, block := range blocks {
for _, token := range block.AddedTokens {
for _, token := range block.Rollup.AddedTokens {
_, err := client.RollupAddTokenSimple(token.EthAddr, clientSetup.RollupVariables.FeeAddToken)
require.Nil(t, err)
}
for _, tx := range block.L1UserTxs {
for _, tx := range block.Rollup.L1UserTxs {
client.CtlSetAddr(tx.FromEthAddr)
_, err := client.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.LoadAmount, tx.Amount,
uint32(tx.TokenID), int64(tx.ToIdx))
@ -347,7 +353,7 @@ func TestSync(t *testing.T) {
// coordinator owned to receive fees.
feeIdxCoordinator = []common.Idx{common.Idx(256), common.Idx(259)}
}
for _, batch := range block.Batches {
for _, batch := range block.Rollup.Batches {
_, err := client.RollupForgeBatch(&eth.RollupForgeBatchArgs{
NewLastIdx: batch.Batch.LastIdx,
NewStRoot: batch.Batch.StateRoot,
@ -377,8 +383,8 @@ func TestSync(t *testing.T) {
block := &blocks[i]
// Count number of L1UserTxs in each queue, to figure out later
// position of L1CoordinatorTxs and L2Txs
for j := range block.L1UserTxs {
tx := &block.L1UserTxs[j]
for j := range block.Rollup.L1UserTxs {
tx := &block.Rollup.L1UserTxs[j]
l1UserTxsLen[*tx.ToForgeL1TxsNum]++
if tx.Type == common.TxTypeForceExit {
forceExits[*tx.ToForgeL1TxsNum] = append(forceExits[*tx.ToForgeL1TxsNum],
@ -388,15 +394,15 @@ func TestSync(t *testing.T) {
})
}
}
for j := range block.Batches {
batch := &block.Batches[j]
for j := range block.Rollup.Batches {
batch := &block.Rollup.Batches[j]
if batch.L1Batch {
// Set BatchNum for forged L1UserTxs to til blocks
bn := batch.Batch.BatchNum
for k := range blocks {
block := &blocks[k]
for l := range block.L1UserTxs {
tx := &block.L1UserTxs[l]
for l := range block.Rollup.L1UserTxs {
tx := &block.Rollup.L1UserTxs[l]
if *tx.ToForgeL1TxsNum == openToForge {
tx.BatchNum = &bn
}
@ -425,8 +431,8 @@ func TestSync(t *testing.T) {
// Fill expected positions in L1CoordinatorTxs and L2Txs
for i := range blocks {
block := &blocks[i]
for j := range block.Batches {
batch := &block.Batches[j]
for j := range block.Rollup.Batches {
batch := &block.Rollup.Batches[j]
position := 0
if batch.L1Batch {
position = l1UserTxsLen[*batch.Batch.ForgeL1TxsNum]
@ -455,8 +461,8 @@ func TestSync(t *testing.T) {
// Fill ExitTree (only AccountIdx and Balance)
for i := range blocks {
block := &blocks[i]
for j := range block.Batches {
batch := &block.Batches[j]
for j := range block.Rollup.Batches {
batch := &block.Rollup.Batches[j]
if batch.L1Batch {
for forgeL1TxsNum, exits := range forceExits {
if forgeL1TxsNum == *batch.Batch.ForgeL1TxsNum {

+ 19
- 20
test/ethclient.go

@ -32,10 +32,10 @@ func init() {
// RollupBlock stores all the data related to the Rollup SC from an ethereum block
type RollupBlock struct {
State eth.RollupState
Vars eth.RollupVariables
Vars common.RollupVariables
Events eth.RollupEvents
Txs map[ethCommon.Hash]*types.Transaction
Constants *eth.RollupPublicConstants
Constants *common.RollupConstants
Eth *EthereumBlock
}
@ -55,10 +55,10 @@ var (
// AuctionBlock stores all the data related to the Auction SC from an ethereum block
type AuctionBlock struct {
State eth.AuctionState
Vars eth.AuctionVariables
Vars common.AuctionVariables
Events eth.AuctionEvents
Txs map[ethCommon.Hash]*types.Transaction
Constants *eth.AuctionConstants
Constants *common.AuctionConstants
Eth *EthereumBlock
}
@ -219,10 +219,10 @@ func (b *Block) Next() *Block {
// ClientSetup is used to initialize the constants of the Smart Contracts and
// other details of the test Client
type ClientSetup struct {
RollupConstants *eth.RollupPublicConstants
RollupVariables *eth.RollupVariables
AuctionConstants *eth.AuctionConstants
AuctionVariables *eth.AuctionVariables
RollupConstants *common.RollupConstants
RollupVariables *common.RollupVariables
AuctionConstants *common.AuctionConstants
AuctionVariables *common.AuctionVariables
VerifyProof bool
}
@ -241,8 +241,8 @@ func NewClientSetupExample() *ClientSetup {
}
tokenHEZ := ethCommon.HexToAddress("0x51D243D62852Bba334DD5cc33f242BAc8c698074")
governanceAddress := ethCommon.HexToAddress("0x688EfD95BA4391f93717CF02A9aED9DBD2855cDd")
rollupConstants := &eth.RollupPublicConstants{
Verifiers: []eth.RollupVerifierStruct{
rollupConstants := &common.RollupConstants{
Verifiers: []common.RollupVerifierStruct{
{
MaxTx: 2048,
NLevels: 32,
@ -254,12 +254,12 @@ func NewClientSetupExample() *ClientSetup {
HermezAuctionContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
WithdrawDelayerContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
}
rollupVariables := &eth.RollupVariables{
rollupVariables := &common.RollupVariables{
FeeAddToken: big.NewInt(11),
ForgeL1L2BatchTimeout: 9,
WithdrawalDelay: 80,
}
auctionConstants := &eth.AuctionConstants{
auctionConstants := &common.AuctionConstants{
BlocksPerSlot: 40,
InitialMinimalBidding: initialMinimalBidding,
GenesisBlockNum: 1,
@ -267,7 +267,7 @@ func NewClientSetupExample() *ClientSetup {
TokenHEZ: tokenHEZ,
HermezRollup: ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"),
}
auctionVariables := &eth.AuctionVariables{
auctionVariables := &common.AuctionVariables{
DonationAddress: ethCommon.HexToAddress("0x61Ed87CF0A1496b49A420DA6D84B58196b98f2e7"),
BootCoordinator: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
DefaultSlotSetBid: [6]*big.Int{
@ -310,8 +310,8 @@ type Client struct {
rw *sync.RWMutex
log bool
addr *ethCommon.Address
rollupConstants *eth.RollupPublicConstants
auctionConstants *eth.AuctionConstants
rollupConstants *common.RollupConstants
auctionConstants *common.AuctionConstants
blocks map[int64]*Block
// state state
blockNum int64 // last mined block num
@ -653,7 +653,7 @@ func (c *Client) RollupL1UserTxERC20ETH(
nextBlock := c.nextBlock()
r := nextBlock.Rollup
queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
if len(queue.L1TxQueue) >= eth.RollupConstMaxL1UserTx {
if len(queue.L1TxQueue) >= common.RollupConstMaxL1UserTx {
r.State.LastToForgeL1TxsNum++
r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct()
queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum]
@ -883,12 +883,11 @@ func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Tra
// }
// RollupConstants returns the Constants of the Rollup Smart Contract
func (c *Client) RollupConstants() (*eth.RollupPublicConstants, error) {
func (c *Client) RollupConstants() (*common.RollupConstants, error) {
c.rw.RLock()
defer c.rw.RUnlock()
log.Error("TODO")
return nil, errTODO
return c.rollupConstants, nil
}
// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
@ -1326,7 +1325,7 @@ func (c *Client) AuctionGetClaimableHEZ(bidder ethCommon.Address) (*big.Int, err
}
// AuctionConstants returns the Constants of the Auction Smart Contract
func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) {
func (c *Client) AuctionConstants() (*common.AuctionConstants, error) {
c.rw.RLock()
defer c.rw.RUnlock()

+ 3
- 3
test/til/sets_test.go

@ -4,7 +4,7 @@ import (
"strings"
"testing"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/common"
"github.com/stretchr/testify/assert"
)
@ -16,7 +16,7 @@ func TestCompileSetsBase(t *testing.T) {
_, err = parser.parse()
assert.Nil(t, err)
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(SetBlockchain0)
assert.Nil(t, err)
_, err = tc.GeneratePoolL2Txs(SetPool0)
@ -25,7 +25,7 @@ func TestCompileSetsBase(t *testing.T) {
func TestCompileSetsMinimumFlow(t *testing.T) {
// minimum flow
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
_, err := tc.GenerateBlocks(SetBlockchainMinimumFlow0)
assert.Nil(t, err)
_, err = tc.GeneratePoolL2Txs(SetPoolL2MinimumFlow0)

+ 6
- 4
test/til/txs.go

@ -30,7 +30,9 @@ func newBlock(blockNum int64) common.BlockData {
Block: common.Block{
EthBlockNum: blockNum,
},
L1UserTxs: []common.L1Tx{},
Rollup: common.RollupData{
L1UserTxs: []common.L1Tx{},
},
}
}
@ -339,7 +341,7 @@ func (tc *Context) GenerateBlocks(set string) ([]common.BlockData, error) {
return nil, fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.lineNum, tc.LastRegisteredTokenID+1, inst.tokenID)
}
tc.LastRegisteredTokenID++
tc.currBlock.AddedTokens = append(tc.currBlock.AddedTokens, newToken)
tc.currBlock.Rollup.AddedTokens = append(tc.currBlock.Rollup.AddedTokens, newToken)
default:
return nil, fmt.Errorf("Line %d: Unexpected type: %s", inst.lineNum, inst.typ)
}
@ -410,7 +412,7 @@ func (tc *Context) setIdxs() error {
}
tc.currBatch.Batch.LastIdx = int64(tc.idx - 1) // `-1` because tc.idx is the next available idx
tc.currBlock.Batches = append(tc.currBlock.Batches, tc.currBatch)
tc.currBlock.Rollup.Batches = append(tc.currBlock.Rollup.Batches, tc.currBatch)
tc.currBatchNum++
tc.currBatch = newBatchData(tc.currBatchNum)
tc.currBatchTest.l1CoordinatorTxs = nil
@ -460,7 +462,7 @@ func (tc *Context) addToL1Queue(tx L1Tx) error {
tx.L1Tx = *nTx
tc.Queues[tc.openToForge] = append(tc.Queues[tc.openToForge], tx)
tc.currBlock.L1UserTxs = append(tc.currBlock.L1UserTxs, tx.L1Tx)
tc.currBlock.Rollup.L1UserTxs = append(tc.currBlock.Rollup.L1UserTxs, tx.L1Tx)
return nil
}

+ 38
- 39
test/til/txs_test.go

@ -5,7 +5,6 @@ import (
"testing"
"github.com/hermeznetwork/hermez-node/common"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -21,13 +20,13 @@ func TestGenerateBlocksNoBatches(t *testing.T) {
> block
`
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(set)
require.Nil(t, err)
assert.Equal(t, 1, len(blocks))
assert.Equal(t, 0, len(blocks[0].Batches))
assert.Equal(t, 2, len(blocks[0].AddedTokens))
assert.Equal(t, 2, len(blocks[0].L1UserTxs))
assert.Equal(t, 0, len(blocks[0].Rollup.Batches))
assert.Equal(t, 2, len(blocks[0].Rollup.AddedTokens))
assert.Equal(t, 2, len(blocks[0].Rollup.L1UserTxs))
}
func TestGenerateBlocks(t *testing.T) {
@ -88,58 +87,58 @@ func TestGenerateBlocks(t *testing.T) {
// batch and last block
Transfer(1) User1-User0: 1 (1)
`
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
blocks, err := tc.GenerateBlocks(set)
require.Nil(t, err)
assert.Equal(t, 2, len(blocks))
assert.Equal(t, 5, len(blocks[0].Batches))
assert.Equal(t, 1, len(blocks[1].Batches))
assert.Equal(t, 9, len(blocks[0].L1UserTxs))
assert.Equal(t, 4, len(blocks[0].Batches[3].L1CoordinatorTxs))
assert.Equal(t, 0, len(blocks[1].L1UserTxs))
assert.Equal(t, 5, len(blocks[0].Rollup.Batches))
assert.Equal(t, 1, len(blocks[1].Rollup.Batches))
assert.Equal(t, 9, len(blocks[0].Rollup.L1UserTxs))
assert.Equal(t, 4, len(blocks[0].Rollup.Batches[3].L1CoordinatorTxs))
assert.Equal(t, 0, len(blocks[1].Rollup.L1UserTxs))
// Check expected values generated by each line
// #0: Deposit(1) A: 10
tc.checkL1TxParams(t, blocks[0].L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1, "A", "", big.NewInt(10), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[0], common.TxTypeCreateAccountDeposit, 1, "A", "", big.NewInt(10), nil)
// #1: Deposit(2) A: 20
tc.checkL1TxParams(t, blocks[0].L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2, "A", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[1], common.TxTypeCreateAccountDeposit, 2, "A", "", big.NewInt(20), nil)
// // #2: Deposit(1) A: 20
tc.checkL1TxParams(t, blocks[0].L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1, "B", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[2], common.TxTypeCreateAccountDeposit, 1, "B", "", big.NewInt(5), nil)
// // #3: CreateAccountDeposit(1) C: 5
tc.checkL1TxParams(t, blocks[0].L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1, "C", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[3], common.TxTypeCreateAccountDeposit, 1, "C", "", big.NewInt(5), nil)
// // #4: CreateAccountDeposit(1) D: 5
tc.checkL1TxParams(t, blocks[0].L1UserTxs[4], common.TxTypeCreateAccountDeposit, 1, "D", "", big.NewInt(5), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[4], common.TxTypeCreateAccountDeposit, 1, "D", "", big.NewInt(5), nil)
// #5: Transfer(1) A-B: 6 (1)
tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(6), common.BatchNum(3))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[0], common.TxTypeTransfer, 1, "A", "B", big.NewInt(6), common.BatchNum(3))
// #6: Transfer(1) B-D: 3 (1)
tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[1], common.TxTypeTransfer, 1, "B", "D", big.NewInt(3), common.BatchNum(3))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[1], common.TxTypeTransfer, 1, "B", "D", big.NewInt(3), common.BatchNum(3))
// #7: Transfer(1) A-D: 1 (1)
tc.checkL2TxParams(t, blocks[0].Batches[2].L2Txs[2], common.TxTypeTransfer, 1, "A", "D", big.NewInt(1), common.BatchNum(3))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[2].L2Txs[2], common.TxTypeTransfer, 1, "A", "D", big.NewInt(1), common.BatchNum(3))
// change of Batch
// #8: CreateAccountDepositTransfer(1) F-A: 15, 10 (3)
tc.checkL1TxParams(t, blocks[0].L1UserTxs[5], common.TxTypeCreateAccountDepositTransfer, 1, "F", "A", big.NewInt(15), big.NewInt(10))
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[5], common.TxTypeCreateAccountDepositTransfer, 1, "F", "A", big.NewInt(15), big.NewInt(10))
// #9: DepositTransfer(1) A-B: 15, 10 (1)
tc.checkL1TxParams(t, blocks[0].L1UserTxs[6], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[6], common.TxTypeDepositTransfer, 1, "A", "B", big.NewInt(15), big.NewInt(10))
// #11: Transfer(1) C-A : 3 (1)
tc.checkL2TxParams(t, blocks[0].Batches[3].L2Txs[0], common.TxTypeTransfer, 1, "C", "A", big.NewInt(3), common.BatchNum(4))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[0], common.TxTypeTransfer, 1, "C", "A", big.NewInt(3), common.BatchNum(4))
// #12: Transfer(2) A-B: 15 (1)
tc.checkL2TxParams(t, blocks[0].Batches[3].L2Txs[1], common.TxTypeTransfer, 2, "A", "B", big.NewInt(15), common.BatchNum(4))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[3].L2Txs[1], common.TxTypeTransfer, 2, "A", "B", big.NewInt(15), common.BatchNum(4))
// #13: Deposit(1) User0: 20
tc.checkL1TxParams(t, blocks[0].L1UserTxs[7], common.TxTypeCreateAccountDeposit, 1, "User0", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[7], common.TxTypeCreateAccountDeposit, 1, "User0", "", big.NewInt(20), nil)
// // #14: Deposit(3) User1: 20
tc.checkL1TxParams(t, blocks[0].L1UserTxs[8], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
tc.checkL1TxParams(t, blocks[0].Rollup.L1UserTxs[8], common.TxTypeCreateAccountDeposit, 3, "User1", "", big.NewInt(20), nil)
// #15: Transfer(1) User0-User1: 15 (1)
tc.checkL2TxParams(t, blocks[0].Batches[4].L2Txs[0], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(5))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[0], common.TxTypeTransfer, 1, "User0", "User1", big.NewInt(15), common.BatchNum(5))
// #16: Transfer(3) User1-User0: 15 (1)
tc.checkL2TxParams(t, blocks[0].Batches[4].L2Txs[1], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(5))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[1], common.TxTypeTransfer, 3, "User1", "User0", big.NewInt(15), common.BatchNum(5))
// #17: Transfer(1) A-C: 1 (1)
tc.checkL2TxParams(t, blocks[0].Batches[4].L2Txs[2], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(5))
tc.checkL2TxParams(t, blocks[0].Rollup.Batches[4].L2Txs[2], common.TxTypeTransfer, 1, "A", "C", big.NewInt(1), common.BatchNum(5))
// change of Batch
// #18: Transfer(1) User1-User0: 1 (1)
tc.checkL2TxParams(t, blocks[1].Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(6))
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[0], common.TxTypeTransfer, 1, "User1", "User0", big.NewInt(1), common.BatchNum(6))
// change of Block (implies also a change of batch)
// #19: Transfer(1) A-B: 1 (1)
tc.checkL2TxParams(t, blocks[1].Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(6))
tc.checkL2TxParams(t, blocks[1].Rollup.Batches[0].L2Txs[1], common.TxTypeTransfer, 1, "A", "B", big.NewInt(1), common.BatchNum(6))
}
func (tc *Context) checkL1TxParams(t *testing.T, tx common.L1Tx, typ common.TxType, tokenID common.TokenID, from, to string, loadAmount, amount *big.Int) {
@ -192,7 +191,7 @@ func TestGeneratePoolL2Txs(t *testing.T) {
> batchL1
> batchL1
`
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
_, err := tc.GenerateBlocks(set)
require.Nil(t, err)
set = `
@ -252,7 +251,7 @@ func TestGeneratePoolL2Txs(t *testing.T) {
> batchL1
> block
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Nil(t, err)
set = `
@ -278,7 +277,7 @@ func TestGenerateErrors(t *testing.T) {
CreateAccountDeposit(1) A: 5
> batchL1
`
tc := NewContext(eth.RollupConstMaxL1UserTx)
tc := NewContext(common.RollupConstMaxL1UserTx)
_, err := tc.GenerateBlocks(set)
assert.Equal(t, "Line 2: Can not process CreateAccountDeposit: TokenID 1 not registered, last registered TokenID: 0", err.Error())
@ -287,7 +286,7 @@ func TestGenerateErrors(t *testing.T) {
Type: Blockchain
AddToken(0)
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 2: AddToken can not register TokenID 0", err.Error())
@ -295,7 +294,7 @@ func TestGenerateErrors(t *testing.T) {
Type: Blockchain
AddToken(2)
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 2: AddToken TokenID should be sequential, expected TokenID: 1, defined TokenID: 2", err.Error())
@ -306,7 +305,7 @@ func TestGenerateErrors(t *testing.T) {
AddToken(3)
AddToken(5)
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 5: AddToken TokenID should be sequential, expected TokenID: 4, defined TokenID: 5", err.Error())
@ -320,7 +319,7 @@ func TestGenerateErrors(t *testing.T) {
Transfer(1) A-B: 6 (1)
> batch
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Equal(t, "Line 5: CreateAccountDeposit(1)BTransfer(1) A-B: 6 (1)\n, err: Expected ':', found 'Transfer'", err.Error())
set = `
@ -334,7 +333,7 @@ func TestGenerateErrors(t *testing.T) {
Transfer(1) A-B: 6 (1)
> batch
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Nil(t, err)
@ -352,7 +351,7 @@ func TestGenerateErrors(t *testing.T) {
Exit(1) A: 3 (1)
> batch
`
tc = NewContext(eth.RollupConstMaxL1UserTx)
tc = NewContext(common.RollupConstMaxL1UserTx)
_, err = tc.GenerateBlocks(set)
require.Nil(t, err)
assert.Equal(t, common.Nonce(3), tc.Users["A"].Accounts[common.TokenID(1)].Nonce)

+ 4
- 5
txselector/txselector_test.go

@ -13,7 +13,6 @@ import (
"github.com/hermeznetwork/hermez-node/db/historydb"
"github.com/hermeznetwork/hermez-node/db/l2db"
"github.com/hermeznetwork/hermez-node/db/statedb"
"github.com/hermeznetwork/hermez-node/eth"
"github.com/hermeznetwork/hermez-node/test"
"github.com/hermeznetwork/hermez-node/test/til"
"github.com/jmoiron/sqlx"
@ -61,7 +60,7 @@ func TestGetL2TxSelection(t *testing.T) {
txsel := initTest(t, til.SetPool0, 5, 5, 10)
test.WipeDB(txsel.l2db.DB())
tc := til.NewContext(eth.RollupConstMaxL1UserTx)
tc := til.NewContext(common.RollupConstMaxL1UserTx)
// generate test transactions
blocks, err := tc.GenerateBlocks(til.SetBlockchain0)
assert.Nil(t, err)
@ -86,18 +85,18 @@ func TestGetL2TxSelection(t *testing.T) {
// Process the 1st batch, which contains the L1CoordinatorTxs necessary
// to create the Coordinator accounts to receive the fees
_, err = txsel.localAccountsDB.ProcessTxs(nil, nil, blocks[0].Batches[0].L1CoordinatorTxs, nil)
_, err = txsel.localAccountsDB.ProcessTxs(nil, nil, blocks[0].Rollup.Batches[0].L1CoordinatorTxs, nil)
require.Nil(t, err)
// add the 1st batch of transactions to the TxSelector
addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Batches[0].L2Txs))
addL2Txs(t, txsel, common.L2TxsToPoolL2Txs(blocks[0].Rollup.Batches[0].L2Txs))
l1CoordTxs, l2Txs, err := txsel.GetL2TxSelection(coordIdxs, 0)
assert.Nil(t, err)
assert.Equal(t, 0, len(l2Txs))
assert.Equal(t, 0, len(l1CoordTxs))
_, _, _, err = txsel.GetL1L2TxSelection(coordIdxs, 0, blocks[0].L1UserTxs)
_, _, _, err = txsel.GetL1L2TxSelection(coordIdxs, 0, blocks[0].Rollup.L1UserTxs)
assert.Nil(t, err)
// TODO once L2DB is updated to return error in case that AddTxTest

Loading…
Cancel
Save