|
|
@ -6,6 +6,8 @@ import ( |
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"math/big" |
|
|
|
"reflect" |
|
|
|
"sync" |
|
|
|
"time" |
|
|
|
|
|
|
|
ethCommon "github.com/ethereum/go-ethereum/common" |
|
|
@ -18,18 +20,75 @@ import ( |
|
|
|
"github.com/mitchellh/copystructure" |
|
|
|
) |
|
|
|
|
|
|
|
func init() { |
|
|
|
copystructure.Copiers[reflect.TypeOf(big.Int{})] = |
|
|
|
func(raw interface{}) (interface{}, error) { |
|
|
|
in := raw.(big.Int) |
|
|
|
out := new(big.Int).Set(&in) |
|
|
|
return *out, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// RollupBlock stores all the data related to the Rollup SC from an ethereum block
|
|
|
|
type RollupBlock struct { |
|
|
|
State eth.RollupState |
|
|
|
Vars eth.RollupVariables |
|
|
|
Events eth.RollupEvents |
|
|
|
} |
|
|
|
State eth.RollupState |
|
|
|
Vars eth.RollupVariables |
|
|
|
Events eth.RollupEvents |
|
|
|
Constants *eth.RollupConstants |
|
|
|
Eth *EthereumBlock |
|
|
|
} |
|
|
|
|
|
|
|
var ( |
|
|
|
errBidClosed = fmt.Errorf("Bid has already been closed") |
|
|
|
errBidNotOpen = fmt.Errorf("Bid has not been opened yet") |
|
|
|
errBidBelowMin = fmt.Errorf("Bid below minimum") |
|
|
|
errCoordNotReg = fmt.Errorf("Coordinator not registered") |
|
|
|
) |
|
|
|
|
|
|
|
// AuctionBlock stores all the data related to the Auction SC from an ethereum block
|
|
|
|
type AuctionBlock struct { |
|
|
|
State eth.AuctionState |
|
|
|
Vars eth.AuctionVariables |
|
|
|
Events eth.AuctionEvents |
|
|
|
State eth.AuctionState |
|
|
|
Vars eth.AuctionVariables |
|
|
|
Events eth.AuctionEvents |
|
|
|
Constants *eth.AuctionConstants |
|
|
|
Eth *EthereumBlock |
|
|
|
} |
|
|
|
|
|
|
|
func (a *AuctionBlock) getSlotNumber(blockNumber int64) int64 { |
|
|
|
if a.Eth.BlockNum >= a.Constants.GenesisBlockNum { |
|
|
|
return (blockNumber - a.Constants.GenesisBlockNum) / int64(a.Constants.BlocksPerSlot) |
|
|
|
} |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
func (a *AuctionBlock) getCurrentSlotNumber() int64 { |
|
|
|
return a.getSlotNumber(a.Eth.BlockNum) |
|
|
|
} |
|
|
|
|
|
|
|
func (a *AuctionBlock) getEpoch(slot int64) int64 { |
|
|
|
return slot % int64(len(a.Vars.MinBidEpoch)) |
|
|
|
} |
|
|
|
|
|
|
|
func (a *AuctionBlock) getMinBidBySlot(slot int64) (*big.Int, error) { |
|
|
|
if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) { |
|
|
|
return nil, errBidClosed |
|
|
|
} |
|
|
|
|
|
|
|
epoch := a.getEpoch(slot) |
|
|
|
var prevBid *big.Int |
|
|
|
slotState, ok := a.State.Slots[slot] |
|
|
|
// If the bidAmount for a slot is 0 it means that it has not yet been bid, so the midBid will be the minimum
|
|
|
|
// bid for the slot time plus the outbidding set, otherwise it will be the bidAmount plus the outbidding
|
|
|
|
if !ok || slotState.BidAmount.Cmp(big.NewInt(0)) == 0 { |
|
|
|
prevBid = a.Vars.MinBidEpoch[epoch] |
|
|
|
} else { |
|
|
|
prevBid = slotState.BidAmount |
|
|
|
} |
|
|
|
outBid := new(big.Int).Set(prevBid) |
|
|
|
outBid.Mul(outBid, big.NewInt(int64(a.Vars.Outbidding))) |
|
|
|
outBid.Div(outBid, big.NewInt(100)) //nolint:gomnd
|
|
|
|
outBid.Add(prevBid, outBid) |
|
|
|
return outBid, nil |
|
|
|
} |
|
|
|
|
|
|
|
// EthereumBlock stores all the generic data related to the an ethereum block
|
|
|
@ -48,17 +107,25 @@ type Block struct { |
|
|
|
Eth *EthereumBlock |
|
|
|
} |
|
|
|
|
|
|
|
// type ethState struct {
|
|
|
|
// blockNum int64
|
|
|
|
// }
|
|
|
|
|
|
|
|
// type state struct {
|
|
|
|
// rollupState eth.RollupState
|
|
|
|
// rollupVars eth.RollupVariables
|
|
|
|
// auctionState eth.AuctionState
|
|
|
|
// auctionVars eth.AuctionVariables
|
|
|
|
// eth ethState
|
|
|
|
// }
|
|
|
|
// Next prepares the successive block.
|
|
|
|
func (b *Block) Next() *Block { |
|
|
|
blockNextRaw, err := copystructure.Copy(b) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
blockNext := blockNextRaw.(*Block) |
|
|
|
blockNext.Rollup.Events = eth.NewRollupEvents() |
|
|
|
blockNext.Auction.Events = eth.NewAuctionEvents() |
|
|
|
blockNext.Eth = &EthereumBlock{ |
|
|
|
BlockNum: b.Eth.BlockNum + 1, |
|
|
|
ParentHash: b.Eth.Hash, |
|
|
|
} |
|
|
|
blockNext.Rollup.Constants = b.Rollup.Constants |
|
|
|
blockNext.Auction.Constants = b.Auction.Constants |
|
|
|
blockNext.Rollup.Eth = blockNext.Eth |
|
|
|
blockNext.Auction.Eth = blockNext.Eth |
|
|
|
return blockNext |
|
|
|
} |
|
|
|
|
|
|
|
// ClientSetup is used to initialize the constants of the Smart Contracts and
|
|
|
|
// other details of the test Client
|
|
|
@ -70,6 +137,45 @@ type ClientSetup struct { |
|
|
|
VerifyProof bool |
|
|
|
} |
|
|
|
|
|
|
|
// NewClientSetupExample returns a ClientSetup example with hardcoded realistic values.
|
|
|
|
// TODO: Fill all values that are currently default.
|
|
|
|
//nolint:gomnd
|
|
|
|
func NewClientSetupExample() *ClientSetup { |
|
|
|
rollupConstants := ð.RollupConstants{} |
|
|
|
rollupVariables := ð.RollupVariables{ |
|
|
|
MaxTxVerifiers: make([]int, 0), |
|
|
|
TokenHEZ: ethCommon.Address{}, |
|
|
|
GovernanceAddress: ethCommon.Address{}, |
|
|
|
SafetyBot: ethCommon.Address{}, |
|
|
|
ConsensusContract: ethCommon.Address{}, |
|
|
|
WithdrawalContract: ethCommon.Address{}, |
|
|
|
FeeAddToken: big.NewInt(1), |
|
|
|
ForgeL1Timeout: 16, |
|
|
|
FeeL1UserTx: big.NewInt(2), |
|
|
|
} |
|
|
|
auctionConstants := ð.AuctionConstants{ |
|
|
|
BlocksPerSlot: 40, |
|
|
|
} |
|
|
|
auctionVariables := ð.AuctionVariables{ |
|
|
|
DonationAddress: ethCommon.Address{}, |
|
|
|
BootCoordinator: ethCommon.Address{}, |
|
|
|
MinBidEpoch: [6]*big.Int{ |
|
|
|
big.NewInt(10), big.NewInt(11), big.NewInt(12), |
|
|
|
big.NewInt(13), big.NewInt(14), big.NewInt(15)}, |
|
|
|
ClosedAuctionSlots: 2, |
|
|
|
OpenAuctionSlots: 100, |
|
|
|
AllocationRatio: [3]uint8{}, |
|
|
|
Outbidding: 10, |
|
|
|
SlotDeadline: 20, |
|
|
|
} |
|
|
|
return &ClientSetup{ |
|
|
|
RollupConstants: rollupConstants, |
|
|
|
RollupVariables: rollupVariables, |
|
|
|
AuctionConstants: auctionConstants, |
|
|
|
AuctionVariables: auctionVariables, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Timer is an interface to simulate a source of time, useful to advance time
|
|
|
|
// virtually.
|
|
|
|
type Timer interface { |
|
|
@ -85,7 +191,9 @@ type Timer interface { |
|
|
|
// Client implements the eth.ClientInterface interface, allowing to manipulate the
|
|
|
|
// values for testing, working with deterministic results.
|
|
|
|
type Client struct { |
|
|
|
rw *sync.RWMutex |
|
|
|
log bool |
|
|
|
addr ethCommon.Address |
|
|
|
rollupConstants *eth.RollupConstants |
|
|
|
auctionConstants *eth.AuctionConstants |
|
|
|
blocks map[int64]*Block |
|
|
@ -101,7 +209,7 @@ type Client struct { |
|
|
|
|
|
|
|
// NewClient returns a new test Client that implements the eth.IClient
|
|
|
|
// interface, at the given initialBlockNumber.
|
|
|
|
func NewClient(l bool, timer Timer, setup *ClientSetup) *Client { |
|
|
|
func NewClient(l bool, timer Timer, addr ethCommon.Address, setup *ClientSetup) *Client { |
|
|
|
blocks := make(map[int64]*Block) |
|
|
|
blockNum := int64(0) |
|
|
|
|
|
|
@ -124,17 +232,19 @@ func NewClient(l bool, timer Timer, setup *ClientSetup) *Client { |
|
|
|
LastToForgeL1TxsNum: 1, |
|
|
|
CurrentIdx: 0, |
|
|
|
}, |
|
|
|
Vars: *setup.RollupVariables, |
|
|
|
Events: eth.NewRollupEvents(), |
|
|
|
Vars: *setup.RollupVariables, |
|
|
|
Events: eth.NewRollupEvents(), |
|
|
|
Constants: setup.RollupConstants, |
|
|
|
}, |
|
|
|
Auction: &AuctionBlock{ |
|
|
|
State: eth.AuctionState{ |
|
|
|
Slots: make(map[int64]eth.SlotState), |
|
|
|
Slots: make(map[int64]*eth.SlotState), |
|
|
|
PendingBalances: make(map[ethCommon.Address]*big.Int), |
|
|
|
Coordinators: make(map[ethCommon.Address]eth.Coordinator), |
|
|
|
Coordinators: make(map[ethCommon.Address]*eth.Coordinator), |
|
|
|
}, |
|
|
|
Vars: *setup.AuctionVariables, |
|
|
|
Events: eth.NewAuctionEvents(), |
|
|
|
Vars: *setup.AuctionVariables, |
|
|
|
Events: eth.NewAuctionEvents(), |
|
|
|
Constants: setup.AuctionConstants, |
|
|
|
}, |
|
|
|
Eth: &EthereumBlock{ |
|
|
|
BlockNum: blockNum, |
|
|
@ -143,16 +253,16 @@ func NewClient(l bool, timer Timer, setup *ClientSetup) *Client { |
|
|
|
ParentHash: ethCommon.Hash{}, |
|
|
|
}, |
|
|
|
} |
|
|
|
blockCurrent.Rollup.Eth = blockCurrent.Eth |
|
|
|
blockCurrent.Auction.Eth = blockCurrent.Eth |
|
|
|
blocks[blockNum] = &blockCurrent |
|
|
|
blockNextRaw, err := copystructure.Copy(&blockCurrent) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
blockNext := blockNextRaw.(*Block) |
|
|
|
blockNext := blockCurrent.Next() |
|
|
|
blocks[blockNum+1] = blockNext |
|
|
|
|
|
|
|
return &Client{ |
|
|
|
rw: &sync.RWMutex{}, |
|
|
|
log: l, |
|
|
|
addr: addr, |
|
|
|
rollupConstants: setup.RollupConstants, |
|
|
|
auctionConstants: setup.AuctionConstants, |
|
|
|
blocks: blocks, |
|
|
@ -197,29 +307,26 @@ func (c *Client) nextBlock() *Block { |
|
|
|
return c.blocks[c.blockNum+1] |
|
|
|
} |
|
|
|
|
|
|
|
func (c *Client) currentBlock() *Block { |
|
|
|
return c.blocks[c.blockNum] |
|
|
|
} |
|
|
|
|
|
|
|
// CtlMineBlock moves one block forward
|
|
|
|
func (c *Client) CtlMineBlock() { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
blockCurrent := c.nextBlock() |
|
|
|
c.blockNum++ |
|
|
|
c.maxBlockNum = c.blockNum |
|
|
|
blockCurrent.Eth = &EthereumBlock{ |
|
|
|
BlockNum: c.blockNum, |
|
|
|
Time: c.timer.Time(), |
|
|
|
Hash: c.hasher.Next(), |
|
|
|
ParentHash: blockCurrent.Eth.Hash, |
|
|
|
} |
|
|
|
blockCurrent.Eth.Time = c.timer.Time() |
|
|
|
blockCurrent.Eth.Hash = c.hasher.Next() |
|
|
|
for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending { |
|
|
|
c.forgeBatchArgs[ethTxHash] = forgeBatchArgs |
|
|
|
} |
|
|
|
c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs) |
|
|
|
|
|
|
|
blockNextRaw, err := copystructure.Copy(blockCurrent) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
blockNext := blockNextRaw.(*Block) |
|
|
|
blockNext.Rollup.Events = eth.NewRollupEvents() |
|
|
|
blockNext.Auction.Events = eth.NewAuctionEvents() |
|
|
|
blockNext := blockCurrent.Next() |
|
|
|
c.blocks[c.blockNum+1] = blockNext |
|
|
|
c.Debugw("TestClient mined block", "blockNum", c.blockNum) |
|
|
|
} |
|
|
@ -227,6 +334,9 @@ func (c *Client) CtlMineBlock() { |
|
|
|
// CtlRollback discards the last mined block. Use this to replace a mined
|
|
|
|
// block to simulate reorgs.
|
|
|
|
func (c *Client) CtlRollback() { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
if c.blockNum == 0 { |
|
|
|
panic("Can't rollback at blockNum = 0") |
|
|
|
} |
|
|
@ -234,13 +344,7 @@ func (c *Client) CtlRollback() { |
|
|
|
delete(c.blocks, c.blockNum) // delete current block
|
|
|
|
c.blockNum-- |
|
|
|
blockCurrent := c.blocks[c.blockNum] |
|
|
|
blockNextRaw, err := copystructure.Copy(blockCurrent) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
|
blockNext := blockNextRaw.(*Block) |
|
|
|
blockNext.Rollup.Events = eth.NewRollupEvents() |
|
|
|
blockNext.Auction.Events = eth.NewAuctionEvents() |
|
|
|
blockNext := blockCurrent.Next() |
|
|
|
c.blocks[c.blockNum+1] = blockNext |
|
|
|
} |
|
|
|
|
|
|
@ -250,6 +354,9 @@ func (c *Client) CtlRollback() { |
|
|
|
|
|
|
|
// EthCurrentBlock returns the current blockNum
|
|
|
|
func (c *Client) EthCurrentBlock() (int64, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
if c.blockNum < c.maxBlockNum { |
|
|
|
panic("blockNum has decreased. " + |
|
|
|
"After a rollback you must mine to reach the same or higher blockNum") |
|
|
@ -273,6 +380,9 @@ func (c *Client) EthCurrentBlock() (int64, error) { |
|
|
|
// EthBlockByNumber returns the *common.Block for the given block number in a
|
|
|
|
// deterministic way.
|
|
|
|
func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common.Block, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
block, ok := c.blocks[blockNum] |
|
|
|
if !ok { |
|
|
|
return nil, fmt.Errorf("block not found") |
|
|
@ -293,6 +403,9 @@ var errTODO = fmt.Errorf("TODO: Not implemented yet") |
|
|
|
|
|
|
|
// CtlAddL1TxUser adds an L1TxUser to the L1UserTxs queue of the Rollup
|
|
|
|
func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
nextBlock := c.nextBlock() |
|
|
|
r := nextBlock.Rollup |
|
|
|
queue := r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] |
|
|
@ -311,8 +424,13 @@ func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) { |
|
|
|
r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{L1Tx: *l1Tx}) |
|
|
|
} |
|
|
|
|
|
|
|
type transactionData struct { |
|
|
|
Name string |
|
|
|
Value interface{} |
|
|
|
} |
|
|
|
|
|
|
|
func (c *Client) newTransaction(name string, value interface{}) *types.Transaction { |
|
|
|
data, err := json.Marshal(value) |
|
|
|
data, err := json.Marshal(transactionData{name, value}) |
|
|
|
if err != nil { |
|
|
|
panic(err) |
|
|
|
} |
|
|
@ -322,11 +440,17 @@ func (c *Client) newTransaction(name string, value interface{}) *types.Transacti |
|
|
|
|
|
|
|
// RollupForgeBatch is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupForgeBatch(*eth.RollupForgeBatchArgs) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// CtlAddBatch adds forged batch to the Rollup, without checking any ZKProof
|
|
|
|
func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
nextBlock := c.nextBlock() |
|
|
|
r := nextBlock.Rollup |
|
|
|
r.State.StateRoot = args.NewStRoot |
|
|
@ -352,6 +476,9 @@ func (c *Client) CtlAddBatch(args *eth.RollupForgeBatchArgs) { |
|
|
|
|
|
|
|
// RollupAddToken is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
nextBlock := c.nextBlock() |
|
|
|
r := nextBlock.Rollup |
|
|
|
if _, ok := r.State.TokenMap[tokenAddress]; ok { |
|
|
@ -372,76 +499,121 @@ func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transact |
|
|
|
|
|
|
|
// RollupWithdrawMerkleProof is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupForceExit is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupForceTransfer is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupCreateAccountDepositTransfer is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupDepositTransfer is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupDeposit is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupDeposit(fromIdx int64, loadAmountF utils.Float16, tokenID int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF utils.Float16) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupCreateAccountDeposit is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16, tokenID int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupGetTokenAddress is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupGetL1TxFromQueue is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupGetQueue is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupGetQueue(queue int64) ([]byte, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupUpdateForgeL1Timeout is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupUpdateFeeL1UserTx is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupUpdateFeeAddToken is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupUpdateTokensHEZ is the interface to call the smart contract function
|
|
|
|
func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
@ -452,11 +624,17 @@ func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (*types.Tr |
|
|
|
|
|
|
|
// RollupConstants returns the Constants of the Rollup Smart Contract
|
|
|
|
func (c *Client) RollupConstants() (*eth.RollupConstants, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
|
|
|
|
func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCommon.Hash, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
block, ok := c.blocks[blockNum] |
|
|
|
if !ok { |
|
|
|
return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum) |
|
|
@ -466,6 +644,9 @@ func (c *Client) RollupEventsByBlock(blockNum int64) (*eth.RollupEvents, *ethCom |
|
|
|
|
|
|
|
// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
|
|
|
|
func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash] |
|
|
|
if !ok { |
|
|
|
return nil, fmt.Errorf("transaction not found") |
|
|
@ -479,104 +660,194 @@ func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForg |
|
|
|
|
|
|
|
// AuctionSetSlotDeadline is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetSlotDeadline is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetSlotDeadline() (uint8, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return 0, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) { return 0, errTODO } |
|
|
|
func (c *Client) AuctionGetOpenAuctionSlots() (uint16, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return 0, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetClosedAuctionSlots() (uint16, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return 0, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetOutbidding is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetOutbidding(newOutbidding uint8) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetOutbidding is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetOutbidding() (uint8, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return 0, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetAllocationRatio is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetAllocationRatio(newAllocationRatio [3]uint8) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetAllocationRatio is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetAllocationRatio() ([3]uint8, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return [3]uint8{}, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetDonationAddress is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetDonationAddress is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetDonationAddress() (*ethCommon.Address, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionSetBootCoordinator is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetBootCoordinator is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetBootCoordinator() (*ethCommon.Address, error) { |
|
|
|
return nil, errTODO |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
currentBlock := c.currentBlock() |
|
|
|
a := currentBlock.Auction |
|
|
|
|
|
|
|
return &a.Vars.BootCoordinator, nil |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionChangeEpochMinBid is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionChangeEpochMinBid(slotEpoch int64, newInitialMinBid *big.Int) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionRegisterCoordinator is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) { |
|
|
|
return nil, errTODO |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
nextBlock := c.nextBlock() |
|
|
|
a := nextBlock.Auction |
|
|
|
|
|
|
|
if _, ok := a.State.Coordinators[forgerAddress]; ok { |
|
|
|
return nil, fmt.Errorf("Already registered") |
|
|
|
} |
|
|
|
a.State.Coordinators[forgerAddress] = ð.Coordinator{ |
|
|
|
WithdrawalAddress: c.addr, |
|
|
|
URL: URL, |
|
|
|
} |
|
|
|
|
|
|
|
a.Events.NewCoordinator = append(a.Events.NewCoordinator, |
|
|
|
eth.AuctionEventNewCoordinator{ |
|
|
|
ForgerAddress: forgerAddress, |
|
|
|
WithdrawalAddress: c.addr, |
|
|
|
URL: URL, |
|
|
|
}) |
|
|
|
|
|
|
|
type data struct { |
|
|
|
ForgerAddress ethCommon.Address |
|
|
|
URL string |
|
|
|
} |
|
|
|
return c.newTransaction("registercoordinator", data{forgerAddress, URL}), nil |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return false, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetCurrentSlotNumber() (int64, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return 0, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetMinBidBySlot is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionGetMinBidEpoch is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionGetMinBidEpoch(epoch uint8) (*big.Int, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
@ -587,16 +858,64 @@ func (c *Client) AuctionGetMinBidEpoch(epoch uint8) (*big.Int, error) { |
|
|
|
|
|
|
|
// AuctionBid is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionBid(slot int64, bidAmount *big.Int, forger ethCommon.Address) (*types.Transaction, error) { |
|
|
|
return nil, errTODO |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
nextBlock := c.nextBlock() |
|
|
|
a := nextBlock.Auction |
|
|
|
|
|
|
|
if slot < a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots) { |
|
|
|
return nil, errBidClosed |
|
|
|
} |
|
|
|
|
|
|
|
if slot >= a.getCurrentSlotNumber()+int64(a.Vars.ClosedAuctionSlots)+int64(a.Vars.OpenAuctionSlots) { |
|
|
|
return nil, errBidNotOpen |
|
|
|
} |
|
|
|
|
|
|
|
minBid, err := a.getMinBidBySlot(slot) |
|
|
|
if err != nil { |
|
|
|
return nil, err |
|
|
|
} |
|
|
|
if bidAmount.Cmp(minBid) == -1 { |
|
|
|
return nil, errBidBelowMin |
|
|
|
} |
|
|
|
|
|
|
|
if _, ok := a.State.Coordinators[forger]; !ok { |
|
|
|
return nil, errCoordNotReg |
|
|
|
} |
|
|
|
|
|
|
|
slotState, ok := a.State.Slots[slot] |
|
|
|
if !ok { |
|
|
|
slotState = ð.SlotState{} |
|
|
|
a.State.Slots[slot] = slotState |
|
|
|
} |
|
|
|
slotState.Forger = forger |
|
|
|
slotState.BidAmount = bidAmount |
|
|
|
|
|
|
|
a.Events.NewBid = append(a.Events.NewBid, |
|
|
|
eth.AuctionEventNewBid{Slot: slot, BidAmount: bidAmount, CoordinatorForger: forger}) |
|
|
|
|
|
|
|
type data struct { |
|
|
|
Slot int64 |
|
|
|
BidAmount *big.Int |
|
|
|
Forger ethCommon.Address |
|
|
|
} |
|
|
|
return c.newTransaction("bid", data{slot, bidAmount, forger}), nil |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionMultiBid is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotEpoch [6]bool, maxBid, closedMinBid, budget *big.Int, forger ethCommon.Address) (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionCanForge is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) { |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return false, errTODO |
|
|
|
} |
|
|
|
|
|
|
@ -607,15 +926,28 @@ func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) { |
|
|
|
|
|
|
|
// AuctionClaimHEZ is the interface to call the smart contract function
|
|
|
|
func (c *Client) AuctionClaimHEZ() (*types.Transaction, error) { |
|
|
|
c.rw.Lock() |
|
|
|
defer c.rw.Unlock() |
|
|
|
|
|
|
|
return nil, errTODO |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionConstants returns the Constants of the Auction Smart Contract
|
|
|
|
func (c *Client) AuctionConstants() (*eth.AuctionConstants, error) { |
|
|
|
return nil, errTODO |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
return c.auctionConstants, nil |
|
|
|
} |
|
|
|
|
|
|
|
// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
|
|
|
|
func (c *Client) AuctionEventsByBlock(blockNum int64) (*eth.AuctionEvents, *ethCommon.Hash, error) { |
|
|
|
return nil, nil, errTODO |
|
|
|
c.rw.RLock() |
|
|
|
defer c.rw.RUnlock() |
|
|
|
|
|
|
|
block, ok := c.blocks[blockNum] |
|
|
|
if !ok { |
|
|
|
return nil, nil, fmt.Errorf("Block %v doesn't exist", blockNum) |
|
|
|
} |
|
|
|
return &block.Auction.Events, &block.Eth.Hash, nil |
|
|
|
} |