From a2bda1890d2edc798b9a79b32f0124e92f901f3a Mon Sep 17 00:00:00 2001 From: Eduard S Date: Wed, 21 Oct 2020 11:48:02 +0200 Subject: [PATCH] Simplify eth code --- common/l1tx.go | 56 +++--- common/l1tx_test.go | 25 +-- eth/auction.go | 308 +++++++++--------------------- eth/client.go | 35 +++- eth/client_test.go | 2 +- eth/ethereum.go | 5 + eth/rollup.go | 129 ++++++------- eth/rollup_test.go | 5 +- eth/wdelayer.go | 176 +++++------------ node/node.go | 5 +- synchronizer/synchronizer.go | 9 +- synchronizer/synchronizer_test.go | 2 +- test/ethclient.go | 131 ++++++++++--- test/ethclient_test.go | 16 +- 14 files changed, 398 insertions(+), 506 deletions(-) diff --git a/common/l1tx.go b/common/l1tx.go index 4ef06c0..7a75564 100644 --- a/common/l1tx.go +++ b/common/l1tx.go @@ -11,8 +11,8 @@ import ( ) const ( - // L1TxBytesLen is the length of the byte array that represents the L1Tx - L1TxBytesLen = 72 + // L1UserTxBytesLen is the length of the byte array that represents the L1Tx + L1UserTxBytesLen = 72 // L1CoordinatorTxBytesLen is the length of the byte array that represents the L1CoordinatorTx L1CoordinatorTxBytesLen = 101 ) @@ -27,20 +27,20 @@ type L1Tx struct { // where type: // - L1UserTx: 0 // - L1CoordinatorTx: 1 - TxID TxID - ToForgeL1TxsNum *int64 // toForgeL1TxsNum in which the tx was forged / will be forged - Position int - UserOrigin bool // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes - FromIdx Idx // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit) - FromEthAddr ethCommon.Address - FromBJJ *babyjub.PublicKey - ToIdx Idx // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer - TokenID TokenID - Amount *big.Int - LoadAmount *big.Int - EthBlockNum int64 // Ethereum Block Number in which this L1Tx was added to the queue - Type TxType - BatchNum *BatchNum + TxID TxID `meddler:"id"` + ToForgeL1TxsNum *int64 `meddler:"to_forge_l1_txs_num"` // toForgeL1TxsNum in which the tx was forged / will be forged + Position int `meddler:"position"` + UserOrigin bool `meddler:"user_origin"` // true if the tx was originated by a user, false if it was aoriginated by a coordinator. Note that this differ from the spec for implementation simplification purpposes + FromIdx Idx `meddler:"from_idx,zeroisnull"` // FromIdx is used by L1Tx/Deposit to indicate the Idx receiver of the L1Tx.LoadAmount (deposit) + FromEthAddr ethCommon.Address `meddler:"from_eth_addr,zeroisnull"` + FromBJJ *babyjub.PublicKey `meddler:"from_bjj,zeroisnull"` + ToIdx Idx `meddler:"to_idx"` // ToIdx is ignored in L1Tx/Deposit, but used in the L1Tx/DepositAndTransfer + TokenID TokenID `meddler:"token_id"` + Amount *big.Int `meddler:"amount,bigint"` + LoadAmount *big.Int `meddler:"load_amount,bigint"` + EthBlockNum int64 `meddler:"eth_block_num"` // Ethereum Block Number in which this L1Tx was added to the queue + Type TxType `meddler:"type"` + BatchNum *BatchNum `meddler:"batch_num"` } // NewL1Tx returns the given L1Tx with the TxId & Type parameters calculated @@ -146,9 +146,9 @@ func (tx L1Tx) Tx() Tx { return genericTx } -// Bytes encodes a L1Tx into []byte -func (tx *L1Tx) Bytes() ([]byte, error) { - var b [L1TxBytesLen]byte +// BytesUser encodes a L1Tx into []byte +func (tx *L1Tx) BytesUser() ([]byte, error) { + var b [L1UserTxBytesLen]byte copy(b[0:20], tx.FromEthAddr.Bytes()) pkCompL := tx.FromBJJ.Compress() pkCompB := SwapEndianness(pkCompL[:]) @@ -193,13 +193,15 @@ func (tx *L1Tx) BytesCoordinatorTx(compressedSignatureBytes []byte) ([]byte, err return b[:], nil } -// L1TxFromBytes decodes a L1Tx from []byte -func L1TxFromBytes(b []byte) (*L1Tx, error) { - if len(b) != L1TxBytesLen { +// L1UserTxFromBytes decodes a L1Tx from []byte +func L1UserTxFromBytes(b []byte) (*L1Tx, error) { + if len(b) != L1UserTxBytesLen { return nil, fmt.Errorf("Can not parse L1Tx bytes, expected length %d, current: %d", 68, len(b)) } - tx := &L1Tx{} + tx := &L1Tx{ + UserOrigin: true, + } var err error tx.FromEthAddr = ethCommon.BytesToAddress(b[0:20]) @@ -231,8 +233,8 @@ func L1TxFromBytes(b []byte) (*L1Tx, error) { return tx, nil } -// L1TxFromCoordinatorBytes decodes a L1Tx from []byte -func L1TxFromCoordinatorBytes(b []byte) (*L1Tx, error) { +// L1CoordinatorTxFromBytes decodes a L1Tx from []byte +func L1CoordinatorTxFromBytes(b []byte) (*L1Tx, error) { if len(b) != L1CoordinatorTxBytesLen { return nil, fmt.Errorf("Can not parse L1CoordinatorTx bytes, expected length %d, current: %d", 101, len(b)) } @@ -240,7 +242,9 @@ func L1TxFromCoordinatorBytes(b []byte) (*L1Tx, error) { bytesMessage1 := []byte("\x19Ethereum Signed Message:\n98") bytesMessage2 := []byte("I authorize this babyjubjub key for hermez rollup account creation") - tx := &L1Tx{} + tx := &L1Tx{ + UserOrigin: false, + } var err error // Ethereum adds 27 to v v := b[0] - byte(27) //nolint:gomnd diff --git a/common/l1tx_test.go b/common/l1tx_test.go index 21a10a8..b2ae2ef 100644 --- a/common/l1tx_test.go +++ b/common/l1tx_test.go @@ -49,7 +49,7 @@ func TestNewL1CoordinatorTx(t *testing.T) { assert.Equal(t, "0x01000000000000cafe005800", l1Tx.TxID.String()) } -func TestL1TxByteParsers(t *testing.T) { +func TestL1userTxByteParsers(t *testing.T) { var pkComp babyjub.PublicKeyComp pkCompL := []byte("0x56ca90f80d7c374ae7485e9bcc47d4ac399460948da6aeeb899311097925a72c") err := pkComp.UnmarshalText(pkCompL) @@ -59,6 +59,7 @@ func TestL1TxByteParsers(t *testing.T) { require.Nil(t, err) l1Tx := &L1Tx{ + UserOrigin: true, ToIdx: 3, TokenID: 5, Amount: big.NewInt(1), @@ -68,21 +69,21 @@ func TestL1TxByteParsers(t *testing.T) { FromEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"), } - encodedData, err := l1Tx.Bytes() + encodedData, err := l1Tx.BytesUser() require.Nil(t, err) - decodedData, err := L1TxFromBytes(encodedData) + decodedData, err := L1UserTxFromBytes(encodedData) require.Nil(t, err) assert.Equal(t, l1Tx, decodedData) - encodedData2, err := decodedData.Bytes() + encodedData2, err := decodedData.BytesUser() require.Nil(t, err) assert.Equal(t, encodedData, encodedData2) // expect error if length!=68 - _, err = L1TxFromBytes(encodedData[:66]) + _, err = L1UserTxFromBytes(encodedData[:66]) require.NotNil(t, err) - _, err = L1TxFromBytes([]byte{}) + _, err = L1UserTxFromBytes([]byte{}) require.NotNil(t, err) - _, err = L1TxFromBytes(nil) + _, err = L1UserTxFromBytes(nil) require.NotNil(t, err) } @@ -113,7 +114,7 @@ func TestL1TxByteParsersCompatibility(t *testing.T) { expected, err := utils.HexDecode("85dab5b9e2e361d0c208d77be90efcc0439b0a530dd02deb2c81068e7a0f7e327df80b4ab79ee1f41a7def613e73a20c32eece5a000001c638db8be880f00020039c0000053cb88d") require.Nil(t, err) - encodedData, err := l1Tx.Bytes() + encodedData, err := l1Tx.BytesUser() require.Nil(t, err) assert.Equal(t, expected, encodedData) } @@ -161,7 +162,7 @@ func TestL1CoordinatorTxByteParsers(t *testing.T) { bytesCoordinatorL1, err := l1Tx.BytesCoordinatorTx(signature) require.Nil(t, err) - l1txDecoded, err := L1TxFromCoordinatorBytes(bytesCoordinatorL1) + l1txDecoded, err := L1CoordinatorTxFromBytes(bytesCoordinatorL1) require.Nil(t, err) assert.Equal(t, l1Tx, l1txDecoded) bytesCoordinatorL12, err := l1txDecoded.BytesCoordinatorTx(signature) @@ -169,11 +170,11 @@ func TestL1CoordinatorTxByteParsers(t *testing.T) { assert.Equal(t, bytesCoordinatorL1, bytesCoordinatorL12) // expect error if length!=68 - _, err = L1TxFromCoordinatorBytes(bytesCoordinatorL1[:66]) + _, err = L1CoordinatorTxFromBytes(bytesCoordinatorL1[:66]) require.NotNil(t, err) - _, err = L1TxFromCoordinatorBytes([]byte{}) + _, err = L1CoordinatorTxFromBytes([]byte{}) require.NotNil(t, err) - _, err = L1TxFromCoordinatorBytes(nil) + _, err = L1CoordinatorTxFromBytes(nil) require.NotNil(t, err) } diff --git a/eth/auction.go b/eth/auction.go index 714028c..ea00e44 100644 --- a/eth/auction.go +++ b/eth/auction.go @@ -265,7 +265,7 @@ type AuctionClient struct { client *EthereumClient address ethCommon.Address tokenAddress ethCommon.Address - gasLimit uint64 + auction *HermezAuctionProtocol.HermezAuctionProtocol contractAbi abi.ABI } @@ -275,11 +275,15 @@ func NewAuctionClient(client *EthereumClient, address, tokenAddress ethCommon.Ad if err != nil { return nil, err } + auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(address, client.Client()) + if err != nil { + return nil, err + } return &AuctionClient{ client: client, address: address, tokenAddress: tokenAddress, - gasLimit: 1000000, //nolint:gomnd + auction: auction, contractAbi: contractAbi, }, nil } @@ -289,13 +293,9 @@ func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transa var tx *types.Transaction var err error if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetSlotDeadline(auth, newDeadline) + return c.auction.SetSlotDeadline(auth, newDeadline) }, ); err != nil { return nil, fmt.Errorf("Failed setting slotDeadline: %w", err) @@ -304,14 +304,9 @@ func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transa } // AuctionGetSlotDeadline is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetSlotDeadline() (uint8, error) { - var slotDeadline uint8 +func (c *AuctionClient) AuctionGetSlotDeadline() (slotDeadline uint8, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - slotDeadline, err = auction.GetSlotDeadline(nil) + slotDeadline, err = c.auction.GetSlotDeadline(nil) return err }); err != nil { return 0, err @@ -320,17 +315,11 @@ func (c *AuctionClient) AuctionGetSlotDeadline() (uint8, error) { } // AuctionSetOpenAuctionSlots is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetOpenAuctionSlots(auth, newOpenAuctionSlots) + return c.auction.SetOpenAuctionSlots(auth, newOpenAuctionSlots) }, ); err != nil { return nil, fmt.Errorf("Failed setting openAuctionSlots: %w", err) @@ -339,14 +328,9 @@ func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) ( } // AuctionGetOpenAuctionSlots is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetOpenAuctionSlots() (uint16, error) { - var openAuctionSlots uint16 +func (c *AuctionClient) AuctionGetOpenAuctionSlots() (openAuctionSlots uint16, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - openAuctionSlots, err = auction.GetOpenAuctionSlots(nil) + openAuctionSlots, err = c.auction.GetOpenAuctionSlots(nil) return err }); err != nil { return 0, err @@ -355,17 +339,11 @@ func (c *AuctionClient) AuctionGetOpenAuctionSlots() (uint16, error) { } // AuctionSetClosedAuctionSlots is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetClosedAuctionSlots(auth, newClosedAuctionSlots) + return c.auction.SetClosedAuctionSlots(auth, newClosedAuctionSlots) }, ); err != nil { return nil, fmt.Errorf("Failed setting closedAuctionSlots: %w", err) @@ -374,14 +352,9 @@ func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint1 } // AuctionGetClosedAuctionSlots is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetClosedAuctionSlots() (uint16, error) { - var closedAuctionSlots uint16 +func (c *AuctionClient) AuctionGetClosedAuctionSlots() (closedAuctionSlots uint16, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - closedAuctionSlots, err = auction.GetClosedAuctionSlots(nil) + closedAuctionSlots, err = c.auction.GetClosedAuctionSlots(nil) return err }); err != nil { return 0, err @@ -390,17 +363,11 @@ func (c *AuctionClient) AuctionGetClosedAuctionSlots() (uint16, error) { } // AuctionSetOutbidding is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( 12500000, //nolint:gomnd func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetOutbidding(auth, newOutbidding) + return c.auction.SetOutbidding(auth, newOutbidding) }, ); err != nil { return nil, fmt.Errorf("Failed setting setOutbidding: %w", err) @@ -409,14 +376,9 @@ func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Trans } // AuctionGetOutbidding is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) { - var outbidding uint16 +func (c *AuctionClient) AuctionGetOutbidding() (outbidding uint16, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - outbidding, err = auction.GetOutbidding(nil) + outbidding, err = c.auction.GetOutbidding(nil) return err }); err != nil { return 0, err @@ -425,17 +387,11 @@ func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) { } // AuctionSetAllocationRatio is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetAllocationRatio(auth, newAllocationRatio) + return c.auction.SetAllocationRatio(auth, newAllocationRatio) }, ); err != nil { return nil, fmt.Errorf("Failed setting allocationRatio: %w", err) @@ -444,14 +400,9 @@ func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) } // AuctionGetAllocationRatio is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) { - var allocationRation [3]uint16 +func (c *AuctionClient) AuctionGetAllocationRatio() (allocationRation [3]uint16, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - allocationRation, err = auction.GetAllocationRatio(nil) + allocationRation, err = c.auction.GetAllocationRatio(nil) return err }); err != nil { return [3]uint16{}, err @@ -460,17 +411,11 @@ func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) { } // AuctionSetDonationAddress is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetDonationAddress(auth, newDonationAddress) + return c.auction.SetDonationAddress(auth, newDonationAddress) }, ); err != nil { return nil, fmt.Errorf("Failed setting donationAddress: %w", err) @@ -479,33 +424,23 @@ func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.A } // AuctionGetDonationAddress is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetDonationAddress() (*ethCommon.Address, error) { - var donationAddress ethCommon.Address +func (c *AuctionClient) AuctionGetDonationAddress() (donationAddress *ethCommon.Address, err error) { + var _donationAddress ethCommon.Address if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - donationAddress, err = auction.GetDonationAddress(nil) + _donationAddress, err = c.auction.GetDonationAddress(nil) return err }); err != nil { return nil, err } - return &donationAddress, nil + return &_donationAddress, nil } // AuctionSetBootCoordinator is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetBootCoordinator(auth, newBootCoordinator) + return c.auction.SetBootCoordinator(auth, newBootCoordinator) }, ); err != nil { return nil, fmt.Errorf("Failed setting bootCoordinator: %w", err) @@ -514,34 +449,24 @@ func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.A } // AuctionGetBootCoordinator is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetBootCoordinator() (*ethCommon.Address, error) { - var bootCoordinator ethCommon.Address +func (c *AuctionClient) AuctionGetBootCoordinator() (bootCoordinator *ethCommon.Address, err error) { + var _bootCoordinator ethCommon.Address if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - bootCoordinator, err = auction.GetBootCoordinator(nil) + _bootCoordinator, err = c.auction.GetBootCoordinator(nil) return err }); err != nil { return nil, err } - return &bootCoordinator, nil + return &_bootCoordinator, nil } // AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function -func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } slotSetToSend := big.NewInt(slotSet) - return auction.ChangeDefaultSlotSetBid(auth, slotSetToSend, newInitialMinBid) + return c.auction.ChangeDefaultSlotSetBid(auth, slotSetToSend, newInitialMinBid) }, ); err != nil { return nil, fmt.Errorf("Failed changing slotSet Bid: %w", err) @@ -550,14 +475,9 @@ func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitial } // AuctionGetClaimableHEZ is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (*big.Int, error) { - var claimableHEZ *big.Int +func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (claimableHEZ *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - claimableHEZ, err = auction.GetClaimableHEZ(nil, claimAddress) + claimableHEZ, err = c.auction.GetClaimableHEZ(nil, claimAddress) return err }); err != nil { return nil, err @@ -566,17 +486,11 @@ func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) ( } // AuctionSetCoordinator is the interface to call the smart contract function -func (c *AuctionClient) AuctionSetCoordinator(forger ethCommon.Address, coordinatorURL string) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionSetCoordinator(forger ethCommon.Address, coordinatorURL string) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.SetCoordinator(auth, forger, coordinatorURL) + return c.auction.SetCoordinator(auth, forger, coordinatorURL) }, ); err != nil { return nil, fmt.Errorf("Failed set coordinator: %w", err) @@ -585,32 +499,22 @@ func (c *AuctionClient) AuctionSetCoordinator(forger ethCommon.Address, coordina } // AuctionGetCurrentSlotNumber is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetCurrentSlotNumber() (int64, error) { +func (c *AuctionClient) AuctionGetCurrentSlotNumber() (currentSlotNumber int64, err error) { var _currentSlotNumber *big.Int if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - _currentSlotNumber, err = auction.GetCurrentSlotNumber(nil) + _currentSlotNumber, err = c.auction.GetCurrentSlotNumber(nil) return err }); err != nil { return 0, err } - currentSlotNumber := _currentSlotNumber.Int64() - return currentSlotNumber, nil + return _currentSlotNumber.Int64(), nil } // AuctionGetMinBidBySlot is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) { - var minBid *big.Int +func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (minBid *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } slotToSend := big.NewInt(slot) - minBid, err = auction.GetMinBidBySlot(nil, slotToSend) + minBid, err = c.auction.GetMinBidBySlot(nil, slotToSend) return err }); err != nil { return big.NewInt(0), err @@ -619,15 +523,10 @@ func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) { } // AuctionGetSlotSet is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetSlotSet(slot int64) (*big.Int, error) { - var slotSet *big.Int +func (c *AuctionClient) AuctionGetSlotSet(slot int64) (slotSet *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } slotToSend := big.NewInt(slot) - slotSet, err = auction.GetSlotSet(nil, slotToSend) + slotSet, err = c.auction.GetSlotSet(nil, slotToSend) return err }); err != nil { return big.NewInt(0), err @@ -636,14 +535,9 @@ func (c *AuctionClient) AuctionGetSlotSet(slot int64) (*big.Int, error) { } // AuctionGetDefaultSlotSetBid is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) { - var minBidSlotSet *big.Int +func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (minBidSlotSet *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - minBidSlotSet, err = auction.GetDefaultSlotSetBid(nil, slotSet) + minBidSlotSet, err = c.auction.GetDefaultSlotSetBid(nil, slotSet) return err }); err != nil { return big.NewInt(0), err @@ -652,28 +546,21 @@ func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, er } // AuctionGetSlotNumber is the interface to call the smart contract function -func (c *AuctionClient) AuctionGetSlotNumber(blockNum int64) (int64, error) { - var slot *big.Int +func (c *AuctionClient) AuctionGetSlotNumber(blockNum int64) (slot int64, err error) { + var _slot *big.Int if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - blockNumBig := big.NewInt(blockNum) - slot, err = auction.GetSlotNumber(nil, blockNumBig) + _slot, err = c.auction.GetSlotNumber(nil, big.NewInt(blockNum)) return err }); err != nil { return 0, err } - return slot.Int64(), nil + return _slot.Int64(), nil } // AuctionBid is the interface to call the smart contract function -func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { tokens, err := ERC777.NewERC777(c.tokenAddress, ec) if err != nil { @@ -703,11 +590,10 @@ func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int) (*types.Trans } // AuctionMultiBid is the interface to call the smart contract function -func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, + maxBid, closedMinBid, budget *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 1000000, //nolint:gomnd func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { tokens, err := ERC777.NewERC777(c.tokenAddress, ec) if err != nil { @@ -752,14 +638,9 @@ func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, sl } // AuctionCanForge is the interface to call the smart contract function -func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) { - var canForge bool +func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (canForge bool, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - canForge, err = auction.CanForge(nil, forger, big.NewInt(blockNum)) + canForge, err = c.auction.CanForge(nil, forger, big.NewInt(blockNum)) return err }); err != nil { return false, err @@ -768,17 +649,11 @@ func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64 } // AuctionClaimHEZ is the interface to call the smart contract function -func (c *AuctionClient) AuctionClaimHEZ() (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionClaimHEZ() (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.ClaimHEZ(auth) + return c.auction.ClaimHEZ(auth) }, ); err != nil { return nil, fmt.Errorf("Failed claim HEZ: %w", err) @@ -787,17 +662,11 @@ func (c *AuctionClient) AuctionClaimHEZ() (*types.Transaction, error) { } // AuctionForge is the interface to call the smart contract function -func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return nil, err - } - return auction.Forge(auth, forger) + return c.auction.Forge(auth, forger) }, ); err != nil { return nil, fmt.Errorf("Failed forge: %w", err) @@ -806,31 +675,27 @@ func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (*types.Transacti } // AuctionConstants returns the Constants of the Auction Smart Contract -func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) { - auctionConstants := new(AuctionConstants) +func (c *AuctionClient) AuctionConstants() (auctionConstants *AuctionConstants, err error) { + auctionConstants = new(AuctionConstants) if err := c.client.Call(func(ec *ethclient.Client) error { - auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) - if err != nil { - return err - } - auctionConstants.BlocksPerSlot, err = auction.BLOCKSPERSLOT(nil) + auctionConstants.BlocksPerSlot, err = c.auction.BLOCKSPERSLOT(nil) if err != nil { return err } - genesisBlock, err := auction.GenesisBlock(nil) + genesisBlock, err := c.auction.GenesisBlock(nil) if err != nil { return err } auctionConstants.GenesisBlockNum = genesisBlock.Int64() - auctionConstants.HermezRollup, err = auction.HermezRollup(nil) + auctionConstants.HermezRollup, err = c.auction.HermezRollup(nil) if err != nil { return err } - auctionConstants.InitialMinimalBidding, err = auction.INITIALMINIMALBIDDING(nil) + auctionConstants.InitialMinimalBidding, err = c.auction.INITIALMINIMALBIDDING(nil) if err != nil { return err } - auctionConstants.TokenHEZ, err = auction.TokenHEZ(nil) + auctionConstants.TokenHEZ, err = c.auction.TokenHEZ(nil) return err }); err != nil { return nil, err @@ -839,10 +704,9 @@ func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) { } // AuctionVariables returns the variables of the Auction Smart Contract -func (c *AuctionClient) AuctionVariables() (*AuctionVariables, error) { - auctionVariables := new(AuctionVariables) +func (c *AuctionClient) AuctionVariables() (auctionVariables *AuctionVariables, err error) { + auctionVariables = new(AuctionVariables) if err := c.client.Call(func(ec *ethclient.Client) error { - var err error auctionVariables.AllocationRatio, err = c.AuctionGetAllocationRatio() if err != nil { return err diff --git a/eth/client.go b/eth/client.go index 0470616..fe74fc0 100644 --- a/eth/client.go +++ b/eth/client.go @@ -5,6 +5,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) @@ -29,14 +30,38 @@ type Client struct { RollupClient } +// RollupConfig is the configuration for the Rollup smart contract interface +type RollupConfig struct { + Address ethCommon.Address +} + +// AuctionConfig is the configuration for the Auction smart contract interface +type AuctionConfig struct { + Address ethCommon.Address + TokenHEZAddress ethCommon.Address +} + +// ClientConfig is the configuration of the Client +type ClientConfig struct { + Ethereum EthereumConfig + Rollup RollupConfig + Auction AuctionConfig +} + // NewClient creates a new Client to interact with Ethereum and the Hermez smart contracts. -func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, config *EthereumConfig) *Client { - ethereumClient := NewEthereumClient(client, account, ks, config) - auctionClient := &AuctionClient{} - rollupCient := &RollupClient{} +func NewClient(client *ethclient.Client, account *accounts.Account, ks *ethKeystore.KeyStore, cfg *ClientConfig) (*Client, error) { + ethereumClient := NewEthereumClient(client, account, ks, &cfg.Ethereum) + auctionClient, err := NewAuctionClient(ethereumClient, cfg.Auction.Address, cfg.Auction.TokenHEZAddress) + if err != nil { + return nil, err + } + rollupCient, err := NewRollupClient(ethereumClient, cfg.Rollup.Address, cfg.Auction.TokenHEZAddress) + if err != nil { + return nil, err + } return &Client{ EthereumClient: *ethereumClient, AuctionClient: *auctionClient, RollupClient: *rollupCient, - } + }, nil } diff --git a/eth/client_test.go b/eth/client_test.go index db71eca..24115cc 100644 --- a/eth/client_test.go +++ b/eth/client_test.go @@ -8,7 +8,7 @@ import ( func TestClientInterface(t *testing.T) { var c ClientInterface - client := NewClient(nil, nil, nil, nil) + client, _ := NewClient(nil, nil, nil, &ClientConfig{}) c = client require.NotNil(t, c) } diff --git a/eth/ethereum.go b/eth/ethereum.go index cd6788a..06236c7 100644 --- a/eth/ethereum.go +++ b/eth/ethereum.go @@ -301,3 +301,8 @@ func (c *EthereumClient) EthERC20Consts(tokenAddress ethCommon.Address) (*ERC20C Decimals: uint64(decimals), }, nil } + +// Client returns the internal ethclient.Client +func (c *EthereumClient) Client() *ethclient.Client { + return c.client +} diff --git a/eth/rollup.go b/eth/rollup.go index 81e2a4b..236368a 100644 --- a/eth/rollup.go +++ b/eth/rollup.go @@ -153,9 +153,9 @@ type RollupState struct { // RollupEventL1UserTx is an event of the Rollup Smart Contract type RollupEventL1UserTx struct { - ToForgeL1TxsNum int64 // QueueIndex *big.Int - Position int // TransactionIndex *big.Int - L1UserTx common.L1Tx + // ToForgeL1TxsNum int64 // QueueIndex *big.Int + // Position int // TransactionIndex *big.Int + L1UserTx common.L1Tx } // RollupEventL1UserTxAux is an event of the Rollup Smart Contract @@ -173,7 +173,8 @@ type RollupEventAddToken struct { // RollupEventForgeBatch is an event of the Rollup Smart Contract type RollupEventForgeBatch struct { - BatchNum int64 + BatchNum int64 + // Sender ethCommon.Address EthTxHash ethCommon.Hash } @@ -279,7 +280,7 @@ type RollupInterface interface { RollupConstants() (*RollupPublicConstants, error) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) - RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, error) + RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, *ethCommon.Address, error) } // @@ -291,7 +292,7 @@ type RollupClient struct { client *EthereumClient address ethCommon.Address tokenHEZAddress ethCommon.Address - gasLimit uint64 + hermez *Hermez.Hermez contractAbi abi.ABI } @@ -301,26 +302,24 @@ func NewRollupClient(client *EthereumClient, address ethCommon.Address, tokenHEZ if err != nil { return nil, err } + hermez, err := Hermez.NewHermez(address, client.Client()) + if err != nil { + return nil, err + } return &RollupClient{ client: client, address: address, tokenHEZAddress: tokenHEZAddress, - gasLimit: 1000000, //nolint:gomnd + hermez: hermez, contractAbi: contractAbi, }, nil } // RollupForgeBatch is the interface to call the smart contract function -func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 1000000, //nolint:gomnd func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - hermez, err := Hermez.NewHermez(c.address, ec) - if err != nil { - return nil, err - } rollupConst, err := c.RollupConstants() if err != nil { return nil, err @@ -362,7 +361,7 @@ func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Tran } feeIdxCoordinator = append(feeIdxCoordinator, bytesFeeIdx[len(bytesFeeIdx)-int(lenBytes):]...) } - return hermez.ForgeBatch(auth, newLastIdx, args.NewStRoot, args.NewExitRoot, l1CoordinatorBytes, l2DataBytes, feeIdxCoordinator, args.VerifierIdx, args.L1Batch, args.ProofA, args.ProofB, args.ProofC) + return c.hermez.ForgeBatch(auth, newLastIdx, args.NewStRoot, args.NewExitRoot, l1CoordinatorBytes, l2DataBytes, feeIdxCoordinator, args.VerifierIdx, args.L1Batch, args.ProofA, args.ProofB, args.ProofC) }, ); err != nil { return nil, fmt.Errorf("Failed forge batch: %w", err) @@ -373,11 +372,9 @@ func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Tran // RollupAddToken is the interface to call the smart contract function. // `feeAddToken` is the amount of HEZ tokens that will be paid to add the // token. `feeAddToken` must match the public value of the smart contract. -func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { tokens, err := ERC777.NewERC777(c.tokenHEZAddress, ec) if err != nil { @@ -403,11 +400,9 @@ func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToke } // RollupWithdrawMerkleProof is the interface to call the smart contract function -func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ *babyjub.PublicKey, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ *babyjub.PublicKey, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { hermez, err := Hermez.NewHermez(c.address, ec) if err != nil { @@ -433,11 +428,9 @@ func (c *RollupClient) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB } // RollupL1UserTxERC20ETH is the interface to call the smart contract function -func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { hermez, err := Hermez.NewHermez(c.address, ec) if err != nil { @@ -469,11 +462,9 @@ func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ *babyjub.PublicKey, fromId } // RollupL1UserTxERC777 is the interface to call the smart contract function -func (c *RollupClient) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupL1UserTxERC777(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { tokens, err := ERC777.NewERC777(c.tokenHEZAddress, ec) if err != nil { @@ -544,11 +535,9 @@ func (c *RollupClient) RollupRegisterTokensCount() (*big.Int, error) { } // RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function -func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { hermez, err := Hermez.NewHermez(c.address, ec) if err != nil { @@ -563,11 +552,9 @@ func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeou } // RollupUpdateFeeAddToken is the interface to call the smart contract function -func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { hermez, err := Hermez.NewHermez(c.address, ec) if err != nil { @@ -582,25 +569,21 @@ func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types. } // RollupConstants returns the Constants of the Rollup Smart Contract -func (c *RollupClient) RollupConstants() (*RollupPublicConstants, error) { - rollupConstants := new(RollupPublicConstants) +func (c *RollupClient) RollupConstants() (rollupConstants *RollupPublicConstants, err error) { + rollupConstants = new(RollupPublicConstants) if err := c.client.Call(func(ec *ethclient.Client) error { - hermez, err := Hermez.NewHermez(c.address, ec) - if err != nil { - return err - } - absoluteMaxL1L2BatchTimeout, err := hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil) + absoluteMaxL1L2BatchTimeout, err := c.hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil) if err != nil { return err } rollupConstants.AbsoluteMaxL1L2BatchTimeout = int64(absoluteMaxL1L2BatchTimeout) - rollupConstants.TokenHEZ, err = hermez.TokenHEZ(nil) + rollupConstants.TokenHEZ, err = c.hermez.TokenHEZ(nil) if err != nil { return err } for i := int64(0); i < int64(LenVerifiers); i++ { var newRollupVerifier RollupVerifierStruct - rollupVerifier, err := hermez.RollupVerifiers(nil, big.NewInt(i)) + rollupVerifier, err := c.hermez.RollupVerifiers(nil, big.NewInt(i)) if err != nil { return err } @@ -608,19 +591,19 @@ func (c *RollupClient) RollupConstants() (*RollupPublicConstants, error) { newRollupVerifier.NLevels = rollupVerifier.NLevels.Int64() rollupConstants.Verifiers = append(rollupConstants.Verifiers, newRollupVerifier) } - rollupConstants.HermezAuctionContract, err = hermez.HermezAuctionContract(nil) + rollupConstants.HermezAuctionContract, err = c.hermez.HermezAuctionContract(nil) if err != nil { return err } - rollupConstants.HermezGovernanceDAOAddress, err = hermez.HermezGovernanceDAOAddress(nil) + rollupConstants.HermezGovernanceDAOAddress, err = c.hermez.HermezGovernanceDAOAddress(nil) if err != nil { return err } - rollupConstants.SafetyAddress, err = hermez.SafetyAddress(nil) + rollupConstants.SafetyAddress, err = c.hermez.SafetyAddress(nil) if err != nil { return err } - rollupConstants.WithdrawDelayerContract, err = hermez.WithdrawDelayerContract(nil) + rollupConstants.WithdrawDelayerContract, err = c.hermez.WithdrawDelayerContract(nil) return err }); err != nil { return nil, err @@ -670,12 +653,14 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC if err != nil { return nil, nil, err } - L1Tx, err := common.L1TxFromBytes(L1UserTxAux.L1UserTx) + L1Tx, err := common.L1UserTxFromBytes(L1UserTxAux.L1UserTx) if err != nil { return nil, nil, err } - L1UserTx.ToForgeL1TxsNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() - L1UserTx.Position = int(new(big.Int).SetBytes(vLog.Topics[2][:]).Int64()) + toForgeL1TxsNum := new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() + L1Tx.ToForgeL1TxsNum = &toForgeL1TxsNum + L1Tx.Position = int(new(big.Int).SetBytes(vLog.Topics[2][:]).Int64()) + L1Tx.UserOrigin = true L1UserTx.L1UserTx = *L1Tx rollupEvents.L1UserTx = append(rollupEvents.L1UserTx, L1UserTx) case logHermezAddToken: @@ -690,6 +675,7 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC var forgeBatch RollupEventForgeBatch forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() forgeBatch.EthTxHash = vLog.TxHash + // forgeBatch.Sender = vLog.Address rollupEvents.ForgeBatch = append(rollupEvents.ForgeBatch, forgeBatch) case logHermezUpdateForgeL1L2BatchTimeout: var updateForgeL1L2BatchTimeout struct { @@ -724,20 +710,29 @@ func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethC return &rollupEvents, &blockHash, nil } -// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction -func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupForgeBatchArgs, error) { +// RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the +// Rollup Smart Contract in the given transaction, and the sender address. +func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupForgeBatchArgs, *ethCommon.Address, error) { tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash) if err != nil { - return nil, err + return nil, nil, err } txData := tx.Data() method, err := c.contractAbi.MethodById(txData[:4]) if err != nil { - return nil, err + return nil, nil, err + } + receipt, err := c.client.client.TransactionReceipt(context.Background(), ethTxHash) + if err != nil { + return nil, nil, err + } + sender, err := c.client.client.TransactionSender(context.Background(), tx, receipt.Logs[0].BlockHash, receipt.Logs[0].Index) + if err != nil { + return nil, nil, err } var aux RollupForgeBatchArgsAux if err := method.Inputs.Unpack(&aux, txData[4:]); err != nil { - return nil, err + return nil, nil, err } rollupForgeBatchArgs := RollupForgeBatchArgs{ L1Batch: aux.L1Batch, @@ -763,16 +758,16 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupFo signature = append(signature, r[:]...) signature = append(signature, s[:]...) signature = append(signature, v) - l1Tx, err := common.L1TxFromCoordinatorBytes(bytesL1Coordinator) + l1Tx, err := common.L1CoordinatorTxFromBytes(bytesL1Coordinator) if err != nil { - return nil, err + return nil, nil, err } rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, *l1Tx) rollupForgeBatchArgs.L1CoordinatorTxsAuths = append(rollupForgeBatchArgs.L1CoordinatorTxsAuths, signature) } rollupConsts, err := c.RollupConstants() if err != nil { - return nil, err + return nil, nil, err } nLevels := rollupConsts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels lenL2TxsBytes := int((nLevels/8)*2 + 2 + 1) @@ -780,7 +775,7 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupFo for i := 0; i < numTxsL2; i++ { l2Tx, err := common.L2TxFromBytes(aux.L2TxsData[i*lenL2TxsBytes:(i+1)*lenL2TxsBytes], int(nLevels)) if err != nil { - return nil, err + return nil, nil, err } rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, *l2Tx) } @@ -796,11 +791,11 @@ func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupFo } feeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:]) if err != nil { - return nil, err + return nil, nil, err } if feeIdxCoordinator != common.Idx(0) { rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, feeIdxCoordinator) } } - return &rollupForgeBatchArgs, nil + return &rollupForgeBatchArgs, &sender, nil } diff --git a/eth/rollup_test.go b/eth/rollup_test.go index 458f7fa..dc95f02 100644 --- a/eth/rollup_test.go +++ b/eth/rollup_test.go @@ -152,7 +152,7 @@ func TestRollupForgeBatch(t *testing.T) { signature = append(signature, r[:]...) signature = append(signature, s[:]...) signature = append(signature, v) - l1Tx, err := common.L1TxFromCoordinatorBytes(bytesL1Coordinator) + l1Tx, err := common.L1CoordinatorTxFromBytes(bytesL1Coordinator) require.Nil(t, err) args.L1CoordinatorTxs = append(args.L1CoordinatorTxs, *l1Tx) args.L1CoordinatorTxsAuths = append(args.L1CoordinatorTxsAuths, signature) @@ -190,8 +190,9 @@ func TestRollupForgeBatch(t *testing.T) { } func TestRollupForgeBatchArgs(t *testing.T) { - args, err := rollupClient.RollupForgeBatchArgs(ethHashForge) + args, sender, err := rollupClient.RollupForgeBatchArgs(ethHashForge) require.Nil(t, err) + assert.Equal(t, *sender, rollupClient.client.account.Address) assert.Equal(t, argsForge.FeeIdxCoordinator, args.FeeIdxCoordinator) assert.Equal(t, argsForge.L1Batch, args.L1Batch) assert.Equal(t, argsForge.L1CoordinatorTxs, args.L1CoordinatorTxs) diff --git a/eth/wdelayer.go b/eth/wdelayer.go index c032b23..74f8ee3 100644 --- a/eth/wdelayer.go +++ b/eth/wdelayer.go @@ -136,7 +136,7 @@ type WDelayerInterface interface { type WDelayerClient struct { client *EthereumClient address ethCommon.Address - gasLimit uint64 + wdelayer *WithdrawalDelayer.WithdrawalDelayer contractAbi abi.ABI } @@ -146,42 +146,36 @@ func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) (*WDel if err != nil { return nil, err } + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(address, client.Client()) + if err != nil { + return nil, err + } return &WDelayerClient{ client: client, address: address, - gasLimit: 1000000, //nolint:gomnd + wdelayer: wdelayer, contractAbi: contractAbi, }, nil } // WDelayerGetHermezGovernanceDAOAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerGetHermezGovernanceDAOAddress() (*ethCommon.Address, error) { - var hermezGovernanceDAOAddress ethCommon.Address +func (c *WDelayerClient) WDelayerGetHermezGovernanceDAOAddress() (hermezGovernanceDAOAddress *ethCommon.Address, err error) { + var _hermezGovernanceDAOAddress ethCommon.Address if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - hermezGovernanceDAOAddress, err = wdelayer.GetHermezGovernanceDAOAddress(nil) + _hermezGovernanceDAOAddress, err = c.wdelayer.GetHermezGovernanceDAOAddress(nil) return err }); err != nil { return nil, err } - return &hermezGovernanceDAOAddress, nil + return &_hermezGovernanceDAOAddress, nil } // WDelayerSetHermezGovernanceDAOAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerSetHermezGovernanceDAOAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerSetHermezGovernanceDAOAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.SetHermezGovernanceDAOAddress(auth, newAddress) + return c.wdelayer.SetHermezGovernanceDAOAddress(auth, newAddress) }, ); err != nil { return nil, fmt.Errorf("Failed setting hermezGovernanceDAOAddress: %w", err) @@ -190,33 +184,23 @@ func (c *WDelayerClient) WDelayerSetHermezGovernanceDAOAddress(newAddress ethCom } // WDelayerGetHermezKeeperAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerGetHermezKeeperAddress() (*ethCommon.Address, error) { - var hermezKeeperAddress ethCommon.Address +func (c *WDelayerClient) WDelayerGetHermezKeeperAddress() (hermezKeeperAddress *ethCommon.Address, err error) { + var _hermezKeeperAddress ethCommon.Address if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - hermezKeeperAddress, err = wdelayer.GetHermezKeeperAddress(nil) + _hermezKeeperAddress, err = c.wdelayer.GetHermezKeeperAddress(nil) return err }); err != nil { return nil, err } - return &hermezKeeperAddress, nil + return &_hermezKeeperAddress, nil } // WDelayerSetHermezKeeperAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerSetHermezKeeperAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerSetHermezKeeperAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.SetHermezKeeperAddress(auth, newAddress) + return c.wdelayer.SetHermezKeeperAddress(auth, newAddress) }, ); err != nil { return nil, fmt.Errorf("Failed setting hermezKeeperAddress: %w", err) @@ -225,33 +209,23 @@ func (c *WDelayerClient) WDelayerSetHermezKeeperAddress(newAddress ethCommon.Add } // WDelayerGetWhiteHackGroupAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerGetWhiteHackGroupAddress() (*ethCommon.Address, error) { - var whiteHackGroupAddress ethCommon.Address +func (c *WDelayerClient) WDelayerGetWhiteHackGroupAddress() (whiteHackGroupAddress *ethCommon.Address, err error) { + var _whiteHackGroupAddress ethCommon.Address if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - whiteHackGroupAddress, err = wdelayer.GetWhiteHackGroupAddress(nil) + _whiteHackGroupAddress, err = c.wdelayer.GetWhiteHackGroupAddress(nil) return err }); err != nil { return nil, err } - return &whiteHackGroupAddress, nil + return &_whiteHackGroupAddress, nil } // WDelayerSetWhiteHackGroupAddress is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerSetWhiteHackGroupAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerSetWhiteHackGroupAddress(newAddress ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.SetWhiteHackGroupAddress(auth, newAddress) + return c.wdelayer.SetWhiteHackGroupAddress(auth, newAddress) }, ); err != nil { return nil, fmt.Errorf("Failed setting whiteHackGroupAddress: %w", err) @@ -260,14 +234,9 @@ func (c *WDelayerClient) WDelayerSetWhiteHackGroupAddress(newAddress ethCommon.A } // WDelayerIsEmergencyMode is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerIsEmergencyMode() (bool, error) { - var ermergencyMode bool +func (c *WDelayerClient) WDelayerIsEmergencyMode() (ermergencyMode bool, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - ermergencyMode, err = wdelayer.IsEmergencyMode(nil) + ermergencyMode, err = c.wdelayer.IsEmergencyMode(nil) return err }); err != nil { return false, err @@ -276,14 +245,9 @@ func (c *WDelayerClient) WDelayerIsEmergencyMode() (bool, error) { } // WDelayerGetWithdrawalDelay is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (*big.Int, error) { - var withdrawalDelay *big.Int +func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (withdrawalDelay *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - withdrawalDelay, err = wdelayer.GetWithdrawalDelay(nil) + withdrawalDelay, err = c.wdelayer.GetWithdrawalDelay(nil) return err }); err != nil { return nil, err @@ -292,14 +256,9 @@ func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (*big.Int, error) { } // WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (*big.Int, error) { - var emergencyModeStartingTime *big.Int +func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (emergencyModeStartingTime *big.Int, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - emergencyModeStartingTime, err = wdelayer.GetEmergencyModeStartingTime(nil) + emergencyModeStartingTime, err = c.wdelayer.GetEmergencyModeStartingTime(nil) return err }); err != nil { return nil, err @@ -308,17 +267,11 @@ func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (*big.Int, error } // WDelayerEnableEmergencyMode is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerEnableEmergencyMode() (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.EnableEmergencyMode(auth) + return c.wdelayer.EnableEmergencyMode(auth) }, ); err != nil { return nil, fmt.Errorf("Failed setting enable emergency mode: %w", err) @@ -327,17 +280,11 @@ func (c *WDelayerClient) WDelayerEnableEmergencyMode() (*types.Transaction, erro } // WDelayerChangeWithdrawalDelay is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.ChangeWithdrawalDelay(auth, newWithdrawalDelay) + return c.wdelayer.ChangeWithdrawalDelay(auth, newWithdrawalDelay) }, ); err != nil { return nil, fmt.Errorf("Failed setting withdrawal delay: %w", err) @@ -346,14 +293,9 @@ func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64 } // WDelayerDepositInfo is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (DepositState, error) { - var depositInfo DepositState +func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error) { if err := c.client.Call(func(ec *ethclient.Client) error { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return err - } - amount, depositTimestamp, err := wdelayer.DepositInfo(nil, owner, token) + amount, depositTimestamp, err := c.wdelayer.DepositInfo(nil, owner, token) depositInfo.Amount = amount depositInfo.DepositTimestamp = depositTimestamp return err @@ -364,17 +306,11 @@ func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (De } // WDelayerDeposit is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.Deposit(auth, owner, token, amount) + return c.wdelayer.Deposit(auth, owner, token, amount) }, ); err != nil { return nil, fmt.Errorf("Failed deposit: %w", err) @@ -383,17 +319,11 @@ func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount } // WDelayerWithdrawal is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.Withdrawal(auth, owner, token) + return c.wdelayer.Withdrawal(auth, owner, token) }, ); err != nil { return nil, fmt.Errorf("Failed withdrawal: %w", err) @@ -402,17 +332,11 @@ func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (*ty } // WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function -func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (*types.Transaction, error) { - var tx *types.Transaction - var err error +func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) { if tx, err = c.client.CallAuth( - c.gasLimit, + 0, func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) { - wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) - if err != nil { - return nil, err - } - return wdelayer.EscapeHatchWithdrawal(auth, to, token, amount) + return c.wdelayer.EscapeHatchWithdrawal(auth, to, token, amount) }, ); err != nil { return nil, fmt.Errorf("Failed escapeHatchWithdrawal: %w", err) diff --git a/node/node.go b/node/node.go index 42a46c5..2e1f0fd 100644 --- a/node/node.go +++ b/node/node.go @@ -82,7 +82,10 @@ func NewNode(mode Mode, cfg *config.Node, coordCfg *config.Coordinator) (*Node, if err != nil { return nil, err } - client := eth.NewClient(ethClient, nil, nil, nil) + client, err := eth.NewClient(ethClient, nil, nil, nil) + if err != nil { + return nil, err + } sync, err := synchronizer.NewSynchronizer(client, historyDB, stateDB) if err != nil { diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 260b1c2..de671e0 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -383,7 +383,7 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) { position := 0 // Get the input for each Tx - forgeBatchArgs, err := s.ethClient.RollupForgeBatchArgs(evtForgeBatch.EthTxHash) + forgeBatchArgs, sender, err := s.ethClient.RollupForgeBatchArgs(evtForgeBatch.EthTxHash) if err != nil { return nil, err } @@ -467,7 +467,7 @@ func (s *Synchronizer) rollupSync(blockNum int64) (*rollupData, error) { batch := &common.Batch{ BatchNum: common.BatchNum(evtForgeBatch.BatchNum), EthBlockNum: blockNum, - // ForgerAddr: , TODO: Get it from ethClient -> Add ForgerAddr to RollupEventForgeBatch + ForgerAddr: *sender, // CollectedFees: , TODO: Clarify where to get them if they are still needed StateRoot: common.Hash(forgeBatchArgs.NewStRoot.Bytes()), NumAccounts: numAccounts, @@ -582,11 +582,6 @@ func getL1UserTx(eventsL1UserTx []eth.RollupEventL1UserTx, blockNum int64) ([]co l1Txs := make([]common.L1Tx, 0) for _, evtL1UserTx := range eventsL1UserTx { - // Fill aditional Tx fields - toForge := evtL1UserTx.ToForgeL1TxsNum - evtL1UserTx.L1UserTx.ToForgeL1TxsNum = &toForge - evtL1UserTx.L1UserTx.Position = evtL1UserTx.Position - evtL1UserTx.L1UserTx.UserOrigin = true evtL1UserTx.L1UserTx.EthBlockNum = blockNum nL1Tx, err := common.NewL1Tx(&evtL1UserTx.L1UserTx) if err != nil { diff --git a/synchronizer/synchronizer_test.go b/synchronizer/synchronizer_test.go index ecc1950..7da744b 100644 --- a/synchronizer/synchronizer_test.go +++ b/synchronizer/synchronizer_test.go @@ -57,7 +57,7 @@ func TestSync(t *testing.T) { blocks, err := s.historyDB.GetBlocks(0, 9999) require.Nil(t, err) - assert.Equal(t, int64(0), blocks[0].EthBlockNum) + assert.Equal(t, int64(1), blocks[0].EthBlockNum) // TODO once transakcio is completed /* diff --git a/test/ethclient.go b/test/ethclient.go index aace309..4865e32 100644 --- a/test/ethclient.go +++ b/test/ethclient.go @@ -10,6 +10,7 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum" ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/hermeznetwork/hermez-node/common" @@ -225,7 +226,9 @@ type ClientSetup struct { VerifyProof bool } -// NewClientSetupExample returns a ClientSetup example with hardcoded realistic values. +// NewClientSetupExample returns a ClientSetup example with hardcoded realistic +// values. With this setup, the rollup genesis will be block 1, and block 0 +// and 1 will be premined. //nolint:gomnd func NewClientSetupExample() *ClientSetup { // rfield, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10) @@ -259,7 +262,7 @@ func NewClientSetupExample() *ClientSetup { auctionConstants := ð.AuctionConstants{ BlocksPerSlot: 40, InitialMinimalBidding: initialMinimalBidding, - GenesisBlockNum: 0, + GenesisBlockNum: 1, GovernanceAddress: governanceAddress, TokenHEZ: tokenHEZ, HermezRollup: ethCommon.HexToAddress("0x474B6e29852257491cf283EfB1A9C61eBFe48369"), @@ -296,6 +299,11 @@ type Timer interface { // blockHash ethCommon.Hash // } +type batch struct { + ForgeBatchArgs eth.RollupForgeBatchArgs + Sender ethCommon.Address +} + // Client implements the eth.ClientInterface interface, allowing to manipulate the // values for testing, working with deterministic results. type Client struct { @@ -311,8 +319,8 @@ type Client struct { timer Timer hasher hasher - forgeBatchArgsPending map[ethCommon.Hash]*eth.RollupForgeBatchArgs - forgeBatchArgs map[ethCommon.Hash]*eth.RollupForgeBatchArgs + forgeBatchArgsPending map[ethCommon.Hash]*batch + forgeBatchArgs map[ethCommon.Hash]*batch } // NewClient returns a new test Client that implements the eth.IClient @@ -326,7 +334,7 @@ func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup) mapL1TxQueue := make(map[int64]*eth.QueueStruct) mapL1TxQueue[0] = eth.NewQueueStruct() mapL1TxQueue[1] = eth.NewQueueStruct() - blockCurrent := Block{ + blockCurrent := &Block{ Rollup: &RollupBlock{ State: eth.RollupState{ StateRoot: big.NewInt(0), @@ -367,11 +375,11 @@ func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup) } blockCurrent.Rollup.Eth = blockCurrent.Eth blockCurrent.Auction.Eth = blockCurrent.Eth - blocks[blockNum] = &blockCurrent + blocks[blockNum] = blockCurrent blockNext := blockCurrent.Next() blocks[blockNum+1] = blockNext - return &Client{ + c := Client{ rw: &sync.RWMutex{}, log: l, addr: addr, @@ -380,9 +388,17 @@ func NewClient(l bool, timer Timer, addr *ethCommon.Address, setup *ClientSetup) blocks: blocks, timer: timer, hasher: hasher, - forgeBatchArgsPending: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs), - forgeBatchArgs: make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs), + forgeBatchArgsPending: make(map[ethCommon.Hash]*batch), + forgeBatchArgs: make(map[ethCommon.Hash]*batch), + blockNum: blockNum, + maxBlockNum: blockNum, } + + for i := int64(1); i < setup.AuctionConstants.GenesisBlockNum+1; i++ { + c.CtlMineBlock() + } + + return &c } // @@ -452,7 +468,7 @@ func (c *Client) CtlMineBlock() { for ethTxHash, forgeBatchArgs := range c.forgeBatchArgsPending { c.forgeBatchArgs[ethTxHash] = forgeBatchArgs } - c.forgeBatchArgsPending = make(map[ethCommon.Hash]*eth.RollupForgeBatchArgs) + c.forgeBatchArgsPending = make(map[ethCommon.Hash]*batch) blockNext := blockCurrent.Next() c.blocks[c.blockNum+1] = blockNext @@ -552,10 +568,10 @@ func (c *Client) EthBlockByNumber(ctx context.Context, blockNum int64) (*common. c.rw.RLock() defer c.rw.RUnlock() - block, ok := c.blocks[blockNum] - if !ok { - return nil, fmt.Errorf("block not found") + if blockNum > c.blockNum { + return nil, ethereum.NotFound } + block := c.blocks[blockNum] return &common.Block{ EthBlockNum: blockNum, Timestamp: time.Unix(block.Eth.Time, 0), @@ -579,9 +595,54 @@ 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) { +// 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] +// if len(queue.L1TxQueue) >= eth.RollupConstMaxL1UserTx { +// r.State.LastToForgeL1TxsNum++ +// r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct() +// queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] +// } +// if int64(l1Tx.FromIdx) > r.State.CurrentIdx { +// panic("l1Tx.FromIdx > r.State.CurrentIdx") +// } +// if int(l1Tx.TokenID)+1 > len(r.State.TokenList) { +// panic("l1Tx.TokenID + 1 > len(r.State.TokenList)") +// } +// queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx) +// r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{ +// L1Tx: *l1Tx, +// ToForgeL1TxsNum: r.State.LastToForgeL1TxsNum, +// Position: len(queue.L1TxQueue) - 1, +// }) +// } + +// RollupL1UserTxERC20ETH sends an L1UserTx to the Rollup. +func (c *Client) RollupL1UserTxERC20ETH( + fromBJJ *babyjub.PublicKey, + fromIdx int64, + loadAmount *big.Int, + amount *big.Int, + tokenID uint32, + toIdx int64, +) (tx *types.Transaction, err error) { c.rw.Lock() defer c.rw.Unlock() + cpy := c.nextBlock().copy() + defer func() { c.revertIfErr(err, cpy) }() + + _, err = common.NewFloat16(amount) + if err != nil { + return nil, err + } + _, err = common.NewFloat16(loadAmount) + if err != nil { + return nil, err + } nextBlock := c.nextBlock() r := nextBlock.Rollup @@ -591,24 +652,34 @@ func (c *Client) CtlAddL1TxUser(l1Tx *common.L1Tx) { r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] = eth.NewQueueStruct() queue = r.State.MapL1TxQueue[r.State.LastToForgeL1TxsNum] } - if int64(l1Tx.FromIdx) > r.State.CurrentIdx { + if fromIdx > r.State.CurrentIdx { panic("l1Tx.FromIdx > r.State.CurrentIdx") } - if int(l1Tx.TokenID)+1 > len(r.State.TokenList) { + if int(tokenID)+1 > len(r.State.TokenList) { panic("l1Tx.TokenID + 1 > len(r.State.TokenList)") } - queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx) - r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{ - L1UserTx: *l1Tx, - ToForgeL1TxsNum: r.State.LastToForgeL1TxsNum, + toForgeL1TxsNum := r.State.LastToForgeL1TxsNum + l1Tx, err := common.NewL1Tx(&common.L1Tx{ + FromIdx: common.Idx(fromIdx), + FromEthAddr: *c.addr, + FromBJJ: fromBJJ, + Amount: amount, + LoadAmount: loadAmount, + TokenID: common.TokenID(tokenID), + ToIdx: common.Idx(toIdx), + ToForgeL1TxsNum: &toForgeL1TxsNum, Position: len(queue.L1TxQueue) - 1, + UserOrigin: true, }) -} + if err != nil { + return nil, err + } -// RollupL1UserTxERC20ETH is the interface to call the smart contract function -func (c *Client) RollupL1UserTxERC20ETH(fromBJJ *babyjub.PublicKey, fromIdx int64, loadAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error) { - log.Error("TODO") - return nil, errTODO + queue.L1TxQueue = append(queue.L1TxQueue, *l1Tx) + r.Events.L1UserTx = append(r.Events.L1UserTx, eth.RollupEventL1UserTx{ + L1UserTx: *l1Tx, + }) + return r.addTransaction(newTransaction("l1UserTxERC20ETH", l1Tx)), nil } // RollupL1UserTxERC777 is the interface to call the smart contract function @@ -710,7 +781,7 @@ func (c *Client) addBatch(args *eth.RollupForgeBatchArgs) (*types.Transaction, e } } ethTx := r.addTransaction(newTransaction("forgebatch", args)) - c.forgeBatchArgsPending[ethTx.Hash()] = args + c.forgeBatchArgsPending[ethTx.Hash()] = &batch{*args, *c.addr} r.Events.ForgeBatch = append(r.Events.ForgeBatch, eth.RollupEventForgeBatch{ BatchNum: int64(len(r.State.ExitRoots)), EthTxHash: ethTx.Hash(), @@ -820,15 +891,15 @@ 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) { +func (c *Client) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*eth.RollupForgeBatchArgs, *ethCommon.Address, error) { c.rw.RLock() defer c.rw.RUnlock() - forgeBatchArgs, ok := c.forgeBatchArgs[ethTxHash] + batch, ok := c.forgeBatchArgs[ethTxHash] if !ok { - return nil, fmt.Errorf("transaction not found") + return nil, nil, fmt.Errorf("transaction not found") } - return forgeBatchArgs, nil + return &batch.ForgeBatchArgs, &batch.Sender, nil } // diff --git a/test/ethclient_test.go b/test/ethclient_test.go index 1bee3c7..a8d9398 100644 --- a/test/ethclient_test.go +++ b/test/ethclient_test.go @@ -42,21 +42,21 @@ func TestClientEth(t *testing.T) { c := NewClient(true, &timer, ðCommon.Address{}, clientSetup) blockNum, err := c.EthCurrentBlock() require.Nil(t, err) - assert.Equal(t, int64(0), blockNum) + assert.Equal(t, int64(1), blockNum) block, err := c.EthBlockByNumber(context.TODO(), 0) require.Nil(t, err) assert.Equal(t, int64(0), block.EthBlockNum) assert.Equal(t, time.Unix(0, 0), block.Timestamp) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex()) - assert.Equal(t, int64(0), c.blockNum) // Mine some empty blocks - c.CtlMineBlock() assert.Equal(t, int64(1), c.blockNum) c.CtlMineBlock() assert.Equal(t, int64(2), c.blockNum) + c.CtlMineBlock() + assert.Equal(t, int64(3), c.blockNum) block, err = c.EthBlockByNumber(context.TODO(), 2) require.Nil(t, err) @@ -154,14 +154,17 @@ func TestClientRollup(t *testing.T) { var keys [N]*keys for i := 0; i < N; i++ { keys[i] = genKeys(int64(i)) - l1UserTx := common.L1Tx{ + tx := common.L1Tx{ FromIdx: 0, FromEthAddr: keys[i].Addr, FromBJJ: keys[i].BJJPublicKey, TokenID: common.TokenID(0), + Amount: big.NewInt(0), LoadAmount: big.NewInt(10 + int64(i)), } - c.CtlAddL1TxUser(&l1UserTx) + _, err := c.RollupL1UserTxERC20ETH(tx.FromBJJ, int64(tx.FromIdx), tx.LoadAmount, + tx.Amount, uint32(tx.TokenID), int64(tx.ToIdx)) + require.Nil(t, err) } c.CtlMineBlock() @@ -231,8 +234,9 @@ func TestClientRollup(t *testing.T) { rollupEvents, _, err = c.RollupEventsByBlock(blockNum) require.Nil(t, err) - rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash) + rollupForgeBatchArgs1, sender, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash) require.Nil(t, err) + assert.Equal(t, *c.addr, *sender) assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1) }