aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@cobinhood.com>2018-10-02 13:25:24 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:49 +0800
commit333af73098bcf40bc1f509ef2327ef6abd1042a1 (patch)
treec03dc63a077de5399ab54fc50d3bf94b5591ce3b
parent3e7dcb52f74c9ab4944d92a35a519631a2ec8298 (diff)
downloaddexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.tar.gz
dexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.tar.zst
dexon-333af73098bcf40bc1f509ef2327ef6abd1042a1.zip
core: vm: add governance contract skeleton
-rw-r--r--core/vm/evm.go3
-rw-r--r--core/vm/governance.go492
-rw-r--r--dex/governance.go14
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
}