diff options
Diffstat (limited to 'core/vm/oracle_contracts.go')
-rw-r--r-- | core/vm/oracle_contracts.go | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go index f21700d86..cd11dc051 100644 --- a/core/vm/oracle_contracts.go +++ b/core/vm/oracle_contracts.go @@ -62,6 +62,7 @@ const ( nodesLoc nodesOffsetByAddressLoc nodesOffsetByNodeKeyAddressLoc + lastProposedHeightLoc crsRoundLoc crsLoc dkgRoundLoc @@ -332,7 +333,8 @@ func (s *GovernanceState) DecTotalStaked(amount *big.Int) { // string location; // string url; // uint256 unstaked; -// uint256 unstaked_at; +// uint256 unstakedAt; +// uint256 lastProposedHeight; // } // // Node[] nodes; @@ -543,6 +545,16 @@ func (s *GovernanceState) GetNodeByID(id coreTypes.NodeID) (*nodeInfo, error) { return node, nil } +// mapping(address => uint256) public lastProposedHeight; +func (s *GovernanceState) LastProposedHeight(addr common.Address) *big.Int { + loc := s.getMapLoc(big.NewInt(lastProposedHeightLoc), addr.Bytes()) + return s.getStateBigInt(loc) +} +func (s *GovernanceState) PutLastProposedHeight(addr common.Address, height *big.Int) { + loc := s.getMapLoc(big.NewInt(lastProposedHeightLoc), addr.Bytes()) + s.setStateBigInt(loc, height) +} + // uint256 public crsRound; func (s *GovernanceState) CRSRound() *big.Int { return s.getStateBigInt(big.NewInt(crsRoundLoc)) @@ -960,6 +972,31 @@ func (s *GovernanceState) Register( s.IncTotalStaked(staked) } +func (s *GovernanceState) Disqualify(n *nodeInfo) error { + nodeAddr, err := publicKeyToNodeKeyAddress(n.PublicKey) + if err != nil { + return err + } + + // Node might already been unstaked in the latest state. + offset := s.NodesOffsetByNodeKeyAddress(nodeAddr) + if offset.Cmp(big.NewInt(0)) < 0 { + return errors.New("node does not exist") + } + + // Fine the node so it's staked value is 1 wei under minStake. + node := s.Node(offset) + extra := new(big.Int).Sub(new(big.Int).Sub(node.Staked, node.Fined), s.MinStake()) + amount := new(big.Int).Add(extra, big.NewInt(1)) + + if amount.Cmp(big.NewInt(0)) > 0 { + node.Fined = new(big.Int).Add(node.Fined, amount) + s.UpdateNode(offset, node) + } + + return nil +} + const decimalMultiplier = 100000000.0 // Configuration returns the current configuration. @@ -2252,6 +2289,16 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re return nil, errExecutionReverted } return res, nil + case "lastProposedHeight": + address := common.Address{} + if err := method.Inputs.Unpack(&address, arguments); err != nil { + return nil, errExecutionReverted + } + res, err := method.Outputs.Pack(g.state.LastProposedHeight(address)) + if err != nil { + return nil, errExecutionReverted + } + return res, nil case "lockupPeriod": res, err := method.Outputs.Pack(g.state.LockupPeriod()) if err != nil { |