Browse Source

Merge pull request #136 from hermeznetwork/feature/ethclient4-sc

Update ethclient
feature/sql-semaphore1
Eduard S 4 years ago
committed by GitHub
parent
commit
5ad447c47c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 1415 additions and 1435 deletions
  1. +316
    -84
      eth/auction.go
  2. +241
    -25
      eth/auction_test.go
  3. +1
    -1
      eth/contracts/README.md
  4. +258
    -504
      eth/contracts/auction/HermezAuctionProtocol.go
  5. +359
    -684
      eth/contracts/hermez/Hermez.go
  6. +151
    -83
      eth/rollup.go
  7. +39
    -0
      eth/rollup_test.go
  8. +50
    -54
      test/ethclient.go

+ 316
- 84
eth/auction.go

@ -1,8 +1,10 @@
package eth package eth
import ( import (
"fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
ethCommon "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
@ -12,8 +14,6 @@ import (
// AuctionConstants are the constants of the Rollup Smart Contract // AuctionConstants are the constants of the Rollup Smart Contract
type AuctionConstants struct { type AuctionConstants struct {
// Blocks to wait before starting with the first slot
DelayGenesis uint16
// Blocks per slot // Blocks per slot
BlocksPerSlot uint8 BlocksPerSlot uint8
// Minimum bid when no one has bid yet // Minimum bid when no one has bid yet
@ -21,6 +21,7 @@ type AuctionConstants struct {
// First block where the first slot begins // First block where the first slot begins
GenesisBlockNum int64 GenesisBlockNum int64
// Hermez Governanze Token smartcontract address who controls some parameters and collects HEZ fee // Hermez Governanze Token smartcontract address who controls some parameters and collects HEZ fee
// Only for test
GovernanceAddress ethCommon.Address GovernanceAddress ethCommon.Address
// ERC777 token with which the bids will be made // ERC777 token with which the bids will be made
TokenHEZ ethCommon.Address TokenHEZ ethCommon.Address
@ -244,11 +245,11 @@ type AuctionInterface interface {
maxBid, closedMinBid, budget *big.Int, forger ethCommon.Address) (*types.Transaction, error) maxBid, closedMinBid, budget *big.Int, forger ethCommon.Address) (*types.Transaction, error)
// Forge // Forge
AuctionCanForge(forger ethCommon.Address) (bool, error)
AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error)
// AuctionForge(forger ethCommon.Address) (bool, error) // Only called from another smart contract // AuctionForge(forger ethCommon.Address) (bool, error) // Only called from another smart contract
// Fees // Fees
AuctionClaimHEZ() (*types.Transaction, error)
AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.Transaction, error)
// //
// Smart Contract Status // Smart Contract Status
@ -264,22 +265,37 @@ type AuctionInterface interface {
// AuctionClient is the implementation of the interface to the Auction Smart Contract in ethereum. // AuctionClient is the implementation of the interface to the Auction Smart Contract in ethereum.
type AuctionClient struct { type AuctionClient struct {
client *EthereumClient
address ethCommon.Address
client *EthereumClient
address ethCommon.Address
gasLimit uint64
} }
// NewAuctionClient creates a new AuctionClient // NewAuctionClient creates a new AuctionClient
func NewAuctionClient(client *EthereumClient, address ethCommon.Address) *AuctionClient { func NewAuctionClient(client *EthereumClient, address ethCommon.Address) *AuctionClient {
return &AuctionClient{ return &AuctionClient{
client: client,
address: address,
client: client,
address: address,
gasLimit: 1000000, //nolint:gomnd
} }
} }
// AuctionSetSlotDeadline is the interface to call the smart contract function // AuctionSetSlotDeadline is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting slotDeadline: %w", err)
}
return tx, nil
} }
// AuctionGetSlotDeadline is the interface to call the smart contract function // AuctionGetSlotDeadline is the interface to call the smart contract function
@ -300,8 +316,21 @@ func (c *AuctionClient) AuctionGetSlotDeadline() (uint8, error) {
// AuctionSetOpenAuctionSlots is the interface to call the smart contract function // AuctionSetOpenAuctionSlots is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting openAuctionSlots: %w", err)
}
return tx, nil
} }
// AuctionGetOpenAuctionSlots is the interface to call the smart contract function // AuctionGetOpenAuctionSlots is the interface to call the smart contract function
@ -322,8 +351,21 @@ func (c *AuctionClient) AuctionGetOpenAuctionSlots() (uint16, error) {
// AuctionSetClosedAuctionSlots is the interface to call the smart contract function // AuctionSetClosedAuctionSlots is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting closedAuctionSlots: %w", err)
}
return tx, nil
} }
// AuctionGetClosedAuctionSlots is the interface to call the smart contract function // AuctionGetClosedAuctionSlots is the interface to call the smart contract function
@ -344,58 +386,91 @@ func (c *AuctionClient) AuctionGetClosedAuctionSlots() (uint16, error) {
// AuctionSetOutbidding is the interface to call the smart contract function // AuctionSetOutbidding is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var 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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting setOutbidding: %w", err)
}
return tx, nil
} }
// AuctionGetOutbidding is the interface to call the smart contract function // AuctionGetOutbidding is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) { func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) {
// TODO: Update
// var outbidding uint8
// 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)
// return err
// }); err != nil {
// return 0, err
// }
// return outbidding, nil
log.Error("TODO")
return 0, errTODO
var outbidding uint16
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)
return err
}); err != nil {
return 0, err
}
return outbidding, nil
} }
// AuctionSetAllocationRatio is the interface to call the smart contract function // AuctionSetAllocationRatio is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting allocationRatio: %w", err)
}
return tx, nil
} }
// AuctionGetAllocationRatio is the interface to call the smart contract function // AuctionGetAllocationRatio is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) { func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) {
// TODO: Update
// var allocationRation [3]uint8
// 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)
// return err
// }); err != nil {
// return [3]uint8{}, err
// }
// return allocationRation, nil
log.Error("TODO")
return [3]uint16{}, errTODO
var allocationRation [3]uint16
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)
return err
}); err != nil {
return [3]uint16{}, err
}
return allocationRation, nil
} }
// AuctionSetDonationAddress is the interface to call the smart contract function // AuctionSetDonationAddress is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting donationAddress: %w", err)
}
return tx, nil
} }
// AuctionGetDonationAddress is the interface to call the smart contract function // AuctionGetDonationAddress is the interface to call the smart contract function
@ -416,8 +491,21 @@ func (c *AuctionClient) AuctionGetDonationAddress() (*ethCommon.Address, error)
// AuctionSetBootCoordinator is the interface to call the smart contract function // AuctionSetBootCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) { func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed setting bootCoordinator: %w", err)
}
return tx, nil
} }
// AuctionGetBootCoordinator is the interface to call the smart contract function // AuctionGetBootCoordinator is the interface to call the smart contract function
@ -438,26 +526,76 @@ func (c *AuctionClient) AuctionGetBootCoordinator() (*ethCommon.Address, error)
// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function // AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error) { func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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)
},
); err != nil {
return nil, fmt.Errorf("Failed changing epoch minBid: %w", err)
}
return tx, nil
} }
// AuctionRegisterCoordinator is the interface to call the smart contract function // AuctionRegisterCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) { func (c *AuctionClient) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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.RegisterCoordinator(auth, forgerAddress, URL)
},
); err != nil {
return nil, fmt.Errorf("Failed register coordinator: %w", err)
}
return tx, nil
} }
// AuctionIsRegisteredCoordinator is the interface to call the smart contract function // AuctionIsRegisteredCoordinator is the interface to call the smart contract function
func (c *AuctionClient) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) { func (c *AuctionClient) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
log.Error("TODO")
return false, errTODO
var registered bool
if err := c.client.Call(func(ec *ethclient.Client) error {
auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
if err != nil {
return err
}
registered, err = auction.IsRegisteredCoordinator(nil, forgerAddress)
return err
}); err != nil {
return false, err
}
return registered, nil
} }
// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function // AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
func (c *AuctionClient) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) { func (c *AuctionClient) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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.UpdateCoordinatorInfo(auth, forgerAddress, newWithdrawAddress, newURL)
},
); err != nil {
return nil, fmt.Errorf("Failed update coordinator info: %w", err)
}
return tx, nil
} }
// AuctionGetCurrentSlotNumber is the interface to call the smart contract function // AuctionGetCurrentSlotNumber is the interface to call the smart contract function
@ -496,22 +634,18 @@ func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function // AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) { func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
// TODO: Update
// var DefaultSlotSetBid *big.Int
// if err := c.client.Call(func(ec *ethclient.Client) error {
// auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
// if err != nil {
// return err
// }
// defaultSlotSetBid, err = auction.GetDefaultSlotSetBid(nil, slotSet)
// return err
// }); err != nil {
// return big.NewInt(0), err
// }
// return defaultSlotSetBid, nil
log.Error("TODO")
return nil, errTODO
var minBidSlotSet *big.Int
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)
return err
}); err != nil {
return big.NewInt(0), err
}
return minBidSlotSet, nil
} }
// AuctionTokensReceived is the interface to call the smart contract function // AuctionTokensReceived is the interface to call the smart contract function
@ -532,9 +666,19 @@ func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, sl
} }
// AuctionCanForge is the interface to call the smart contract function // AuctionCanForge is the interface to call the smart contract function
func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address) (bool, error) {
log.Error("TODO")
return false, errTODO
func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
var canForge bool
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))
return err
}); err != nil {
return false, err
}
return canForge, nil
} }
// AuctionForge is the interface to call the smart contract function // AuctionForge is the interface to call the smart contract function
@ -543,15 +687,103 @@ func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address) (bool, error)
// } // }
// AuctionClaimHEZ is the interface to call the smart contract function // AuctionClaimHEZ is the interface to call the smart contract function
func (c *AuctionClient) AuctionClaimHEZ() (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
func (c *AuctionClient) AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.Transaction, error) {
var tx *types.Transaction
var err error
if tx, err = c.client.CallAuth(
c.gasLimit,
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, claimAddress)
},
); err != nil {
return nil, fmt.Errorf("Failed claim HEZ: %w", err)
}
return tx, nil
} }
// AuctionConstants returns the Constants of the Auction Smart Contract // AuctionConstants returns the Constants of the Auction Smart Contract
func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) { func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) {
log.Error("TODO")
return nil, errTODO
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)
if err != nil {
return err
}
genesisBlock, err := auction.GenesisBlock(nil)
if err != nil {
return err
}
auctionConstants.GenesisBlockNum = genesisBlock.Int64()
auctionConstants.HermezRollup, err = auction.HermezRollup(nil)
if err != nil {
return err
}
auctionConstants.InitialMinimalBidding, err = auction.INITIALMINIMALBIDDING(nil)
if err != nil {
return err
}
auctionConstants.TokenHEZ, err = auction.TokenHEZ(nil)
return err
}); err != nil {
return nil, err
}
return auctionConstants, nil
}
// AuctionVariables returns the variables of the Auction Smart Contract
func (c *AuctionClient) AuctionVariables() (*AuctionVariables, 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
}
bootCoordinator, err := c.AuctionGetBootCoordinator()
if err != nil {
return err
}
auctionVariables.BootCoordinator = *bootCoordinator
auctionVariables.ClosedAuctionSlots, err = c.AuctionGetClosedAuctionSlots()
if err != nil {
return err
}
var defaultSlotSetBid [6]*big.Int
for i := uint8(0); i < 6; i++ {
bid, err := c.AuctionGetDefaultSlotSetBid(i)
if err != nil {
return err
}
defaultSlotSetBid[i] = bid
}
auctionVariables.DefaultSlotSetBid = defaultSlotSetBid
donationAddress, err := c.AuctionGetDonationAddress()
if err != nil {
return err
}
auctionVariables.DonationAddress = *donationAddress
auctionVariables.OpenAuctionSlots, err = c.AuctionGetOpenAuctionSlots()
if err != nil {
return err
}
auctionVariables.Outbidding, err = c.AuctionGetOutbidding()
if err != nil {
return err
}
auctionVariables.SlotDeadline, err = c.AuctionGetSlotDeadline()
return err
}); err != nil {
return nil, err
}
return auctionVariables, nil
} }
// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract

+ 241
- 25
eth/auction_test.go

@ -1,42 +1,116 @@
package eth package eth
import ( import (
"io/ioutil"
"math/big"
"os" "os"
"testing" "testing"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
const slotDeadlineConst = uint8(20) const slotDeadlineConst = uint8(20)
const openAuctionSlotsConst = 4320
const closedAuctionSlotsConst = 2
const outbiddingConst = 10
const openAuctionSlotsConst = uint16(4320)
const closedAuctionSlotsConst = uint16(2)
const outbiddingConst = uint16(1000)
const currentSlotConst = 0 const currentSlotConst = 0
var allocationRatioConst [3]uint8 = [3]uint8{40, 40, 20}
var allocationRatioConst [3]uint16 = [3]uint16{4000, 4000, 2000}
var auctionClient *AuctionClient var auctionClient *AuctionClient
var donationAddressConstStr = os.Getenv("DONATION_ADDRESS")
var bootCoordinatorConstStr = os.Getenv("BOOT_COORDINATOR_ADDRESS")
var integration = os.Getenv("INTEGRATION")
/*var donationAddressStr = os.Getenv("DONATION_ADDRESS")
var bootCoordinatorStr = os.Getenv("BOOT_COORDINATOR_ADDRESS")
var ehtClientDialURL = os.Getenv("ETHCLIENT_DIAL_URL") var ehtClientDialURL = os.Getenv("ETHCLIENT_DIAL_URL")
var auctionAddressStr = os.Getenv("AUCTION_ADDRESS")
var auctionAddressStr = os.Getenv("AUCTION_ADDRESS")*/
var integration = os.Getenv("INTEGRATION")
var donationAddressStr = "0x6c365935CA8710200C7595F0a72EB6023A7706Cd"
var bootCoordinatorStr = "0xc783df8a850f42e7f7e57013759c285caa701eb6"
var DONATION = common.HexToAddress(donationAddressStr)
var BOOTCOORDINATOR = common.HexToAddress(bootCoordinatorStr)
var ehtClientDialURL = "http://localhost:8545"
var auctionAddressStr = "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5"
// var ownerAddressStr = "0xc783df8a850f42e7F7e57013759C285caa701eB6"
var governanceAddressStr = "0xead9c93b79ae7c1591b1fb5323bd777e86e150d4"
var governancePrivateKey = "d49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb"
var minBidStr = "10000000000000000000"
var URL = "http://localhost:3000"
var newURL = "http://localhost:3002"
var BLOCKSPERSLOT = uint8(40)
var TOKENHEZ = common.HexToAddress("0xf4e77E5Da47AC3125140c470c71cBca77B5c638c")
var HERMEZROLLUP = common.HexToAddress("0xc4905364b78a742ccce7B890A89514061E47068D")
var password = "pass"
func TestNewAction(t *testing.T) { func TestNewAction(t *testing.T) {
key, err := crypto.HexToECDSA(governancePrivateKey)
require.Nil(t, err)
dir, err := ioutil.TempDir("", "tmpks")
require.Nil(t, err)
ks := keystore.NewKeyStore(dir, keystore.StandardScryptN, keystore.StandardScryptP)
account, err := ks.ImportECDSA(key, password)
require.Nil(t, err)
err = ks.Unlock(account, password)
require.Nil(t, err)
// Init eth client
ethClient, err := ethclient.Dial(ehtClientDialURL)
require.Nil(t, err)
ethereumClient := NewEthereumClient(ethClient, &account, ks, nil)
auctionAddress := common.HexToAddress(auctionAddressStr)
if integration != "" { if integration != "" {
// Init eth client
ethClient, err := ethclient.Dial(ehtClientDialURL)
require.Nil(t, err)
ethereumClient := NewEthereumClient(ethClient, nil, nil, nil)
auctionAddress := common.HexToAddress(auctionAddressStr)
auctionClient = NewAuctionClient(ethereumClient, auctionAddress) auctionClient = NewAuctionClient(ethereumClient, auctionAddress)
} }
} }
func TestAuctionGetCurrentSlotNumber(t *testing.T) {
if auctionClient != nil {
currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber()
require.Nil(t, err)
currentSlotInt := int(currentSlot)
assert.Equal(t, currentSlotConst, currentSlotInt)
}
}
func TestAuctionConstants(t *testing.T) {
INITMINBID := new(big.Int)
INITMINBID.SetString(minBidStr, 10)
if auctionClient != nil {
auctionConstants, err := auctionClient.AuctionConstants()
require.Nil(t, err)
assert.Equal(t, auctionConstants.BlocksPerSlot, BLOCKSPERSLOT)
// assert.Equal(t, auctionConstants.GenesisBlockNum, GENESISBLOCKNUM)
assert.Equal(t, auctionConstants.HermezRollup, HERMEZROLLUP)
assert.Equal(t, auctionConstants.InitialMinimalBidding, INITMINBID)
assert.Equal(t, auctionConstants.TokenHEZ, TOKENHEZ)
}
}
func TestAuctionVariables(t *testing.T) {
INITMINBID := new(big.Int)
INITMINBID.SetString(minBidStr, 10)
defaultSlotSetBid := [6]*big.Int{INITMINBID, INITMINBID, INITMINBID, INITMINBID, INITMINBID, INITMINBID}
if auctionClient != nil {
auctionVariables, err := auctionClient.AuctionVariables()
require.Nil(t, err)
assert.Equal(t, auctionVariables.AllocationRatio, allocationRatioConst)
assert.Equal(t, auctionVariables.BootCoordinator, &BOOTCOORDINATOR)
assert.Equal(t, auctionVariables.ClosedAuctionSlots, closedAuctionSlotsConst)
assert.Equal(t, auctionVariables.DefaultSlotSetBid, defaultSlotSetBid)
assert.Equal(t, auctionVariables.DonationAddress, &DONATION)
assert.Equal(t, auctionVariables.OpenAuctionSlots, openAuctionSlotsConst)
assert.Equal(t, auctionVariables.Outbidding, outbiddingConst)
assert.Equal(t, auctionVariables.SlotDeadline, slotDeadlineConst)
}
}
func TestAuctionGetSlotDeadline(t *testing.T) { func TestAuctionGetSlotDeadline(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
slotDeadline, err := auctionClient.AuctionGetSlotDeadline() slotDeadline, err := auctionClient.AuctionGetSlotDeadline()
@ -45,12 +119,37 @@ func TestAuctionGetSlotDeadline(t *testing.T) {
} }
} }
func TestAuctionSetSlotDeadline(t *testing.T) {
newSlotDeadline := uint8(25)
if auctionClient != nil {
_, err := auctionClient.AuctionSetSlotDeadline(newSlotDeadline)
require.Nil(t, err)
slotDeadline, err := auctionClient.AuctionGetSlotDeadline()
require.Nil(t, err)
assert.Equal(t, newSlotDeadline, slotDeadline)
_, err = auctionClient.AuctionSetSlotDeadline(slotDeadlineConst)
require.Nil(t, err)
}
}
func TestAuctionGetOpenAuctionSlots(t *testing.T) { func TestAuctionGetOpenAuctionSlots(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots() openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots()
require.Nil(t, err) require.Nil(t, err)
openAuctionSlotsInt := int(openAuctionSlots)
assert.Equal(t, openAuctionSlotsConst, openAuctionSlotsInt)
assert.Equal(t, openAuctionSlotsConst, openAuctionSlots)
}
}
func TestAuctionSetOpenAuctionSlots(t *testing.T) {
newOpenAuctionSlots := uint16(4500)
if auctionClient != nil {
_, err := auctionClient.AuctionSetOpenAuctionSlots(newOpenAuctionSlots)
require.Nil(t, err)
openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots()
require.Nil(t, err)
assert.Equal(t, newOpenAuctionSlots, openAuctionSlots)
_, err = auctionClient.AuctionSetOpenAuctionSlots(openAuctionSlotsConst)
require.Nil(t, err)
} }
} }
@ -58,8 +157,20 @@ func TestAuctionGetClosedAuctionSlots(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots() closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots()
require.Nil(t, err) require.Nil(t, err)
closedAuctionSlotsInt := int(closedAuctionSlots)
assert.Equal(t, closedAuctionSlotsConst, closedAuctionSlotsInt)
assert.Equal(t, closedAuctionSlotsConst, closedAuctionSlots)
}
}
func TestAuctionSetClosedAuctionSlots(t *testing.T) {
newClosedAuctionSlots := uint16(5)
if auctionClient != nil {
_, err := auctionClient.AuctionSetClosedAuctionSlots(newClosedAuctionSlots)
require.Nil(t, err)
closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots()
require.Nil(t, err)
assert.Equal(t, newClosedAuctionSlots, closedAuctionSlots)
_, err = auctionClient.AuctionSetClosedAuctionSlots(closedAuctionSlotsConst)
require.Nil(t, err)
} }
} }
@ -67,8 +178,20 @@ func TestAuctionGetOutbidding(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
outbidding, err := auctionClient.AuctionGetOutbidding() outbidding, err := auctionClient.AuctionGetOutbidding()
require.Nil(t, err) require.Nil(t, err)
outbiddingInt := int(outbidding)
assert.Equal(t, outbiddingConst, outbiddingInt)
assert.Equal(t, outbiddingConst, outbidding)
}
}
func TestAuctionSetOutbidding(t *testing.T) {
newOutbidding := uint16(0xb)
if auctionClient != nil {
_, err := auctionClient.AuctionSetOutbidding(newOutbidding)
require.Nil(t, err)
outbidding, err := auctionClient.AuctionGetOutbidding()
require.Nil(t, err)
assert.Equal(t, newOutbidding, outbidding)
_, err = auctionClient.AuctionSetOutbidding(outbiddingConst)
require.Nil(t, err)
} }
} }
@ -80,11 +203,24 @@ func TestAuctionGetAllocationRatio(t *testing.T) {
} }
} }
func TestAuctionSetAllocationRatio(t *testing.T) {
newAllocationRatio := [3]uint16{3000, 3000, 4000}
if auctionClient != nil {
_, err := auctionClient.AuctionSetAllocationRatio(newAllocationRatio)
require.Nil(t, err)
allocationRatio, err := auctionClient.AuctionGetAllocationRatio()
require.Nil(t, err)
assert.Equal(t, newAllocationRatio, allocationRatio)
_, err = auctionClient.AuctionSetAllocationRatio(allocationRatioConst)
require.Nil(t, err)
}
}
func TestAuctionGetDonationAddress(t *testing.T) { func TestAuctionGetDonationAddress(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
donationAddress, err := auctionClient.AuctionGetDonationAddress() donationAddress, err := auctionClient.AuctionGetDonationAddress()
require.Nil(t, err) require.Nil(t, err)
donationAddressConst := common.HexToAddress(donationAddressConstStr)
donationAddressConst := common.HexToAddress(donationAddressStr)
assert.Equal(t, &donationAddressConst, donationAddress) assert.Equal(t, &donationAddressConst, donationAddress)
} }
} }
@ -93,16 +229,96 @@ func TestAuctionGetBootCoordinator(t *testing.T) {
if auctionClient != nil { if auctionClient != nil {
bootCoordinator, err := auctionClient.AuctionGetBootCoordinator() bootCoordinator, err := auctionClient.AuctionGetBootCoordinator()
require.Nil(t, err) require.Nil(t, err)
bootCoordinatorConst := common.HexToAddress(bootCoordinatorConstStr)
bootCoordinatorConst := common.HexToAddress(bootCoordinatorStr)
assert.Equal(t, &bootCoordinatorConst, bootCoordinator) assert.Equal(t, &bootCoordinatorConst, bootCoordinator)
} }
} }
func TestAuctionGetCurrentSlotNumber(t *testing.T) {
func TestAuctionSetDonationAddress(t *testing.T) {
newDonationAddress := common.HexToAddress(governanceAddressStr)
if auctionClient != nil { if auctionClient != nil {
currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber()
_, err := auctionClient.AuctionSetDonationAddress(newDonationAddress)
require.Nil(t, err)
donationAddress, err := auctionClient.AuctionGetDonationAddress()
require.Nil(t, err)
assert.Equal(t, &newDonationAddress, donationAddress)
donationAddressConst := common.HexToAddress(donationAddressStr)
_, err = auctionClient.AuctionSetDonationAddress(donationAddressConst)
require.Nil(t, err)
}
}
func TestAuctionSetBootCoordinator(t *testing.T) {
newBootCoordinator := common.HexToAddress(governanceAddressStr)
if auctionClient != nil {
_, err := auctionClient.AuctionSetBootCoordinator(newBootCoordinator)
require.Nil(t, err)
bootCoordinator, err := auctionClient.AuctionGetBootCoordinator()
require.Nil(t, err)
assert.Equal(t, &newBootCoordinator, bootCoordinator)
bootCoordinatorConst := common.HexToAddress(bootCoordinatorStr)
_, err = auctionClient.AuctionSetBootCoordinator(bootCoordinatorConst)
require.Nil(t, err)
}
}
func TestAuctionGetDefaultSlotSetBid(t *testing.T) {
slotSet := uint8(3)
if auctionClient != nil {
minBid, err := auctionClient.AuctionGetDefaultSlotSetBid(slotSet)
require.Nil(t, err)
assert.Equal(t, minBid.String(), minBidStr)
}
}
func TestAuctionChangeEpochMinBid(t *testing.T) {
slotSet := int64(3)
set := uint8(3)
newInitialMinBid := new(big.Int)
newInitialMinBid.SetString("20000000000000000000", 10)
if auctionClient != nil {
_, err := auctionClient.AuctionChangeDefaultSlotSetBid(slotSet, newInitialMinBid)
require.Nil(t, err)
minBid, err := auctionClient.AuctionGetDefaultSlotSetBid(set)
require.Nil(t, err)
assert.Equal(t, minBid, newInitialMinBid)
newMinBid := new(big.Int)
newMinBid.SetString("10000000000000000000", 10)
_, err = auctionClient.AuctionChangeDefaultSlotSetBid(slotSet, newMinBid)
require.Nil(t, err)
}
}
func TestAuctionIsRegisteredCoordinator(t *testing.T) {
forgerAddress := common.HexToAddress(governanceAddressStr)
if auctionClient != nil {
registered, err := auctionClient.AuctionIsRegisteredCoordinator(forgerAddress)
require.Nil(t, err)
assert.Equal(t, registered, false)
}
}
func TestAuctionRegisterCoordinator(t *testing.T) {
forgerAddress := common.HexToAddress(governanceAddressStr)
if auctionClient != nil {
_, err := auctionClient.AuctionRegisterCoordinator(forgerAddress, URL)
require.Nil(t, err)
}
}
func TestAuctionIsRegisteredCoordinatorTrue(t *testing.T) {
forgerAddress := common.HexToAddress(governanceAddressStr)
if auctionClient != nil {
registered, err := auctionClient.AuctionIsRegisteredCoordinator(forgerAddress)
require.Nil(t, err)
assert.Equal(t, registered, true)
}
}
func TestAuctionUpdateCoordinatorInfo(t *testing.T) {
forgerAddress := common.HexToAddress(governanceAddressStr)
if auctionClient != nil {
_, err := auctionClient.AuctionUpdateCoordinatorInfo(forgerAddress, forgerAddress, newURL)
require.Nil(t, err) require.Nil(t, err)
currentSlotInt := int(currentSlot)
assert.Equal(t, currentSlotConst, currentSlotInt)
} }
} }

+ 1
- 1
eth/contracts/README.md

@ -9,6 +9,6 @@ abigen --abi=HermezAuctionProtocol.abi --bin=HermezAuctionProtocol.bin --pkg=Her
``` ```
You must compile the contracts to get the `.bin` and `.abi` files. The contracts used are in the repo: https://github.com/hermeznetwork/contracts-circuits You must compile the contracts to get the `.bin` and `.abi` files. The contracts used are in the repo: https://github.com/hermeznetwork/contracts-circuits
Specifically they have been processed in the commit with hash: `0ba124d60e192afda99ef4703aa13b8fef4a392a`
Specifically they have been processed in the commit with hash: `745e8d588496d7762d4084a54bafd4435061ae35`
> abigen version 1.9.21 > abigen version 1.9.21

+ 258
- 504
eth/contracts/auction/HermezAuctionProtocol.go
File diff suppressed because it is too large
View File


+ 359
- 684
eth/contracts/hermez/Hermez.go
File diff suppressed because it is too large
View File


+ 151
- 83
eth/rollup.go

@ -5,7 +5,9 @@ import (
ethCommon "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/hermeznetwork/hermez-node/common" "github.com/hermeznetwork/hermez-node/common"
Hermez "github.com/hermeznetwork/hermez-node/eth/contracts/hermez"
"github.com/hermeznetwork/hermez-node/log" "github.com/hermeznetwork/hermez-node/log"
"github.com/hermeznetwork/hermez-node/utils" "github.com/hermeznetwork/hermez-node/utils"
"github.com/iden3/go-iden3-crypto/babyjub" "github.com/iden3/go-iden3-crypto/babyjub"
@ -24,7 +26,7 @@ type RollupConstants struct {
// Maxim Deposit allowed // Maxim Deposit allowed
MaxAmountDeposit *big.Int MaxAmountDeposit *big.Int
MaxAmountL2 *big.Int MaxAmountL2 *big.Int
MaxTokens uint32
MaxTokens int64
// maximum L1 transactions allowed to be queued for a batch // maximum L1 transactions allowed to be queued for a batch
MaxL1Tx int MaxL1Tx int
// maximum L1 user transactions allowed to be queued for a batch // maximum L1 user transactions allowed to be queued for a batch
@ -33,19 +35,28 @@ type RollupConstants struct {
L1CoordinatorBytes int L1CoordinatorBytes int
L1UserBytes int L1UserBytes int
L2Bytes int L2Bytes int
MaxTxVerifiers []int
TokenHEZ ethCommon.Address
// Only test
GovernanceAddress ethCommon.Address
// Only test
SafetyBot ethCommon.Address
// Only test
ConsensusContract ethCommon.Address
// Only test
WithdrawalContract ethCommon.Address
ReservedIDx uint32
LastIDx uint32
ExitIDx uint32
NoLimitToken int
NumBuckets int
MaxWDelay int64
} }
// RollupVariables are the variables of the Rollup Smart Contract // RollupVariables are the variables of the Rollup Smart Contract
type RollupVariables struct { type RollupVariables struct {
MaxTxVerifiers []int
TokenHEZ ethCommon.Address
GovernanceAddress ethCommon.Address
SafetyBot ethCommon.Address
ConsensusContract ethCommon.Address
WithdrawalContract ethCommon.Address
FeeAddToken *big.Int
ForgeL1Timeout int64
FeeL1UserTx *big.Int
FeeAddToken *big.Int
ForgeL1Timeout int64
} }
// QueueStruct is the queue of L1Txs for a batch // QueueStruct is the queue of L1Txs for a batch
@ -80,7 +91,9 @@ type RollupState struct {
// RollupEventL1UserTx is an event of the Rollup Smart Contract // RollupEventL1UserTx is an event of the Rollup Smart Contract
type RollupEventL1UserTx struct { type RollupEventL1UserTx struct {
L1Tx common.L1Tx
L1Tx common.L1Tx
QueueIndex *big.Int
TransactionIndex *big.Int
} }
// RollupEventAddToken is an event of the Rollup Smart Contract // RollupEventAddToken is an event of the Rollup Smart Contract
@ -95,14 +108,9 @@ type RollupEventForgeBatch struct {
EthTxHash ethCommon.Hash EthTxHash ethCommon.Hash
} }
// RollupEventUpdateForgeL1Timeout is an event of the Rollup Smart Contract
type RollupEventUpdateForgeL1Timeout struct {
ForgeL1Timeout int64
}
// RollupEventUpdateFeeL1UserTx is an event of the Rollup Smart Contract
type RollupEventUpdateFeeL1UserTx struct {
FeeL1UserTx *big.Int
// RollupEventUpdateForgeL1L2BatchTimeout is an event of the Rollup Smart Contract
type RollupEventUpdateForgeL1L2BatchTimeout struct {
ForgeL1Timeout *big.Int
} }
// RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract // RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract
@ -110,40 +118,32 @@ type RollupEventUpdateFeeAddToken struct {
FeeAddToken *big.Int FeeAddToken *big.Int
} }
// RollupEventUpdateTokenHez is an event of the Rollup Smart Contract
type RollupEventUpdateTokenHez struct {
TokenHEZ ethCommon.Address
}
// RollupEventWithdraw is an event of the Rollup Smart Contract
type RollupEventWithdraw struct {
Idx int64
NumExitRoot int
// RollupEventWithdrawEvent is an event of the Rollup Smart Contract
type RollupEventWithdrawEvent struct {
Idx *big.Int
NumExitRoot *big.Int
InstantWithdraw bool
} }
// RollupEvents is the list of events in a block of the Rollup Smart Contract // RollupEvents is the list of events in a block of the Rollup Smart Contract
type RollupEvents struct { //nolint:structcheck type RollupEvents struct { //nolint:structcheck
L1UserTx []RollupEventL1UserTx
AddToken []RollupEventAddToken
ForgeBatch []RollupEventForgeBatch
UpdateForgeL1Timeout []RollupEventUpdateForgeL1Timeout
UpdateFeeL1UserTx []RollupEventUpdateFeeL1UserTx
UpdateFeeAddToken []RollupEventUpdateFeeAddToken
UpdateTokenHez []RollupEventUpdateTokenHez
Withdraw []RollupEventWithdraw
L1UserTx []RollupEventL1UserTx
AddToken []RollupEventAddToken
ForgeBatch []RollupEventForgeBatch
UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
UpdateFeeAddToken []RollupEventUpdateFeeAddToken
WithdrawEvent []RollupEventWithdrawEvent
} }
// NewRollupEvents creates an empty RollupEvents with the slices initialized. // NewRollupEvents creates an empty RollupEvents with the slices initialized.
func NewRollupEvents() RollupEvents { func NewRollupEvents() RollupEvents {
return RollupEvents{ return RollupEvents{
L1UserTx: make([]RollupEventL1UserTx, 0),
AddToken: make([]RollupEventAddToken, 0),
ForgeBatch: make([]RollupEventForgeBatch, 0),
UpdateForgeL1Timeout: make([]RollupEventUpdateForgeL1Timeout, 0),
UpdateFeeL1UserTx: make([]RollupEventUpdateFeeL1UserTx, 0),
UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
UpdateTokenHez: make([]RollupEventUpdateTokenHez, 0),
Withdraw: make([]RollupEventWithdraw, 0),
L1UserTx: make([]RollupEventL1UserTx, 0),
AddToken: make([]RollupEventAddToken, 0),
ForgeBatch: make([]RollupEventForgeBatch, 0),
UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
WithdrawEvent: make([]RollupEventWithdrawEvent, 0),
} }
} }
@ -175,8 +175,7 @@ type RollupInterface interface {
RollupForgeBatch(*RollupForgeBatchArgs) (*types.Transaction, error) RollupForgeBatch(*RollupForgeBatchArgs) (*types.Transaction, error)
RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error) RollupAddToken(tokenAddress ethCommon.Address) (*types.Transaction, error)
// RollupWithdrawSNARK() (*types.Transaction, error) // TODO (Not defined in Hermez.sol)
RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey,
RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey,
numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error)
RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (*types.Transaction, error) RollupForceExit(fromIdx int64, amountF utils.Float16, tokenID int64) (*types.Transaction, error)
RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (*types.Transaction, error) RollupForceTransfer(fromIdx int64, amountF utils.Float16, tokenID, toIdx int64) (*types.Transaction, error)
@ -190,16 +189,14 @@ type RollupInterface interface {
RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16, RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF utils.Float16,
tokenID int64) (*types.Transaction, error) tokenID int64) (*types.Transaction, error)
RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error)
RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error)
RollupGetQueue(queue int64) ([]byte, error)
RollupGetCurrentTokens() (*big.Int, error)
// RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error)
// RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error)
// RollupGetQueue(queue int64) ([]byte, error)
// Governance Public Functions // Governance Public Functions
RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (*types.Transaction, error)
RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (*types.Transaction, error)
RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error)
RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error)
RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (*types.Transaction, error)
// RollupUpdateGovernance() (*types.Transaction, error) // TODO (Not defined in Hermez.sol)
// //
// Smart Contract Status // Smart Contract Status
@ -216,6 +213,16 @@ type RollupInterface interface {
// RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum. // RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum.
type RollupClient struct { type RollupClient struct {
client *EthereumClient
address ethCommon.Address
}
// NewRollupClient creates a new RollupClient
func NewRollupClient(client *EthereumClient, address ethCommon.Address) *RollupClient {
return &RollupClient{
client: client,
address: address,
}
} }
// RollupForgeBatch is the interface to call the smart contract function // RollupForgeBatch is the interface to call the smart contract function
@ -235,8 +242,8 @@ func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address) (*types.Tr
// return nil, errTODO // return nil, errTODO
// } // }
// RollupWithdrawMerkleProof is the interface to call the smart contract function
func (c *RollupClient) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
// RollupWithdraw is the interface to call the smart contract function
func (c *RollupClient) RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
log.Error("TODO") log.Error("TODO")
return nil, errTODO return nil, errTODO
} }
@ -284,31 +291,28 @@ func (c *RollupClient) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey,
} }
// RollupGetTokenAddress is the interface to call the smart contract function // RollupGetTokenAddress is the interface to call the smart contract function
func (c *RollupClient) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
log.Error("TODO")
/* func (c *RollupClient) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
return nil, errTODO return nil, errTODO
}
} */
// RollupGetL1TxFromQueue is the interface to call the smart contract function
func (c *RollupClient) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
// RollupGetCurrentTokens is the interface to call the smart contract function
func (c *RollupClient) RollupGetCurrentTokens() (*big.Int, error) {
log.Error("TODO") log.Error("TODO")
return nil, errTODO return nil, errTODO
} }
// RollupGetQueue is the interface to call the smart contract function
func (c *RollupClient) RollupGetQueue(queue int64) ([]byte, error) {
log.Error("TODO")
// RollupGetL1TxFromQueue is the interface to call the smart contract function
/* func (c *RollupClient) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
return nil, errTODO return nil, errTODO
}
} */
// RollupUpdateForgeL1Timeout is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (*types.Transaction, error) {
log.Error("TODO")
// RollupGetQueue is the interface to call the smart contract function
/* func (c *RollupClient) RollupGetQueue(queue int64) ([]byte, error) {
return nil, errTODO return nil, errTODO
}
}*/
// RollupUpdateFeeL1UserTx is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (*types.Transaction, error) {
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error) {
log.Error("TODO") log.Error("TODO")
return nil, errTODO return nil, errTODO
} }
@ -319,21 +323,85 @@ func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.
return nil, errTODO return nil, errTODO
} }
// RollupUpdateTokensHEZ is the interface to call the smart contract function
func (c *RollupClient) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (*types.Transaction, error) {
log.Error("TODO")
return nil, errTODO
}
// RollupUpdateGovernance is the interface to call the smart contract function
// func (c *RollupClient) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
// return nil, errTODO
// }
// RollupConstants returns the Constants of the Rollup Smart Contract // RollupConstants returns the Constants of the Rollup Smart Contract
func (c *RollupClient) RollupConstants() (*RollupConstants, error) { func (c *RollupClient) RollupConstants() (*RollupConstants, error) {
log.Error("TODO")
return nil, errTODO
rollupConstants := new(RollupConstants)
if err := c.client.Call(func(ec *ethclient.Client) error {
rollup, err := Hermez.NewHermez(c.address, ec)
if err != nil {
return err
}
// rollupConstants.GovernanceAddress :=
l1CoordinatorBytes, err := rollup.L1COORDINATORBYTES(nil)
if err != nil {
return err
}
rollupConstants.L1CoordinatorBytes = int(l1CoordinatorBytes.Int64())
l1UserBytes, err := rollup.L1USERBYTES(nil)
if err != nil {
return err
}
rollupConstants.L1UserBytes = int(l1UserBytes.Int64())
l2Bytes, err := rollup.L2BYTES(nil)
if err != nil {
return err
}
rollupConstants.L2Bytes = int(l2Bytes.Int64())
rollupConstants.LastIDx, err = rollup.LASTIDX(nil)
if err != nil {
return err
}
rollupConstants.MaxAmountDeposit, err = rollup.MAXLOADAMOUNT(nil)
if err != nil {
return err
}
rollupConstants.MaxAmountL2, err = rollup.MAXAMOUNT(nil)
if err != nil {
return err
}
maxL1Tx, err := rollup.MAXL1TX(nil)
if err != nil {
return err
}
rollupConstants.MaxL1Tx = int(maxL1Tx.Int64())
maxL1UserTx, err := rollup.MAXL1USERTX(nil)
if err != nil {
return err
}
rollupConstants.MaxL1UserTx = int(maxL1UserTx.Int64())
maxTokens, err := rollup.MAXTOKENS(nil)
if err != nil {
return err
}
rollupConstants.MaxTokens = maxTokens.Int64()
maxWDelay, err := rollup.MAXWITHDRAWALDELAY(nil)
if err != nil {
return err
}
rollupConstants.MaxWDelay = maxWDelay.Int64()
noLimitToken, err := rollup.NOLIMIT(nil)
if err != nil {
return err
}
rollupConstants.NoLimitToken = int(noLimitToken.Int64())
numBuckets, err := rollup.NUMBUCKETS(nil)
if err != nil {
return err
}
rollupConstants.NumBuckets = int(numBuckets.Int64())
// rollupConstants.ReservedIDx =
rollupConstants.Rfield, err = rollup.RFIELD(nil)
if err != nil {
return err
}
// rollupConstants.SafetyBot =
// rollupConstants.TokenHEZ =
// rollupConstants.WithdrawalContract =
return nil
}); err != nil {
return nil, err
}
return rollupConstants, nil
} }
// RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract

+ 39
- 0
eth/rollup_test.go

@ -0,0 +1,39 @@
package eth
import (
"io/ioutil"
"testing"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
var rollupClient *RollupClient
func TestNewRollupClient(t *testing.T) {
key, err := crypto.HexToECDSA(governancePrivateKey)
require.Nil(t, err)
dir, err := ioutil.TempDir("", "tmpks")
require.Nil(t, err)
ks := keystore.NewKeyStore(dir, keystore.StandardScryptN, keystore.StandardScryptP)
account, err := ks.ImportECDSA(key, password)
require.Nil(t, err)
err = ks.Unlock(account, password)
require.Nil(t, err)
// Init eth client
ethClient, err := ethclient.Dial(ehtClientDialURL)
require.Nil(t, err)
ethereumClient := NewEthereumClient(ethClient, &account, ks, nil)
if integration != "" {
rollupClient = NewRollupClient(ethereumClient, HERMEZROLLUP)
}
}
func TestRollupConstants(t *testing.T) {
if rollupClient != nil {
_, err := rollupClient.RollupConstants()
require.Nil(t, err)
}
}

+ 50
- 54
test/ethclient.go

@ -231,20 +231,18 @@ func NewClientSetupExample() *ClientSetup {
L1CoordinatorBytes: 101, L1CoordinatorBytes: 101,
L1UserBytes: 68, L1UserBytes: 68,
L2Bytes: 11, L2Bytes: 11,
}
rollupVariables := &eth.RollupVariables{
MaxTxVerifiers: []int{512, 1024, 2048}, MaxTxVerifiers: []int{512, 1024, 2048},
TokenHEZ: tokenHEZ, TokenHEZ: tokenHEZ,
GovernanceAddress: governanceAddress, GovernanceAddress: governanceAddress,
SafetyBot: ethCommon.HexToAddress("0x84d8B79E84fe87B14ad61A554e740f6736bF4c20"), SafetyBot: ethCommon.HexToAddress("0x84d8B79E84fe87B14ad61A554e740f6736bF4c20"),
ConsensusContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"), ConsensusContract: ethCommon.HexToAddress("0x8E442975805fb1908f43050c9C1A522cB0e28D7b"),
WithdrawalContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"), WithdrawalContract: ethCommon.HexToAddress("0x5CB7979cBdbf65719BEE92e4D15b7b7Ed3D79114"),
FeeAddToken: big.NewInt(11),
ForgeL1Timeout: 9,
FeeL1UserTx: big.NewInt(22),
}
rollupVariables := &eth.RollupVariables{
FeeAddToken: big.NewInt(11),
ForgeL1Timeout: 9,
} }
auctionConstants := &eth.AuctionConstants{ auctionConstants := &eth.AuctionConstants{
DelayGenesis: 0,
BlocksPerSlot: 40, BlocksPerSlot: 40,
InitialMinimalBidding: initialMinimalBidding, InitialMinimalBidding: initialMinimalBidding,
GenesisBlockNum: 0, GenesisBlockNum: 0,
@ -633,8 +631,8 @@ func (c *Client) RollupAddToken(tokenAddress ethCommon.Address) (tx *types.Trans
// return nil, errTODO // return nil, errTODO
// } // }
// RollupWithdrawMerkleProof is the interface to call the smart contract function
func (c *Client) RollupWithdrawMerkleProof(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (tx *types.Transaction, err error) {
// RollupWithdraw is the interface to call the smart contract function
func (c *Client) RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (tx *types.Transaction, err error) {
c.rw.Lock() c.rw.Lock()
defer c.rw.Unlock() defer c.rw.Unlock()
cpy := c.nextBlock().copy() cpy := c.nextBlock().copy()
@ -677,6 +675,15 @@ func (c *Client) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey
return nil, errTODO return nil, errTODO
} }
// RollupGetCurrentTokens is the interface to call the smart contract function
func (c *Client) RollupGetCurrentTokens() (*big.Int, error) {
c.rw.RLock()
defer c.rw.RUnlock()
log.Error("TODO")
return nil, errTODO
}
// RollupDepositTransfer is the interface to call the smart contract function // RollupDepositTransfer is the interface to call the smart contract function
func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) { func (c *Client) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF utils.Float16, tokenID int64, toIdx int64) (tx *types.Transaction, err error) {
c.rw.Lock() c.rw.Lock()
@ -722,45 +729,34 @@ func (c *Client) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAm
} }
// RollupGetTokenAddress is the interface to call the smart contract function // RollupGetTokenAddress is the interface to call the smart contract function
func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
c.rw.RLock()
defer c.rw.RUnlock()
log.Error("TODO")
return nil, errTODO
}
// func (c *Client) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
// c.rw.RLock()
// defer c.rw.RUnlock()
//
// log.Error("TODO")
// return nil, errTODO
// }
// RollupGetL1TxFromQueue is the interface to call the smart contract function // RollupGetL1TxFromQueue is the interface to call the smart contract function
func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
c.rw.RLock()
defer c.rw.RUnlock()
log.Error("TODO")
return nil, errTODO
}
// func (c *Client) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
// c.rw.RLock()
// defer c.rw.RUnlock()
//
// log.Error("TODO")
// return nil, errTODO
// }
// RollupGetQueue is the interface to call the smart contract function // RollupGetQueue is the interface to call the smart contract function
func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
c.rw.RLock()
defer c.rw.RUnlock()
log.Error("TODO")
return nil, errTODO
}
// RollupUpdateForgeL1Timeout is the interface to call the smart contract function
func (c *Client) RollupUpdateForgeL1Timeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
defer func() { c.revertIfErr(err, cpy) }()
log.Error("TODO")
return nil, errTODO
}
// func (c *Client) RollupGetQueue(queue int64) ([]byte, error) {
// c.rw.RLock()
// defer c.rw.RUnlock()
//
// log.Error("TODO")
// return nil, errTODO
// }
// RollupUpdateFeeL1UserTx is the interface to call the smart contract function
func (c *Client) RollupUpdateFeeL1UserTx(newFeeL1UserTx *big.Int) (tx *types.Transaction, err error) {
// RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
func (c *Client) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (tx *types.Transaction, err error) {
c.rw.Lock() c.rw.Lock()
defer c.rw.Unlock() defer c.rw.Unlock()
cpy := c.nextBlock().copy() cpy := c.nextBlock().copy()
@ -782,15 +778,15 @@ func (c *Client) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Tra
} }
// RollupUpdateTokensHEZ is the interface to call the smart contract function // RollupUpdateTokensHEZ is the interface to call the smart contract function
func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
c.rw.Lock()
defer c.rw.Unlock()
cpy := c.nextBlock().copy()
defer func() { c.revertIfErr(err, cpy) }()
log.Error("TODO")
return nil, errTODO
}
// func (c *Client) RollupUpdateTokensHEZ(newTokenHEZ ethCommon.Address) (tx *types.Transaction, err error) {
// c.rw.Lock()
// defer c.rw.Unlock()
// cpy := c.nextBlock().copy()
// defer func() { c.revertIfErr(err, cpy) }()
//
// log.Error("TODO")
// return nil, errTODO
// }
// RollupUpdateGovernance is the interface to call the smart contract function // RollupUpdateGovernance is the interface to call the smart contract function
// func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol) // func (c *Client) RollupUpdateGovernance() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
@ -1132,13 +1128,13 @@ func (c *Client) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [
} }
// AuctionCanForge is the interface to call the smart contract function // AuctionCanForge is the interface to call the smart contract function
func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) {
func (c *Client) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
c.rw.RLock() c.rw.RLock()
defer c.rw.RUnlock() defer c.rw.RUnlock()
currentBlock := c.currentBlock() currentBlock := c.currentBlock()
a := currentBlock.Auction a := currentBlock.Auction
return a.canForge(forger, a.Eth.BlockNum)
return a.canForge(forger, blockNum)
} }
// AuctionForge is the interface to call the smart contract function // AuctionForge is the interface to call the smart contract function
@ -1147,7 +1143,7 @@ func (c *Client) AuctionCanForge(forger ethCommon.Address) (bool, error) {
// } // }
// AuctionClaimHEZ is the interface to call the smart contract function // AuctionClaimHEZ is the interface to call the smart contract function
func (c *Client) AuctionClaimHEZ() (tx *types.Transaction, err error) {
func (c *Client) AuctionClaimHEZ(claimAddress ethCommon.Address) (tx *types.Transaction, err error) {
c.rw.Lock() c.rw.Lock()
defer c.rw.Unlock() defer c.rw.Unlock()
cpy := c.nextBlock().copy() cpy := c.nextBlock().copy()

Loading…
Cancel
Save