diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-12-28 13:14:37 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:55 +0800 |
commit | fe239cd01509d340d3450e0275f60f0536ec5455 (patch) | |
tree | 0fa3882d29af0e3103160472f4a175757374f1c5 /core/vm/governance.go | |
parent | f41cab3f7b7f614c4f6e1802a890839ba51ca5e6 (diff) | |
download | dexon-fe239cd01509d340d3450e0275f60f0536ec5455.tar.gz dexon-fe239cd01509d340d3450e0275f60f0536ec5455.tar.zst dexon-fe239cd01509d340d3450e0275f60f0536ec5455.zip |
core/vm: Add fine to governance. (#107)
* core/vm: Add Fined field to nodeInfo.
* core/vm: Add PayFine to Governance
* Not qualify if staked-fine < minStake()
* Add test for fine
* Update genesis hash
Diffstat (limited to 'core/vm/governance.go')
-rw-r--r-- | core/vm/governance.go | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/core/vm/governance.go b/core/vm/governance.go index 8be5b03b2..a58985766 100644 --- a/core/vm/governance.go +++ b/core/vm/governance.go @@ -153,6 +153,10 @@ const GovernanceABIJSON = ` "type": "uint256" }, { + "name": "fined", + "type": "uint256" + }, + { "name": "name", "type": "string" }, @@ -909,6 +913,20 @@ const GovernanceABIJSON = ` "payable": false, "stateMutability": "nonpayable", "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "NodeAddress", + "type": "address" + } + ], + "name": "payFine", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" } ] ` @@ -1075,6 +1093,12 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (ret []by return nil, errExecutionReverted } return g.withdraw(address) + case "payFine": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + return g.payFine(address) // -------------------------------- // Solidity auto generated methods. @@ -1506,6 +1530,7 @@ func (s *GovernanceStateHelper) PushRoundHeight(height *big.Int) { // address owner; // bytes publicKey; // uint256 staked; +// uint256 fined; // string name; // string email; // string location; @@ -1519,6 +1544,7 @@ type nodeInfo struct { Owner common.Address PublicKey []byte Staked *big.Int + Fined *big.Int Name string Email string Location string @@ -1526,7 +1552,7 @@ type nodeInfo struct { Unstaked bool } -const nodeStructSize = 8 +const nodeStructSize = 9 func (s *GovernanceStateHelper) LenNodes() *big.Int { return s.getStateBigInt(big.NewInt(nodesLoc)) @@ -1550,24 +1576,28 @@ func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo { loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2)) node.Staked = s.getStateBigInt(loc) - // Name. + // Fined. loc = new(big.Int).Add(elementBaseLoc, big.NewInt(3)) + node.Fined = s.getStateBigInt(loc) + + // Name. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(4)) node.Name = string(s.readBytes(loc)) // Email. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(4)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(5)) node.Email = string(s.readBytes(loc)) // Location. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(5)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(6)) node.Location = string(s.readBytes(loc)) // Url. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(6)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) node.Url = string(s.readBytes(loc)) // Unstaked. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(8)) node.Unstaked = s.getStateBigInt(loc).Cmp(big.NewInt(0)) > 0 return node @@ -1595,24 +1625,28 @@ func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) { loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2)) s.setStateBigInt(loc, n.Staked) - // Name. + // Fined. loc = new(big.Int).Add(elementBaseLoc, big.NewInt(3)) + s.setStateBigInt(loc, n.Fined) + + // Name. + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(4)) s.writeBytes(loc, []byte(n.Name)) // Email. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(4)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(5)) s.writeBytes(loc, []byte(n.Email)) // Location. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(5)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(6)) s.writeBytes(loc, []byte(n.Location)) // Url. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(6)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) s.writeBytes(loc, []byte(n.Url)) // Unstaked. - loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7)) + loc = new(big.Int).Add(elementBaseLoc, big.NewInt(8)) val := big.NewInt(0) if n.Unstaked { val = big.NewInt(1) @@ -1625,7 +1659,10 @@ func (s *GovernanceStateHelper) PopLastNode() { newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1)) s.setStateBigInt(big.NewInt(nodesLoc), newArrayLength) - s.UpdateNode(newArrayLength, &nodeInfo{Staked: big.NewInt(0)}) + s.UpdateNode(newArrayLength, &nodeInfo{ + Staked: big.NewInt(0), + Fined: big.NewInt(0), + }) } func (s *GovernanceStateHelper) Nodes() []*nodeInfo { var nodes []*nodeInfo @@ -1638,7 +1675,7 @@ func (s *GovernanceStateHelper) QualifiedNodes() []*nodeInfo { var nodes []*nodeInfo for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ { node := s.Node(big.NewInt(i)) - if node.Staked.Cmp(s.MinStake()) >= 0 { + if new(big.Int).Sub(node.Staked, node.Fined).Cmp(s.MinStake()) >= 0 { nodes = append(nodes, node) } } @@ -1953,6 +1990,7 @@ func (s *GovernanceStateHelper) Stake( Owner: addr, PublicKey: publicKey, Staked: staked, + Fined: big.NewInt(0), Name: name, Email: email, Location: location, @@ -2380,6 +2418,7 @@ func (g *GovernanceContract) stake( Owner: caller, PublicKey: publicKey, Staked: big.NewInt(0), + Fined: big.NewInt(0), Name: name, Email: email, Location: location, @@ -2409,6 +2448,11 @@ func (g *GovernanceContract) undelegateHelper(nodeAddr, caller common.Address) ( return nil, errExecutionReverted } + node := g.state.Node(nodeOffset) + if node.Fined.Cmp(big.NewInt(0)) > 0 { + return nil, errExecutionReverted + } + delegator := g.state.Delegator(nodeAddr, offset) // Set undelegate time. @@ -2416,7 +2460,6 @@ func (g *GovernanceContract) undelegateHelper(nodeAddr, caller common.Address) ( g.state.UpdateDelegator(nodeAddr, offset, delegator) // Subtract from the total staked of node. - node := g.state.Node(nodeOffset) node.Staked = new(big.Int).Sub(node.Staked, delegator.Value) g.state.UpdateNode(nodeOffset, node) @@ -2496,6 +2539,11 @@ func (g *GovernanceContract) unstake() ([]byte, error) { return nil, errExecutionReverted } + node := g.state.Node(offset) + if node.Fined.Cmp(big.NewInt(0)) > 0 { + return nil, errExecutionReverted + } + // Undelegate all delegators. lenDelegators := g.state.LenDelegators(caller) i := new(big.Int).Sub(lenDelegators, big.NewInt(1)) @@ -2508,7 +2556,6 @@ func (g *GovernanceContract) unstake() ([]byte, error) { } // Mark node as unstaked. - node := g.state.Node(offset) node.Unstaked = true g.state.UpdateNode(offset, node) @@ -2517,6 +2564,32 @@ func (g *GovernanceContract) unstake() ([]byte, error) { return g.useGas(100000) } +func (g *GovernanceContract) payFine(nodeAddr common.Address) ([]byte, error) { + caller := g.contract.Caller() + + nodeOffset := g.state.NodesOffset(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 + } + + node.Fined = new(big.Int).Sub(node.Fined, g.contract.Value()) + g.state.UpdateNode(nodeOffset, node) + + // TODO: paid fine should be added to award pool. + + return g.useGas(100000) +} + func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([]byte, error) { round := g.state.Round() |