diff options
author | Wei-Ning Huang <w@cobinhood.com> | 2018-10-02 13:25:24 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:49 +0800 |
commit | 333af73098bcf40bc1f509ef2327ef6abd1042a1 (patch) | |
tree | c03dc63a077de5399ab54fc50d3bf94b5591ce3b | |
parent | 3e7dcb52f74c9ab4944d92a35a519631a2ec8298 (diff) | |
download | dexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.tar.gz dexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.tar.zst dexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.zip |
core: vm: add governance contract skeleton
-rw-r--r-- | core/vm/evm.go | 3 | ||||
-rw-r--r-- | core/vm/governance.go | 492 | ||||
-rw-r--r-- | dex/governance.go | 14 |
3 files changed, 502 insertions, 7 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go index 31902621b..fcab628e1 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -43,6 +43,9 @@ 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) + } precompiles := PrecompiledContractsHomestead if evm.ChainConfig().IsByzantium(evm.BlockNumber) { precompiles = PrecompiledContractsByzantium diff --git a/core/vm/governance.go b/core/vm/governance.go new file mode 100644 index 000000000..c3b316a64 --- /dev/null +++ b/core/vm/governance.go @@ -0,0 +1,492 @@ +package vm + +import ( + "math/big" + "strings" + + "github.com/dexon-foundation/dexon/accounts/abi" + "github.com/dexon-foundation/dexon/common" +) + +var GovernanceContractAddress = common.BytesToAddress([]byte{0XED}) // Reverse of DEX0 +var multisigAddress = common.BytesToAddress([]byte("0x.....")) +var minStake = big.NewInt(10000000000000) + +const abiJSON = ` +[ + { + "constant": true, + "inputs": [], + "name": "round", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "lambdaBA", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + } + ], + "name": "crs", + "outputs": [ + { + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "phiRatio", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "offset", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "lambdaDKG", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "k", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "numChains", + "outputs": [ + { + "name": "", + "type": "int256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "name": "DKGMasterPublicKeys", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "uint256" + } + ], + "name": "DKGComplaints", + "outputs": [ + { + "name": "", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "governanceMultisig", + "outputs": [ + { + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "int256" + }, + { + "name": "", + "type": "int256" + } + ], + "name": "updateConfiguration", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "proposeCRS", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "addDKGMasterPublicKey", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "uint256" + }, + { + "name": "", + "type": "bytes" + } + ], + "name": "addDKGComplaint", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "", + "type": "bytes" + } + ], + "name": "stake", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "unstake", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } +] +` + +var abiObject abi.ABI +var sig2Method map[string]abi.Method + +func init() { + // Parse governance contract ABI. + abiObject, err := abi.JSON(strings.NewReader(abiJSON)) + if err != nil { + panic(err) + } + + sig2Method = make(map[string]abi.Method) + + // Construct dispatch table. + for _, method := range abiObject.Methods { + sig2Method[method.Sig()] = method + } +} + +// RunGovernanceContract executes governance contract. +func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) ( + ret []byte, err error) { + // Parse input. + method, exists := sig2Method[string(input[:4])] + if !exists { + return nil, errExecutionReverted + } + + // Dispatch method call. + g := NewGovernanceContract(evm, contract) + argument := input[4:] + + switch method.Name { + case "stake": + var publicKey []byte + if err := method.Inputs.Unpack(&publicKey, argument); err != nil { + return nil, errExecutionReverted + } + return g.stake(publicKey) + case "unstake": + return g.unstake() + case "proposeCRS": + return g.proposeCRS() + case "addDKGMasterPublicKey": + return g.addDKGMasterPublicKey() + case "addDKGComplaint": + return g.addDKGComplaint() + } + return nil, nil +} + +// State manipulation helper fro the governance contract. +type StateHelper struct { + StateDB StateDB +} + +// 0: address public governanceMultisig; +func (s *StateHelper) governanceMultisig() common.Address { + return common.Address{} +} + +// 1: int256 public numChains; +func (s *StateHelper) numChains() *big.Int { + return nil +} + +// 2: int256 public lambdaBA; +func (s *StateHelper) lambdaBA() *big.Int { + return nil +} + +// 3: int256 public lambdaDKG; +func (s *StateHelper) lambdaDKG() *big.Int { + return nil +} + +// 4: int256 public k; +func (s *StateHelper) k() *big.Int { + return nil +} + +// 5: int256 public phiRatio; // stored as PhiRatio * 10^6 +func (s *StateHelper) phiRatio() *big.Int { + return nil +} + +// struct Node { +// address owner; +// bytes publicKey; +// uint256 staked; +// } +// +// 6: Node[] nodes; + +type nodeInfo struct { + owner common.Address + publicKey []byte + staked *big.Int +} + +func (s *StateHelper) nodesLength() *big.Int { + return nil +} +func (s *StateHelper) node(offset *big.Int) *nodeInfo { + return nil +} +func (s *StateHelper) pushNode(n *nodeInfo) { +} + +// 7: mapping(address => uint256) public offset; +func (s *StateHelper) offset(addr common.Address) *big.Int { + return nil +} +func (s *StateHelper) putOffset(addr common.Address, offset *big.Int) { +} +func (s *StateHelper) deleteOffset(addr common.Address) { +} + +// 8: uint256 public round; +func (s *StateHelper) round() *big.Int { + return nil +} +func (s *StateHelper) incRound() *big.Int { + return nil +} + +// 9: mapping(uint256 => bytes32) public crs; +func (s *StateHelper) crs(round *big.Int) common.Hash { + return common.Hash{} +} +func (s *StateHelper) pushCRS(round *big.Int, crs []byte) common.Hash { + return common.Hash{} +} + +// 10: mapping(uint256 => bytes[]) public DKGMasterPublicKeys; +func (s *StateHelper) dkgMasterPublicKey(round *big.Int) [][]byte { + return nil +} +func (s *StateHelper) addDKGMasterPublicKey(round *big.Int, pk []byte) { +} + +// 11: mapping(uint256 => bytes[]) public DKGComplaints; +func (s *StateHelper) dkgComplaint(round *big.Int) [][]byte { + return nil +} +func (s *StateHelper) addDKGComplaint(round *big.Int, complaint []byte) { +} + +type GovernanceContract struct { + evm *EVM + state StateHelper + contract *Contract +} + +func NewGovernanceContract(evm *EVM, contract *Contract) *GovernanceContract { + return &GovernanceContract{ + evm: evm, + state: StateHelper{evm.StateDB}, + contract: contract, + } +} + +func (G *GovernanceContract) updateConfiguration() ([]byte, error) { + return nil, nil +} + +func (g *GovernanceContract) stake(publicKey []byte) ([]byte, error) { + return nil, nil +} + +func (g *GovernanceContract) unstake() ([]byte, error) { + return nil, nil +} + +func (g *GovernanceContract) proposeCRS() ([]byte, error) { + return nil, nil +} + +func (g *GovernanceContract) addDKGMasterPublicKey() ([]byte, error) { + return nil, nil +} + +func (g *GovernanceContract) addDKGComplaint() ([]byte, error) { + return nil, nil +} diff --git a/dex/governance.go b/dex/governance.go index 44df77361..95109690a 100644 --- a/dex/governance.go +++ b/dex/governance.go @@ -15,13 +15,13 @@ func NewDexconGovernance() *DexconGovernance { return &DexconGovernance{} } -// GetConfiguration return the total ordering K constant. -func (d *DexconGovernance) GetConfiguration(round uint64) *types.Config { +// Configuration return the total ordering K constant. +func (d *DexconGovernance) Configuration(round uint64) *types.Config { return &types.Config{} } -// GetCRS returns the CRS for a given round. -func (d *DexconGovernance) GetCRS(round uint64) coreCommon.Hash { +// CRS returns the CRS for a given round. +func (d *DexconGovernance) CRS(round uint64) coreCommon.Hash { return coreCommon.Hash{} } @@ -29,8 +29,8 @@ func (d *DexconGovernance) GetCRS(round uint64) coreCommon.Hash { func (d *DexconGovernance) ProposeCRS(round uint64, signedCRS []byte) { } -// GetValidatorSet returns the current notary set. -func (d *DexconGovernance) GetNodeSet(round uint64) []crypto.PublicKey { +// NodeSet returns the current notary set. +func (d *DexconGovernance) NodeSet(round uint64) []crypto.PublicKey { return nil } @@ -38,7 +38,7 @@ func (d *DexconGovernance) GetNodeSet(round uint64) []crypto.PublicKey { func (d *DexconGovernance) AddDKGComplaint(complaint *types.DKGComplaint) { } -// GetDKGComplaints gets all the DKGComplaints of round. +// DKGComplaints gets all the DKGComplaints of round. func (d *DexconGovernance) DKGComplaints(round uint64) []*types.DKGComplaint { return nil } |