aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorWei-Ning Huang <w@cobinhood.com>2018-10-04 17:01:32 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:49 +0800
commit6f442cd7793daad014aa0d55b3b7320392c22f02 (patch)
treeb786b698c609273a36b90b6150b0cd2eaa2bde08 /core
parentb67ef6594e03b45bb9e683631a7bf9584f6a3437 (diff)
downloaddexon-6f442cd7793daad014aa0d55b3b7320392c22f02.tar.gz
dexon-6f442cd7793daad014aa0d55b3b7320392c22f02.tar.zst
dexon-6f442cd7793daad014aa0d55b3b7320392c22f02.zip
core: vm: implement the rest of governance contract methods
Diffstat (limited to 'core')
-rw-r--r--core/vm/governance.go407
1 files changed, 275 insertions, 132 deletions
diff --git a/core/vm/governance.go b/core/vm/governance.go
index 652d86357..e9e57c4c9 100644
--- a/core/vm/governance.go
+++ b/core/vm/governance.go
@@ -23,14 +23,23 @@ const abiJSON = `
[
{
"constant": true,
- "inputs": [],
- "name": "round",
- "outputs": [
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ },
{
"name": "",
"type": "uint256"
}
],
+ "name": "dkgComplaints",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
"payable": false,
"stateMutability": "view",
"type": "function"
@@ -38,7 +47,7 @@ const abiJSON = `
{
"constant": true,
"inputs": [],
- "name": "lambdaBA",
+ "name": "notarySetSize",
"outputs": [
{
"name": "",
@@ -51,17 +60,26 @@ const abiJSON = `
},
{
"constant": true,
- "inputs": [
+ "inputs": [],
+ "name": "dkgSetSize",
+ "outputs": [
{
"name": "",
"type": "uint256"
}
],
- "name": "crs",
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
+ "name": "lambdaBA",
"outputs": [
{
"name": "",
- "type": "bytes32"
+ "type": "uint256"
}
],
"payable": false,
@@ -70,14 +88,19 @@ const abiJSON = `
},
{
"constant": true,
- "inputs": [],
- "name": "numNotarySet",
- "outputs": [
+ "inputs": [
{
"name": "",
"type": "uint256"
}
],
+ "name": "crs",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
"payable": false,
"stateMutability": "view",
"type": "function"
@@ -173,20 +196,6 @@ const abiJSON = `
},
{
"constant": true,
- "inputs": [],
- "name": "numChains",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": true,
"inputs": [
{
"name": "",
@@ -197,7 +206,7 @@ const abiJSON = `
"type": "uint256"
}
],
- "name": "DKGMasterPublicKeys",
+ "name": "dkgMasterPublicKeys",
"outputs": [
{
"name": "",
@@ -211,7 +220,7 @@ const abiJSON = `
{
"constant": true,
"inputs": [],
- "name": "numDKGSet",
+ "name": "numChains",
"outputs": [
{
"name": "",
@@ -224,29 +233,6 @@ const abiJSON = `
},
{
"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": [
@@ -277,24 +263,44 @@ const abiJSON = `
"constant": false,
"inputs": [
{
- "name": "numChains",
- "type": "int256"
+ "name": "NumChains",
+ "type": "uint256"
},
{
- "name": "lambdaBA",
- "type": "int256"
+ "name": "LambdaBA",
+ "type": "uint256"
},
{
- "name": "lambdaDKG",
- "type": "int256"
+ "name": "LambdaDKG",
+ "type": "uint256"
},
{
"name": "K",
- "type": "int256"
+ "type": "uint256"
},
{
"name": "PhiRatio",
- "type": "int256"
+ "type": "uint256"
+ },
+ {
+ "name": "NotarySetSize",
+ "type": "uint256"
+ },
+ {
+ "name": "DKGSetSize",
+ "type": "uint256"
+ },
+ {
+ "name": "RoundInterval",
+ "type": "uint256"
+ },
+ {
+ "name": "MinBlockInterval",
+ "type": "uint256"
+ },
+ {
+ "name": "MaxBlockInterval",
+ "type": "uint256"
}
],
"name": "updateConfiguration",
@@ -307,7 +313,7 @@ const abiJSON = `
"constant": false,
"inputs": [
{
- "name": "",
+ "name": "SignedCRS",
"type": "bytes"
}
],
@@ -321,11 +327,11 @@ const abiJSON = `
"constant": false,
"inputs": [
{
- "name": "round",
+ "name": "Round",
"type": "uint256"
},
{
- "name": "publicKey",
+ "name": "PublicKey",
"type": "bytes"
}
],
@@ -339,11 +345,11 @@ const abiJSON = `
"constant": false,
"inputs": [
{
- "name": "round",
+ "name": "Round",
"type": "uint256"
},
{
- "name": "complaint",
+ "name": "Complaint",
"type": "bytes"
}
],
@@ -357,7 +363,7 @@ const abiJSON = `
"constant": false,
"inputs": [
{
- "name": "publicKey",
+ "name": "PublicKey",
"type": "bytes"
}
],
@@ -397,6 +403,19 @@ func init() {
}
}
+type configParams struct {
+ NumChains uint32
+ LambdaBA uint64
+ LambdaDKG uint64
+ K int
+ PhiRatio float32
+ NotarySetSize uint32
+ DKGSetSize uint32
+ RoundInterval uint64
+ MinBlockInterval uint64
+ MaxBlockInterval uint64
+}
+
// RunGovernanceContract executes governance contract.
func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
ret []byte, err error) {
@@ -412,32 +431,35 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
// Dispatch method call.
g := newGovernanceContract(evm, contract)
- argument := input[4:]
+ arguments := input[4:]
switch method.Name {
+ case "updateConfiguration":
+ var config configParams
+ if err := method.Inputs.Unpack(&config, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ g.updateConfiguration(&config)
case "stake":
var publicKey []byte
- if err := method.Inputs.Unpack(&publicKey, argument); err != nil {
+ if err := method.Inputs.Unpack(&publicKey, arguments); err != nil {
return nil, errExecutionReverted
}
return g.stake(publicKey)
case "unstake":
return g.unstake()
case "proposeCRS":
- args := struct {
- Round *big.Int
- SignedCRS []byte
- }{}
- if err := method.Inputs.Unpack(&args, argument); err != nil {
+ var signedCRS []byte
+ if err := method.Inputs.Unpack(&signedCRS, arguments); err != nil {
return nil, errExecutionReverted
}
- return g.proposeCRS(args.Round, args.SignedCRS)
+ return g.proposeCRS(signedCRS)
case "addDKGMasterPublicKey":
args := struct {
Round *big.Int
PublicKey []byte
}{}
- if err := method.Inputs.Unpack(&args, argument); err != nil {
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
return nil, errExecutionReverted
}
return g.addDKGMasterPublicKey(args.Round, args.PublicKey)
@@ -446,10 +468,129 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
Round *big.Int
Complaint []byte
}{}
- if err := method.Inputs.Unpack(&args, argument); err != nil {
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
return nil, errExecutionReverted
}
return g.addDKGComplaint(args.Round, args.Complaint)
+
+ case "dkgComplaints":
+ round, index := new(big.Int), new(big.Int)
+ args := []interface{}{&round, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ complaints := g.state.dkgComplaints(round)
+ if int(index.Uint64()) >= len(complaints) {
+ return nil, errExecutionReverted
+ }
+ complaint := complaints[index.Uint64()]
+ res, err := method.Outputs.Pack(complaint)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgMasterPublicKeys":
+ round, index := new(big.Int), new(big.Int)
+ args := []interface{}{&round, &index}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ pks := g.state.dkgMasterPublicKeys(round)
+ if int(index.Uint64()) >= len(pks) {
+ return nil, errExecutionReverted
+ }
+ pk := pks[index.Uint64()]
+ res, err := method.Outputs.Pack(pk)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "crs":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.crs(round))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "governanceMultisig":
+ res, err := method.Outputs.Pack(g.state.governanceMultisig())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "k":
+ res, err := method.Outputs.Pack(g.state.k())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lambdaBA":
+ res, err := method.Outputs.Pack(g.state.lambdaBA())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "lambdaDKG":
+ res, err := method.Outputs.Pack(g.state.lambdaDKG())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "maxBlockInterval":
+ res, err := method.Outputs.Pack(g.state.maxBlockInterval())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "minBlockInterval":
+ res, err := method.Outputs.Pack(g.state.minBlockInterval())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "numChains":
+ res, err := method.Outputs.Pack(g.state.numChains())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "dkgSetSize":
+ res, err := method.Outputs.Pack(g.state.dkgSetSize())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "notarySetSize":
+ res, err := method.Outputs.Pack(g.state.notarySetSize())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "offset":
+ addr := common.Address{}
+ if err := method.Inputs.Unpack(&addr, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.offset(addr))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "phiRatio":
+ res, err := method.Outputs.Pack(g.state.phiRatio())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "roundInterval":
+ res, err := method.Outputs.Pack(g.state.roundInterval())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
}
return nil, nil
}
@@ -635,17 +776,27 @@ func (s *StateHelper) deleteOffset(addr common.Address) {
s.setStateBigInt(loc, big.NewInt(0))
}
-// 2: mapping(uint256 => bytes32) public crs;
-func (s *StateHelper) crs(round *big.Int) common.Hash {
- loc := s.getMapLoc(big.NewInt(2), common.BigToHash(round).Bytes())
+// 2: bytes32[] public crs;
+func (s *StateHelper) lenCRS() *big.Int {
+ return s.getStateBigInt(big.NewInt(2))
+}
+func (s *StateHelper) crs(index *big.Int) common.Hash {
+ baseLoc := s.getSlotLoc(big.NewInt(2))
+ loc := new(big.Int).Add(baseLoc, new(big.Int).Mul(index, big.NewInt(32)))
return s.getState(common.BigToHash(loc))
}
-func (s *StateHelper) putCRS(round *big.Int, crs common.Hash) {
- loc := s.getMapLoc(big.NewInt(2), common.BigToHash(round).Bytes())
+func (s *StateHelper) pushCRS(crs common.Hash) {
+ // increase length by 1.
+ length := s.getStateBigInt(big.NewInt(2))
+ s.setStateBigInt(big.NewInt(2), new(big.Int).Add(length, big.NewInt(1)))
+
+ baseLoc := s.getSlotLoc(big.NewInt(2))
+ loc := new(big.Int).Add(baseLoc, new(big.Int).Mul(length, big.NewInt(32)))
+
s.setState(common.BigToHash(loc), crs)
}
-// 3: mapping(uint256 => bytes[]) public DKGMasterPublicKeys;
+// 3: mapping(uint256 => bytes[]) public dkgMasterPublicKeys;
func (s *StateHelper) dkgMasterPublicKeys(round *big.Int) [][]byte {
loc := s.getMapLoc(big.NewInt(3), common.BigToHash(round).Bytes())
@@ -672,7 +823,7 @@ func (s *StateHelper) pushDKGMasterPublicKey(round *big.Int, pk []byte) {
s.writeBytes(elementLoc, pk)
}
-// 4: mapping(uint256 => bytes[]) public DKGComplaints;
+// 4: mapping(uint256 => bytes[]) public dkgComplaints;
func (s *StateHelper) dkgComplaints(round *big.Int) [][]byte {
loc := s.getMapLoc(big.NewInt(4), common.BigToHash(round).Bytes())
@@ -686,8 +837,8 @@ func (s *StateHelper) dkgComplaints(round *big.Int) [][]byte {
}
return data
}
-func (s *StateHelper) addDKGComplaint(round *big.Int, complaint []byte) {
- loc := s.getMapLoc(big.NewInt(3), common.BigToHash(round).Bytes())
+func (s *StateHelper) pushDKGComplaint(round *big.Int, complaint []byte) {
+ loc := s.getMapLoc(big.NewInt(4), common.BigToHash(round).Bytes())
// increase length by 1.
arrayLength := s.getStateBigInt(loc)
@@ -699,70 +850,60 @@ func (s *StateHelper) addDKGComplaint(round *big.Int, complaint []byte) {
s.writeBytes(elementLoc, complaint)
}
-// 5: uint256 public round;
-func (s *StateHelper) round() *big.Int {
- return s.getStateBigInt(big.NewInt(5))
-}
-func (s *StateHelper) incRound() *big.Int {
- newRound := new(big.Int).Add(s.round(), big.NewInt(1))
- s.setStateBigInt(big.NewInt(5), newRound)
- return newRound
-}
-
-// 6: address public governanceMultisig;
+// 5: address public governanceMultisig;
func (s *StateHelper) governanceMultisig() common.Address {
- val := s.getState(common.BigToHash(big.NewInt(6)))
+ val := s.getState(common.BigToHash(big.NewInt(5)))
return common.BytesToAddress(val.Bytes())
}
-// 7: uint256 public numChains;
+// 6: uint256 public numChains;
func (s *StateHelper) numChains() *big.Int {
- return s.getStateBigInt(big.NewInt(7))
+ return s.getStateBigInt(big.NewInt(6))
}
-// 8: uint256 public lambdaBA;
+// 7: uint256 public lambdaBA;
func (s *StateHelper) lambdaBA() *big.Int {
- return s.getStateBigInt(big.NewInt(8))
+ return s.getStateBigInt(big.NewInt(7))
}
-// 9: uint256 public lambdaDKG;
+// 8: uint256 public lambdaDKG;
func (s *StateHelper) lambdaDKG() *big.Int {
- return s.getStateBigInt(big.NewInt(9))
+ return s.getStateBigInt(big.NewInt(8))
}
-// 10: uint256 public k;
+// 9: uint256 public k;
func (s *StateHelper) k() *big.Int {
- return s.getStateBigInt(big.NewInt(10))
+ return s.getStateBigInt(big.NewInt(9))
}
-// 11: uint256 public phiRatio; // stored as PhiRatio * 10^6
+// 10: uint256 public phiRatio; // stored as PhiRatio * 10^6
func (s *StateHelper) phiRatio() *big.Int {
- return s.getStateBigInt(big.NewInt(11))
+ return s.getStateBigInt(big.NewInt(10))
}
-// 12: uint256 public numNotarySet;
-func (s *StateHelper) numNotarySet() *big.Int {
- return s.getStateBigInt(big.NewInt(12))
+// 11: uint256 public notarySetSize;
+func (s *StateHelper) notarySetSize() *big.Int {
+ return s.getStateBigInt(big.NewInt(11))
}
-// 13: uint256 public numDKGSet;
-func (s *StateHelper) numDKGSet() *big.Int {
- return s.getStateBigInt(big.NewInt(13))
+// 12: uint256 public dkgSetSize;
+func (s *StateHelper) dkgSetSize() *big.Int {
+ return s.getStateBigInt(big.NewInt(12))
}
-// 14: uint256 public roundInterval
+// 13: uint256 public roundInterval
func (s *StateHelper) roundInterval() *big.Int {
- return s.getStateBigInt(big.NewInt(14))
+ return s.getStateBigInt(big.NewInt(13))
}
-// 15: uint256 public minBlockInterval
+// 14: uint256 public minBlockInterval
func (s *StateHelper) minBlockInterval() *big.Int {
- return s.getStateBigInt(big.NewInt(15))
+ return s.getStateBigInt(big.NewInt(14))
}
-// 16: uint256 public maxBlockInterval
+// 15: uint256 public maxBlockInterval
func (s *StateHelper) maxBlockInterval() *big.Int {
- return s.getStateBigInt(big.NewInt(16))
+ return s.getStateBigInt(big.NewInt(15))
}
// GovernanceContract represents the governance contract of DEXCON.
@@ -784,7 +925,17 @@ func (g *GovernanceContract) penalize() {
g.contract.UseGas(g.contract.Gas)
}
-func (g *GovernanceContract) updateConfiguration() ([]byte, error) {
+func (g *GovernanceContract) updateConfiguration(config *configParams) ([]byte, error) {
+ g.state.setStateBigInt(big.NewInt(6), big.NewInt(int64(config.NumChains)))
+ g.state.setStateBigInt(big.NewInt(7), big.NewInt(int64(config.LambdaBA)))
+ g.state.setStateBigInt(big.NewInt(8), big.NewInt(int64(config.LambdaDKG)))
+ g.state.setStateBigInt(big.NewInt(9), big.NewInt(int64(config.K)))
+ g.state.setStateBigInt(big.NewInt(10), big.NewInt(int64(config.PhiRatio)))
+ g.state.setStateBigInt(big.NewInt(11), big.NewInt(int64(config.NotarySetSize)))
+ g.state.setStateBigInt(big.NewInt(12), big.NewInt(int64(config.DKGSetSize)))
+ g.state.setStateBigInt(big.NewInt(13), big.NewInt(int64(config.RoundInterval)))
+ g.state.setStateBigInt(big.NewInt(14), big.NewInt(int64(config.MinBlockInterval)))
+ g.state.setStateBigInt(big.NewInt(15), big.NewInt(int64(config.MaxBlockInterval)))
return nil, nil
}
@@ -838,19 +989,12 @@ func (g *GovernanceContract) unstake() ([]byte, error) {
return nil, nil
}
-func (g *GovernanceContract) proposeCRS(round *big.Int, signedCRS []byte) ([]byte, error) {
- crs := g.state.crs(round)
-
- // Revert if CRS for that round already exists.
- if crs != (common.Hash{}) {
- return nil, errExecutionReverted
- }
-
- prevRound := g.state.round()
- prevCRS := g.state.crs(prevRound)
+func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
+ round := g.state.lenCRS()
+ prevCRS := g.state.crs(round)
// round should be the next round number, abort otherwise.
- if new(big.Int).Add(prevRound, big.NewInt(1)).Cmp(round) != 0 {
+ if new(big.Int).Add(round, big.NewInt(1)).Cmp(round) != 0 {
g.penalize()
return nil, errExecutionReverted
}
@@ -876,7 +1020,7 @@ func (g *GovernanceContract) proposeCRS(round *big.Int, signedCRS []byte) ([]byt
dkgComplaints = append(dkgComplaints, x)
}
- threshold := int(g.state.numDKGSet().Uint64() / 3)
+ threshold := int(g.state.dkgSetSize().Uint64() / 3)
dkgGPK, err := core.NewDKGGroupPublicKey(
round.Uint64(), dkgMasterPKs, dkgComplaints, threshold)
@@ -894,8 +1038,7 @@ func (g *GovernanceContract) proposeCRS(round *big.Int, signedCRS []byte) ([]byt
// Save new CRS into state and increase round.
newCRS := crypto.Keccak256(signedCRS)
- g.state.incRound()
- g.state.putCRS(round, common.BytesToHash(newCRS))
+ g.state.pushCRS(common.BytesToHash(newCRS))
// To encourage DKG set to propose the correct value, correctly submitting
// this should cause nothing.
@@ -940,7 +1083,7 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
return nil, errExecutionReverted
}
- g.state.addDKGComplaint(round, comp)
+ g.state.pushDKGComplaint(round, comp)
// Set this to relatively high to prevent spamming
g.contract.UseGas(10000000)