diff options
author | Wei-Ning Huang <w@dexon.org> | 2019-01-25 19:24:35 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-03-12 12:19:09 +0800 |
commit | ae0afc07282e21345904f1a2177eff24d2594429 (patch) | |
tree | 9d6e436d6264664299b6cd9b106ebf45fb48d29e | |
parent | 64932c8ccf85754da0631f736967bf36dc41e213 (diff) | |
download | dexon-ae0afc07282e21345904f1a2177eff24d2594429.tar.gz dexon-ae0afc07282e21345904f1a2177eff24d2594429.tar.zst dexon-ae0afc07282e21345904f1a2177eff24d2594429.zip |
core: vm: refactor governance and add node info oracle (#174)
-rw-r--r-- | core/vm/evm.go | 7 | ||||
-rw-r--r-- | core/vm/oracle.go | 88 | ||||
-rw-r--r-- | core/vm/oracle_contract_abi.go (renamed from core/vm/governance_abi.go) | 90 | ||||
-rw-r--r-- | core/vm/oracle_contracts.go (renamed from core/vm/governance.go) | 1028 | ||||
-rw-r--r-- | core/vm/oracle_contracts_test.go (renamed from core/vm/governance_test.go) | 422 | ||||
-rw-r--r-- | test/genesis.json | 2 |
6 files changed, 954 insertions, 683 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go index 2eba9c2cb..422d52ccb 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -48,8 +48,8 @@ type ( // run runs the given contract and takes care of running precompiles with a fallback to the byte code interpreter. func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, error) { if contract.CodeAddr != nil { - if *contract.CodeAddr == GovernanceContractAddress { - return RunGovernanceContract(evm, input, contract) + if o := OracleContracts[*contract.CodeAddr]; o != nil { + return RunOracleContract(o, evm, input, contract) } precompiles := PrecompiledContractsHomestead if evm.ChainConfig().IsByzantium(evm.BlockNumber) { @@ -216,7 +216,8 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.ChainConfig().IsByzantium(evm.BlockNumber) { precompiles = PrecompiledContractsByzantium } - if precompiles[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 && addr != GovernanceContractAddress { + if precompiles[addr] == nil && OracleContracts[addr] == nil && + evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 { // Calling a non existing account, don't do anything, but ping the tracer if evm.vmConfig.Debug && evm.depth == 0 { evm.vmConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) diff --git a/core/vm/oracle.go b/core/vm/oracle.go new file mode 100644 index 000000000..493736e8c --- /dev/null +++ b/core/vm/oracle.go @@ -0,0 +1,88 @@ +// Copyright 2019 The dexon-consensus Authors +// This file is part of the dexon-consensus library. +// +// The dexon-consensus library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus library. If not, see +// <http://www.gnu.org/licenses/>. + +package vm + +import ( + "strings" + + "github.com/dexon-foundation/dexon/accounts/abi" + "github.com/dexon-foundation/dexon/common" +) + +var GovernanceContractAddress = common.HexToAddress("63751838d6485578b23e8b051d40861ecc416794") +var NodeInfoOracleAddress = common.HexToAddress("58a7c88ad1f32e7252bebba54def98d3e7b3df11") + +var GovernanceABI *OracleContractABI +var NodeInfoOracleABI *OracleContractABI + +func init() { + GovernanceABI = NewOracleContractABI(GovernanceABIJSON) + NodeInfoOracleABI = NewOracleContractABI(NodeInfoOracleABIJSON) +} + +// OracleContract represent special system contracts written in Go. +type OracleContract interface { + Run(evm *EVM, input []byte, contract *Contract) (ret []byte, err error) +} + +// A map representing available system oracle contracts. +var OracleContracts = map[common.Address]OracleContract{ + GovernanceContractAddress: &GovernanceContract{}, + NodeInfoOracleAddress: &NodeInfoOracleContract{}, +} + +// Run oracle contract. +func RunOracleContract(oracle OracleContract, evm *EVM, input []byte, contract *Contract) (ret []byte, err error) { + return oracle.Run(evm, input, contract) +} + +// OracleContractABI represents ABI information for a given contract. +type OracleContractABI struct { + ABI abi.ABI + Name2Method map[string]abi.Method + Sig2Method map[string]abi.Method + Events map[string]abi.Event +} + +// NewOracleContractABI parse the ABI. +func NewOracleContractABI(abiDefinition string) *OracleContractABI { + abiObject, err := abi.JSON(strings.NewReader(abiDefinition)) + if err != nil { + panic(err) + } + + sig2Method := make(map[string]abi.Method) + name2Method := make(map[string]abi.Method) + + for _, method := range abiObject.Methods { + sig2Method[string(method.Id())] = method + name2Method[method.Name] = method + } + + events := make(map[string]abi.Event) + for _, event := range abiObject.Events { + events[event.Name] = event + } + + return &OracleContractABI{ + ABI: abiObject, + Name2Method: name2Method, + Sig2Method: sig2Method, + Events: events, + } +} diff --git a/core/vm/governance_abi.go b/core/vm/oracle_contract_abi.go index c3ad691b6..1c630c1c8 100644 --- a/core/vm/governance_abi.go +++ b/core/vm/oracle_contract_abi.go @@ -1106,3 +1106,93 @@ const GovernanceABIJSON = ` } ] ` + +const NodeInfoOracleABIJSON = ` +[ + { + "constant": true, + "inputs": [ + { + "name": "Round", + "type": "uint256" + }, + { + "name": "NodeAddress", + "type": "address" + }, + { + "name": "Index", + "type": "uint256" + } + ], + "name": "delegators", + "outputs": [ + { + "name": "owner", + "type": "address" + }, + { + "name": "value", + "type": "uint256" + }, + { + "name": "undelegated_at", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "Round", + "type": "uint256" + }, + { + "name": "NodeAddress", + "type": "address" + } + ], + "name": "delegatorsLength", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "Round", + "type": "uint256" + }, + { + "name": "NodeAddress", + "type": "address" + }, + { + "name": "DelegatorAddress", + "type": "address" + } + ], + "name": "delegatorsOffset", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + } +] +` diff --git a/core/vm/governance.go b/core/vm/oracle_contracts.go index 684e22104..5f83ca68f 100644 --- a/core/vm/governance.go +++ b/core/vm/oracle_contracts.go @@ -22,7 +22,6 @@ import ( "errors" "math/big" "sort" - "strings" "github.com/dexon-foundation/dexon/accounts/abi" "github.com/dexon-foundation/dexon/common" @@ -41,13 +40,6 @@ import ( dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg" ) -var GovernanceContractAddress = common.HexToAddress("63751838d6485578b23e8b051d40861ecc416794") - -var abiObject abi.ABI -var GovernanceContractName2Method map[string]abi.Method -var sig2Method map[string]abi.Method -var events map[string]abi.Event - type Bytes32 [32]byte type ReportType uint64 @@ -58,464 +50,6 @@ const ( ReportTypeForkBlock ) -func init() { - var err error - - // Parse governance contract ABI. - abiObject, err = abi.JSON(strings.NewReader(GovernanceABIJSON)) - if err != nil { - panic(err) - } - - sig2Method = make(map[string]abi.Method) - GovernanceContractName2Method = make(map[string]abi.Method) - - // Construct dispatch table. - for _, method := range abiObject.Methods { - sig2Method[string(method.Id())] = method - GovernanceContractName2Method[method.Name] = method - } - - events = make(map[string]abi.Event) - - // Event cache. - for _, event := range abiObject.Events { - events[event.Name] = event - } -} - -// RunGovernanceContract executes governance contract. -func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (ret []byte, err error) { - if len(input) < 4 { - return nil, nil - } - - // Parse input. - method, exists := sig2Method[string(input[:4])] - if !exists { - return nil, errExecutionReverted - } - - // Dispatch method call. - g := newGovernanceContract(evm, contract) - arguments := input[4:] - - switch method.Name { - case "addDKGComplaint": - args := struct { - Round *big.Int - Complaint []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.addDKGComplaint(args.Round, args.Complaint) - case "addDKGMasterPublicKey": - args := struct { - Round *big.Int - PublicKey []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.addDKGMasterPublicKey(args.Round, args.PublicKey) - case "addDKGMPKReady": - args := struct { - Round *big.Int - MPKReady []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.addDKGMPKReady(args.Round, args.MPKReady) - case "addDKGFinalize": - args := struct { - Round *big.Int - Finalize []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.addDKGFinalize(args.Round, args.Finalize) - case "delegate": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - return g.delegate(address) - case "delegatorsLength": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.LenDelegators(address)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "nodesLength": - res, err := method.Outputs.Pack(g.state.LenNodes()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "payFine": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - return g.payFine(address) - case "proposeCRS": - args := struct { - Round *big.Int - SignedCRS []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.proposeCRS(args.Round, args.SignedCRS) - case "report": - args := struct { - Type *big.Int - Arg1 []byte - Arg2 []byte - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.report(args.Type, args.Arg1, args.Arg2) - case "stake": - args := struct { - PublicKey []byte - Name string - Email string - Location string - Url string - }{} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - return g.stake(args.PublicKey, args.Name, args.Email, args.Location, args.Url) - case "transferOwnership": - var newOwner common.Address - if err := method.Inputs.Unpack(&newOwner, arguments); err != nil { - return nil, errExecutionReverted - } - return g.transferOwnership(newOwner) - case "undelegate": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - return g.undelegate(address) - case "unstake": - return g.unstake() - case "updateConfiguration": - var cfg rawConfigStruct - if err := method.Inputs.Unpack(&cfg, arguments); err != nil { - return nil, errExecutionReverted - } - return g.updateConfiguration(&cfg) - case "withdraw": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - return g.withdraw(address) - - // -------------------------------- - // Solidity auto generated methods. - // -------------------------------- - - case "blockGasLimit": - res, err := method.Outputs.Pack(g.state.BlockGasLimit()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "crs": - round := new(big.Int) - if err := method.Inputs.Unpack(&round, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.CRS(round)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "delegators": - nodeAddr, index := common.Address{}, new(big.Int) - args := []interface{}{&nodeAddr, &index} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - delegator := g.state.Delegator(nodeAddr, index) - res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "delegatorsOffset": - nodeAddr, delegatorAddr := common.Address{}, common.Address{} - args := []interface{}{&nodeAddr, &delegatorAddr} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.DelegatorsOffset(nodeAddr, delegatorAddr)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgComplaints": - round, index := new(big.Int), new(big.Int) - args := []interface{}{&round, &index} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - complaints := g.state.DKGComplaints(round) - if int(index.Uint64()) >= len(complaints) { - return nil, errExecutionReverted - } - complaint := complaints[index.Uint64()] - res, err := method.Outputs.Pack(complaint) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgReadys": - round, addr := new(big.Int), common.Address{} - args := []interface{}{&round, &addr} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - ready := g.state.DKGMPKReady(round, addr) - res, err := method.Outputs.Pack(ready) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgReadysCount": - round := new(big.Int) - if err := method.Inputs.Unpack(&round, arguments); err != nil { - return nil, errExecutionReverted - } - count := g.state.DKGMPKReadysCount(round) - res, err := method.Outputs.Pack(count) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - - case "dkgFinalizeds": - round, addr := new(big.Int), common.Address{} - args := []interface{}{&round, &addr} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - finalized := g.state.DKGFinalized(round, addr) - res, err := method.Outputs.Pack(finalized) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgFinalizedsCount": - round := new(big.Int) - if err := method.Inputs.Unpack(&round, arguments); err != nil { - return nil, errExecutionReverted - } - count := g.state.DKGFinalizedsCount(round) - res, err := method.Outputs.Pack(count) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgMasterPublicKeys": - round, index := new(big.Int), new(big.Int) - args := []interface{}{&round, &index} - if err := method.Inputs.Unpack(&args, arguments); err != nil { - return nil, errExecutionReverted - } - mpks := g.state.DKGMasterPublicKeys(round) - if int(index.Uint64()) >= len(mpks) { - return nil, errExecutionReverted - } - mpk := mpks[index.Uint64()] - res, err := method.Outputs.Pack(mpk) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "dkgSetSize": - res, err := method.Outputs.Pack(g.state.DKGSetSize()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "finedRecords": - record := Bytes32{} - if err := method.Inputs.Unpack(&record, arguments); err != nil { - return nil, errExecutionReverted - } - value := g.state.FineRecords(record) - res, err := method.Outputs.Pack(value) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "fineValues": - index := new(big.Int) - if err := method.Inputs.Unpack(&index, arguments); err != nil { - return nil, errExecutionReverted - } - value := g.state.FineValue(index) - res, err := method.Outputs.Pack(value) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "k": - res, err := method.Outputs.Pack(g.state.K()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "lambdaBA": - res, err := method.Outputs.Pack(g.state.LambdaBA()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "lambdaDKG": - res, err := method.Outputs.Pack(g.state.LambdaDKG()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "lastHalvedAmount": - res, err := method.Outputs.Pack(g.state.LastHalvedAmount()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "lockupPeriod": - res, err := method.Outputs.Pack(g.state.LockupPeriod()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "minBlockInterval": - res, err := method.Outputs.Pack(g.state.MinBlockInterval()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "miningVelocity": - res, err := method.Outputs.Pack(g.state.MiningVelocity()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "minStake": - res, err := method.Outputs.Pack(g.state.MinStake()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "nextHalvingSupply": - res, err := method.Outputs.Pack(g.state.NextHalvingSupply()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "numChains": - res, err := method.Outputs.Pack(g.state.NumChains()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "nodes": - index := new(big.Int) - if err := method.Inputs.Unpack(&index, arguments); err != nil { - return nil, errExecutionReverted - } - info := g.state.Node(index) - res, err := method.Outputs.Pack( - info.Owner, info.PublicKey, info.Staked, info.Fined, - info.Name, info.Email, info.Location, info.Url) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "nodesOffsetByAddress": - address := common.Address{} - if err := method.Inputs.Unpack(&address, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.NodesOffsetByAddress(address)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "nodesOffsetByID": - var id Bytes32 - if err := method.Inputs.Unpack(&id, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.NodesOffsetByID(id)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "notarySetSize": - res, err := method.Outputs.Pack(g.state.NotarySetSize()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "owner": - res, err := method.Outputs.Pack(g.state.Owner()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "phiRatio": - res, err := method.Outputs.Pack(g.state.PhiRatio()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "roundHeight": - round := new(big.Int) - if err := method.Inputs.Unpack(&round, arguments); err != nil { - return nil, errExecutionReverted - } - res, err := method.Outputs.Pack(g.state.RoundHeight(round)) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "roundInterval": - res, err := method.Outputs.Pack(g.state.RoundInterval()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "totalStaked": - res, err := method.Outputs.Pack(g.state.TotalStaked()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - case "totalSupply": - res, err := method.Outputs.Pack(g.state.TotalSupply()) - if err != nil { - return nil, errExecutionReverted - } - return res, nil - } - return nil, errExecutionReverted -} - // Storage position enums. const ( roundHeightLoc = iota @@ -1401,7 +935,7 @@ func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) { func (s *GovernanceStateHelper) emitConfigurationChangedEvent() { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["ConfigurationChanged"].Id()}, + Topics: []common.Hash{GovernanceABI.Events["ConfigurationChanged"].Id()}, Data: []byte{}, }) } @@ -1410,7 +944,7 @@ func (s *GovernanceStateHelper) emitConfigurationChangedEvent() { func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["CRSProposed"].Id(), common.BigToHash(round)}, + Topics: []common.Hash{GovernanceABI.Events["CRSProposed"].Id(), common.BigToHash(round)}, Data: crs.Bytes(), }) } @@ -1419,7 +953,7 @@ func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Staked"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Staked"].Id(), nodeAddr.Hash()}, Data: []byte{}, }) } @@ -1428,7 +962,7 @@ func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) { func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Unstaked"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Unstaked"].Id(), nodeAddr.Hash()}, Data: []byte{}, }) } @@ -1437,7 +971,7 @@ func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) { func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } @@ -1446,7 +980,7 @@ func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Add func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } @@ -1455,7 +989,7 @@ func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.A func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Withdrawn"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } @@ -1487,7 +1021,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report } s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["ForkReported"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["ForkReported"].Id(), nodeAddr.Hash()}, Data: data, }) } @@ -1496,7 +1030,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["Fined"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Fined"].Id(), nodeAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } @@ -1505,7 +1039,7 @@ func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.I func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{events["FinePaid"].Id(), nodeAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["FinePaid"].Id(), nodeAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } @@ -1517,14 +1051,6 @@ type GovernanceContract struct { contract *Contract } -func newGovernanceContract(evm *EVM, contract *Contract) *GovernanceContract { - return &GovernanceContract{ - evm: evm, - state: GovernanceStateHelper{evm.StateDB}, - contract: contract, - } -} - func (g *GovernanceContract) Address() common.Address { return GovernanceContractAddress } @@ -2148,6 +1674,442 @@ func (g *GovernanceContract) report(reportType *big.Int, arg1, arg2 []byte) ([]b return nil, nil } +// Run executes governance contract. +func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (ret []byte, err error) { + if len(input) < 4 { + return nil, errExecutionReverted + } + + // Initialize contract state. + g.evm = evm + g.state = GovernanceStateHelper{evm.StateDB} + g.contract = contract + + // Parse input. + method, exists := GovernanceABI.Sig2Method[string(input[:4])] + if !exists { + return nil, errExecutionReverted + } + + arguments := input[4:] + + // Dispatch method call. + switch method.Name { + case "addDKGComplaint": + args := struct { + Round *big.Int + Complaint []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.addDKGComplaint(args.Round, args.Complaint) + case "addDKGMasterPublicKey": + args := struct { + Round *big.Int + PublicKey []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.addDKGMasterPublicKey(args.Round, args.PublicKey) + case "addDKGMPKReady": + args := struct { + Round *big.Int + MPKReady []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.addDKGMPKReady(args.Round, args.MPKReady) + case "addDKGFinalize": + args := struct { + Round *big.Int + Finalize []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.addDKGFinalize(args.Round, args.Finalize) + case "delegate": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + return g.delegate(address) + case "delegatorsLength": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.LenDelegators(address)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "nodesLength": + res, err := method.Outputs.Pack(g.state.LenNodes()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "payFine": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + return g.payFine(address) + case "proposeCRS": + args := struct { + Round *big.Int + SignedCRS []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.proposeCRS(args.Round, args.SignedCRS) + case "report": + args := struct { + Type *big.Int + Arg1 []byte + Arg2 []byte + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.report(args.Type, args.Arg1, args.Arg2) + case "stake": + args := struct { + PublicKey []byte + Name string + Email string + Location string + Url string + }{} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + return g.stake(args.PublicKey, args.Name, args.Email, args.Location, args.Url) + case "transferOwnership": + var newOwner common.Address + if err := method.Inputs.Unpack(&newOwner, arguments); err != nil { + return nil, errExecutionReverted + } + return g.transferOwnership(newOwner) + case "undelegate": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + return g.undelegate(address) + case "unstake": + return g.unstake() + case "updateConfiguration": + var cfg rawConfigStruct + if err := method.Inputs.Unpack(&cfg, arguments); err != nil { + return nil, errExecutionReverted + } + return g.updateConfiguration(&cfg) + case "withdraw": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + return g.withdraw(address) + + // -------------------------------- + // Solidity auto generated methods. + // -------------------------------- + + case "blockGasLimit": + res, err := method.Outputs.Pack(g.state.BlockGasLimit()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "crs": + round := new(big.Int) + if err := method.Inputs.Unpack(&round, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.CRS(round)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "delegators": + nodeAddr, index := common.Address{}, new(big.Int) + args := []interface{}{&nodeAddr, &index} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + delegator := g.state.Delegator(nodeAddr, index) + res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "delegatorsOffset": + nodeAddr, delegatorAddr := common.Address{}, common.Address{} + args := []interface{}{&nodeAddr, &delegatorAddr} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.DelegatorsOffset(nodeAddr, delegatorAddr)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgComplaints": + round, index := new(big.Int), new(big.Int) + args := []interface{}{&round, &index} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + complaints := g.state.DKGComplaints(round) + if int(index.Uint64()) >= len(complaints) { + return nil, errExecutionReverted + } + complaint := complaints[index.Uint64()] + res, err := method.Outputs.Pack(complaint) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgReadys": + round, addr := new(big.Int), common.Address{} + args := []interface{}{&round, &addr} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + ready := g.state.DKGMPKReady(round, addr) + res, err := method.Outputs.Pack(ready) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgReadysCount": + round := new(big.Int) + if err := method.Inputs.Unpack(&round, arguments); err != nil { + return nil, errExecutionReverted + } + count := g.state.DKGMPKReadysCount(round) + res, err := method.Outputs.Pack(count) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + + case "dkgFinalizeds": + round, addr := new(big.Int), common.Address{} + args := []interface{}{&round, &addr} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + finalized := g.state.DKGFinalized(round, addr) + res, err := method.Outputs.Pack(finalized) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgFinalizedsCount": + round := new(big.Int) + if err := method.Inputs.Unpack(&round, arguments); err != nil { + return nil, errExecutionReverted + } + count := g.state.DKGFinalizedsCount(round) + res, err := method.Outputs.Pack(count) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgMasterPublicKeys": + round, index := new(big.Int), new(big.Int) + args := []interface{}{&round, &index} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + mpks := g.state.DKGMasterPublicKeys(round) + if int(index.Uint64()) >= len(mpks) { + return nil, errExecutionReverted + } + mpk := mpks[index.Uint64()] + res, err := method.Outputs.Pack(mpk) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgSetSize": + res, err := method.Outputs.Pack(g.state.DKGSetSize()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "finedRecords": + record := Bytes32{} + if err := method.Inputs.Unpack(&record, arguments); err != nil { + return nil, errExecutionReverted + } + value := g.state.FineRecords(record) + res, err := method.Outputs.Pack(value) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "fineValues": + index := new(big.Int) + if err := method.Inputs.Unpack(&index, arguments); err != nil { + return nil, errExecutionReverted + } + value := g.state.FineValue(index) + res, err := method.Outputs.Pack(value) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "k": + res, err := method.Outputs.Pack(g.state.K()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "lambdaBA": + res, err := method.Outputs.Pack(g.state.LambdaBA()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "lambdaDKG": + res, err := method.Outputs.Pack(g.state.LambdaDKG()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "lastHalvedAmount": + res, err := method.Outputs.Pack(g.state.LastHalvedAmount()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "lockupPeriod": + res, err := method.Outputs.Pack(g.state.LockupPeriod()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "minBlockInterval": + res, err := method.Outputs.Pack(g.state.MinBlockInterval()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "miningVelocity": + res, err := method.Outputs.Pack(g.state.MiningVelocity()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "minStake": + res, err := method.Outputs.Pack(g.state.MinStake()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "nextHalvingSupply": + res, err := method.Outputs.Pack(g.state.NextHalvingSupply()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "numChains": + res, err := method.Outputs.Pack(g.state.NumChains()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "nodes": + index := new(big.Int) + if err := method.Inputs.Unpack(&index, arguments); err != nil { + return nil, errExecutionReverted + } + info := g.state.Node(index) + res, err := method.Outputs.Pack( + info.Owner, info.PublicKey, info.Staked, info.Fined, + info.Name, info.Email, info.Location, info.Url) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "nodesOffsetByAddress": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.NodesOffsetByAddress(address)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "nodesOffsetByID": + var id Bytes32 + if err := method.Inputs.Unpack(&id, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.NodesOffsetByID(id)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "notarySetSize": + res, err := method.Outputs.Pack(g.state.NotarySetSize()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "owner": + res, err := method.Outputs.Pack(g.state.Owner()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "phiRatio": + res, err := method.Outputs.Pack(g.state.PhiRatio()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "roundHeight": + round := new(big.Int) + if err := method.Inputs.Unpack(&round, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.RoundHeight(round)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "roundInterval": + res, err := method.Outputs.Pack(g.state.RoundInterval()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "totalStaked": + res, err := method.Outputs.Pack(g.state.TotalStaked()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "totalSupply": + res, err := method.Outputs.Pack(g.state.TotalSupply()) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + } + return nil, errExecutionReverted +} + func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte, error) { // Only owner can update configuration. if g.contract.Caller() != g.state.Owner() { @@ -2158,7 +2120,7 @@ func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte, } func PackProposeCRS(round uint64, signedCRS []byte) ([]byte, error) { - method := GovernanceContractName2Method["proposeCRS"] + method := GovernanceABI.Name2Method["proposeCRS"] res, err := method.Inputs.Pack(big.NewInt(int64(round)), signedCRS) if err != nil { return nil, err @@ -2168,7 +2130,7 @@ func PackProposeCRS(round uint64, signedCRS []byte) ([]byte, error) { } func PackAddDKGMasterPublicKey(round uint64, mpk *dkgTypes.MasterPublicKey) ([]byte, error) { - method := GovernanceContractName2Method["addDKGMasterPublicKey"] + method := GovernanceABI.Name2Method["addDKGMasterPublicKey"] encoded, err := rlp.EncodeToBytes(mpk) if err != nil { return nil, err @@ -2182,7 +2144,7 @@ func PackAddDKGMasterPublicKey(round uint64, mpk *dkgTypes.MasterPublicKey) ([]b } func PackAddDKGMPKReady(round uint64, ready *dkgTypes.MPKReady) ([]byte, error) { - method := GovernanceContractName2Method["addDKGMPKReady"] + method := GovernanceABI.Name2Method["addDKGMPKReady"] encoded, err := rlp.EncodeToBytes(ready) if err != nil { return nil, err @@ -2196,7 +2158,7 @@ func PackAddDKGMPKReady(round uint64, ready *dkgTypes.MPKReady) ([]byte, error) } func PackAddDKGComplaint(round uint64, complaint *dkgTypes.Complaint) ([]byte, error) { - method := GovernanceContractName2Method["addDKGComplaint"] + method := GovernanceABI.Name2Method["addDKGComplaint"] encoded, err := rlp.EncodeToBytes(complaint) if err != nil { return nil, err @@ -2211,7 +2173,7 @@ func PackAddDKGComplaint(round uint64, complaint *dkgTypes.Complaint) ([]byte, e } func PackAddDKGFinalize(round uint64, final *dkgTypes.Finalize) ([]byte, error) { - method := GovernanceContractName2Method["addDKGFinalize"] + method := GovernanceABI.Name2Method["addDKGFinalize"] encoded, err := rlp.EncodeToBytes(final) if err != nil { return nil, err @@ -2226,7 +2188,7 @@ func PackAddDKGFinalize(round uint64, final *dkgTypes.Finalize) ([]byte, error) } func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) { - method := GovernanceContractName2Method["report"] + method := GovernanceABI.Name2Method["report"] vote1Bytes, err := rlp.EncodeToBytes(vote1) if err != nil { @@ -2248,7 +2210,7 @@ func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) { } func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) { - method := GovernanceContractName2Method["report"] + method := GovernanceABI.Name2Method["report"] block1Bytes, err := rlp.EncodeToBytes(block1) if err != nil { @@ -2268,3 +2230,87 @@ func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) { data := append(method.Id(), res...) return data, nil } + +// NodeInfoOracleContract representing a oracle providing the node information. +type NodeInfoOracleContract struct { +} + +func (g *NodeInfoOracleContract) Run(evm *EVM, input []byte, contract *Contract) (ret []byte, err error) { + if len(input) < 4 { + return nil, errExecutionReverted + } + + // Parse input. + method, exists := NodeInfoOracleABI.Sig2Method[string(input[:4])] + if !exists { + return nil, errExecutionReverted + } + + arguments := input[4:] + + getConfigState := func(round *big.Int) (*GovernanceStateHelper, error) { + configRound := big.NewInt(0) + if round.Uint64() >= core.ConfigRoundShift { + configRound = new(big.Int).Sub(round, big.NewInt(int64(core.ConfigRoundShift))) + } + + gs := &GovernanceStateHelper{evm.StateDB} + height := gs.RoundHeight(configRound).Uint64() + if round.Uint64() > 0 && height == 0 { + return nil, errExecutionReverted + } + statedb, err := evm.StateAtNumber(height) + return &GovernanceStateHelper{statedb}, err + } + + // Dispatch method call. + switch method.Name { + case "delegators": + round, nodeAddr, index := new(big.Int), common.Address{}, new(big.Int) + args := []interface{}{&round, &nodeAddr, &index} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + state, err := getConfigState(round) + if err != nil { + return nil, err + } + delegator := state.Delegator(nodeAddr, index) + res, err := method.Outputs.Pack(delegator.Owner, delegator.Value, delegator.UndelegatedAt) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "delegatorsLength": + round, address := new(big.Int), common.Address{} + args := []interface{}{&round, &address} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + state, err := getConfigState(round) + if err != nil { + return nil, err + } + res, err := method.Outputs.Pack(state.LenDelegators(address)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "delegatorsOffset": + round, nodeAddr, delegatorAddr := new(big.Int), common.Address{}, common.Address{} + args := []interface{}{&round, &nodeAddr, &delegatorAddr} + if err := method.Inputs.Unpack(&args, arguments); err != nil { + return nil, errExecutionReverted + } + state, err := getConfigState(round) + if err != nil { + return nil, err + } + res, err := method.Outputs.Pack(state.DelegatorsOffset(nodeAddr, delegatorAddr)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + } + return nil, errExecutionReverted +} diff --git a/core/vm/governance_test.go b/core/vm/oracle_contracts_test.go index 292e4ef1d..ce2ba825b 100644 --- a/core/vm/governance_test.go +++ b/core/vm/oracle_contracts_test.go @@ -91,7 +91,7 @@ func TestGovernanceStateHelper(t *testing.T) { suite.Run(t, new(GovernanceStateHelperTestSuite)) } -type GovernanceContractTestSuite struct { +type OracleContractsTestSuite struct { suite.Suite config *params.DexconConfig @@ -100,7 +100,7 @@ type GovernanceContractTestSuite struct { s *GovernanceStateHelper } -func (g *GovernanceContractTestSuite) SetupTest() { +func (g *OracleContractsTestSuite) SetupTest() { memDB := ethdb.NewMemDatabase() stateDB, err := state.New(common.Hash{}, state.NewDatabase(memDB)) if err != nil { @@ -137,7 +137,7 @@ func (g *GovernanceContractTestSuite) SetupTest() { g.stateDB.Commit(true) } -func (g *GovernanceContractTestSuite) newPrefundAccount() (*ecdsa.PrivateKey, common.Address) { +func (g *OracleContractsTestSuite) newPrefundAccount() (*ecdsa.PrivateKey, common.Address) { privKey, err := crypto.GenerateKey() if err != nil { panic(err) @@ -148,7 +148,9 @@ func (g *GovernanceContractTestSuite) newPrefundAccount() (*ecdsa.PrivateKey, co return privKey, address } -func (g *GovernanceContractTestSuite) call(caller common.Address, input []byte, value *big.Int) ([]byte, error) { +func (g *OracleContractsTestSuite) call( + contractAddr common.Address, caller common.Address, input []byte, value *big.Int) ([]byte, error) { + context := Context{ CanTransfer: func(db StateDB, addr common.Address, amount *big.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 @@ -168,41 +170,44 @@ func (g *GovernanceContractTestSuite) call(caller common.Address, input []byte, } return 0, false }, + StateAtNumber: func(n uint64) (*state.StateDB, error) { + return g.stateDB, nil + }, Time: big.NewInt(time.Now().UnixNano() / 1000000), BlockNumber: big.NewInt(0), } evm := NewEVM(context, g.stateDB, params.TestChainConfig, Config{IsBlockProposer: true}) - ret, _, err := evm.Call(AccountRef(caller), GovernanceContractAddress, input, 10000000, value) + ret, _, err := evm.Call(AccountRef(caller), contractAddr, input, 10000000, value) return ret, err } -func (g *GovernanceContractTestSuite) TestTransferOwnership() { +func (g *OracleContractsTestSuite) TestTransferOwnership() { _, addr := g.newPrefundAccount() - input, err := abiObject.Pack("transferOwnership", addr) + input, err := GovernanceABI.ABI.Pack("transferOwnership", addr) g.Require().NoError(err) // Call with non-owner. - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NotNil(err) // Call with owner. - _, err = g.call(g.config.Owner, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(addr, g.s.Owner()) } -func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { +func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) balanceBeforeStake := g.stateDB.GetBalance(addr) - input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) g.Require().Equal(1, int(g.s.LenNodes().Uint64())) @@ -215,13 +220,13 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(new(big.Int).Add(big.NewInt(1), amount), g.stateDB.GetBalance(GovernanceContractAddress)) // Staking again should fail. - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NotNil(err) // Unstake. - input, err = abiObject.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake") g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64())) @@ -233,9 +238,9 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { // Wait for lockup time than withdraw. time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) @@ -247,26 +252,26 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { // 2nd node Stake. privKey2, addr2 := g.newPrefundAccount() pk2 := crypto.FromECDSAPub(&privKey2.PublicKey) - input, err = abiObject.Pack("stake", pk2, "Test2", "test2@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err = GovernanceABI.ABI.Pack("stake", pk2, "Test2", "test2@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr2, input, amount) + _, err = g.call(GovernanceContractAddress, addr2, input, amount) g.Require().NoError(err) g.Require().Equal("Test2", g.s.Node(big.NewInt(0)).Name) g.Require().Equal(0, int(g.s.NodesOffsetByAddress(addr2).Int64())) // 1st node Stake. - input, err = abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err = GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) g.Require().Equal(2, len(g.s.QualifiedNodes())) g.Require().Equal(new(big.Int).Mul(amount, big.NewInt(2)).String(), g.s.TotalStaked().String()) // 2nd node Unstake. - input, err = abiObject.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake") g.Require().NoError(err) - _, err = g.call(addr2, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr2, input, big.NewInt(0)) g.Require().NoError(err) node = g.s.Node(big.NewInt(0)) g.Require().Equal("Test2", node.Name) @@ -275,9 +280,9 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(amount.String(), g.s.TotalStaked().String()) time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr2) + input, err = GovernanceABI.ABI.Pack("withdraw", addr2) g.Require().NoError(err) - _, err = g.call(addr2, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr2, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(1, len(g.s.QualifiedNodes())) @@ -286,17 +291,17 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(-1, int(g.s.NodesOffsetByAddress(addr2).Int64())) // 1st node Unstake. - input, err = abiObject.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake") g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String()) time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, int(g.s.LenNodes().Uint64())) @@ -309,15 +314,15 @@ func (g *GovernanceContractTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress)) } -func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { +func (g *OracleContractsTestSuite) TestDelegateUndelegate() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) // Stake. - input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - _, err = g.call(addr, input, ownerStaked) + _, err = g.call(GovernanceContractAddress, addr, input, ownerStaked) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) g.Require().Equal(addr, g.s.Delegator(addr, big.NewInt(0)).Owner) @@ -328,10 +333,10 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NoError(err) g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator)) g.Require().Equal(addrDelegator, g.s.Delegator(addr, big.NewInt(1)).Owner) @@ -340,7 +345,7 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { g.Require().Equal(1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64())) // Same person delegate the 2nd time should fail. - _, err = g.call(addrDelegator, input, big.NewInt(1e18)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(1e18)) g.Require().NotNil(err) // Not yet qualified. @@ -348,7 +353,7 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { // 2nd delegator delegate to 1st node. _, addrDelegator2 := g.newPrefundAccount() - _, err = g.call(addrDelegator2, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount) g.Require().NoError(err) g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator2)) g.Require().Equal(addrDelegator2, g.s.Delegator(addr, big.NewInt(2)).Owner) @@ -362,21 +367,21 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { // Undelegate addrDelegator. balanceBeforeUnDelegate := g.stateDB.GetBalance(addrDelegator) - input, err = abiObject.Pack("undelegate", addr) + input, err = GovernanceABI.ABI.Pack("undelegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().Equal(new(big.Int).Add(amount, ownerStaked), g.s.Node(big.NewInt(0)).Staked) g.Require().Equal(g.s.Node(big.NewInt(0)).Staked.String(), g.s.TotalStaked().String()) g.Require().NoError(err) // Undelegate the second time should fail. - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().Error(err) // Withdraw within lockup time should fail. - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().NotNil(err) g.Require().Equal(3, int(g.s.LenDelegators(addr).Uint64())) @@ -385,9 +390,9 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { // Wait for lockup time than withdraw. time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(2, int(g.s.LenDelegators(addr).Uint64())) @@ -396,16 +401,16 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { // Withdraw when their is no delegation should fail. time.Sleep(time.Second) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().Error(err) // Undelegate addrDelegator2. balanceBeforeUnDelegate = g.stateDB.GetBalance(addrDelegator2) - input, err = abiObject.Pack("undelegate", addr) + input, err = GovernanceABI.ABI.Pack("undelegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked) @@ -413,9 +418,9 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { // Wait for lockup time than withdraw. time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64())) @@ -429,31 +434,31 @@ func (g *GovernanceContractTestSuite) TestDelegateUndelegate() { g.Require().Equal(1, int(g.s.LenNodes().Uint64())) g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64())) - input, err = abiObject.Pack("undelegate", addr) + input, err = GovernanceABI.ABI.Pack("undelegate", addr) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(big.NewInt(0).String(), g.s.Node(big.NewInt(0)).Staked.String()) g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String()) time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().Equal(0, int(g.s.LenNodes().Uint64())) g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64())) } -func (g *GovernanceContractTestSuite) TestFine() { +func (g *OracleContractsTestSuite) TestFine() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) // Stake. - input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - _, err = g.call(addr, input, ownerStaked) + _, err = g.call(GovernanceContractAddress, addr, input, ownerStaked) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) g.Require().Equal(addr, g.s.Delegator(addr, big.NewInt(0)).Owner) @@ -464,10 +469,10 @@ func (g *GovernanceContractTestSuite) TestFine() { balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NoError(err) g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator)) g.Require().Equal(addrDelegator, g.s.Delegator(addr, big.NewInt(1)).Owner) @@ -478,9 +483,9 @@ func (g *GovernanceContractTestSuite) TestFine() { g.Require().Equal(1, len(g.s.QualifiedNodes())) // Paying to node without fine should fail. - input, err = abiObject.Pack("payFine", addr) + input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NotNil(err) // Fined. @@ -496,50 +501,50 @@ func (g *GovernanceContractTestSuite) TestFine() { g.Require().Equal(0, len(g.s.QualifiedNodes())) // Cannot undelegate before fines are paied. - input, err = abiObject.Pack("undelegate", addr) + input, err = GovernanceABI.ABI.Pack("undelegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().NotNil(err) // Only delegators can pay fine. _, addrDelegator2 := g.newPrefundAccount() - input, err = abiObject.Pack("payFine", addr) + input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, big.NewInt(5e5)) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(5e5)) g.Require().NotNil(err) // Paying more than fine should fail. payAmount := new(big.Int).Add(amount, amount) - input, err = abiObject.Pack("payFine", addr) + input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, payAmount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, payAmount) g.Require().NotNil(err) // Pay the fine. - input, err = abiObject.Pack("payFine", addr) + input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NoError(err) // Qualified. g.Require().Equal(1, len(g.s.QualifiedNodes())) // Can undelegate after all fines are paied. - input, err = abiObject.Pack("undelegate", addr) + input, err = GovernanceABI.ABI.Pack("undelegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().NoError(err) } -func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() { +func (g *OracleContractsTestSuite) TestUnstakeWithExtraDelegators() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err := abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) // 1st delegator delegate to 1st node. @@ -547,10 +552,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() { balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NoError(err) g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator)) g.Require().Equal(addrDelegator, g.s.Delegator(addr, big.NewInt(1)).Owner) @@ -560,10 +565,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() { _, addrDelegator2 := g.newPrefundAccount() balanceBeforeDelegate = g.stateDB.GetBalance(addrDelegator2) - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount) g.Require().NoError(err) g.Require().Equal(new(big.Int).Sub(balanceBeforeDelegate, amount), g.stateDB.GetBalance(addrDelegator2)) g.Require().Equal(addrDelegator2, g.s.Delegator(addr, big.NewInt(2)).Owner) @@ -572,19 +577,19 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() { g.Require().Equal(1, len(g.s.QualifiedNodes())) // Unstake. - input, err = abiObject.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake") g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) time.Sleep(time.Second * 2) - input, err = abiObject.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw", addr) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64())) @@ -597,10 +602,10 @@ func (g *GovernanceContractTestSuite) TestUnstakeWithExtraDelegators() { g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress)) } -func (g *GovernanceContractTestSuite) TestUpdateConfiguration() { +func (g *OracleContractsTestSuite) TestUpdateConfiguration() { _, addr := g.newPrefundAccount() - input, err := abiObject.Pack("updateConfiguration", + input, err := GovernanceABI.ABI.Pack("updateConfiguration", new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)), big.NewInt(1000), big.NewInt(8000000), @@ -617,156 +622,156 @@ func (g *GovernanceContractTestSuite) TestUpdateConfiguration() { g.Require().NoError(err) // Call with non-owner. - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NotNil(err) // Call with owner. - _, err = g.call(g.config.Owner, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, g.config.Owner, input, big.NewInt(0)) g.Require().NoError(err) } -func (g *GovernanceContractTestSuite) TestConfigurationReading() { +func (g *OracleContractsTestSuite) TestConfigurationReading() { _, addr := g.newPrefundAccount() // CRS. - input, err := abiObject.Pack("crs", big.NewInt(0)) + input, err := GovernanceABI.ABI.Pack("crs", big.NewInt(0)) g.Require().NoError(err) - res, err := g.call(addr, input, big.NewInt(0)) + res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var crs0 [32]byte - err = abiObject.Unpack(&crs0, "crs", res) + err = GovernanceABI.ABI.Unpack(&crs0, "crs", res) g.Require().NoError(err) g.Require().Equal(crypto.Keccak256Hash([]byte(g.config.GenesisCRSText)), common.BytesToHash(crs0[:])) // Owner. - input, err = abiObject.Pack("owner") + input, err = GovernanceABI.ABI.Pack("owner") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var owner common.Address - err = abiObject.Unpack(&owner, "owner", res) + err = GovernanceABI.ABI.Unpack(&owner, "owner", res) g.Require().NoError(err) g.Require().Equal(g.config.Owner, owner) // MinStake. - input, err = abiObject.Pack("minStake") + input, err = GovernanceABI.ABI.Pack("minStake") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var value *big.Int - err = abiObject.Unpack(&value, "minStake", res) + err = GovernanceABI.ABI.Unpack(&value, "minStake", res) g.Require().NoError(err) g.Require().Equal(g.config.MinStake.String(), value.String()) // BlockReward. - input, err = abiObject.Pack("miningVelocity") + input, err = GovernanceABI.ABI.Pack("miningVelocity") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "miningVelocity", res) + err = GovernanceABI.ABI.Unpack(&value, "miningVelocity", res) g.Require().NoError(err) g.Require().Equal(g.config.MiningVelocity, float32(value.Uint64())/decimalMultiplier) // BlockGasLimit. - input, err = abiObject.Pack("blockGasLimit") + input, err = GovernanceABI.ABI.Pack("blockGasLimit") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "blockGasLimit", res) + err = GovernanceABI.ABI.Unpack(&value, "blockGasLimit", res) g.Require().NoError(err) g.Require().Equal(g.config.BlockGasLimit, value.Uint64()) // NumChains. - input, err = abiObject.Pack("numChains") + input, err = GovernanceABI.ABI.Pack("numChains") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "numChains", res) + err = GovernanceABI.ABI.Unpack(&value, "numChains", res) g.Require().NoError(err) g.Require().Equal(g.config.NumChains, uint32(value.Uint64())) // LambdaBA. - input, err = abiObject.Pack("lambdaBA") + input, err = GovernanceABI.ABI.Pack("lambdaBA") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "lambdaBA", res) + err = GovernanceABI.ABI.Unpack(&value, "lambdaBA", res) g.Require().NoError(err) g.Require().Equal(g.config.LambdaBA, value.Uint64()) // LambdaDKG. - input, err = abiObject.Pack("lambdaDKG") + input, err = GovernanceABI.ABI.Pack("lambdaDKG") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "lambdaDKG", res) + err = GovernanceABI.ABI.Unpack(&value, "lambdaDKG", res) g.Require().NoError(err) g.Require().Equal(g.config.LambdaDKG, value.Uint64()) // K. - input, err = abiObject.Pack("k") + input, err = GovernanceABI.ABI.Pack("k") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "k", res) + err = GovernanceABI.ABI.Unpack(&value, "k", res) g.Require().NoError(err) g.Require().Equal(g.config.K, uint32(value.Uint64())) // PhiRatio. - input, err = abiObject.Pack("phiRatio") + input, err = GovernanceABI.ABI.Pack("phiRatio") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "phiRatio", res) + err = GovernanceABI.ABI.Unpack(&value, "phiRatio", res) g.Require().NoError(err) g.Require().Equal(g.config.PhiRatio, float32(value.Uint64())/decimalMultiplier) // NotarySetSize. - input, err = abiObject.Pack("notarySetSize") + input, err = GovernanceABI.ABI.Pack("notarySetSize") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "notarySetSize", res) + err = GovernanceABI.ABI.Unpack(&value, "notarySetSize", res) g.Require().NoError(err) g.Require().Equal(g.config.NotarySetSize, uint32(value.Uint64())) // DKGSetSize. - input, err = abiObject.Pack("dkgSetSize") + input, err = GovernanceABI.ABI.Pack("dkgSetSize") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "dkgSetSize", res) + err = GovernanceABI.ABI.Unpack(&value, "dkgSetSize", res) g.Require().NoError(err) g.Require().Equal(g.config.DKGSetSize, uint32(value.Uint64())) // RoundInterval. - input, err = abiObject.Pack("roundInterval") + input, err = GovernanceABI.ABI.Pack("roundInterval") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "roundInterval", res) + err = GovernanceABI.ABI.Unpack(&value, "roundInterval", res) g.Require().NoError(err) g.Require().Equal(g.config.RoundInterval, value.Uint64()) // MinBlockInterval. - input, err = abiObject.Pack("minBlockInterval") + input, err = GovernanceABI.ABI.Pack("minBlockInterval") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "minBlockInterval", res) + err = GovernanceABI.ABI.Unpack(&value, "minBlockInterval", res) g.Require().NoError(err) g.Require().Equal(g.config.MinBlockInterval, value.Uint64()) } -func (g *GovernanceContractTestSuite) TestReportForkVote() { +func (g *OracleContractsTestSuite) TestReportForkVote() { key, addr := g.newPrefundAccount() pkBytes := crypto.FromECDSAPub(&key.PublicKey) // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err := abiObject.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) pubKey := coreEcdsa.NewPublicKeyFromECDSA(&key.PublicKey) @@ -789,23 +794,23 @@ func (g *GovernanceContractTestSuite) TestReportForkVote() { g.Require().NoError(err) // Report wrong type (fork block) - input, err = abiObject.Pack("report", big.NewInt(2), vote1Bytes, vote2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), vote1Bytes, vote2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().Error(err) - input, err = abiObject.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) node := g.s.Node(big.NewInt(0)) g.Require().Equal(node.Fined, g.s.FineValue(big.NewInt(1))) // Duplicate report should fail. - input, err = abiObject.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), vote1Bytes, vote2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().Error(err) // Check if finedRecords is set. @@ -813,26 +818,26 @@ func (g *GovernanceContractTestSuite) TestReportForkVote() { sort.Sort(sortBytes(payloads)) hash := Bytes32(crypto.Keccak256Hash(payloads...)) - input, err = abiObject.Pack("finedRecords", hash) + input, err = GovernanceABI.ABI.Pack("finedRecords", hash) g.Require().NoError(err) - res, err := g.call(addr, input, big.NewInt(0)) + res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var value bool - err = abiObject.Unpack(&value, "finedRecords", res) + err = GovernanceABI.ABI.Unpack(&value, "finedRecords", res) g.Require().NoError(err) g.Require().True(value) } -func (g *GovernanceContractTestSuite) TestReportForkBlock() { +func (g *OracleContractsTestSuite) TestReportForkBlock() { key, addr := g.newPrefundAccount() pkBytes := crypto.FromECDSAPub(&key.PublicKey) // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err := abiObject.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) privKey := coreEcdsa.NewPrivateKeyFromECDSA(key) @@ -866,23 +871,23 @@ func (g *GovernanceContractTestSuite) TestReportForkBlock() { g.Require().NoError(err) // Report wrong type (fork vote) - input, err = abiObject.Pack("report", big.NewInt(1), block1Bytes, block2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(1), block1Bytes, block2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().Error(err) - input, err = abiObject.Pack("report", big.NewInt(2), block1Bytes, block2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), block1Bytes, block2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) node := g.s.Node(big.NewInt(0)) g.Require().Equal(node.Fined, g.s.FineValue(big.NewInt(2))) // Duplicate report should fail. - input, err = abiObject.Pack("report", big.NewInt(2), block1Bytes, block2Bytes) + input, err = GovernanceABI.ABI.Pack("report", big.NewInt(2), block1Bytes, block2Bytes) g.Require().NoError(err) - _, err = g.call(addr, input, big.NewInt(0)) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().Error(err) // Check if finedRecords is set. @@ -890,113 +895,113 @@ func (g *GovernanceContractTestSuite) TestReportForkBlock() { sort.Sort(sortBytes(payloads)) hash := Bytes32(crypto.Keccak256Hash(payloads...)) - input, err = abiObject.Pack("finedRecords", hash) + input, err = GovernanceABI.ABI.Pack("finedRecords", hash) g.Require().NoError(err) - res, err := g.call(addr, input, big.NewInt(0)) + res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var value bool - err = abiObject.Unpack(&value, "finedRecords", res) + err = GovernanceABI.ABI.Unpack(&value, "finedRecords", res) g.Require().NoError(err) g.Require().True(value) } -func (g *GovernanceContractTestSuite) TestMiscVariableReading() { +func (g *OracleContractsTestSuite) TestMiscVariableReading() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) - input, err := abiObject.Pack("totalSupply") + input, err := GovernanceABI.ABI.Pack("totalSupply") g.Require().NoError(err) - res, err := g.call(addr, input, big.NewInt(0)) + res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - input, err = abiObject.Pack("totalStaked") + input, err = GovernanceABI.ABI.Pack("totalStaked") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err = abiObject.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err = GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) - _, err = g.call(addr, input, amount) + _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) // 1st delegator delegate to 1st node. _, addrDelegator := g.newPrefundAccount() amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) g.Require().NoError(err) // 2st delegator delegate to 1st node. _, addrDelegator2 := g.newPrefundAccount() - input, err = abiObject.Pack("delegate", addr) + input, err = GovernanceABI.ABI.Pack("delegate", addr) g.Require().NoError(err) - _, err = g.call(addrDelegator2, input, amount) + _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount) g.Require().NoError(err) - input, err = abiObject.Pack("nodes", big.NewInt(0)) + input, err = GovernanceABI.ABI.Pack("nodes", big.NewInt(0)) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - input, err = abiObject.Pack("nodesLength") + input, err = GovernanceABI.ABI.Pack("nodesLength") g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) var value *big.Int - err = abiObject.Unpack(&value, "nodesLength", res) + err = GovernanceABI.ABI.Unpack(&value, "nodesLength", res) g.Require().NoError(err) g.Require().Equal(1, int(value.Uint64())) - input, err = abiObject.Pack("nodesOffsetByAddress", addr) + input, err = GovernanceABI.ABI.Pack("nodesOffsetByAddress", addr) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "nodesOffsetByAddress", res) + err = GovernanceABI.ABI.Unpack(&value, "nodesOffsetByAddress", res) g.Require().NoError(err) g.Require().Equal(0, int(value.Uint64())) id, err := publicKeyToNodeID(pk) g.Require().NoError(err) - input, err = abiObject.Pack("nodesOffsetByID", id) + input, err = GovernanceABI.ABI.Pack("nodesOffsetByID", id) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "nodesOffsetByID", res) + err = GovernanceABI.ABI.Unpack(&value, "nodesOffsetByID", res) g.Require().NoError(err) g.Require().Equal(0, int(value.Uint64())) - input, err = abiObject.Pack("delegators", addr, big.NewInt(0)) + input, err = GovernanceABI.ABI.Pack("delegators", addr, big.NewInt(0)) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - input, err = abiObject.Pack("delegatorsLength", addr) + input, err = GovernanceABI.ABI.Pack("delegatorsLength", addr) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "delegatorsLength", res) + err = GovernanceABI.ABI.Unpack(&value, "delegatorsLength", res) g.Require().NoError(err) g.Require().Equal(3, int(value.Uint64())) - input, err = abiObject.Pack("delegatorsOffset", addr, addrDelegator2) + input, err = GovernanceABI.ABI.Pack("delegatorsOffset", addr, addrDelegator2) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) - err = abiObject.Unpack(&value, "delegatorsOffset", res) + err = GovernanceABI.ABI.Unpack(&value, "delegatorsOffset", res) g.Require().NoError(err) g.Require().Equal(2, int(value.Uint64())) - input, err = abiObject.Pack("fineValues", big.NewInt(0)) + input, err = GovernanceABI.ABI.Pack("fineValues", big.NewInt(0)) g.Require().NoError(err) - res, err = g.call(addr, input, big.NewInt(0)) + res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) } -func (g *GovernanceContractTestSuite) TestHalvingCondition() { +func (g *OracleContractsTestSuite) TestHalvingCondition() { // TotalSupply 2.5B reached g.s.MiningHalved() g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3.25e9)).String(), @@ -1012,6 +1017,47 @@ func (g *GovernanceContractTestSuite) TestHalvingCondition() { g.s.LastHalvedAmount().String()) } +func (g *OracleContractsTestSuite) TestNodeInfoOracleContract() { + privKey, addr := g.newPrefundAccount() + pk := crypto.FromECDSAPub(&privKey.PublicKey) + + // Stake. + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) + input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + g.Require().NoError(err) + _, err = g.call(GovernanceContractAddress, addr, input, amount) + g.Require().NoError(err) + + // Invalid round. + input, err = NodeInfoOracleABI.ABI.Pack("delegators", big.NewInt(100), addr, big.NewInt(0)) + g.Require().NoError(err) + res, err := g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0)) + g.Require().Error(err) + + round := big.NewInt(0) + input, err = NodeInfoOracleABI.ABI.Pack("delegators", round, addr, big.NewInt(0)) + g.Require().NoError(err) + res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0)) + g.Require().NoError(err) + + var value *big.Int + input, err = NodeInfoOracleABI.ABI.Pack("delegatorsLength", round, addr) + g.Require().NoError(err) + res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0)) + g.Require().NoError(err) + err = NodeInfoOracleABI.ABI.Unpack(&value, "delegatorsLength", res) + g.Require().NoError(err) + g.Require().Equal(1, int(value.Uint64())) + + input, err = NodeInfoOracleABI.ABI.Pack("delegatorsOffset", round, addr, addr) + g.Require().NoError(err) + res, err = g.call(NodeInfoOracleAddress, addr, input, big.NewInt(0)) + g.Require().NoError(err) + err = NodeInfoOracleABI.ABI.Unpack(&value, "delegatorsOffset", res) + g.Require().NoError(err) + g.Require().Equal(0, int(value.Uint64())) +} + func TestGovernanceContract(t *testing.T) { - suite.Run(t, new(GovernanceContractTestSuite)) + suite.Run(t, new(OracleContractsTestSuite)) } diff --git a/test/genesis.json b/test/genesis.json index 7ab90e48b..0785f36c7 100644 --- a/test/genesis.json +++ b/test/genesis.json @@ -1,7 +1,7 @@ { "config": { "chainId": 237, - "dMoment": 1547480026, + "dMoment": 0, "homesteadBlock": 0, "daoForkBlock": 0, "daoForkSupport": true, |