diff options
author | Wei-Ning Huang <w@dexon.org> | 2019-03-11 15:47:29 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-06-12 17:27:22 +0800 |
commit | 04cb64b849988c1cf71fd66a3142f01e8ba7cb23 (patch) | |
tree | 1e31ce72bf75a0e81ff95b9bcf7b4d6db26cfa98 | |
parent | a03655ca09836a282db33fadf2fcd78d898364a4 (diff) | |
download | go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar.gz go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar.bz2 go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar.lz go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar.xz go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.tar.zst go-tangerine-04cb64b849988c1cf71fd66a3142f01e8ba7cb23.zip |
core: vm: remove delegation mechanism (#245)
The current delegation mechanism are prone to unstaking attack. i.e. a
malicious attacker could unstake a small amount from a lot of node it
staked before and make them unqualified, which leads to potential
failure of the network.
Since DEXON does not use consensus like DPoS, node is required to have
at least MinStake in order to become a node. Voting mechanism is not
required in our system since qualified node does not depends on the
number of votes. Instead of managing the delegation mechanism in
governance contract, we should let the owner manage the delegation and
reward distribution mechanism on their own.
-rw-r--r-- | cmd/gdex/dao_test.go | 2 | ||||
-rw-r--r-- | core/genesis.go | 5 | ||||
-rw-r--r-- | core/genesis_test.go | 2 | ||||
-rw-r--r-- | core/vm/oracle.go | 4 | ||||
-rw-r--r-- | core/vm/oracle_contract_abi.go | 255 | ||||
-rw-r--r-- | core/vm/oracle_contracts.go | 573 | ||||
-rw-r--r-- | core/vm/oracle_contracts_test.go | 421 | ||||
-rw-r--r-- | params/config.go | 6 |
8 files changed, 267 insertions, 1001 deletions
diff --git a/cmd/gdex/dao_test.go b/cmd/gdex/dao_test.go index 9a768c3fc..1e8cfc487 100644 --- a/cmd/gdex/dao_test.go +++ b/cmd/gdex/dao_test.go @@ -77,7 +77,7 @@ var daoProForkGenesis = `{ } }` -var daoGenesisHash = common.HexToHash("0x917e74766af045b81b7e45650fc40af9bd41282eaaac7ec3f89d8f10d82f434e") +var daoGenesisHash = common.HexToHash("0xa530369e97a85c4f3522bf5e89be851b00aac7c30080c4ca624ce7c4ff5c9a80") var daoGenesisForkBlock = big.NewInt(314) // TestDAOForkBlockNewChain tests that the DAO hard-fork number and the nodes support/opposition is correctly diff --git a/core/genesis.go b/core/genesis.go index f6935830c..7f2cafbf5 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -302,9 +302,10 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { for _, addr := range keys { account := g.Alloc[addr] if account.Staked.Cmp(big.NewInt(0)) > 0 { - govStateHelper.Stake(addr, account.PublicKey, account.Staked, + govStateHelper.Register(addr, account.PublicKey, account.NodeInfo.Name, account.NodeInfo.Email, - account.NodeInfo.Location, account.NodeInfo.Url) + account.NodeInfo.Location, account.NodeInfo.Url, + account.Staked) } } diff --git a/core/genesis_test.go b/core/genesis_test.go index c083ed9aa..de843e05a 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -43,7 +43,7 @@ func TestDefaultGenesisBlock(t *testing.T) { func TestSetupGenesis(t *testing.T) { var ( - customghash = common.HexToHash("0xbd64608d51b78fd61aeb6d91669fd3ff09c12c7552f0923b0c2d19910887efda") + customghash = common.HexToHash("0x1f619d2e0f8293d83dad154ef95f6e09dcfdbe92b7f06f658d5dece20e5132e4") customg = Genesis{ Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, Alloc: GenesisAlloc{ diff --git a/core/vm/oracle.go b/core/vm/oracle.go index 14ba9b2f5..81755cd9b 100644 --- a/core/vm/oracle.go +++ b/core/vm/oracle.go @@ -25,14 +25,11 @@ import ( ) 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. @@ -45,7 +42,6 @@ var OracleContracts = map[common.Address]OracleContract{ GovernanceContractAddress: &GovernanceContract{ coreDKGUtils: &defaultCoreDKGUtils{}, }, - NodeInfoOracleAddress: &NodeInfoOracleContract{}, } // Run oracle contract. diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go index 2de3d650f..23fb99ae5 100644 --- a/core/vm/oracle_contract_abi.go +++ b/core/vm/oracle_contract_abi.go @@ -24,29 +24,6 @@ const GovernanceABIJSON = ` [ { "constant": true, - "inputs": [ - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "delegatorsOffset", - "outputs": [ - { - "name": "", - "type": "int256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, "inputs": [], "name": "notarySetSize", "outputs": [ @@ -128,6 +105,14 @@ const GovernanceABIJSON = ` { "name": "url", "type": "string" + }, + { + "name": "unstaked", + "type": "uint256" + }, + { + "name": "unstaked_at", + "type": "uint256" } ], "payable": false, @@ -196,37 +181,6 @@ const GovernanceABIJSON = ` { "name": "", "type": "address" - }, - { - "name": "", - "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": "", - "type": "address" } ], "name": "dkgFinalizeds", @@ -637,6 +591,11 @@ const GovernanceABIJSON = ` "indexed": true, "name": "NodeAddress", "type": "address" + }, + { + "indexed": false, + "name": "Amount", + "type": "uint256" } ], "name": "Staked", @@ -649,21 +608,14 @@ const GovernanceABIJSON = ` "indexed": true, "name": "NodeAddress", "type": "address" - } - ], - "name": "Unstaked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ + }, { - "indexed": true, - "name": "NodeAddress", - "type": "address" + "indexed": false, + "name": "Amount", + "type": "uint256" } ], - "name": "NodeRemoved", + "name": "Unstaked", "type": "event" }, { @@ -675,17 +627,12 @@ const GovernanceABIJSON = ` "type": "address" }, { - "indexed": true, - "name": "DelegatorAddress", - "type": "address" - }, - { "indexed": false, "name": "Amount", "type": "uint256" } ], - "name": "Delegated", + "name": "Withdrawn", "type": "event" }, { @@ -695,19 +642,9 @@ const GovernanceABIJSON = ` "indexed": true, "name": "NodeAddress", "type": "address" - }, - { - "indexed": true, - "name": "DelegatorAddress", - "type": "address" - }, - { - "indexed": false, - "name": "Amount", - "type": "uint256" } ], - "name": "Undelegated", + "name": "NodeAdded", "type": "event" }, { @@ -717,19 +654,9 @@ const GovernanceABIJSON = ` "indexed": true, "name": "NodeAddress", "type": "address" - }, - { - "indexed": true, - "name": "DelegatorAddress", - "type": "address" - }, - { - "indexed": false, - "name": "Amount", - "type": "uint256" } ], - "name": "Withdrawn", + "name": "NodeRemoved", "type": "event" }, { @@ -893,25 +820,6 @@ const GovernanceABIJSON = ` "type": "function" }, { - "constant": true, - "inputs": [ - { - "name": "NodeAddress", - "type": "address" - } - ], - "name": "delegatorsLength", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { "constant": false, "inputs": [ { @@ -1025,7 +933,7 @@ const GovernanceABIJSON = ` "type": "string" } ], - "name": "stake", + "name": "register", "outputs": [], "payable": true, "stateMutability": "payable", @@ -1034,21 +942,7 @@ const GovernanceABIJSON = ` { "constant": false, "inputs": [], - "name": "unstake", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "NodeAddress", - "type": "address" - } - ], - "name": "delegate", + "name": "stake", "outputs": [], "payable": true, "stateMutability": "payable", @@ -1058,11 +952,11 @@ const GovernanceABIJSON = ` "constant": false, "inputs": [ { - "name": "NodeAddress", - "type": "address" + "name": "Amount", + "type": "uint256" } ], - "name": "undelegate", + "name": "unstake", "outputs": [], "payable": false, "stateMutability": "nonpayable", @@ -1070,12 +964,7 @@ const GovernanceABIJSON = ` }, { "constant": false, - "inputs": [ - { - "name": "NodeAddress", - "type": "address" - } - ], + "inputs": [], "name": "withdraw", "outputs": [], "payable": false, @@ -1134,93 +1023,3 @@ 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/oracle_contracts.go b/core/vm/oracle_contracts.go index 5c5a44185..0904c2430 100644 --- a/core/vm/oracle_contracts.go +++ b/core/vm/oracle_contracts.go @@ -59,8 +59,6 @@ const ( nodesLoc nodesOffsetByAddressLoc nodesOffsetByNodeKeyAddressLoc - delegatorsLoc - delegatorsOffsetLoc crsRoundLoc crsLoc dkgRoundLoc @@ -316,22 +314,26 @@ func (s *GovernanceState) DecTotalStaked(amount *big.Int) { // string email; // string location; // string url; +// uint256 unstaked; +// uint256 unstaked_at; // } // // Node[] nodes; type nodeInfo struct { - Owner common.Address - PublicKey []byte - Staked *big.Int - Fined *big.Int - Name string - Email string - Location string - Url string + Owner common.Address + PublicKey []byte + Staked *big.Int + Fined *big.Int + Name string + Email string + Location string + Url string + Unstaked *big.Int + UnstakedAt *big.Int } -const nodeStructSize = 8 +const nodeStructSize = 10 func (s *GovernanceState) LenNodes() *big.Int { return s.getStateBigInt(big.NewInt(nodesLoc)) @@ -375,6 +377,14 @@ func (s *GovernanceState) Node(index *big.Int) *nodeInfo { loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) node.Url = string(s.readBytes(loc)) + // Unstaked. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(8)) + node.Unstaked = s.getStateBigInt(loc) + + // UnstakedAt. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(9)) + node.UnstakedAt = s.getStateBigInt(loc) + return node } func (s *GovernanceState) PushNode(n *nodeInfo) { @@ -420,6 +430,14 @@ func (s *GovernanceState) UpdateNode(index *big.Int, n *nodeInfo) { // Url. loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) s.writeBytes(loc, []byte(n.Url)) + + // Unstaked. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(8)) + s.setStateBigInt(loc, n.Unstaked) + + // UnstakedAt. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(9)) + s.setStateBigInt(loc, n.UnstakedAt) } func (s *GovernanceState) PopLastNode() { // Decrease length by 1. @@ -428,8 +446,10 @@ func (s *GovernanceState) PopLastNode() { s.setStateBigInt(big.NewInt(nodesLoc), newArrayLength) s.UpdateNode(newArrayLength, &nodeInfo{ - Staked: big.NewInt(0), - Fined: big.NewInt(0), + Staked: big.NewInt(0), + Fined: big.NewInt(0), + Unstaked: big.NewInt(0), + UnstakedAt: big.NewInt(0), }) } func (s *GovernanceState) Nodes() []*nodeInfo { @@ -487,6 +507,15 @@ func (s *GovernanceState) PutNodeOffsets(n *nodeInfo, offset *big.Int) error { s.PutNodesOffsetByAddress(n.Owner, offset) return nil } +func (s *GovernanceState) DeleteNodeOffsets(n *nodeInfo) error { + address, err := publicKeyToNodeKeyAddress(n.PublicKey) + if err != nil { + return err + } + s.DeleteNodesOffsetByNodeKeyAddress(address) + s.DeleteNodesOffsetByAddress(n.Owner) + return nil +} func (s *GovernanceState) GetNodeOwnerByID(id coreTypes.NodeID) (common.Address, error) { offset := s.NodesOffsetByNodeKeyAddress(idToAddress(id)) @@ -497,99 +526,6 @@ func (s *GovernanceState) GetNodeOwnerByID(id coreTypes.NodeID) (common.Address, return node.Owner, nil } -// struct Delegator { -// address node; -// address owner; -// uint256 value; -// uint256 undelegated_at; -// } - -type delegatorInfo struct { - Owner common.Address - Value *big.Int - UndelegatedAt *big.Int -} - -const delegatorStructSize = 3 - -// mapping(address => Delegator[]) public delegators; -func (s *GovernanceState) LenDelegators(nodeAddr common.Address) *big.Int { - loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes()) - return s.getStateBigInt(loc) -} -func (s *GovernanceState) Delegator(nodeAddr common.Address, offset *big.Int) *delegatorInfo { - delegator := new(delegatorInfo) - - loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes()) - arrayBaseLoc := s.getSlotLoc(loc) - elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(big.NewInt(delegatorStructSize), offset)) - - // Owner. - loc = elementBaseLoc - delegator.Owner = common.BytesToAddress(s.getState(common.BigToHash(elementBaseLoc)).Bytes()) - - // Value. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(1)) - delegator.Value = s.getStateBigInt(loc) - - // UndelegatedAt. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2)) - delegator.UndelegatedAt = s.getStateBigInt(loc) - - return delegator -} -func (s *GovernanceState) PushDelegator(nodeAddr common.Address, delegator *delegatorInfo) { - // Increase length by 1. - arrayLength := s.LenDelegators(nodeAddr) - loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes()) - s.setStateBigInt(loc, new(big.Int).Add(arrayLength, big.NewInt(1))) - - s.UpdateDelegator(nodeAddr, arrayLength, delegator) -} -func (s *GovernanceState) UpdateDelegator(nodeAddr common.Address, offset *big.Int, delegator *delegatorInfo) { - loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes()) - arrayBaseLoc := s.getSlotLoc(loc) - elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(big.NewInt(delegatorStructSize), offset)) - - // Owner. - loc = elementBaseLoc - s.setState(common.BigToHash(loc), delegator.Owner.Hash()) - - // Value. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(1)) - s.setStateBigInt(loc, delegator.Value) - - // UndelegatedAt. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2)) - s.setStateBigInt(loc, delegator.UndelegatedAt) -} -func (s *GovernanceState) PopLastDelegator(nodeAddr common.Address) { - // Decrease length by 1. - arrayLength := s.LenDelegators(nodeAddr) - newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1)) - loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes()) - s.setStateBigInt(loc, newArrayLength) - - s.UpdateDelegator(nodeAddr, newArrayLength, &delegatorInfo{ - Value: big.NewInt(0), - UndelegatedAt: big.NewInt(0), - }) -} - -// mapping(address => mapping(address => uint256)) delegatorsOffset; -func (s *GovernanceState) DelegatorsOffset(nodeAddr, delegatorAddr common.Address) *big.Int { - loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes()) - return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1)) -} -func (s *GovernanceState) PutDelegatorOffset(nodeAddr, delegatorAddr common.Address, offset *big.Int) { - loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes()) - s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1))) -} -func (s *GovernanceState) DeleteDelegatorsOffset(nodeAddr, delegatorAddr common.Address) { - loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes()) - s.setStateBigInt(loc, big.NewInt(0)) -} - // uint256 public crsRound; func (s *GovernanceState) CRSRound() *big.Int { return s.getStateBigInt(big.NewInt(crsRoundLoc)) @@ -900,20 +836,22 @@ func (s *GovernanceState) Initialize(config *params.DexconConfig, totalSupply *b s.SetDKGRound(big.NewInt(int64(dexCore.DKGDelayRound))) } -// Stake is a helper function for creating genesis state. -func (s *GovernanceState) Stake( - addr common.Address, publicKey []byte, staked *big.Int, - name, email, location, url string) { +// Register is a helper function for creating genesis state. +func (s *GovernanceState) Register( + addr common.Address, publicKey []byte, + name, email, location, url string, staked *big.Int) { offset := s.LenNodes() node := &nodeInfo{ - Owner: addr, - PublicKey: publicKey, - Staked: staked, - Fined: big.NewInt(0), - Name: name, - Email: email, - Location: location, - Url: url, + Owner: addr, + PublicKey: publicKey, + Staked: staked, + Fined: big.NewInt(0), + Name: name, + Email: email, + Location: location, + Url: url, + Unstaked: big.NewInt(0), + UnstakedAt: big.NewInt(0), } s.PushNode(node) if err := s.PutNodeOffsets(node, offset); err != nil { @@ -924,14 +862,6 @@ func (s *GovernanceState) Stake( return } - offset = s.LenDelegators(addr) - s.PushDelegator(addr, &delegatorInfo{ - Owner: addr, - Value: staked, - UndelegatedAt: big.NewInt(0), - }) - s.PutDelegatorOffset(addr, addr, offset) - // Add to network total staked. s.IncTotalStaked(staked) } @@ -1024,56 +954,47 @@ func (s *GovernanceState) emitCRSProposed(round *big.Int, crs common.Hash) { } // event Staked(address indexed NodeAddress, uint256 Amount); -func (s *GovernanceState) emitStaked(nodeAddr common.Address) { +func (s *GovernanceState) emitStaked(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, Topics: []common.Hash{GovernanceABI.Events["Staked"].Id(), nodeAddr.Hash()}, - Data: []byte{}, + Data: common.BigToHash(amount).Bytes(), }) } -// event Unstaked(address indexed NodeAddress); -func (s *GovernanceState) emitUnstaked(nodeAddr common.Address) { +// event Unstaked(address indexed NodeAddress, uint256 Amount); +func (s *GovernanceState) emitUnstaked(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, Topics: []common.Hash{GovernanceABI.Events["Unstaked"].Id(), nodeAddr.Hash()}, - Data: []byte{}, - }) -} - -// event NodeRemoved(address indexed NodeAddress); -func (s *GovernanceState) emitNodeRemoved(nodeAddr common.Address) { - s.StateDB.AddLog(&types.Log{ - Address: GovernanceContractAddress, - Topics: []common.Hash{GovernanceABI.Events["NodeRemoved"].Id(), nodeAddr.Hash()}, - Data: []byte{}, + Data: common.BigToHash(amount).Bytes(), }) } -// event Delegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount); -func (s *GovernanceState) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) { +// event Withdrawn(address indexed NodeAddress, uint256 Amount); +func (s *GovernanceState) emitWithdrawn(nodeAddr common.Address, amount *big.Int) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{GovernanceABI.Events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, + Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash()}, Data: common.BigToHash(amount).Bytes(), }) } -// event Undelegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount); -func (s *GovernanceState) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) { +// event NodeAdded(address indexed NodeAddress); +func (s *GovernanceState) emitNodeAdded(nodeAddr common.Address) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{GovernanceABI.Events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, - Data: common.BigToHash(amount).Bytes(), + Topics: []common.Hash{GovernanceABI.Events["NodeAdded"].Id(), nodeAddr.Hash()}, + Data: []byte{}, }) } -// event Withdrawn(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount); -func (s *GovernanceState) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) { +// event NodeRemoved(address indexed NodeAddress); +func (s *GovernanceState) emitNodeRemoved(nodeAddr common.Address) { s.StateDB.AddLog(&types.Log{ Address: GovernanceContractAddress, - Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()}, - Data: common.BigToHash(amount).Bytes(), + Topics: []common.Hash{GovernanceABI.Events["NodeRemoved"].Id(), nodeAddr.Hash()}, + Data: []byte{}, }) } @@ -1476,47 +1397,6 @@ func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([] return g.useGas(100000) } -func (g *GovernanceContract) delegate(nodeAddr common.Address) ([]byte, error) { - offset := g.state.NodesOffsetByAddress(nodeAddr) - if offset.Cmp(big.NewInt(0)) < 0 { - return nil, errExecutionReverted - } - - caller := g.contract.Caller() - value := g.contract.Value() - - // Can not delegate if no fund was sent. - if value.Cmp(big.NewInt(0)) == 0 { - return nil, errExecutionReverted - } - - // Can not delegate if already delegated. - delegatorOffset := g.state.DelegatorsOffset(nodeAddr, caller) - if delegatorOffset.Cmp(big.NewInt(0)) >= 0 { - return nil, errExecutionReverted - } - - // Add to the total staked of node. - node := g.state.Node(offset) - node.Staked = new(big.Int).Add(node.Staked, g.contract.Value()) - g.state.UpdateNode(offset, node) - - // Add to network total staked. - g.state.IncTotalStaked(g.contract.Value()) - - // Push delegator record. - offset = g.state.LenDelegators(nodeAddr) - g.state.PushDelegator(nodeAddr, &delegatorInfo{ - Owner: caller, - Value: value, - UndelegatedAt: big.NewInt(0), - }) - g.state.PutDelegatorOffset(nodeAddr, caller, offset) - g.state.emitDelegated(nodeAddr, caller, value) - - return g.useGas(200000) -} - func (g *GovernanceContract) updateConfiguration(cfg *rawConfigStruct) ([]byte, error) { // Only owner can update configuration. if g.contract.Caller() != g.state.Owner() { @@ -1528,7 +1408,7 @@ func (g *GovernanceContract) updateConfiguration(cfg *rawConfigStruct) ([]byte, return nil, nil } -func (g *GovernanceContract) stake( +func (g *GovernanceContract) register( publicKey []byte, name, email, location, url string) ([]byte, error) { // Reject invalid inputs. @@ -1537,6 +1417,7 @@ func (g *GovernanceContract) stake( } caller := g.contract.Caller() + value := g.contract.Value() offset := g.state.NodesOffsetByAddress(caller) // Can not stake if already staked. @@ -1546,119 +1427,121 @@ func (g *GovernanceContract) stake( offset = g.state.LenNodes() node := &nodeInfo{ - Owner: caller, - PublicKey: publicKey, - Staked: big.NewInt(0), - Fined: big.NewInt(0), - Name: name, - Email: email, - Location: location, - Url: url, + Owner: caller, + PublicKey: publicKey, + Staked: value, + Fined: big.NewInt(0), + Name: name, + Email: email, + Location: location, + Url: url, + Unstaked: big.NewInt(0), + UnstakedAt: big.NewInt(0), } g.state.PushNode(node) if err := g.state.PutNodeOffsets(node, offset); err != nil { return g.penalize() } + g.state.emitNodeAdded(caller) - // Delegate fund to itself. - if g.contract.Value().Cmp(big.NewInt(0)) > 0 { - if ret, err := g.delegate(caller); err != nil { - return ret, err - } + if value.Cmp(big.NewInt(0)) > 0 { + g.state.IncTotalStaked(value) + g.state.emitStaked(caller, value) } - - g.state.emitStaked(caller) return g.useGas(100000) } -func (g *GovernanceContract) undelegateHelper(nodeAddr, caller common.Address) ([]byte, error) { - nodeOffset := g.state.NodesOffsetByAddress(nodeAddr) - if nodeOffset.Cmp(big.NewInt(0)) < 0 { +func (g *GovernanceContract) stake() ([]byte, error) { + caller := g.contract.Caller() + value := g.contract.Value() + + if big.NewInt(0).Cmp(value) == 0 { return nil, errExecutionReverted } - offset := g.state.DelegatorsOffset(nodeAddr, caller) + offset := g.state.NodesOffsetByAddress(caller) if offset.Cmp(big.NewInt(0)) < 0 { return nil, errExecutionReverted } - node := g.state.Node(nodeOffset) + node := g.state.Node(offset) if node.Fined.Cmp(big.NewInt(0)) > 0 { return nil, errExecutionReverted } - delegator := g.state.Delegator(nodeAddr, offset) + node.Staked = new(big.Int).Add(node.Staked, value) + g.state.UpdateNode(offset, node) + + g.state.IncTotalStaked(value) + g.state.emitStaked(caller, value) + return g.useGas(100000) +} - if delegator.UndelegatedAt.Cmp(big.NewInt(0)) != 0 { +func (g *GovernanceContract) unstake(amount *big.Int) ([]byte, error) { + caller := g.contract.Caller() + + offset := g.state.NodesOffsetByAddress(caller) + if offset.Cmp(big.NewInt(0)) < 0 { return nil, errExecutionReverted } - // Set undelegate time. - delegator.UndelegatedAt = g.evm.Time - g.state.UpdateDelegator(nodeAddr, offset, delegator) + node := g.state.Node(offset) - // Subtract from the total staked of node. - node.Staked = new(big.Int).Sub(node.Staked, delegator.Value) - g.state.UpdateNode(nodeOffset, node) + // Can not unstake if there are unpaied fine. + if node.Fined.Cmp(big.NewInt(0)) > 0 { + return nil, errExecutionReverted + } - // Subtract to network total staked. - g.state.DecTotalStaked(delegator.Value) + // Can not unstake if there are unwithdrawn stake. + if node.Unstaked.Cmp(big.NewInt(0)) > 0 { + return nil, errExecutionReverted + } + if node.Staked.Cmp(amount) < 0 { + return nil, errExecutionReverted + } - g.state.emitUndelegated(nodeAddr, caller, delegator.Value) + node.Staked = new(big.Int).Sub(node.Staked, amount) + node.Unstaked = amount + node.UnstakedAt = g.evm.Time + g.state.UpdateNode(offset, node) - return g.useGas(100000) -} + g.state.DecTotalStaked(amount) + g.state.emitUnstaked(caller, amount) -func (g *GovernanceContract) undelegate(nodeAddr common.Address) ([]byte, error) { - return g.undelegateHelper(nodeAddr, g.contract.Caller()) + return g.useGas(100000) } -func (g *GovernanceContract) withdraw(nodeAddr common.Address) ([]byte, error) { +func (g *GovernanceContract) withdraw() ([]byte, error) { caller := g.contract.Caller() - nodeOffset := g.state.NodesOffsetByAddress(nodeAddr) - if nodeOffset.Cmp(big.NewInt(0)) < 0 { + offset := g.state.NodesOffsetByAddress(caller) + if offset.Cmp(big.NewInt(0)) < 0 { return nil, errExecutionReverted } - offset := g.state.DelegatorsOffset(nodeAddr, caller) - if offset.Cmp(big.NewInt(0)) < 0 { + node := g.state.Node(offset) + + // Can not withdraw if there are unpaied fine. + if node.Fined.Cmp(big.NewInt(0)) > 0 { return nil, errExecutionReverted } - delegator := g.state.Delegator(nodeAddr, offset) - - // Not yet undelegated. - if delegator.UndelegatedAt.Cmp(big.NewInt(0)) == 0 { - return g.penalize() + // Can not withdraw if there are no pending withdrawal. + if node.Unstaked.Cmp(big.NewInt(0)) == 0 { + return nil, errExecutionReverted } - unlockTime := new(big.Int).Add(delegator.UndelegatedAt, g.state.LockupPeriod()) + unlockTime := new(big.Int).Add(node.UnstakedAt, g.state.LockupPeriod()) if g.evm.Time.Cmp(unlockTime) <= 0 { return g.penalize() } - length := g.state.LenDelegators(nodeAddr) - lastIndex := new(big.Int).Sub(length, big.NewInt(1)) - - // Delete the delegator. - if offset.Cmp(lastIndex) != 0 { - lastNode := g.state.Delegator(nodeAddr, lastIndex) - g.state.UpdateDelegator(nodeAddr, offset, lastNode) - g.state.PutDelegatorOffset(nodeAddr, lastNode.Owner, offset) - } - g.state.DeleteDelegatorsOffset(nodeAddr, caller) - g.state.PopLastDelegator(nodeAddr) - - // Return the staked fund. - if !g.transfer(GovernanceContractAddress, delegator.Owner, delegator.Value) { - return nil, errExecutionReverted - } - - g.state.emitWithdrawn(nodeAddr, delegator.Owner, delegator.Value) + amount := node.Unstaked + node.Unstaked = big.NewInt(0) + node.UnstakedAt = big.NewInt(0) + g.state.UpdateNode(offset, node) - // We are the last delegator to withdraw the fund, remove the node info. - if g.state.LenDelegators(nodeAddr).Cmp(big.NewInt(0)) == 0 { + if node.Staked.Cmp(big.NewInt(0)) == 0 { length := g.state.LenNodes() lastIndex := new(big.Int).Sub(length, big.NewInt(1)) @@ -1670,55 +1553,26 @@ func (g *GovernanceContract) withdraw(nodeAddr common.Address) ([]byte, error) { panic(err) } } - g.state.DeleteNodesOffsetByAddress(nodeAddr) + g.state.DeleteNodeOffsets(node) g.state.PopLastNode() - g.state.emitNodeRemoved(nodeAddr) + g.state.emitNodeRemoved(caller) } - return g.useGas(100000) -} - -func (g *GovernanceContract) unstake() ([]byte, error) { - caller := g.contract.Caller() - offset := g.state.NodesOffsetByAddress(caller) - if offset.Cmp(big.NewInt(0)) < 0 { - return nil, errExecutionReverted - } - - node := g.state.Node(offset) - if node.Fined.Cmp(big.NewInt(0)) > 0 { + // Return the staked fund. + if !g.transfer(GovernanceContractAddress, node.Owner, amount) { return nil, errExecutionReverted } - - // Undelegate all delegators. - lenDelegators := g.state.LenDelegators(caller) - i := new(big.Int).Sub(lenDelegators, big.NewInt(1)) - for i.Cmp(big.NewInt(0)) >= 0 { - delegator := g.state.Delegator(caller, i) - if ret, err := g.undelegateHelper(caller, delegator.Owner); err != nil { - return ret, err - } - i = i.Sub(i, big.NewInt(1)) - } - - g.state.emitUnstaked(caller) + g.state.emitWithdrawn(caller, amount) return g.useGas(100000) } func (g *GovernanceContract) payFine(nodeAddr common.Address) ([]byte, error) { - caller := g.contract.Caller() - nodeOffset := g.state.NodesOffsetByAddress(nodeAddr) if nodeOffset.Cmp(big.NewInt(0)) < 0 { return nil, errExecutionReverted } - offset := g.state.DelegatorsOffset(nodeAddr, caller) - if offset.Cmp(big.NewInt(0)) < 0 { - return nil, errExecutionReverted - } - node := g.state.Node(nodeOffset) if node.Fined.Cmp(big.NewInt(0)) <= 0 || node.Fined.Cmp(g.contract.Value()) < 0 { return nil, errExecutionReverted @@ -2017,22 +1871,6 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re 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 { @@ -2072,7 +1910,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re return nil, errExecutionReverted } return g.resetDKG(args.NewSignedCRS) - case "stake": + case "register": args := struct { PublicKey []byte Name string @@ -2083,21 +1921,21 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re 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) + return g.register(args.PublicKey, args.Name, args.Email, args.Location, args.Url) + case "stake": + return g.stake() 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 { + case "unstake": + amount := new(big.Int) + if err := method.Inputs.Unpack(&amount, arguments); err != nil { return nil, errExecutionReverted } - return g.undelegate(address) - case "unstake": - return g.unstake() + return g.unstake(amount) case "updateConfiguration": var cfg rawConfigStruct if err := method.Inputs.Unpack(&cfg, arguments); err != nil { @@ -2105,11 +1943,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re } 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) + return g.withdraw() // -------------------------------- // Solidity auto generated methods. @@ -2133,29 +1967,6 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re 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": index := new(big.Int) if err := method.Inputs.Unpack(&index, arguments); err != nil { @@ -2328,7 +2139,8 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re 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) + info.Name, info.Email, info.Location, info.Url, + info.Unstaked, info.UnstakedAt) if err != nil { return nil, errExecutionReverted } @@ -2525,72 +2337,3 @@ func PackResetDKG(newSignedCRS []byte) ([]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:] - - // 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(evm, 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(evm, 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(evm, 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/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go index 81afe810c..f8f327a68 100644 --- a/core/vm/oracle_contracts_test.go +++ b/core/vm/oracle_contracts_test.go @@ -235,20 +235,20 @@ func (g *OracleContractsTestSuite) TestTransferOwnership() { g.Require().Equal(addr, g.s.Owner()) } -func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { +func (g *OracleContractsTestSuite) TestStakingMechanism() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) - // Stake. - amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) + // Register with some stake. + amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) balanceBeforeStake := g.stateDB.GetBalance(addr) - input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("register", pk, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) g.Require().Equal(1, int(g.s.LenNodes().Uint64())) - g.Require().Equal(1, len(g.s.QualifiedNodes())) + g.Require().Equal(0, len(g.s.QualifiedNodes())) g.Require().Equal("Test1", g.s.Node(big.NewInt(0)).Name) g.Require().Equal(amount.String(), g.s.TotalStaked().String()) @@ -256,40 +256,75 @@ func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(new(big.Int).Sub(balanceBeforeStake, amount), g.stateDB.GetBalance(addr)) g.Require().Equal(new(big.Int).Add(big.NewInt(1), amount), g.stateDB.GetBalance(GovernanceContractAddress)) - // Staking again should fail. + // Registering again should fail. _, err = g.call(GovernanceContractAddress, addr, input, amount) - g.Require().NotNil(err) + g.Require().Error(err) + + // Stake more to qualify. + input, err = GovernanceABI.ABI.Pack("stake") + g.Require().NoError(err) + _, err = g.call(GovernanceContractAddress, addr, input, amount) + g.Require().NoError(err) + g.Require().Equal(1, len(g.s.QualifiedNodes())) + g.Require().Equal(new(big.Int).Add(amount, amount).String(), g.s.TotalStaked().String()) + + // Unstake more then staked should fail. + unstakeAmount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e6)) + input, err = GovernanceABI.ABI.Pack("unstake", unstakeAmount) + g.Require().NoError(err) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) + g.Require().Error(err) // Unstake. - input, err = GovernanceABI.ABI.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake", amount) g.Require().NoError(err) _, 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())) - g.Require().Equal(1, int(g.s.LenNodes().Uint64())) + g.Require().Equal(amount.String(), g.s.TotalStaked().String()) - node := g.s.Node(big.NewInt(0)) - g.Require().Equal(big.NewInt(0).String(), node.Staked.String()) - g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String()) + // Withdraw immediately should fail. + input, err = GovernanceABI.ABI.Pack("withdraw") + g.Require().NoError(err) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) + g.Require().Error(err) // Wait for lockup time than withdraw. time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw") + g.Require().NoError(err) + _, 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.LenNodes().Uint64())) + + // Unstake all to remove node. + input, err = GovernanceABI.ABI.Pack("unstake", amount) + g.Require().NoError(err) + _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) + g.Require().NoError(err) + + time.Sleep(time.Second * 2) + input, err = GovernanceABI.ABI.Pack("withdraw") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, len(g.s.QualifiedNodes())) - g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64())) g.Require().Equal(0, int(g.s.LenNodes().Uint64())) + node := g.s.Node(big.NewInt(0)) + g.Require().Equal(big.NewInt(0).String(), node.Staked.String()) + g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String()) + // Stake 2 nodes, and unstake the first then the second. + amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) // 2nd node Stake. privKey2, addr2 := g.newPrefundAccount() pk2 := crypto.FromECDSAPub(&privKey2.PublicKey) - input, err = GovernanceABI.ABI.Pack("stake", pk2, "Test2", "test2@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err = GovernanceABI.ABI.Pack("register", pk2, "Test2", "test2@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr2, input, amount) g.Require().NoError(err) @@ -297,19 +332,21 @@ func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(0, int(g.s.NodesOffsetByAddress(addr2).Int64())) // 1st node Stake. - input, err = GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err = GovernanceABI.ABI.Pack("register", pk, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) + g.Require().Equal(2, int(g.s.LenNodes().Uint64())) 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 = GovernanceABI.ABI.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake", amount) g.Require().NoError(err) _, 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) g.Require().Equal(big.NewInt(0).String(), node.Staked.String()) @@ -317,18 +354,18 @@ func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(amount.String(), g.s.TotalStaked().String()) time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr2) + input, err = GovernanceABI.ABI.Pack("withdraw") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr2, input, big.NewInt(0)) g.Require().NoError(err) - g.Require().Equal(1, len(g.s.QualifiedNodes())) + g.Require().Equal(1, len(g.s.QualifiedNodes())) g.Require().Equal(1, int(g.s.LenNodes().Uint64())) g.Require().Equal("Test1", g.s.Node(big.NewInt(0)).Name) g.Require().Equal(-1, int(g.s.NodesOffsetByAddress(addr2).Int64())) // 1st node Unstake. - input, err = GovernanceABI.ABI.Pack("unstake") + input, err = GovernanceABI.ABI.Pack("unstake", amount) g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) @@ -336,14 +373,13 @@ func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(big.NewInt(0).String(), g.s.TotalStaked().String()) time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) + input, err = GovernanceABI.ABI.Pack("withdraw") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) g.Require().NoError(err) g.Require().Equal(0, int(g.s.LenNodes().Uint64())) g.Require().Equal(-1, int(g.s.NodesOffsetByAddress(addr).Int64())) - g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addr).Int64())) // Check balance. g.Require().Equal(balanceBeforeStake, g.stateDB.GetBalance(addr)) @@ -351,178 +387,26 @@ func (g *OracleContractsTestSuite) TestStakeUnstakeWithoutExtraDelegators() { g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress)) } -func (g *OracleContractsTestSuite) TestDelegateUndelegate() { - privKey, addr := g.newPrefundAccount() - pk := crypto.FromECDSAPub(&privKey.PublicKey) - - // Stake. - 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(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) - g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked) - - // 1st delegator delegate to 1st node. - _, addrDelegator := g.newPrefundAccount() - - balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) - amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - - _, 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) - 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().Equal(1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64())) - - // Same person delegate the 2nd time should fail. - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(1e18)) - g.Require().NotNil(err) - - // Not yet qualified. - g.Require().Equal(0, len(g.s.QualifiedNodes())) - - // 2nd delegator delegate to 1st node. - _, addrDelegator2 := g.newPrefundAccount() - _, 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) - g.Require().Equal(new(big.Int).Add(ownerStaked, new(big.Int).Mul(amount, big.NewInt(2))), - g.s.Node(big.NewInt(0)).Staked) - g.Require().Equal(g.s.Node(big.NewInt(0)).Staked.String(), g.s.TotalStaked().String()) - g.Require().Equal(2, int(g.s.DelegatorsOffset(addr, addrDelegator2).Int64())) - - // Qualified. - g.Require().Equal(1, len(g.s.QualifiedNodes())) - - // Undelegate addrDelegator. - balanceBeforeUnDelegate := g.stateDB.GetBalance(addrDelegator) - input, err = GovernanceABI.ABI.Pack("undelegate", addr) - g.Require().NoError(err) - _, 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(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().Error(err) - - // Withdraw within lockup time should fail. - input, err = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().NotNil(err) - - g.Require().Equal(3, int(g.s.LenDelegators(addr).Uint64())) - g.Require().Equal(balanceBeforeUnDelegate, g.stateDB.GetBalance(addrDelegator)) - g.Require().NotEqual(-1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64())) - - // Wait for lockup time than withdraw. - time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().NoError(err) - - g.Require().Equal(2, int(g.s.LenDelegators(addr).Uint64())) - g.Require().Equal(new(big.Int).Add(balanceBeforeUnDelegate, amount), g.stateDB.GetBalance(addrDelegator)) - g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64())) - - // Withdraw when their is no delegation should fail. - time.Sleep(time.Second) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().Error(err) - - // Undelegate addrDelegator2. - balanceBeforeUnDelegate = g.stateDB.GetBalance(addrDelegator2) - input, err = GovernanceABI.ABI.Pack("undelegate", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) - g.Require().NoError(err) - - g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked) - g.Require().Equal(g.s.Node(big.NewInt(0)).Staked.String(), g.s.TotalStaked().String()) - - // Wait for lockup time than withdraw. - time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) - g.Require().NoError(err) - - g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64())) - g.Require().Equal(new(big.Int).Add(balanceBeforeUnDelegate, amount), g.stateDB.GetBalance(addrDelegator2)) - g.Require().Equal(-1, int(g.s.DelegatorsOffset(addr, addrDelegator2).Int64())) - - // Unqualified - g.Require().Equal(0, len(g.s.QualifiedNodes())) - - // Owner undelegate itself. - g.Require().Equal(1, int(g.s.LenNodes().Uint64())) - g.Require().Equal(1, int(g.s.LenDelegators(addr).Uint64())) - - input, err = GovernanceABI.ABI.Pack("undelegate", addr) - g.Require().NoError(err) - _, 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 = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, 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 *OracleContractsTestSuite) TestFine() { privKey, addr := g.newPrefundAccount() pk := crypto.FromECDSAPub(&privKey.PublicKey) // Stake. - input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("register", pk, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) - ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) + ownerStaked := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) _, 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) + g.Require().Equal(1, len(g.s.QualifiedNodes())) g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked) - // 1st delegator delegate to 1st node. - _, addrDelegator := g.newPrefundAccount() - - balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) + _, finePayer := g.newPrefundAccount() amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - - _, 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) - g.Require().Equal(new(big.Int).Add(amount, ownerStaked), g.s.Node(big.NewInt(0)).Staked) - g.Require().Equal(1, int(g.s.DelegatorsOffset(addr, addrDelegator).Int64())) - - // Qualified. - g.Require().Equal(1, len(g.s.QualifiedNodes())) // Paying to node without fine should fail. input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, finePayer, input, amount) g.Require().NotNil(err) // Fined. @@ -537,106 +421,27 @@ func (g *OracleContractsTestSuite) TestFine() { // Not qualified after fined. g.Require().Equal(0, len(g.s.QualifiedNodes())) - // Cannot undelegate before fines are paied. - input, err = GovernanceABI.ABI.Pack("undelegate", addr) + // Cannot unstake before fines are paied. + input, err = GovernanceABI.ABI.Pack("unstake", big.NewInt(10)) g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().NotNil(err) - - // Only delegators can pay fine. - _, addrDelegator2 := g.newPrefundAccount() - input, err = GovernanceABI.ABI.Pack("payFine", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(5e5)) + _, err = g.call(GovernanceContractAddress, finePayer, input, big.NewInt(0)) g.Require().NotNil(err) // Paying more than fine should fail. payAmount := new(big.Int).Add(amount, amount) input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, payAmount) + _, err = g.call(GovernanceContractAddress, finePayer, input, payAmount) g.Require().NotNil(err) // Pay the fine. input, err = GovernanceABI.ABI.Pack("payFine", addr) g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) + _, err = g.call(GovernanceContractAddress, finePayer, input, amount) g.Require().NoError(err) // Qualified. g.Require().Equal(1, len(g.s.QualifiedNodes())) - - // Can undelegate after all fines are paied. - input, err = GovernanceABI.ABI.Pack("undelegate", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().NoError(err) -} - -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 := 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) - - // 1st delegator delegate to 1st node. - _, addrDelegator := g.newPrefundAccount() - - balanceBeforeDelegate := g.stateDB.GetBalance(addrDelegator) - amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - - _, 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) - g.Require().Equal(0, len(g.s.QualifiedNodes())) - - // 2st delegator delegate to 1st node. - _, addrDelegator2 := g.newPrefundAccount() - - balanceBeforeDelegate = g.stateDB.GetBalance(addrDelegator2) - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - - _, 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) - - // Node is now qualified. - g.Require().Equal(1, len(g.s.QualifiedNodes())) - - // Unstake. - input, err = GovernanceABI.ABI.Pack("unstake") - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) - g.Require().NoError(err) - - time.Sleep(time.Second * 2) - input, err = GovernanceABI.ABI.Pack("withdraw", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, big.NewInt(0)) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator2, input, big.NewInt(0)) - g.Require().NoError(err) - - g.Require().Equal(0, int(g.s.LenDelegators(addr).Uint64())) - g.Require().Equal(0, int(g.s.LenNodes().Uint64())) - - // Check balance. - g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addr)) - g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addrDelegator)) - g.Require().Equal(balanceBeforeDelegate, g.stateDB.GetBalance(addrDelegator2)) - g.Require().Equal(big.NewInt(1), g.stateDB.GetBalance(GovernanceContractAddress)) } func (g *OracleContractsTestSuite) TestUpdateConfiguration() { @@ -805,7 +610,7 @@ func (g *OracleContractsTestSuite) TestReportForkVote() { // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("register", pkBytes, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) @@ -871,7 +676,7 @@ func (g *OracleContractsTestSuite) TestReportForkBlock() { // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5)) - input, err := GovernanceABI.ABI.Pack("stake", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("register", pkBytes, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) @@ -958,26 +763,11 @@ func (g *OracleContractsTestSuite) TestMiscVariableReading() { // 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") + input, err = GovernanceABI.ABI.Pack("register", 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) - // 1st delegator delegate to 1st node. - _, addrDelegator := g.newPrefundAccount() - amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3e5)) - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator, input, amount) - g.Require().NoError(err) - - // 2st delegator delegate to 1st node. - _, addrDelegator2 := g.newPrefundAccount() - input, err = GovernanceABI.ABI.Pack("delegate", addr) - g.Require().NoError(err) - _, err = g.call(GovernanceContractAddress, addrDelegator2, input, amount) - g.Require().NoError(err) - input, err = GovernanceABI.ABI.Pack("nodes", big.NewInt(0)) g.Require().NoError(err) res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) @@ -1010,27 +800,6 @@ func (g *OracleContractsTestSuite) TestMiscVariableReading() { g.Require().NoError(err) g.Require().Equal(0, int(value.Uint64())) - input, err = GovernanceABI.ABI.Pack("delegators", addr, big.NewInt(0)) - g.Require().NoError(err) - res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) - g.Require().NoError(err) - - input, err = GovernanceABI.ABI.Pack("delegatorsLength", addr) - g.Require().NoError(err) - res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) - g.Require().NoError(err) - err = GovernanceABI.ABI.Unpack(&value, "delegatorsLength", res) - g.Require().NoError(err) - g.Require().Equal(3, int(value.Uint64())) - - input, err = GovernanceABI.ABI.Pack("delegatorsOffset", addr, addrDelegator2) - g.Require().NoError(err) - res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) - g.Require().NoError(err) - err = GovernanceABI.ABI.Unpack(&value, "delegatorsOffset", res) - g.Require().NoError(err) - g.Require().Equal(2, int(value.Uint64())) - input, err = GovernanceABI.ABI.Pack("fineValues", big.NewInt(0)) g.Require().NoError(err) res, err = g.call(GovernanceContractAddress, addr, input, big.NewInt(0)) @@ -1053,47 +822,6 @@ func (g *OracleContractsTestSuite) 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())) -} - type testCoreMock struct { newDKGGPKError error tsigReturn bool @@ -1123,8 +851,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() { // Stake. amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)) - input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", - "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org") + input, err := GovernanceABI.ABI.Pack("register", pk, "Test1", "test1@dexon.org", "Taipei", "https://dexon.org") g.Require().NoError(err) _, err = g.call(GovernanceContractAddress, addr, input, amount) g.Require().NoError(err) @@ -1270,6 +997,6 @@ func (g *OracleContractsTestSuite) TestResetDKG() { } } -func TestGovernanceContract(t *testing.T) { +func TestOracleContracts(t *testing.T) { suite.Run(t, new(OracleContractsTestSuite)) } diff --git a/params/config.go b/params/config.go index 38e338e37..208b6fab6 100644 --- a/params/config.go +++ b/params/config.go @@ -26,9 +26,9 @@ import ( // Genesis hashes to enforce below configs on. var ( - MainnetGenesisHash = common.HexToHash("0x0894598473a31c7cd2fa64864c33ded539a8fe0c4535035851ff57c421dbdd16") - TestnetGenesisHash = common.HexToHash("0xc5c55f7f0211bab328ce33b3ecbffd115464b70fd019cab1b21aa632d54e83fe") - YilanGenesisHash = common.HexToHash("0x523850d25315b5d0fc368b2219236e3e88a9dd544afe699b908d71d5ebd45de3") + MainnetGenesisHash = common.HexToHash("0xcf52354de5cb9e38930ef7db9a5fba771d9ac1738398ba3495d2a22897ff64d4") + TestnetGenesisHash = common.HexToHash("0x7ffc113d55e3a43f071b7475efc8eb6a866c723c5b3b2ebc7e4657a8f80d2f6c") + YilanGenesisHash = common.HexToHash("0x35c657b55ee61ffb9b4dbbea43507693da612a0bc89b8713f6865cfd3ed5f2e9") ) // TrustedCheckpoints associates each known checkpoint with the genesis hash of |