Browse Source

Merge pull request #158 from hermeznetwork/feature/ethclient8-sc

Update ethclient contracts & add wdelayer events
feature/sql-semaphore1
Eduard S 4 years ago
committed by GitHub
parent
commit
f797e7abcb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 391 additions and 93 deletions
  1. +35
    -8
      eth/auction.go
  2. +45
    -29
      eth/auction_test.go
  3. +3
    -0
      eth/ethereum.go
  4. +63
    -0
      eth/helpers.go
  5. +23
    -7
      eth/main_test.go
  6. +126
    -8
      eth/wdelayer.go
  7. +96
    -41
      eth/wdelayer_test.go

+ 35
- 8
eth/auction.go

@ -281,10 +281,10 @@ type AuctionClient struct {
}
// NewAuctionClient creates a new AuctionClient. `tokenAddress` is the address of the HEZ tokens.
func NewAuctionClient(client *EthereumClient, address, tokenAddress ethCommon.Address) *AuctionClient {
func NewAuctionClient(client *EthereumClient, address, tokenAddress ethCommon.Address) (*AuctionClient, error) {
contractAbi, err := abi.JSON(strings.NewReader(string(HermezAuctionProtocol.HermezAuctionProtocolABI)))
if err != nil {
fmt.Println(err)
return nil, err
}
return &AuctionClient{
client: client,
@ -292,7 +292,7 @@ func NewAuctionClient(client *EthereumClient, address, tokenAddress ethCommon.Ad
tokenAddress: tokenAddress,
gasLimit: 1000000, //nolint:gomnd
contractAbi: contractAbi,
}
}, nil
}
// AuctionSetSlotDeadline is the interface to call the smart contract function
@ -841,6 +841,25 @@ func (c *AuctionClient) AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.
return tx, nil
}
// 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
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.Forge(auth, forger)
},
); err != nil {
return nil, fmt.Errorf("Failed forge: %w", err)
}
return tx, nil
}
// AuctionConstants returns the Constants of the Auction Smart Contract
func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) {
auctionConstants := new(AuctionConstants)
@ -939,9 +958,12 @@ var (
logHEZClaimed = crypto.Keccak256Hash([]byte("HEZClaimed(address,uint128)"))
)
// 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 and the blockHash where the eents happened. If there
// are no events in that block, blockHash is nil.
func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) {
var auctionEvents AuctionEvents
var blockHash ethCommon.Hash
query := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNum),
@ -949,15 +971,20 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e
Addresses: []ethCommon.Address{
c.address,
},
BlockHash: nil, // TODO: Maybe we can put the blockHash here to make sure we get the results from the known block.
Topics: [][]ethCommon.Hash{},
Topics: [][]ethCommon.Hash{},
}
logs, err := c.client.client.FilterLogs(context.TODO(), query)
if err != nil {
fmt.Println(err)
return nil, nil, err
}
if len(logs) > 0 {
blockHash = logs[0].BlockHash
}
for _, vLog := range logs {
if vLog.BlockHash != blockHash {
return nil, nil, ErrBlockHashMismatchEvent
}
switch vLog.Topics[0] {
case logNewBid:
var auxNewBid struct {
@ -1061,5 +1088,5 @@ func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *e
auctionEvents.HEZClaimed = append(auctionEvents.HEZClaimed, HEZClaimed)
}
}
return &auctionEvents, nil, nil
return &auctionEvents, &blockHash, nil
}

+ 45
- 29
eth/auction_test.go

@ -1,7 +1,6 @@
package eth
import (
"context"
"math/big"
"testing"
@ -19,7 +18,8 @@ var allocationRatioConst [3]uint16 = [3]uint16{4000, 4000, 2000}
var auctionClient *AuctionClient
var genesisBlock = 91
//var genesisBlock = 91
var genesisBlock = 98
var minBidStr = "10000000000000000000"
var URL = "http://localhost:3000"
@ -41,7 +41,7 @@ func TestAuctionConstants(t *testing.T) {
require.Nil(t, err)
assert.Equal(t, auctionConstants.BlocksPerSlot, BLOCKSPERSLOT)
// assert.Equal(t, auctionConstants.GenesisBlockNum, GENESISBLOCKNUM)
assert.Equal(t, auctionConstants.HermezRollup, hermezRollupAddressConst)
assert.Equal(t, auctionConstants.HermezRollup, hermezRollupAddressTestConst)
assert.Equal(t, auctionConstants.InitialMinimalBidding, INITMINBID)
assert.Equal(t, auctionConstants.TokenHEZ, tokenHezAddressConst)
}
@ -77,8 +77,8 @@ func TestAuctionSetSlotDeadline(t *testing.T) {
slotDeadline, err := auctionClient.AuctionGetSlotDeadline()
require.Nil(t, err)
assert.Equal(t, newSlotDeadline, slotDeadline)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newSlotDeadline, auctionEvents.NewSlotDeadline[0].NewSlotDeadline)
}
@ -96,8 +96,8 @@ func TestAuctionSetOpenAuctionSlots(t *testing.T) {
openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots()
require.Nil(t, err)
assert.Equal(t, newOpenAuctionSlots, openAuctionSlots)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newOpenAuctionSlots, auctionEvents.NewOpenAuctionSlots[0].NewOpenAuctionSlots)
}
@ -115,8 +115,8 @@ func TestAuctionSetClosedAuctionSlots(t *testing.T) {
closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots()
require.Nil(t, err)
assert.Equal(t, newClosedAuctionSlots, closedAuctionSlots)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newClosedAuctionSlots, auctionEvents.NewClosedAuctionSlots[0].NewClosedAuctionSlots)
_, err = auctionClient.AuctionSetClosedAuctionSlots(closedAuctionSlots)
require.Nil(t, err)
@ -136,8 +136,8 @@ func TestAuctionSetOutbidding(t *testing.T) {
outbidding, err := auctionClient.AuctionGetOutbidding()
require.Nil(t, err)
assert.Equal(t, newOutbidding, outbidding)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newOutbidding, auctionEvents.NewOutbidding[0].NewOutbidding)
_, err = auctionClient.AuctionSetOutbidding(outbiddingConst)
require.Nil(t, err)
@ -157,8 +157,8 @@ func TestAuctionSetAllocationRatio(t *testing.T) {
allocationRatio, err := auctionClient.AuctionGetAllocationRatio()
require.Nil(t, err)
assert.Equal(t, newAllocationRatio, allocationRatio)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newAllocationRatio, auctionEvents.NewAllocationRatio[0].NewAllocationRatio)
_, err = auctionClient.AuctionSetAllocationRatio(allocationRatioConst)
require.Nil(t, err)
@ -184,8 +184,8 @@ func TestAuctionSetDonationAddress(t *testing.T) {
donationAddress, err := auctionClient.AuctionGetDonationAddress()
require.Nil(t, err)
assert.Equal(t, &newDonationAddress, donationAddress)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newDonationAddress, auctionEvents.NewDonationAddress[0].NewDonationAddress)
_, err = auctionClient.AuctionSetDonationAddress(donationAddressConst)
require.Nil(t, err)
@ -199,8 +199,8 @@ func TestAuctionSetBootCoordinator(t *testing.T) {
bootCoordinator, err := auctionClient.AuctionGetBootCoordinator()
require.Nil(t, err)
assert.Equal(t, &newBootCoordinator, bootCoordinator)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, newBootCoordinator, auctionEvents.NewBootCoordinator[0].NewBootCoordinator)
_, err = auctionClient.AuctionSetBootCoordinator(bootCoordinatorAddressConst)
require.Nil(t, err)
@ -233,8 +233,8 @@ func TestAuctionChangeDefaultSlotSetBid(t *testing.T) {
minBid, err := auctionClient.AuctionGetDefaultSlotSetBid(set)
require.Nil(t, err)
assert.Equal(t, minBid, newInitialMinBid)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, slotSet, auctionEvents.NewDefaultSlotSetBid[0].SlotSet)
assert.Equal(t, newInitialMinBid, auctionEvents.NewDefaultSlotSetBid[0].NewInitialMinBid)
newMinBid := new(big.Int)
@ -264,8 +264,8 @@ func TestAuctionRegisterCoordinator(t *testing.T) {
_, err := auctionClient.AuctionRegisterCoordinator(forgerAddress, URL)
require.Nil(t, err)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, forgerAddress, auctionEvents.NewCoordinator[0].ForgerAddress)
assert.Equal(t, forgerAddress, auctionEvents.NewCoordinator[0].WithdrawalAddress)
assert.Equal(t, URL, auctionEvents.NewCoordinator[0].CoordinatorURL)
@ -284,8 +284,8 @@ func TestAuctionUpdateCoordinatorInfo(t *testing.T) {
_, err := auctionClient.AuctionUpdateCoordinatorInfo(forgerAddress, forgerAddress, newURL)
require.Nil(t, err)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, forgerAddress, auctionEvents.CoordinatorUpdated[0].ForgerAddress)
assert.Equal(t, forgerAddress, auctionEvents.CoordinatorUpdated[0].WithdrawalAddress)
assert.Equal(t, newURL, auctionEvents.CoordinatorUpdated[0].CoordinatorURL)
@ -299,8 +299,8 @@ func TestAuctionBid(t *testing.T) {
forgerAddress := governanceAddressConst
_, err = auctionClient.AuctionBid(currentSlot+4, bidAmount, forgerAddress)
require.Nil(t, err)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, bidAmount, auctionEvents.NewBid[0].BidAmount)
assert.Equal(t, forgerAddress, auctionEvents.NewBid[0].CoordinatorForger)
assert.Equal(t, currentSlot+4, auctionEvents.NewBid[0].Slot)
@ -337,8 +337,8 @@ func TestAuctionMultiBid(t *testing.T) {
forgerAddress := governanceAddressConst
_, err = auctionClient.AuctionMultiBid(currentSlot+4, currentSlot+10, slotSet, maxBid, minBid, budget, forgerAddress)
require.Nil(t, err)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, forgerAddress, auctionEvents.NewBid[0].CoordinatorForger)
assert.Equal(t, currentSlot+4, auctionEvents.NewBid[0].Slot)
assert.Equal(t, forgerAddress, auctionEvents.NewBid[1].CoordinatorForger)
@ -365,8 +365,24 @@ func TestAuctionClaimHEZ(t *testing.T) {
_, err := auctionClient.AuctionClaimHEZ(governanceAddressConst)
require.Nil(t, err)
header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil)
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64())
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(currentBlockNum)
assert.Equal(t, amount, auctionEvents.HEZClaimed[0].Amount)
assert.Equal(t, governanceAddressConst, auctionEvents.HEZClaimed[0].Owner)
}
func TestAuctionForge(t *testing.T) {
auctionClientHermez, err := NewAuctionClient(ethereumClientHermez, auctionAddressConst, tokenHezAddressConst)
require.Nil(t, err)
slotConst := 4
blockNum := int64(int(BLOCKSPERSLOT)*slotConst + genesisBlock)
currentBlockNum, _ := auctionClient.client.EthCurrentBlock()
blocksToAdd := blockNum - currentBlockNum
addBlocks(blocksToAdd, ethClientDialURL)
currentBlockNum, _ = auctionClient.client.EthCurrentBlock()
assert.Equal(t, currentBlockNum, blockNum)
_, err = auctionClientHermez.AuctionForge(bootCoordinatorAddressConst)
require.Contains(t, err.Error(), "Can't forge")
_, err = auctionClientHermez.AuctionForge(governanceAddressConst)
require.Nil(t, err)
}

+ 3
- 0
eth/ethereum.go

@ -30,6 +30,9 @@ var (
ErrReceiptStatusFailed = fmt.Errorf("receipt status is failed")
// ErrReceiptNotReceived is used when unable to retrieve a transaction
ErrReceiptNotReceived = fmt.Errorf("receipt not available")
// ErrBlockHashMismatchEvent is used when there's a block hash mismatch
// beetween different events of the same block
ErrBlockHashMismatchEvent = fmt.Errorf("block hash mismatch in event log")
)
const (

+ 63
- 0
eth/helpers.go

@ -0,0 +1,63 @@
package eth
import (
"fmt"
"net/http"
"strconv"
"strings"
)
func addBlock(url string) {
method := "POST"
payload := strings.NewReader("{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_mine\",\n \"params\":[],\n \"id\":1\n}")
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer func() {
if err := res.Body.Close(); err != nil {
fmt.Println("Error when closing:", err)
}
}()
}
func addBlocks(numBlocks int64, url string) {
for i := int64(0); i < numBlocks; i++ {
addBlock(url)
}
}
func addTime(seconds float64, url string) {
secondsStr := strconv.FormatFloat(seconds, 'E', -1, 32)
method := "POST"
payload := strings.NewReader("{\n \"jsonrpc\":\"2.0\",\n \"method\":\"evm_increaseTime\",\n \"params\":[" + secondsStr + "],\n \"id\":1\n}")
client := &http.Client{}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer func() {
if err := res.Body.Close(); err != nil {
fmt.Println("Error when closing:", err)
}
}()
}

+ 23
- 7
eth/main_test.go

@ -19,13 +19,15 @@ var tokenHezStr = os.Getenv("TOKEN_ADDRESS")
var hermezStr = os.Getenv("HERMEZ_ADDRESS")
var governanceAddressStr = os.Getenv("GOV_ADDRESS")
var governancePrivateKey = os.Getenv("GOV_PK")
var ehtClientDialURL = os.Getenv("ETHCLIENT_DIAL_URL")*/
var ehtClientDialURL = "http://localhost:8545"
var ethClientDialURL = os.Getenv("ETHCLIENT_DIAL_URL")*/
var ethClientDialURL = "http://localhost:8545"
var password = "pass"
// Smart Contract Addresses
var (
auctionAddressStr = "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5"
// auctionAddressStr = "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5"
// wdelayerAddressStr = "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8"
auctionAddressStr = "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3"
auctionAddressConst = ethCommon.HexToAddress(auctionAddressStr)
donationAddressStr = "0x6c365935CA8710200C7595F0a72EB6023A7706Cd"
donationAddressConst = ethCommon.HexToAddress(donationAddressStr)
@ -35,7 +37,7 @@ var (
tokenHezAddressConst = ethCommon.HexToAddress(tokenHezAddressStr)
hermezRollupAddressStr = "0xc4905364b78a742ccce7B890A89514061E47068D"
hermezRollupAddressConst = ethCommon.HexToAddress(hermezRollupAddressStr)
wdelayerAddressStr = "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8"
wdelayerAddressStr = "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00"
wdelayerAddressConst = ethCommon.HexToAddress(wdelayerAddressStr)
)
@ -60,6 +62,10 @@ var (
auxAddressSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29089"
auxAddressStr = "0x3d91185a02774C70287F6c74Dd26d13DFB58ff16"
auxAddressConst = ethCommon.HexToAddress(auxAddressStr)
hermezRollupTestSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29088"
hermezRollupTestAddressStr = "0xEa960515F8b4C237730F028cBAcF0a28E7F45dE0"
hermezRollupAddressTestConst = ethCommon.HexToAddress(hermezRollupTestAddressStr)
)
var (
@ -68,12 +74,14 @@ var (
accountWhite *accounts.Account
accountGovDAO *accounts.Account
accountAux *accounts.Account
accountHermez *accounts.Account
ks *keystore.KeyStore
ethClient *ethclient.Client
ethereumClientWhite *EthereumClient
ethereumClientKep *EthereumClient
ethereumClientGovDAO *EthereumClient
ethereumClientAux *EthereumClient
ethereumClientHermez *EthereumClient
)
func addKey(ks *keystore.KeyStore, skHex string) *accounts.Account {
@ -108,8 +116,9 @@ func TestMain(m *testing.M) {
accountWhite = addKey(ks, whiteHackGroupAddressSK)
accountGovDAO = addKey(ks, hermezGovernanceDAOAddressSK)
accountAux = addKey(ks, auxAddressSK)
accountHermez = addKey(ks, hermezRollupTestSK)
ethClient, err = ethclient.Dial(ehtClientDialURL)
ethClient, err = ethclient.Dial(ethClientDialURL)
if err != nil {
panic(err)
}
@ -117,14 +126,21 @@ func TestMain(m *testing.M) {
// Controllable Governance Address
ethereumClientGov := NewEthereumClient(ethClient, accountGov, ks, nil)
auctionClient = NewAuctionClient(ethereumClientGov, auctionAddressConst, tokenHezAddressConst)
auctionClient, err = NewAuctionClient(ethereumClientGov, auctionAddressConst, tokenHezAddressConst)
if err != nil {
panic(err)
}
rollupClient = NewRollupClient(ethereumClientGov, hermezRollupAddressConst)
wdelayerClient = NewWDelayerClient(ethereumClientGov, wdelayerAddressConst)
wdelayerClient, err = NewWDelayerClient(ethereumClientGov, wdelayerAddressConst)
if err != nil {
panic(err)
}
ethereumClientKep = NewEthereumClient(ethClient, accountKep, ks, nil)
ethereumClientWhite = NewEthereumClient(ethClient, accountWhite, ks, nil)
ethereumClientGovDAO = NewEthereumClient(ethClient, accountGovDAO, ks, nil)
ethereumClientAux = NewEthereumClient(ethClient, accountAux, ks, nil)
ethereumClientHermez = NewEthereumClient(ethClient, accountHermez, ks, nil)
exitVal = m.Run()
}

+ 126
- 8
eth/wdelayer.go

@ -1,12 +1,17 @@
package eth
import (
"context"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
WithdrawalDelayer "github.com/hermeznetwork/hermez-node/eth/contracts/withdrawdelayer"
)
@ -128,18 +133,24 @@ type WDelayerInterface interface {
// WDelayerClient is the implementation of the interface to the WithdrawDelayer Smart Contract in ethereum.
type WDelayerClient struct {
client *EthereumClient
address ethCommon.Address
gasLimit uint64
client *EthereumClient
address ethCommon.Address
gasLimit uint64
contractAbi abi.ABI
}
// NewWDelayerClient creates a new WDelayerClient
func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) *WDelayerClient {
return &WDelayerClient{
client: client,
address: address,
gasLimit: 1000000, //nolint:gomnd
func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) (*WDelayerClient, error) {
contractAbi, err := abi.JSON(strings.NewReader(string(WithdrawalDelayer.WithdrawalDelayerABI)))
if err != nil {
return nil, err
}
return &WDelayerClient{
client: client,
address: address,
gasLimit: 1000000, //nolint:gomnd
contractAbi: contractAbi,
}, nil
}
// WDelayerGetHermezGovernanceDAOAddress is the interface to call the smart contract function
@ -407,3 +418,110 @@ func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Addre
}
return tx, nil
}
var (
logDeposit = crypto.Keccak256Hash([]byte("Deposit(address,address,uint192,uint64)"))
logWithdraw = crypto.Keccak256Hash([]byte("Withdraw(address,address,uint192)"))
logEmergencyModeEnabled = crypto.Keccak256Hash([]byte("EmergencyModeEnabled()"))
logNewWithdrawalDelay = crypto.Keccak256Hash([]byte("NewWithdrawalDelay(uint64)"))
logEscapeHatchWithdrawal = crypto.Keccak256Hash([]byte("EscapeHatchWithdrawal(address,address,address)"))
logNewHermezKeeperAddress = crypto.Keccak256Hash([]byte("NewHermezKeeperAddress(address)"))
logNewWhiteHackGroupAddress = crypto.Keccak256Hash([]byte("NewWhiteHackGroupAddress(address)"))
logNewHermezGovernanceDAOAddress = crypto.Keccak256Hash([]byte("NewHermezGovernanceDAOAddress(address)"))
)
// WDelayerEventsByBlock returns the events in a block that happened in the
// WDelayer Smart Contract and the blockHash where the eents happened. If
// there are no events in that block, blockHash is nil.
func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) {
var wdelayerEvents WDelayerEvents
var blockHash ethCommon.Hash
query := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNum),
ToBlock: big.NewInt(blockNum),
Addresses: []ethCommon.Address{
c.address,
},
BlockHash: nil,
Topics: [][]ethCommon.Hash{},
}
logs, err := c.client.client.FilterLogs(context.Background(), query)
if err != nil {
return nil, nil, err
}
if len(logs) > 0 {
blockHash = logs[0].BlockHash
}
for _, vLog := range logs {
if vLog.BlockHash != blockHash {
return nil, nil, ErrBlockHashMismatchEvent
}
switch vLog.Topics[0] {
case logDeposit:
var deposit WDelayerEventDeposit
err := c.contractAbi.Unpack(&deposit, "Deposit", vLog.Data)
if err != nil {
return nil, nil, err
}
deposit.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
deposit.Token = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
wdelayerEvents.Deposit = append(wdelayerEvents.Deposit, deposit)
case logWithdraw:
var withdraw WDelayerEventWithdraw
err := c.contractAbi.Unpack(&withdraw, "Withdraw", vLog.Data)
if err != nil {
return nil, nil, err
}
withdraw.Token = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
withdraw.Owner = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
wdelayerEvents.Withdraw = append(wdelayerEvents.Withdraw, withdraw)
case logEmergencyModeEnabled:
var emergencyModeEnabled WDelayerEventEmergencyModeEnabled
wdelayerEvents.EmergencyModeEnabled = append(wdelayerEvents.EmergencyModeEnabled, emergencyModeEnabled)
case logNewWithdrawalDelay:
var withdrawalDelay WDelayerEventNewWithdrawalDelay
err := c.contractAbi.Unpack(&withdrawalDelay, "NewWithdrawalDelay", vLog.Data)
if err != nil {
return nil, nil, err
}
wdelayerEvents.NewWithdrawalDelay = append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay)
case logEscapeHatchWithdrawal:
var escapeHatchWithdrawal WDelayerEventEscapeHatchWithdrawal
escapeHatchWithdrawal.Who = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
escapeHatchWithdrawal.To = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
escapeHatchWithdrawal.Token = ethCommon.BytesToAddress(vLog.Topics[3].Bytes())
wdelayerEvents.EscapeHatchWithdrawal = append(wdelayerEvents.EscapeHatchWithdrawal, escapeHatchWithdrawal)
case logNewHermezKeeperAddress:
var keeperAddress WDelayerEventNewHermezKeeperAddress
err := c.contractAbi.Unpack(&keeperAddress, "NewHermezKeeperAddress", vLog.Data)
if err != nil {
return nil, nil, err
}
wdelayerEvents.NewHermezKeeperAddress = append(wdelayerEvents.NewHermezKeeperAddress, keeperAddress)
case logNewWhiteHackGroupAddress:
var whiteHackGroupAddress WDelayerEventNewWhiteHackGroupAddress
err := c.contractAbi.Unpack(&whiteHackGroupAddress, "NewWhiteHackGroupAddress", vLog.Data)
if err != nil {
return nil, nil, err
}
wdelayerEvents.NewWhiteHackGroupAddress = append(wdelayerEvents.NewWhiteHackGroupAddress, whiteHackGroupAddress)
case logNewHermezGovernanceDAOAddress:
var governanceDAOAddress WDelayerEventNewHermezGovernanceDAOAddress
err := c.contractAbi.Unpack(&governanceDAOAddress, "NewHermezGovernanceDAOAddress", vLog.Data)
if err != nil {
return nil, nil, err
}
wdelayerEvents.NewHermezGovernanceDAOAddress = append(wdelayerEvents.NewHermezGovernanceDAOAddress, governanceDAOAddress)
}
}
return &wdelayerEvents, &blockHash, nil
}

+ 96
- 41
eth/wdelayer_test.go

@ -3,6 +3,7 @@ package eth
import (
"math/big"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -14,6 +15,7 @@ var wdelayerClient *WDelayerClient
var initWithdrawalDelay = big.NewInt(60)
var newWithdrawalDelay = big.NewInt(79)
var maxEmergencyModeTime = time.Hour * 24 * 7 * 26
func TestWDelayerGetHermezGovernanceDAOAddress(t *testing.T) {
governanceAddress, err := wdelayerClient.WDelayerGetHermezGovernanceDAOAddress()
@ -22,13 +24,18 @@ func TestWDelayerGetHermezGovernanceDAOAddress(t *testing.T) {
}
func TestWDelayerSetHermezGovernanceDAOAddress(t *testing.T) {
wdelayerClientGov := NewWDelayerClient(ethereumClientGovDAO, wdelayerAddressConst)
_, err := wdelayerClientGov.WDelayerSetHermezGovernanceDAOAddress(auxAddressConst)
wdelayerClientGov, err := NewWDelayerClient(ethereumClientGovDAO, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientGov.WDelayerSetHermezGovernanceDAOAddress(auxAddressConst)
require.Nil(t, err)
auxAddress, err := wdelayerClient.WDelayerGetHermezGovernanceDAOAddress()
require.Nil(t, err)
assert.Equal(t, &auxAddressConst, auxAddress)
wdelayerClientAux := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, auxAddressConst, wdelayerEvents.NewHermezGovernanceDAOAddress[0].NewHermezGovernanceDAOAddress)
wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientAux.WDelayerSetHermezGovernanceDAOAddress(hermezGovernanceDAOAddressConst)
require.Nil(t, err)
}
@ -40,13 +47,18 @@ func TestWDelayerGetHermezKeeperAddress(t *testing.T) {
}
func TestWDelayerSetHermezKeeperAddress(t *testing.T) {
wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
_, err := wdelayerClientKep.WDelayerSetHermezKeeperAddress(auxAddressConst)
wdelayerClientKep, err := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientKep.WDelayerSetHermezKeeperAddress(auxAddressConst)
require.Nil(t, err)
auxAddress, err := wdelayerClient.WDelayerGetHermezKeeperAddress()
require.Nil(t, err)
assert.Equal(t, &auxAddressConst, auxAddress)
wdelayerClientAux := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, auxAddressConst, wdelayerEvents.NewHermezKeeperAddress[0].NewHermezKeeperAddress)
wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientAux.WDelayerSetHermezKeeperAddress(hermezKeeperAddressConst)
require.Nil(t, err)
}
@ -58,13 +70,18 @@ func TestWDelayerGetWhiteHackGroupAddress(t *testing.T) {
}
func TestWDelayerSetWhiteHackGroupAddress(t *testing.T) {
wdelayerClientWhite := NewWDelayerClient(ethereumClientWhite, wdelayerAddressConst)
_, err := wdelayerClientWhite.WDelayerSetWhiteHackGroupAddress(auxAddressConst)
wdelayerClientWhite, err := NewWDelayerClient(ethereumClientWhite, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientWhite.WDelayerSetWhiteHackGroupAddress(auxAddressConst)
require.Nil(t, err)
auxAddress, err := wdelayerClient.WDelayerGetWhiteHackGroupAddress()
require.Nil(t, err)
assert.Equal(t, &auxAddressConst, auxAddress)
wdelayerClientAux := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, auxAddressConst, wdelayerEvents.NewWhiteHackGroupAddress[0].NewWhiteHackGroupAddress)
wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientAux.WDelayerSetWhiteHackGroupAddress(whiteHackGroupAddressConst)
require.Nil(t, err)
}
@ -81,22 +98,68 @@ func TestWDelayerGetWithdrawalDelay(t *testing.T) {
assert.Equal(t, initWithdrawalDelay, withdrawalDelay)
}
func TestWDelayerEnableEmergencyMode(t *testing.T) {
wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
_, err := wdelayerClientKep.WDelayerEnableEmergencyMode()
func TestWDelayerChangeWithdrawalDelay(t *testing.T) {
wdelayerClientKep, err := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
require.Nil(t, err)
emergencyMode, err := wdelayerClient.WDelayerIsEmergencyMode()
_, err = wdelayerClientKep.WDelayerChangeWithdrawalDelay(newWithdrawalDelay.Uint64())
require.Nil(t, err)
assert.Equal(t, true, emergencyMode)
withdrawalDelay, err := wdelayerClient.WDelayerGetWithdrawalDelay()
require.Nil(t, err)
assert.Equal(t, newWithdrawalDelay, withdrawalDelay)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, newWithdrawalDelay.Uint64(), wdelayerEvents.NewWithdrawalDelay[0].WithdrawalDelay)
}
func TestWDelayerChangeWithdrawalDelay(t *testing.T) {
wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
_, err := wdelayerClientKep.WDelayerChangeWithdrawalDelay(newWithdrawalDelay.Uint64())
func TestWDelayerDeposit(t *testing.T) {
amount := new(big.Int)
amount.SetString("1100000000000000000", 10)
wdelayerClientHermez, err := NewWDelayerClient(ethereumClientHermez, wdelayerAddressConst)
require.Nil(t, err)
withdrawalDelay, err := wdelayerClient.WDelayerGetWithdrawalDelay()
_, err = wdelayerClientHermez.WDelayerDeposit(auxAddressConst, tokenHezAddressConst, amount)
require.Nil(t, err)
assert.Equal(t, newWithdrawalDelay, withdrawalDelay)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, amount, wdelayerEvents.Deposit[0].Amount)
assert.Equal(t, auxAddressConst, wdelayerEvents.Deposit[0].Owner)
assert.Equal(t, tokenHezAddressConst, wdelayerEvents.Deposit[0].Token)
}
func TestWDelayerDepositInfo(t *testing.T) {
amount := new(big.Int)
amount.SetString("1100000000000000000", 10)
state, err := wdelayerClient.WDelayerDepositInfo(auxAddressConst, tokenHezAddressConst)
require.Nil(t, err)
assert.Equal(t, state.Amount, amount)
}
func TestWDelayerWithdrawal(t *testing.T) {
amount := new(big.Int)
amount.SetString("1100000000000000000", 10)
_, err := wdelayerClient.WDelayerWithdrawal(auxAddressConst, tokenHezAddressConst)
require.Contains(t, err.Error(), "Withdrawal not allowed yet")
addBlocks(newWithdrawalDelay.Int64(), ethClientDialURL)
_, err = wdelayerClient.WDelayerWithdrawal(auxAddressConst, tokenHezAddressConst)
require.Nil(t, err)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, amount, wdelayerEvents.Withdraw[0].Amount)
assert.Equal(t, auxAddressConst, wdelayerEvents.Withdraw[0].Owner)
assert.Equal(t, tokenHezAddressConst, wdelayerEvents.Withdraw[0].Token)
}
func TestWDelayerEnableEmergencyMode(t *testing.T) {
wdelayerClientKep, err := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientKep.WDelayerEnableEmergencyMode()
require.Nil(t, err)
emergencyMode, err := wdelayerClient.WDelayerIsEmergencyMode()
require.Nil(t, err)
assert.Equal(t, true, emergencyMode)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
auxEvent := new(WDelayerEventEmergencyModeEnabled)
assert.Equal(t, auxEvent, &wdelayerEvents.EmergencyModeEnabled[0])
}
func TestWDelayerGetEmergencyModeStartingTime(t *testing.T) {
@ -109,26 +172,18 @@ func TestWDelayerGetEmergencyModeStartingTime(t *testing.T) {
assert.True(t, emergencyModeStartingTime.Cmp(big.NewInt(0)) == 1)
}
/* func TestWDelayerDeposit(t *testing.T) {
if wdelayerClient != nil {
}
}
func TestWDelayerDepositInfo(t *testing.T) {
if wdelayerClient != nil {
}
}
func TestWDelayerWithdrawal(t *testing.T) {
if wdelayerClient != nil {
}
}
func TestWDelayerEscapeHatchWithdrawal(t *testing.T) {
if wdelayerClient != nil {
}
} */
wdelayerClientWhite, err := NewWDelayerClient(ethereumClientWhite, wdelayerAddressConst)
require.Nil(t, err)
_, err = wdelayerClientWhite.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHezAddressConst)
require.Contains(t, err.Error(), "NO MAX_EMERGENCY_MODE_TIME")
seconds := maxEmergencyModeTime.Seconds()
addTime(seconds, ethClientDialURL)
_, err = wdelayerClientWhite.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHezAddressConst)
require.Nil(t, err)
currentBlockNum, _ := wdelayerClient.client.EthCurrentBlock()
wdelayerEvents, _, _ := wdelayerClient.WDelayerEventsByBlock(currentBlockNum)
assert.Equal(t, tokenHezAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].Token)
assert.Equal(t, governanceAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].To)
assert.Equal(t, whiteHackGroupAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].Who)
}

Loading…
Cancel
Save