Browse Source

Simplify eth code

feature/sql-semaphore1
Eduard S 4 years ago
parent
commit
a2bda1890d
14 changed files with 398 additions and 506 deletions
  1. +30
    -26
      common/l1tx.go
  2. +13
    -12
      common/l1tx_test.go
  3. +86
    -222
      eth/auction.go
  4. +30
    -5
      eth/client.go
  5. +1
    -1
      eth/client_test.go
  6. +5
    -0
      eth/ethereum.go
  7. +62
    -67
      eth/rollup.go
  8. +3
    -2
      eth/rollup_test.go
  9. +50
    -126
      eth/wdelayer.go
  10. +4
    -1
      node/node.go
  11. +2
    -7
      synchronizer/synchronizer.go
  12. +1
    -1
      synchronizer/synchronizer_test.go
  13. +101
    -30
      test/ethclient.go
  14. +10
    -6
      test/ethclient_test.go

+ 30
- 26
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

+ 13
- 12
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)
}

+ 86
- 222
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

+ 30
- 5
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
}

+ 1
- 1
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)
}

+ 5
- 0
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
}

+ 62
- 67
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
}

+ 3
- 2
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)

+ 50
- 126
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)

+ 4
- 1
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 {

+ 2
- 7
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 {

+ 1
- 1
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
/*

+ 101
- 30
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 := &eth.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
}
//

+ 10
- 6
test/ethclient_test.go

@ -42,21 +42,21 @@ func TestClientEth(t *testing.T) {
c := NewClient(true, &timer, &ethCommon.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)
}

Loading…
Cancel
Save