diff --git a/eth/auction.go b/eth/auction.go index 668aabc..2b7a329 100644 --- a/eth/auction.go +++ b/eth/auction.go @@ -1,17 +1,21 @@ package eth import ( + "context" "encoding/binary" "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" HermezAuctionProtocol "github.com/hermeznetwork/hermez-node/eth/contracts/auction" ERC777 "github.com/hermeznetwork/hermez-node/eth/contracts/erc777" - "github.com/hermeznetwork/hermez-node/log" "golang.org/x/crypto/sha3" ) @@ -132,14 +136,14 @@ type AuctionEventNewAllocationRatio struct { type AuctionEventNewCoordinator struct { ForgerAddress ethCommon.Address WithdrawalAddress ethCommon.Address - URL string + CoordinatorURL string } // AuctionEventCoordinatorUpdated is an event of the Auction Smart Contract type AuctionEventCoordinatorUpdated struct { ForgerAddress ethCommon.Address WithdrawalAddress ethCommon.Address - URL string + CoordinatorURL string } // AuctionEventNewForgeAllocated is an event of the Auction Smart Contract @@ -239,6 +243,8 @@ type AuctionInterface interface { AuctionGetCurrentSlotNumber() (int64, error) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) + AuctionGetSlotSet(slot int64) (*big.Int, error) + AuctionGetSlotNumber(blockNum int64) (*big.Int, error) // Bidding // AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, @@ -271,15 +277,21 @@ type AuctionClient struct { address ethCommon.Address tokenAddress ethCommon.Address gasLimit uint64 + contractAbi abi.ABI } // NewAuctionClient creates a new AuctionClient. `tokenAddress` is the address of the HEZ tokens. func NewAuctionClient(client *EthereumClient, address, tokenAddress ethCommon.Address) *AuctionClient { + contractAbi, err := abi.JSON(strings.NewReader(string(HermezAuctionProtocol.HermezAuctionProtocolABI))) + if err != nil { + fmt.Println(err) + } return &AuctionClient{ client: client, address: address, tokenAddress: tokenAddress, gasLimit: 1000000, //nolint:gomnd + contractAbi: contractAbi, } } @@ -685,10 +697,22 @@ func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, er return minBidSlotSet, nil } -// AuctionTokensReceived is the interface to call the smart contract function -// func (c *AuctionClient) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error { -// return errTODO -// } +// AuctionGetSlotNumber is the interface to call the smart contract function +func (c *AuctionClient) AuctionGetSlotNumber(blockNum int64) (*big.Int, error) { + var slot *big.Int + if err := c.client.Call(func(ec *ethclient.Client) error { + auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec) + if err != nil { + return err + } + blockNumBig := big.NewInt(blockNum) + slot, err = auction.GetSlotNumber(nil, blockNumBig) + return err + }); err != nil { + return big.NewInt(0), err + } + return slot, nil +} // AuctionBid is the interface to call the smart contract function func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int, forger ethCommon.Address) (*types.Transaction, error) { @@ -898,8 +922,144 @@ func (c *AuctionClient) AuctionVariables() (*AuctionVariables, error) { return auctionVariables, nil } +var ( + logNewBid = crypto.Keccak256Hash([]byte("NewBid(uint128,uint128,address)")) + logNewSlotDeadline = crypto.Keccak256Hash([]byte("NewSlotDeadline(uint8)")) + logNewClosedAuctionSlots = crypto.Keccak256Hash([]byte("NewClosedAuctionSlots(uint16)")) + logNewOutbidding = crypto.Keccak256Hash([]byte("NewOutbidding(uint16)")) + logNewDonationAddress = crypto.Keccak256Hash([]byte("NewDonationAddress(address)")) + logNewBootCoordinator = crypto.Keccak256Hash([]byte("NewBootCoordinator(address)")) + logNewOpenAuctionSlots = crypto.Keccak256Hash([]byte("NewOpenAuctionSlots(uint16)")) + logNewAllocationRatio = crypto.Keccak256Hash([]byte("NewAllocationRatio(uint16[3])")) + logNewCoordinator = crypto.Keccak256Hash([]byte("NewCoordinator(address,address,string)")) + logCoordinatorUpdated = crypto.Keccak256Hash([]byte("CoordinatorUpdated(address,address,string)")) + logNewForgeAllocated = crypto.Keccak256Hash([]byte("NewForgeAllocated(address,uint128,uint128,uint128,uint128)")) + logNewDefaultSlotSetBid = crypto.Keccak256Hash([]byte("NewDefaultSlotSetBid(uint128,uint128)")) + logNewForge = crypto.Keccak256Hash([]byte("NewForge(address,uint128)")) + logHEZClaimed = crypto.Keccak256Hash([]byte("HEZClaimed(address,uint128)")) +) + // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) { - log.Error("TODO") - return nil, nil, errTODO + var auctionEvents AuctionEvents + + query := ethereum.FilterQuery{ + FromBlock: big.NewInt(blockNum), + ToBlock: big.NewInt(blockNum), + 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{}, + } + + logs, err := c.client.client.FilterLogs(context.TODO(), query) + if err != nil { + fmt.Println(err) + } + for _, vLog := range logs { + switch vLog.Topics[0] { + case logNewBid: + var auxNewBid struct { + Slot *big.Int + BidAmount *big.Int + Address ethCommon.Address + } + var newBid AuctionEventNewBid + if err := c.contractAbi.Unpack(&auxNewBid, "NewBid", vLog.Data); err != nil { + return nil, nil, err + } + newBid.BidAmount = auxNewBid.BidAmount + newBid.Slot = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64() + newBid.CoordinatorForger = ethCommon.BytesToAddress(vLog.Topics[2].Bytes()) + auctionEvents.NewBid = append(auctionEvents.NewBid, newBid) + case logNewSlotDeadline: + var newSlotDeadline AuctionEventNewSlotDeadline + if err := c.contractAbi.Unpack(&newSlotDeadline, "NewSlotDeadline", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewSlotDeadline = append(auctionEvents.NewSlotDeadline, newSlotDeadline) + case logNewClosedAuctionSlots: + var newClosedAuctionSlots AuctionEventNewClosedAuctionSlots + if err := c.contractAbi.Unpack(&newClosedAuctionSlots, "NewClosedAuctionSlots", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewClosedAuctionSlots = append(auctionEvents.NewClosedAuctionSlots, newClosedAuctionSlots) + case logNewOutbidding: + var newOutbidding AuctionEventNewOutbidding + if err := c.contractAbi.Unpack(&newOutbidding, "NewOutbidding", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewOutbidding = append(auctionEvents.NewOutbidding, newOutbidding) + case logNewDonationAddress: + var newDonationAddress AuctionEventNewDonationAddress + if err := c.contractAbi.Unpack(&newDonationAddress, "NewDonationAddress", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewDonationAddress = append(auctionEvents.NewDonationAddress, newDonationAddress) + case logNewBootCoordinator: + var newBootCoordinator AuctionEventNewBootCoordinator + if err := c.contractAbi.Unpack(&newBootCoordinator, "NewBootCoordinator", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewBootCoordinator = append(auctionEvents.NewBootCoordinator, newBootCoordinator) + case logNewOpenAuctionSlots: + var newOpenAuctionSlots AuctionEventNewOpenAuctionSlots + if err := c.contractAbi.Unpack(&newOpenAuctionSlots, "NewOpenAuctionSlots", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewOpenAuctionSlots = append(auctionEvents.NewOpenAuctionSlots, newOpenAuctionSlots) + case logNewAllocationRatio: + var newAllocationRatio AuctionEventNewAllocationRatio + if err := c.contractAbi.Unpack(&newAllocationRatio, "NewAllocationRatio", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewAllocationRatio = append(auctionEvents.NewAllocationRatio, newAllocationRatio) + case logNewCoordinator: + var newCoordinator AuctionEventNewCoordinator + if err := c.contractAbi.Unpack(&newCoordinator, "NewCoordinator", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.NewCoordinator = append(auctionEvents.NewCoordinator, newCoordinator) + case logCoordinatorUpdated: + var coordinatorUpdated AuctionEventCoordinatorUpdated + if err := c.contractAbi.Unpack(&coordinatorUpdated, "CoordinatorUpdated", vLog.Data); err != nil { + return nil, nil, err + } + auctionEvents.CoordinatorUpdated = append(auctionEvents.CoordinatorUpdated, coordinatorUpdated) + case logNewForgeAllocated: + var newForgeAllocated AuctionEventNewForgeAllocated + if err := c.contractAbi.Unpack(&newForgeAllocated, "NewForgeAllocated", vLog.Data); err != nil { + return nil, nil, err + } + newForgeAllocated.Forger = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) + newForgeAllocated.CurrentSlot = new(big.Int).SetBytes(vLog.Topics[2][:]).Int64() + auctionEvents.NewForgeAllocated = append(auctionEvents.NewForgeAllocated, newForgeAllocated) + case logNewDefaultSlotSetBid: + var auxNewDefaultSlotSetBid struct { + SlotSet *big.Int + NewInitialMinBid *big.Int + } + var newDefaultSlotSetBid AuctionEventNewDefaultSlotSetBid + if err := c.contractAbi.Unpack(&auxNewDefaultSlotSetBid, "NewDefaultSlotSetBid", vLog.Data); err != nil { + return nil, nil, err + } + newDefaultSlotSetBid.NewInitialMinBid = auxNewDefaultSlotSetBid.NewInitialMinBid + newDefaultSlotSetBid.SlotSet = auxNewDefaultSlotSetBid.SlotSet.Int64() + auctionEvents.NewDefaultSlotSetBid = append(auctionEvents.NewDefaultSlotSetBid, newDefaultSlotSetBid) + case logNewForge: + var newForge AuctionEventNewForge + newForge.Forger = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) + newForge.CurrentSlot = new(big.Int).SetBytes(vLog.Topics[2][:]).Int64() + auctionEvents.NewForge = append(auctionEvents.NewForge, newForge) + case logHEZClaimed: + var HEZClaimed AuctionEventHEZClaimed + if err := c.contractAbi.Unpack(&HEZClaimed, "HEZClaimed", vLog.Data); err != nil { + return nil, nil, err + } + HEZClaimed.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes()) + auctionEvents.HEZClaimed = append(auctionEvents.HEZClaimed, HEZClaimed) + } + } + return &auctionEvents, nil, nil } diff --git a/eth/auction_test.go b/eth/auction_test.go index 6670a53..d942e82 100644 --- a/eth/auction_test.go +++ b/eth/auction_test.go @@ -1,15 +1,10 @@ package eth import ( - "io/ioutil" + "context" "math/big" - "os" "testing" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -24,264 +19,207 @@ var allocationRatioConst [3]uint16 = [3]uint16{4000, 4000, 2000} var auctionClient *AuctionClient -/*var donationAddressStr = os.Getenv("DONATION_ADDRESS") -var bootCoordinatorStr = os.Getenv("BOOT_COORDINATOR_ADDRESS") -var auctionAddressStr = os.Getenv("AUCTION_ADDRESS") -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 integration = os.Getenv("INTEGRATION") - -var donationAddressStr = "0x6c365935CA8710200C7595F0a72EB6023A7706Cd" -var bootCoordinatorStr = "0xc783df8a850f42e7f7e57013759c285caa701eb6" -var auctionAddressStr = "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5" -var tokenHezStr = "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c" //nolint:gosec -var hermezStr = "0xc4905364b78a742ccce7B890A89514061E47068D" -var governanceAddressStr = "0xead9c93b79ae7c1591b1fb5323bd777e86e150d4" -var governancePrivateKey = "d49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb" -var ehtClientDialURL = "http://localhost:8545" -var DONATION = common.HexToAddress(donationAddressStr) -var BOOTCOORDINATOR = common.HexToAddress(bootCoordinatorStr) -var TOKENHEZ = common.HexToAddress(tokenHezStr) -var HERMEZROLLUP = common.HexToAddress(hermezStr) +var genesisBlock = 91 var minBidStr = "10000000000000000000" var URL = "http://localhost:3000" var newURL = "http://localhost:3002" var BLOCKSPERSLOT = uint8(40) -var password = "pass" - -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) - tokenAddress := common.HexToAddress(tokenHezStr) - if integration != "" { - auctionClient = NewAuctionClient(ethereumClient, auctionAddress, tokenAddress) - } -} func TestAuctionGetCurrentSlotNumber(t *testing.T) { - if auctionClient != nil { - currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber() - require.Nil(t, err) - currentSlotInt := int(currentSlot) - assert.Equal(t, currentSlotConst, currentSlotInt) - } + 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) - } + + 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, hermezRollupAddressConst) + assert.Equal(t, auctionConstants.InitialMinimalBidding, INITMINBID) + assert.Equal(t, auctionConstants.TokenHEZ, tokenHezAddressConst) } 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) - } + + auctionVariables, err := auctionClient.AuctionVariables() + require.Nil(t, err) + assert.Equal(t, auctionVariables.AllocationRatio, allocationRatioConst) + assert.Equal(t, auctionVariables.BootCoordinator, bootCoordinatorAddressConst) + assert.Equal(t, auctionVariables.ClosedAuctionSlots, closedAuctionSlotsConst) + assert.Equal(t, auctionVariables.DefaultSlotSetBid, defaultSlotSetBid) + assert.Equal(t, auctionVariables.DonationAddress, donationAddressConst) + assert.Equal(t, auctionVariables.OpenAuctionSlots, openAuctionSlotsConst) + assert.Equal(t, auctionVariables.Outbidding, outbiddingConst) + assert.Equal(t, auctionVariables.SlotDeadline, slotDeadlineConst) } func TestAuctionGetSlotDeadline(t *testing.T) { - if auctionClient != nil { - slotDeadline, err := auctionClient.AuctionGetSlotDeadline() - require.Nil(t, err) - assert.Equal(t, slotDeadlineConst, slotDeadline) - } + slotDeadline, err := auctionClient.AuctionGetSlotDeadline() + require.Nil(t, err) + assert.Equal(t, slotDeadlineConst, slotDeadline) } 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) - } + + _, err := auctionClient.AuctionSetSlotDeadline(newSlotDeadline) + require.Nil(t, err) + 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()) + assert.Equal(t, newSlotDeadline, auctionEvents.NewSlotDeadline[0].NewSlotDeadline) } func TestAuctionGetOpenAuctionSlots(t *testing.T) { - if auctionClient != nil { - openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots() - require.Nil(t, err) - assert.Equal(t, openAuctionSlotsConst, openAuctionSlots) - } + openAuctionSlots, err := auctionClient.AuctionGetOpenAuctionSlots() + require.Nil(t, err) + 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) - } + + _, err := auctionClient.AuctionSetOpenAuctionSlots(newOpenAuctionSlots) + require.Nil(t, err) + 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()) + assert.Equal(t, newOpenAuctionSlots, auctionEvents.NewOpenAuctionSlots[0].NewOpenAuctionSlots) } func TestAuctionGetClosedAuctionSlots(t *testing.T) { - if auctionClient != nil { - closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots() - require.Nil(t, err) - assert.Equal(t, closedAuctionSlotsConst, closedAuctionSlots) - } + closedAuctionSlots, err := auctionClient.AuctionGetClosedAuctionSlots() + require.Nil(t, err) + 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) - } + newClosedAuctionSlots := uint16(1) + + _, err := auctionClient.AuctionSetClosedAuctionSlots(newClosedAuctionSlots) + require.Nil(t, err) + 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()) + assert.Equal(t, newClosedAuctionSlots, auctionEvents.NewClosedAuctionSlots[0].NewClosedAuctionSlots) + _, err = auctionClient.AuctionSetClosedAuctionSlots(closedAuctionSlots) + require.Nil(t, err) } func TestAuctionGetOutbidding(t *testing.T) { - if auctionClient != nil { - outbidding, err := auctionClient.AuctionGetOutbidding() - require.Nil(t, err) - assert.Equal(t, outbiddingConst, outbidding) - } + outbidding, err := auctionClient.AuctionGetOutbidding() + require.Nil(t, err) + 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) - } + + _, err := auctionClient.AuctionSetOutbidding(newOutbidding) + require.Nil(t, err) + 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()) + assert.Equal(t, newOutbidding, auctionEvents.NewOutbidding[0].NewOutbidding) + _, err = auctionClient.AuctionSetOutbidding(outbiddingConst) + require.Nil(t, err) } func TestAuctionGetAllocationRatio(t *testing.T) { - if auctionClient != nil { - allocationRatio, err := auctionClient.AuctionGetAllocationRatio() - require.Nil(t, err) - assert.Equal(t, allocationRatioConst, allocationRatio) - } + allocationRatio, err := auctionClient.AuctionGetAllocationRatio() + require.Nil(t, err) + assert.Equal(t, allocationRatioConst, allocationRatio) } 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) - } + + _, err := auctionClient.AuctionSetAllocationRatio(newAllocationRatio) + require.Nil(t, err) + 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()) + assert.Equal(t, newAllocationRatio, auctionEvents.NewAllocationRatio[0].NewAllocationRatio) + _, err = auctionClient.AuctionSetAllocationRatio(allocationRatioConst) + require.Nil(t, err) } func TestAuctionGetDonationAddress(t *testing.T) { - if auctionClient != nil { - donationAddress, err := auctionClient.AuctionGetDonationAddress() - require.Nil(t, err) - donationAddressConst := common.HexToAddress(donationAddressStr) - assert.Equal(t, &donationAddressConst, donationAddress) - } + donationAddress, err := auctionClient.AuctionGetDonationAddress() + require.Nil(t, err) + assert.Equal(t, &donationAddressConst, donationAddress) } func TestAuctionGetBootCoordinator(t *testing.T) { - if auctionClient != nil { - bootCoordinator, err := auctionClient.AuctionGetBootCoordinator() - require.Nil(t, err) - bootCoordinatorConst := common.HexToAddress(bootCoordinatorStr) - assert.Equal(t, &bootCoordinatorConst, bootCoordinator) - } + bootCoordinator, err := auctionClient.AuctionGetBootCoordinator() + require.Nil(t, err) + assert.Equal(t, &bootCoordinatorAddressConst, bootCoordinator) } func TestAuctionSetDonationAddress(t *testing.T) { - newDonationAddress := common.HexToAddress(governanceAddressStr) - if auctionClient != nil { - _, 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) - } + newDonationAddress := governanceAddressConst + + _, err := auctionClient.AuctionSetDonationAddress(newDonationAddress) + require.Nil(t, err) + 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()) + assert.Equal(t, newDonationAddress, auctionEvents.NewDonationAddress[0].NewDonationAddress) + _, 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) - } + newBootCoordinator := governanceAddressConst + + _, err := auctionClient.AuctionSetBootCoordinator(newBootCoordinator) + require.Nil(t, err) + 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()) + assert.Equal(t, newBootCoordinator, auctionEvents.NewBootCoordinator[0].NewBootCoordinator) + _, err = auctionClient.AuctionSetBootCoordinator(bootCoordinatorAddressConst) + require.Nil(t, err) } func TestAuctionGetSlotSet(t *testing.T) { slot := int64(10) - if auctionClient != nil { - slotSet, err := auctionClient.AuctionGetSlotSet(slot) - require.Nil(t, err) - assert.Equal(t, slotSet, big.NewInt(4)) - } + + slotSet, err := auctionClient.AuctionGetSlotSet(slot) + require.Nil(t, err) + assert.Equal(t, slotSet, big.NewInt(4)) } 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) - } + + minBid, err := auctionClient.AuctionGetDefaultSlotSetBid(slotSet) + require.Nil(t, err) + assert.Equal(t, minBid.String(), minBidStr) } func TestAuctionChangeDefaultSlotSetBid(t *testing.T) { @@ -289,87 +227,146 @@ func TestAuctionChangeDefaultSlotSetBid(t *testing.T) { 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) - } + + _, err := auctionClient.AuctionChangeDefaultSlotSetBid(slotSet, newInitialMinBid) + require.Nil(t, err) + 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()) + assert.Equal(t, slotSet, auctionEvents.NewDefaultSlotSetBid[0].SlotSet) + assert.Equal(t, newInitialMinBid, auctionEvents.NewDefaultSlotSetBid[0].NewInitialMinBid) + newMinBid := new(big.Int) + newMinBid.SetString("10000000000000000000", 10) + _, err = auctionClient.AuctionChangeDefaultSlotSetBid(slotSet, newMinBid) + require.Nil(t, err) } func TestAuctionGetClaimableHEZ(t *testing.T) { - forgerAddress := common.HexToAddress(governanceAddressStr) - if auctionClient != nil { - claimableHEZ, err := auctionClient.AuctionGetClaimableHEZ(forgerAddress) - require.Nil(t, err) - assert.Equal(t, claimableHEZ.Int64(), int64(0)) - } + forgerAddress := governanceAddressConst + + claimableHEZ, err := auctionClient.AuctionGetClaimableHEZ(forgerAddress) + require.Nil(t, err) + assert.Equal(t, claimableHEZ.Int64(), int64(0)) } 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) - } + forgerAddress := governanceAddressConst + + 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) - } + forgerAddress := governanceAddressConst + + _, err := auctionClient.AuctionRegisterCoordinator(forgerAddress, URL) + require.Nil(t, err) + header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil) + auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64()) + assert.Equal(t, forgerAddress, auctionEvents.NewCoordinator[0].ForgerAddress) + assert.Equal(t, forgerAddress, auctionEvents.NewCoordinator[0].WithdrawalAddress) + assert.Equal(t, URL, auctionEvents.NewCoordinator[0].CoordinatorURL) } 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) - } + forgerAddress := governanceAddressConst + + 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) - } + forgerAddress := governanceAddressConst + + _, err := auctionClient.AuctionUpdateCoordinatorInfo(forgerAddress, forgerAddress, newURL) + require.Nil(t, err) + header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil) + auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64()) + assert.Equal(t, forgerAddress, auctionEvents.CoordinatorUpdated[0].ForgerAddress) + assert.Equal(t, forgerAddress, auctionEvents.CoordinatorUpdated[0].WithdrawalAddress) + assert.Equal(t, newURL, auctionEvents.CoordinatorUpdated[0].CoordinatorURL) } func TestAuctionBid(t *testing.T) { - if auctionClient != nil { - currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber() - require.Nil(t, err) - bidAmount := new(big.Int) - bidAmount.SetString("11000000000000000000", 10) - forgerAddress := common.HexToAddress(governanceAddressStr) - _, err = auctionClient.AuctionBid(currentSlot+4, bidAmount, forgerAddress) - require.Nil(t, err) - } + currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber() + require.Nil(t, err) + bidAmount := new(big.Int) + bidAmount.SetString("12000000000000000000", 10) + 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()) + 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) +} + +func TestAuctionGetSlotNumber(t *testing.T) { + slotConst := 4 + blockNum := int(BLOCKSPERSLOT)*slotConst + genesisBlock + + slot, err := auctionClient.AuctionGetSlotNumber(int64(blockNum)) + require.Nil(t, err) + assert.Equal(t, slot, big.NewInt(int64(slotConst))) +} + +func TestAuctionCanForge(t *testing.T) { + slotConst := 4 + blockNum := int(BLOCKSPERSLOT)*slotConst + genesisBlock + + canForge, err := auctionClient.AuctionCanForge(governanceAddressConst, int64(blockNum)) + require.Nil(t, err) + assert.Equal(t, canForge, true) } func TestAuctionMultiBid(t *testing.T) { - if auctionClient != nil { - currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber() - require.Nil(t, err) - slotSet := [6]bool{false, true, false, true, false, true} - maxBid := new(big.Int) - maxBid.SetString("11000000000000000000", 10) - minBid := new(big.Int) - minBid.SetString("11000000000000000000", 10) - budget := new(big.Int) - budget.SetString("110000000000000000000", 10) - forgerAddress := common.HexToAddress(governanceAddressStr) - _, err = auctionClient.AuctionMultiBid(currentSlot+5, currentSlot+10, slotSet, maxBid, minBid, budget, forgerAddress) - require.Nil(t, err) - } + currentSlot, err := auctionClient.AuctionGetCurrentSlotNumber() + require.Nil(t, err) + slotSet := [6]bool{true, false, true, false, true, false} + maxBid := new(big.Int) + maxBid.SetString("15000000000000000000", 10) + minBid := new(big.Int) + minBid.SetString("11000000000000000000", 10) + budget := new(big.Int) + budget.SetString("45200000000000000000", 10) + 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()) + 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) + assert.Equal(t, currentSlot+6, auctionEvents.NewBid[1].Slot) + assert.Equal(t, forgerAddress, auctionEvents.NewBid[2].CoordinatorForger) + assert.Equal(t, currentSlot+8, auctionEvents.NewBid[2].Slot) + assert.Equal(t, forgerAddress, auctionEvents.NewBid[3].CoordinatorForger) + assert.Equal(t, currentSlot+10, auctionEvents.NewBid[3].Slot) +} + +func TestAuctionGetClaimableHEZ2(t *testing.T) { + forgerAddress := governanceAddressConst + amount := new(big.Int) + amount.SetString("11000000000000000000", 10) + + claimableHEZ, err := auctionClient.AuctionGetClaimableHEZ(forgerAddress) + require.Nil(t, err) + assert.Equal(t, claimableHEZ, amount) +} + +func TestAuctionClaimHEZ(t *testing.T) { + amount := new(big.Int) + amount.SetString("11000000000000000000", 10) + + _, err := auctionClient.AuctionClaimHEZ(governanceAddressConst) + require.Nil(t, err) + header, _ := auctionClient.client.client.HeaderByNumber(context.Background(), nil) + auctionEvents, _, _ := auctionClient.AuctionEventsByBlock(header.Number.Int64()) + assert.Equal(t, amount, auctionEvents.HEZClaimed[0].Amount) + assert.Equal(t, governanceAddressConst, auctionEvents.HEZClaimed[0].Owner) } diff --git a/eth/main_test.go b/eth/main_test.go new file mode 100644 index 0000000..e714b73 --- /dev/null +++ b/eth/main_test.go @@ -0,0 +1,132 @@ +package eth + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/keystore" + ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" +) + +/*var donationAddressStr = os.Getenv("DONATION_ADDRESS") +var bootCoordinatorStr = os.Getenv("BOOT_COORDINATOR_ADDRESS") +var auctionAddressStr = os.Getenv("AUCTION_ADDRESS") +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 password = "pass" + +// Smart Contract Addresses +var ( + auctionAddressStr = "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5" + auctionAddressConst = ethCommon.HexToAddress(auctionAddressStr) + donationAddressStr = "0x6c365935CA8710200C7595F0a72EB6023A7706Cd" + donationAddressConst = ethCommon.HexToAddress(donationAddressStr) + bootCoordinatorAddressStr = "0xc783df8a850f42e7f7e57013759c285caa701eb6" + bootCoordinatorAddressConst = ethCommon.HexToAddress(bootCoordinatorAddressStr) + tokenHezAddressStr = "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c" //nolint:gosec + tokenHezAddressConst = ethCommon.HexToAddress(tokenHezAddressStr) + hermezRollupAddressStr = "0xc4905364b78a742ccce7B890A89514061E47068D" + hermezRollupAddressConst = ethCommon.HexToAddress(hermezRollupAddressStr) + wdelayerAddressStr = "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8" + wdelayerAddressConst = ethCommon.HexToAddress(wdelayerAddressStr) +) + +// Ethereum Accounts +var ( + hermezGovernanceDAOAddressSK = "2a8aede924268f84156a00761de73998dac7bf703408754b776ff3f873bcec60" + hermezGovernanceDAOAddressStr = "0x84Fae3d3Cba24A97817b2a18c2421d462dbBCe9f" + hermezGovernanceDAOAddressConst = ethCommon.HexToAddress(hermezGovernanceDAOAddressStr) + + whiteHackGroupAddressSK = "8b24fd94f1ce869d81a34b95351e7f97b2cd88a891d5c00abc33d0ec9501902e" + whiteHackGroupAddressStr = "0xfa3BdC8709226Da0dA13A4d904c8b66f16c3c8BA" + whiteHackGroupAddressConst = ethCommon.HexToAddress(whiteHackGroupAddressStr) + + hermezKeeperAddressSK = "7f307c41137d1ed409f0a7b028f6c7596f12734b1d289b58099b99d60a96efff" + hermezKeeperAddressStr = "0xFbC51a9582D031f2ceaaD3959256596C5D3a5468" + hermezKeeperAddressConst = ethCommon.HexToAddress(hermezKeeperAddressStr) + + governanceAddressSK = "d49743deccbccc5dc7baa8e69e5be03298da8688a15dd202e20f15d5e0e9a9fb" + governanceAddressStr = "0xead9c93b79ae7c1591b1fb5323bd777e86e150d4" + governanceAddressConst = ethCommon.HexToAddress(governanceAddressStr) + + auxAddressSK = "28d1bfbbafe9d1d4f5a11c3c16ab6bf9084de48d99fbac4058bdfa3c80b29089" + auxAddressStr = "0x3d91185a02774C70287F6c74Dd26d13DFB58ff16" + auxAddressConst = ethCommon.HexToAddress(auxAddressStr) +) + +var ( + accountGov *accounts.Account + accountKep *accounts.Account + accountWhite *accounts.Account + accountGovDAO *accounts.Account + accountAux *accounts.Account + ks *keystore.KeyStore + ethClient *ethclient.Client + ethereumClientWhite *EthereumClient + ethereumClientKep *EthereumClient + ethereumClientGovDAO *EthereumClient + ethereumClientAux *EthereumClient +) + +func addKey(ks *keystore.KeyStore, skHex string) *accounts.Account { + key, err := crypto.HexToECDSA(skHex) + if err != nil { + panic(err) + } + account, err := ks.ImportECDSA(key, password) + if err != nil { + panic(err) + } + err = ks.Unlock(account, password) + if err != nil { + panic(err) + } + return &account +} + +func TestMain(m *testing.M) { + exitVal := 0 + + if os.Getenv("INTEGRATION") != "" { + dir, err := ioutil.TempDir("", "tmpks") + if err != nil { + panic(err) + } + ks = keystore.NewKeyStore(dir, keystore.LightScryptN, keystore.LightScryptP) + + // Load ethereum accounts from private keys + accountGov = addKey(ks, governanceAddressSK) + accountKep = addKey(ks, hermezKeeperAddressSK) + accountWhite = addKey(ks, whiteHackGroupAddressSK) + accountGovDAO = addKey(ks, hermezGovernanceDAOAddressSK) + accountAux = addKey(ks, auxAddressSK) + + ethClient, err = ethclient.Dial(ehtClientDialURL) + if err != nil { + panic(err) + } + + // Controllable Governance Address + + ethereumClientGov := NewEthereumClient(ethClient, accountGov, ks, nil) + auctionClient = NewAuctionClient(ethereumClientGov, auctionAddressConst, tokenHezAddressConst) + rollupClient = NewRollupClient(ethereumClientGov, hermezRollupAddressConst) + wdelayerClient = NewWDelayerClient(ethereumClientGov, wdelayerAddressConst) + + ethereumClientKep = NewEthereumClient(ethClient, accountKep, ks, nil) + ethereumClientWhite = NewEthereumClient(ethClient, accountWhite, ks, nil) + ethereumClientGovDAO = NewEthereumClient(ethClient, accountGovDAO, ks, nil) + ethereumClientAux = NewEthereumClient(ethClient, accountAux, ks, nil) + + exitVal = m.Run() + } + os.Exit(exitVal) +} diff --git a/eth/rollup_test.go b/eth/rollup_test.go index a8d820e..684d286 100644 --- a/eth/rollup_test.go +++ b/eth/rollup_test.go @@ -1,36 +1,13 @@ 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() diff --git a/eth/wdelayer.go b/eth/wdelayer.go index bb2d490..ce7d30d 100644 --- a/eth/wdelayer.go +++ b/eth/wdelayer.go @@ -1,10 +1,14 @@ package eth import ( + "fmt" "math/big" + "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/ethclient" + WithdrawalDelayer "github.com/hermeznetwork/hermez-node/eth/contracts/withdrawdelayer" ) // WDelayerConstants are the constants of the Rollup Smart Contract @@ -140,75 +144,266 @@ func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) *WDela // WDelayerGetHermezGovernanceDAOAddress is the interface to call the smart contract function func (c *WDelayerClient) WDelayerGetHermezGovernanceDAOAddress() (*ethCommon.Address, error) { - return nil, errTODO + var hermezGovernanceDAOAddress ethCommon.Address + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + hermezGovernanceDAOAddress, err = wdelayer.GetHermezGovernanceDAOAddress(nil) + return err + }); err != nil { + return nil, err + } + return &hermezGovernanceDAOAddress, nil } // WDelayerSetHermezGovernanceDAOAddress is the interface to call the smart contract function -func WDelayerSetHermezGovernanceDAOAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerSetHermezGovernanceDAOAddress(newAddress 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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.SetHermezGovernanceDAOAddress(auth, newAddress) + }, + ); err != nil { + return nil, fmt.Errorf("Failed setting hermezGovernanceDAOAddress: %w", err) + } + return tx, nil } // WDelayerGetHermezKeeperAddress is the interface to call the smart contract function -func WDelayerGetHermezKeeperAddress() (*ethCommon.Address, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerGetHermezKeeperAddress() (*ethCommon.Address, error) { + var hermezKeeperAddress ethCommon.Address + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + hermezKeeperAddress, err = wdelayer.GetHermezKeeperAddress(nil) + return err + }); err != nil { + return nil, err + } + return &hermezKeeperAddress, nil } // WDelayerSetHermezKeeperAddress is the interface to call the smart contract function -func WDelayerSetHermezKeeperAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerSetHermezKeeperAddress(newAddress 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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.SetHermezKeeperAddress(auth, newAddress) + }, + ); err != nil { + return nil, fmt.Errorf("Failed setting hermezKeeperAddress: %w", err) + } + return tx, nil } // WDelayerGetWhiteHackGroupAddress is the interface to call the smart contract function -func WDelayerGetWhiteHackGroupAddress() (*ethCommon.Address, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerGetWhiteHackGroupAddress() (*ethCommon.Address, error) { + var whiteHackGroupAddress ethCommon.Address + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + whiteHackGroupAddress, err = wdelayer.GetWhiteHackGroupAddress(nil) + return err + }); err != nil { + return nil, err + } + return &whiteHackGroupAddress, nil } // WDelayerSetWhiteHackGroupAddress is the interface to call the smart contract function -func WDelayerSetWhiteHackGroupAddress(newAddress ethCommon.Address) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerSetWhiteHackGroupAddress(newAddress 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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.SetWhiteHackGroupAddress(auth, newAddress) + }, + ); err != nil { + return nil, fmt.Errorf("Failed setting whiteHackGroupAddress: %w", err) + } + return tx, nil } // WDelayerIsEmergencyMode is the interface to call the smart contract function -func WDelayerIsEmergencyMode() (bool, error) { - return false, errTODO +func (c *WDelayerClient) WDelayerIsEmergencyMode() (bool, error) { + var ermergencyMode bool + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + ermergencyMode, err = wdelayer.IsEmergencyMode(nil) + return err + }); err != nil { + return false, err + } + return ermergencyMode, nil } // WDelayerGetWithdrawalDelay is the interface to call the smart contract function -func WDelayerGetWithdrawalDelay() (*big.Int, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (*big.Int, error) { + var withdrawalDelay *big.Int + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + withdrawalDelay, err = wdelayer.GetWithdrawalDelay(nil) + return err + }); err != nil { + return nil, err + } + return withdrawalDelay, nil } // WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function -func WDelayerGetEmergencyModeStartingTime() (*big.Int, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (*big.Int, error) { + var emergencyModeStartingTime *big.Int + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + emergencyModeStartingTime, err = wdelayer.GetEmergencyModeStartingTime(nil) + return err + }); err != nil { + return nil, err + } + return emergencyModeStartingTime, nil } // WDelayerEnableEmergencyMode is the interface to call the smart contract function -func WDelayerEnableEmergencyMode() (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerEnableEmergencyMode() (*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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.EnableEmergencyMode(auth) + }, + ); err != nil { + return nil, fmt.Errorf("Failed setting enable emergency mode: %w", err) + } + return tx, nil } // WDelayerChangeWithdrawalDelay is the interface to call the smart contract function -func WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.ChangeWithdrawalDelay(auth, newWithdrawalDelay) + }, + ); err != nil { + return nil, fmt.Errorf("Failed setting withdrawal delay: %w", err) + } + return tx, nil } // WDelayerDepositInfo is the interface to call the smart contract function -func WDelayerDepositInfo(owner, token ethCommon.Address) (*big.Int, uint64, error) { - return big.NewInt(0), 0, errTODO +func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (DepositState, error) { + var depositInfo DepositState + if err := c.client.Call(func(ec *ethclient.Client) error { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return err + } + amount, depositTimestamp, err := wdelayer.DepositInfo(nil, owner, token) + depositInfo.Amount = amount + depositInfo.DepositTimestamp = depositTimestamp + return err + }); err != nil { + return depositInfo, err + } + return depositInfo, nil } // WDelayerDeposit is the interface to call the smart contract function -func WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (*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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.Deposit(auth, owner, token, amount) + }, + ); err != nil { + return nil, fmt.Errorf("Failed deposit: %w", err) + } + return tx, nil } // WDelayerWithdrawal is the interface to call the smart contract function -func WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerWithdrawal(owner, token 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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.Withdrawal(auth, owner, token) + }, + ); err != nil { + return nil, fmt.Errorf("Failed withdrawal: %w", err) + } + return tx, nil } // WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function -func WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address) (*types.Transaction, error) { - return nil, errTODO +func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token 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) { + wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(c.address, ec) + if err != nil { + return nil, err + } + return wdelayer.EscapeHatchWithdrawal(auth, to, token) + }, + ); err != nil { + return nil, fmt.Errorf("Failed escapeHatchWithdrawal: %w", err) + } + return tx, nil } diff --git a/eth/wdelayer_test.go b/eth/wdelayer_test.go new file mode 100644 index 0000000..e081a9a --- /dev/null +++ b/eth/wdelayer_test.go @@ -0,0 +1,134 @@ +package eth + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var wdelayerClient *WDelayerClient + +// var wdelayerClientKep *WDelayerClient + +var initWithdrawalDelay = big.NewInt(60) +var newWithdrawalDelay = big.NewInt(79) + +func TestWDelayerGetHermezGovernanceDAOAddress(t *testing.T) { + governanceAddress, err := wdelayerClient.WDelayerGetHermezGovernanceDAOAddress() + require.Nil(t, err) + assert.Equal(t, &hermezGovernanceDAOAddressConst, governanceAddress) +} + +func TestWDelayerSetHermezGovernanceDAOAddress(t *testing.T) { + wdelayerClientGov := NewWDelayerClient(ethereumClientGovDAO, wdelayerAddressConst) + _, 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) + _, err = wdelayerClientAux.WDelayerSetHermezGovernanceDAOAddress(hermezGovernanceDAOAddressConst) + require.Nil(t, err) +} + +func TestWDelayerGetHermezKeeperAddress(t *testing.T) { + keeperAddress, err := wdelayerClient.WDelayerGetHermezKeeperAddress() + require.Nil(t, err) + assert.Equal(t, &hermezKeeperAddressConst, keeperAddress) +} + +func TestWDelayerSetHermezKeeperAddress(t *testing.T) { + wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst) + _, 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) + _, err = wdelayerClientAux.WDelayerSetHermezKeeperAddress(hermezKeeperAddressConst) + require.Nil(t, err) +} + +func TestWDelayerGetWhiteHackGroupAddress(t *testing.T) { + whiteHackGroupAddress, err := wdelayerClient.WDelayerGetWhiteHackGroupAddress() + require.Nil(t, err) + assert.Equal(t, &whiteHackGroupAddressConst, whiteHackGroupAddress) +} + +func TestWDelayerSetWhiteHackGroupAddress(t *testing.T) { + wdelayerClientWhite := NewWDelayerClient(ethereumClientWhite, wdelayerAddressConst) + _, 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) + _, err = wdelayerClientAux.WDelayerSetWhiteHackGroupAddress(whiteHackGroupAddressConst) + require.Nil(t, err) +} + +func TestWDelayerIsEmergencyMode(t *testing.T) { + emergencyMode, err := wdelayerClient.WDelayerIsEmergencyMode() + require.Nil(t, err) + assert.Equal(t, false, emergencyMode) +} + +func TestWDelayerGetWithdrawalDelay(t *testing.T) { + withdrawalDelay, err := wdelayerClient.WDelayerGetWithdrawalDelay() + require.Nil(t, err) + assert.Equal(t, initWithdrawalDelay, withdrawalDelay) +} + +func TestWDelayerEnableEmergencyMode(t *testing.T) { + wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst) + _, err := wdelayerClientKep.WDelayerEnableEmergencyMode() + require.Nil(t, err) + emergencyMode, err := wdelayerClient.WDelayerIsEmergencyMode() + require.Nil(t, err) + assert.Equal(t, true, emergencyMode) +} + +func TestWDelayerChangeWithdrawalDelay(t *testing.T) { + wdelayerClientKep := NewWDelayerClient(ethereumClientKep, wdelayerAddressConst) + _, err := wdelayerClientKep.WDelayerChangeWithdrawalDelay(newWithdrawalDelay.Uint64()) + require.Nil(t, err) + withdrawalDelay, err := wdelayerClient.WDelayerGetWithdrawalDelay() + require.Nil(t, err) + assert.Equal(t, newWithdrawalDelay, withdrawalDelay) +} + +func TestWDelayerGetEmergencyModeStartingTime(t *testing.T) { + emergencyModeStartingTime, err := wdelayerClient.WDelayerGetEmergencyModeStartingTime() + require.Nil(t, err) + // `emergencyModeStartingTime` is initialized to 0 in the smart + // contract construction. Since we called WDelayerEnableEmergencyMode + // previously, `emergencyModeStartingTime` is set to the time when the + // call was made, so it's > 0. + 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 { + + } +} */ diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index fdc4d21..86adcde 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -503,7 +503,7 @@ func (s *Synchronizer) auctionSync(blockNum int64) (*auctionData, error) { coordinator := &common.Coordinator{ Forger: eNewCoordinator.ForgerAddress, WithdrawAddr: eNewCoordinator.WithdrawalAddress, - URL: eNewCoordinator.URL, + URL: eNewCoordinator.CoordinatorURL, } auctionData.coordinators = append(auctionData.coordinators, coordinator) } @@ -527,7 +527,7 @@ func (s *Synchronizer) auctionSync(blockNum int64) (*auctionData, error) { coordinator := &common.Coordinator{ Forger: eCoordinatorUpdated.ForgerAddress, WithdrawAddr: eCoordinatorUpdated.WithdrawalAddress, - URL: eCoordinatorUpdated.URL, + URL: eCoordinatorUpdated.CoordinatorURL, } auctionData.coordinators = append(auctionData.coordinators, coordinator) } diff --git a/test/ethclient.go b/test/ethclient.go index bc29ed6..a81d232 100644 --- a/test/ethclient.go +++ b/test/ethclient.go @@ -1004,7 +1004,7 @@ func (c *Client) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL eth.AuctionEventNewCoordinator{ ForgerAddress: forgerAddress, WithdrawalAddress: c.addr, - URL: URL, + CoordinatorURL: URL, }) type data struct { @@ -1061,6 +1061,24 @@ func (c *Client) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) { return nil, errTODO } +// AuctionGetSlotSet is the interface to call the smart contract function +func (c *Client) AuctionGetSlotSet(slot int64) (*big.Int, error) { + c.rw.RLock() + defer c.rw.RUnlock() + + log.Error("TODO") + return nil, errTODO +} + +// AuctionGetSlotNumber is the interface to call the smart contract function +func (c *Client) AuctionGetSlotNumber(blockNum int64) (*big.Int, error) { + c.rw.RLock() + defer c.rw.RUnlock() + + log.Error("TODO") + return nil, errTODO +} + // AuctionTokensReceived is the interface to call the smart contract function // func (c *Client) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error { // return errTODO