aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/utils/flags.go2
-rw-r--r--core/vm/governance.go555
-rw-r--r--dex/api_backend.go2
-rw-r--r--dex/backend.go2
-rw-r--r--dex/config.go2
-rw-r--r--dex/governance.go114
6 files changed, 441 insertions, 236 deletions
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 03ae8e663..c116bdce0 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -40,9 +40,9 @@ import (
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/dashboard"
"github.com/dexon-foundation/dexon/dex"
+ "github.com/dexon-foundation/dexon/dex/gasprice"
"github.com/dexon-foundation/dexon/eth"
"github.com/dexon-foundation/dexon/eth/downloader"
- "github.com/dexon-foundation/dexon/eth/gasprice"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/ethstats"
"github.com/dexon-foundation/dexon/les"
diff --git a/core/vm/governance.go b/core/vm/governance.go
index d35fd54e4..fa9f578be 100644
--- a/core/vm/governance.go
+++ b/core/vm/governance.go
@@ -210,6 +210,25 @@ const abiJSON = `
},
{
"constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "roundHeight",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [],
"name": "minBlockInterval",
"outputs": [
@@ -356,6 +375,20 @@ const abiJSON = `
"constant": false,
"inputs": [
{
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
"name": "NumChains",
"type": "uint256"
},
@@ -406,6 +439,24 @@ const abiJSON = `
"constant": false,
"inputs": [
{
+ "name": "round",
+ "type": "uint256"
+ },
+ {
+ "name": "height",
+ "type": "uint256"
+ }
+ ],
+ "name": "snapshotRound",
+ "outputs": [],
+ "payable": false,
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "constant": false,
+ "inputs": [
+ {
"name": "SignedCRS",
"type": "bytes"
}
@@ -544,26 +595,6 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
arguments := input[4:]
switch method.Name {
- case "updateConfiguration":
- var cfg params.DexconConfig
- if err := method.Inputs.Unpack(&cfg, arguments); err != nil {
- return nil, errExecutionReverted
- }
- g.updateConfiguration(&cfg)
- case "stake":
- var publicKey []byte
- if err := method.Inputs.Unpack(&publicKey, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.stake(publicKey)
- case "unstake":
- return g.unstake()
- case "proposeCRS":
- var signedCRS []byte
- if err := method.Inputs.Unpack(&signedCRS, arguments); err != nil {
- return nil, errExecutionReverted
- }
- return g.proposeCRS(signedCRS)
case "addDKGComplaint":
args := struct {
Round *big.Int
@@ -591,6 +622,41 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
return nil, errExecutionReverted
}
return g.addDKGFinalize(args.Round, args.Finalize)
+ case "proposeCRS":
+ var signedCRS []byte
+ if err := method.Inputs.Unpack(&signedCRS, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.proposeCRS(signedCRS)
+ case "stake":
+ var publicKey []byte
+ if err := method.Inputs.Unpack(&publicKey, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.stake(publicKey)
+ case "snapshotRound":
+ args := struct {
+ Round *big.Int
+ Height *big.Int
+ }{}
+ if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.snapshotRound(args.Round, args.Height)
+ case "transferOwnership":
+ var newOwner common.Address
+ if err := method.Inputs.Unpack(&newOwner, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ return g.transferOwnership(newOwner)
+ case "unstake":
+ return g.unstake()
+ case "updateConfiguration":
+ var cfg params.DexconConfig
+ if err := method.Inputs.Unpack(&cfg, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ g.updateConfiguration(&cfg)
// --------------------------------
// Solidity auto generated methods.
@@ -601,7 +667,7 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&round, arguments); err != nil {
return nil, errExecutionReverted
}
- res, err := method.Outputs.Pack(g.state.crs(round))
+ res, err := method.Outputs.Pack(g.state.CRS(round))
if err != nil {
return nil, errExecutionReverted
}
@@ -612,7 +678,7 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&args, arguments); err != nil {
return nil, errExecutionReverted
}
- complaints := g.state.dkgComplaints(round)
+ complaints := g.state.DKGComplaints(round)
if int(index.Uint64()) >= len(complaints) {
return nil, errExecutionReverted
}
@@ -628,7 +694,7 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&args, arguments); err != nil {
return nil, errExecutionReverted
}
- finalized := g.state.dkgFinalized(round, addr)
+ finalized := g.state.DKGFinalized(round, addr)
res, err := method.Outputs.Pack(finalized)
if err != nil {
return nil, errExecutionReverted
@@ -639,7 +705,7 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&round, arguments); err != nil {
return nil, errExecutionReverted
}
- count := g.state.dkgFinalizedsCount(round)
+ count := g.state.DKGFinalizedsCount(round)
res, err := method.Outputs.Pack(count)
if err != nil {
return nil, errExecutionReverted
@@ -651,7 +717,7 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&args, arguments); err != nil {
return nil, errExecutionReverted
}
- pks := g.state.dkgMasterPublicKeys(round)
+ pks := g.state.DKGMasterPublicKeys(round)
if int(index.Uint64()) >= len(pks) {
return nil, errExecutionReverted
}
@@ -662,43 +728,43 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
}
return res, nil
case "dkgSetSize":
- res, err := method.Outputs.Pack(g.state.dkgSetSize())
+ res, err := method.Outputs.Pack(g.state.DKGSetSize())
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "k":
- res, err := method.Outputs.Pack(g.state.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())
+ 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())
+ 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())
+ 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())
+ 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())
+ res, err := method.Outputs.Pack(g.state.NumChains())
if err != nil {
return nil, errExecutionReverted
}
@@ -708,14 +774,14 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&index, arguments); err != nil {
return nil, errExecutionReverted
}
- info := g.state.node(index)
- res, err := method.Outputs.Pack(info.owner, info.publicKey, info.staked)
+ info := g.state.Node(index)
+ res, err := method.Outputs.Pack(info.Owner, info.PublicKey, info.Staked)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "notarySetSize":
- res, err := method.Outputs.Pack(g.state.notarySetSize())
+ res, err := method.Outputs.Pack(g.state.NotarySetSize())
if err != nil {
return nil, errExecutionReverted
}
@@ -725,25 +791,35 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
if err := method.Inputs.Unpack(&addr, arguments); err != nil {
return nil, errExecutionReverted
}
- res, err := method.Outputs.Pack(g.state.offset(addr))
+ res, err := method.Outputs.Pack(g.state.Offset(addr))
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "owner":
- res, err := method.Outputs.Pack(g.state.owner())
+ res, err := method.Outputs.Pack(g.state.Owner())
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "phiRatio":
- res, err := method.Outputs.Pack(g.state.phiRatio())
+ res, err := method.Outputs.Pack(g.state.PhiRatio())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
+ case "RoundHeight":
+ round := new(big.Int)
+ if err := method.Inputs.Unpack(&round, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.RoundHeight(round))
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "roundInterval":
- res, err := method.Outputs.Pack(g.state.roundInterval())
+ res, err := method.Outputs.Pack(g.state.RoundInterval())
if err != nil {
return nil, errExecutionReverted
}
@@ -754,7 +830,8 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (
// Storage position enums.
const (
- nodesLoc = iota
+ RoundHeightLoc = iota
+ nodesLoc
offsetLoc
crsLoc
dkgMasterPublicKeysLoc
@@ -909,6 +986,26 @@ func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []
s.writeBytes(elementLoc, data)
}
+// uint256[] public RoundHeight;
+func (s *GovernanceStateHelper) LenRoundHeight() *big.Int {
+ return s.getStateBigInt(big.NewInt(RoundHeightLoc))
+}
+func (s *GovernanceStateHelper) RoundHeight(round *big.Int) *big.Int {
+ baseLoc := s.getSlotLoc(big.NewInt(RoundHeightLoc))
+ loc := new(big.Int).Add(baseLoc, round)
+ return s.getStateBigInt(loc)
+}
+func (s *GovernanceStateHelper) PushRoundHeight(height *big.Int) {
+ // increase length by 1.
+ length := s.getStateBigInt(big.NewInt(RoundHeightLoc))
+ s.setStateBigInt(big.NewInt(RoundHeightLoc), new(big.Int).Add(length, big.NewInt(1)))
+
+ baseLoc := s.getSlotLoc(big.NewInt(RoundHeightLoc))
+ loc := new(big.Int).Add(baseLoc, length)
+
+ s.setStateBigInt(loc, height)
+}
+
// struct Node {
// address owner;
// bytes publicKey;
@@ -918,26 +1015,15 @@ func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []
// Node[] nodes;
type nodeInfo struct {
- owner common.Address
- publicKey []byte
- staked *big.Int
+ Owner common.Address
+ PublicKey []byte
+ Staked *big.Int
}
-// Stake is a helper function for creating genesis state.
-func (s *GovernanceStateHelper) Stake(addr common.Address, publicKey []byte, staked *big.Int) {
- offset := s.nodesLength()
- s.pushNode(&nodeInfo{
- owner: addr,
- publicKey: publicKey,
- staked: staked,
- })
- s.putOffset(addr, offset)
-}
-
-func (s *GovernanceStateHelper) nodesLength() *big.Int {
+func (s *GovernanceStateHelper) NodesLength() *big.Int {
return s.getStateBigInt(big.NewInt(nodesLoc))
}
-func (s *GovernanceStateHelper) node(index *big.Int) *nodeInfo {
+func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo {
node := new(nodeInfo)
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
@@ -945,66 +1031,73 @@ func (s *GovernanceStateHelper) node(index *big.Int) *nodeInfo {
// owner.
loc := elementBaseLoc
- node.owner = common.BytesToAddress(s.getState(common.BigToHash(elementBaseLoc)).Bytes())
+ node.Owner = common.BytesToAddress(s.getState(common.BigToHash(elementBaseLoc)).Bytes())
// publicKey.
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(1))
- node.publicKey = s.readBytes(loc)
+ node.PublicKey = s.readBytes(loc)
// staked.
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2))
- node.staked = s.getStateBigInt(loc)
+ node.Staked = s.getStateBigInt(loc)
return nil
}
-func (s *GovernanceStateHelper) pushNode(n *nodeInfo) {
+func (s *GovernanceStateHelper) PushNode(n *nodeInfo) {
// increase length by 1
- arrayLength := s.nodesLength()
+ arrayLength := s.NodesLength()
s.setStateBigInt(big.NewInt(nodesLoc), new(big.Int).Add(arrayLength, big.NewInt(1)))
- s.updateNode(arrayLength, n)
+ s.UpdateNode(arrayLength, n)
}
-func (s *GovernanceStateHelper) updateNode(index *big.Int, n *nodeInfo) {
+func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) {
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(index, big.NewInt(3)))
// owner.
loc := elementBaseLoc
- s.setState(common.BigToHash(loc), n.owner.Hash())
+ s.setState(common.BigToHash(loc), n.Owner.Hash())
// publicKey.
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(1))
- s.writeBytes(loc, n.publicKey)
+ s.writeBytes(loc, n.PublicKey)
// staked.
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2))
- s.setStateBigInt(loc, n.staked)
+ s.setStateBigInt(loc, n.Staked)
+}
+func (s *GovernanceStateHelper) Nodes() []*nodeInfo {
+ var nodes []*nodeInfo
+ for i := int64(0); i < int64(s.NodesLength().Uint64()); i++ {
+ nodes = append(nodes, s.Node(big.NewInt(i)))
+ }
+ return nodes
}
// mapping(address => uint256) public offset;
-func (s *GovernanceStateHelper) offset(addr common.Address) *big.Int {
+func (s *GovernanceStateHelper) Offset(addr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) putOffset(addr common.Address, offset *big.Int) {
+func (s *GovernanceStateHelper) PutOffset(addr common.Address, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) deleteOffset(addr common.Address) {
+func (s *GovernanceStateHelper) DeleteOffset(addr common.Address) {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
// bytes32[] public crs;
-func (s *GovernanceStateHelper) lenCRS() *big.Int {
+func (s *GovernanceStateHelper) LenCRS() *big.Int {
return s.getStateBigInt(big.NewInt(crsLoc))
}
-func (s *GovernanceStateHelper) crs(index *big.Int) common.Hash {
+func (s *GovernanceStateHelper) CRS(index *big.Int) common.Hash {
baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
loc := new(big.Int).Add(baseLoc, index)
return s.getState(common.BigToHash(loc))
}
-func (s *GovernanceStateHelper) pushCRS(crs common.Hash) {
+func (s *GovernanceStateHelper) PushCRS(crs common.Hash) {
// increase length by 1.
length := s.getStateBigInt(big.NewInt(crsLoc))
s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Add(length, big.NewInt(1)))
@@ -1016,28 +1109,28 @@ func (s *GovernanceStateHelper) pushCRS(crs common.Hash) {
}
// bytes[][] public dkgMasterPublicKeys;
-func (s *GovernanceStateHelper) dkgMasterPublicKeys(round *big.Int) [][]byte {
+func (s *GovernanceStateHelper) DKGMasterPublicKeys(round *big.Int) [][]byte {
return s.read2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
}
-func (s *GovernanceStateHelper) pushDKGMasterPublicKey(round *big.Int, pk []byte) {
+func (s *GovernanceStateHelper) PushDKGMasterPublicKey(round *big.Int, pk []byte) {
s.appendTo2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round, pk)
}
// bytes[][] public dkgComplaints;
-func (s *GovernanceStateHelper) dkgComplaints(round *big.Int) [][]byte {
+func (s *GovernanceStateHelper) DKGComplaints(round *big.Int) [][]byte {
return s.read2DByteArray(big.NewInt(dkgComplaintsLoc), round)
}
-func (s *GovernanceStateHelper) pushDKGComplaint(round *big.Int, complaint []byte) {
+func (s *GovernanceStateHelper) PushDKGComplaint(round *big.Int, complaint []byte) {
s.appendTo2DByteArray(big.NewInt(dkgComplaintsLoc), round, complaint)
}
// mapping(address => bool)[] public dkgFinalized;
-func (s *GovernanceStateHelper) dkgFinalized(round *big.Int, addr common.Address) bool {
+func (s *GovernanceStateHelper) DKGFinalized(round *big.Int, addr common.Address) bool {
baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinailizedLoc)), round)
mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *GovernanceStateHelper) putDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
+func (s *GovernanceStateHelper) PutDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinailizedLoc)), round)
mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
res := big.NewInt(0)
@@ -1048,74 +1141,88 @@ func (s *GovernanceStateHelper) putDKGFinalized(round *big.Int, addr common.Addr
}
// uint256[] public dkgFinalizedsCount;
-func (s *GovernanceStateHelper) dkgFinalizedsCount(round *big.Int) *big.Int {
+func (s *GovernanceStateHelper) DKGFinalizedsCount(round *big.Int) *big.Int {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
return s.getStateBigInt(loc)
}
-func (s *GovernanceStateHelper) incDKGFinalizedsCount(round *big.Int) {
+func (s *GovernanceStateHelper) IncDKGFinalizedsCount(round *big.Int) {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
// address public owner;
-func (s *GovernanceStateHelper) owner() common.Address {
+func (s *GovernanceStateHelper) Owner() common.Address {
val := s.getState(common.BigToHash(big.NewInt(ownerLoc)))
return common.BytesToAddress(val.Bytes())
}
+func (s *GovernanceStateHelper) SetOwner(newOwner common.Address) {
+ s.setState(common.BigToHash(big.NewInt(ownerLoc)), newOwner.Hash())
+}
// uint256 public numChains;
-func (s *GovernanceStateHelper) numChains() *big.Int {
+func (s *GovernanceStateHelper) NumChains() *big.Int {
return s.getStateBigInt(big.NewInt(numChainsLoc))
}
// uint256 public lambdaBA;
-func (s *GovernanceStateHelper) lambdaBA() *big.Int {
+func (s *GovernanceStateHelper) LambdaBA() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaBALoc))
}
// uint256 public lambdaDKG;
-func (s *GovernanceStateHelper) lambdaDKG() *big.Int {
+func (s *GovernanceStateHelper) LambdaDKG() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaDKGLoc))
}
// uint256 public k;
-func (s *GovernanceStateHelper) k() *big.Int {
+func (s *GovernanceStateHelper) K() *big.Int {
return s.getStateBigInt(big.NewInt(kLoc))
}
// uint256 public phiRatio; // stored as PhiRatio * 10^6
-func (s *GovernanceStateHelper) phiRatio() *big.Int {
+func (s *GovernanceStateHelper) PhiRatio() *big.Int {
return s.getStateBigInt(big.NewInt(phiRatioLoc))
}
// uint256 public notarySetSize;
-func (s *GovernanceStateHelper) notarySetSize() *big.Int {
+func (s *GovernanceStateHelper) NotarySetSize() *big.Int {
return s.getStateBigInt(big.NewInt(notarySetSizeLoc))
}
// uint256 public dkgSetSize;
-func (s *GovernanceStateHelper) dkgSetSize() *big.Int {
+func (s *GovernanceStateHelper) DKGSetSize() *big.Int {
return s.getStateBigInt(big.NewInt(dkgSetSizeLoc))
}
// uint256 public roundInterval;
-func (s *GovernanceStateHelper) roundInterval() *big.Int {
+func (s *GovernanceStateHelper) RoundInterval() *big.Int {
return s.getStateBigInt(big.NewInt(roundIntervalLoc))
}
// uint256 public minBlockInterval;
-func (s *GovernanceStateHelper) minBlockInterval() *big.Int {
+func (s *GovernanceStateHelper) MinBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(minBlockIntervalLoc))
}
// uint256 public maxBlockInterval;
-func (s *GovernanceStateHelper) maxBlockInterval() *big.Int {
+func (s *GovernanceStateHelper) MaxBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(maxBlockIntervalLoc))
}
-// GetConfiguration returns the current configuration.
-func (s *GovernanceStateHelper) GetConfiguration() *params.DexconConfig {
+// Stake is a helper function for creating genesis state.
+func (s *GovernanceStateHelper) Stake(addr common.Address, publicKey []byte, staked *big.Int) {
+ offset := s.NodesLength()
+ s.PushNode(&nodeInfo{
+ Owner: addr,
+ PublicKey: publicKey,
+ Staked: staked,
+ })
+ s.PutOffset(addr, offset)
+}
+
+// Configuration returns the current configuration.
+func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
return &params.DexconConfig{
NumChains: uint32(s.getStateBigInt(big.NewInt(numChainsLoc)).Uint64()),
LambdaBA: s.getStateBigInt(big.NewInt(lambdaBALoc)).Uint64(),
@@ -1181,9 +1288,118 @@ func (g *GovernanceContract) penalize() {
g.contract.UseGas(g.contract.Gas)
}
+func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
+ caller := g.contract.Caller()
+
+ // Finalized caller is not allowed to propose complaint.
+ if g.state.DKGFinalized(round, caller) {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ // Calculate 2f
+ threshold := new(big.Int).Mul(
+ big.NewInt(2),
+ new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
+
+ // If 2f + 1 of DKG set is finalized, one can not propose complaint anymore.
+ if g.state.DKGFinalizedsCount(round).Cmp(threshold) > 0 {
+ return nil, errExecutionReverted
+ }
+
+ var dkgComplaint coreTypes.DKGComplaint
+ if err := rlp.DecodeBytes(comp, &dkgComplaint); err != nil {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+ verified, _ := core.VerifyDKGComplaintSignature(&dkgComplaint)
+ if !verified {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ // Verify that the message is sent from the caller.
+ signer := nodeIDToAddress(dkgComplaint.ProposerID)
+ if signer != caller {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ g.state.PushDKGComplaint(round, comp)
+
+ // Set this to relatively high to prevent spamming
+ g.contract.UseGas(10000000)
+ return nil, nil
+}
+
+func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, pk []byte) ([]byte, error) {
+ caller := g.contract.Caller()
+ offset := g.state.Offset(caller)
+
+ // Can not add dkg mpk if not staked.
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ return nil, errExecutionReverted
+ }
+
+ var dkgMasterPK coreTypes.DKGMasterPublicKey
+ if err := rlp.DecodeBytes(pk, &dkgMasterPK); err != nil {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+ verified, _ := core.VerifyDKGMasterPublicKeySignature(&dkgMasterPK)
+ if !verified {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ // Verify that the message is sent from the caller.
+ signer := nodeIDToAddress(dkgMasterPK.ProposerID)
+ if signer != caller {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ g.state.PushDKGMasterPublicKey(round, pk)
+
+ // DKG operation is expensive.
+ g.contract.UseGas(100000)
+ return nil, nil
+}
+
+func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]byte, error) {
+ caller := g.contract.Caller()
+
+ var dkgFinalize coreTypes.DKGFinalize
+ if err := rlp.DecodeBytes(finalize, &dkgFinalize); err != nil {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+ verified, _ := core.VerifyDKGFinalizeSignature(&dkgFinalize)
+ if !verified {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ // Verify that the message is sent from the caller.
+ signer := nodeIDToAddress(dkgFinalize.ProposerID)
+ if signer != caller {
+ g.penalize()
+ return nil, errExecutionReverted
+ }
+
+ if !g.state.DKGFinalized(round, caller) {
+ g.state.PutDKGFinalized(round, caller, true)
+ g.state.IncDKGFinalizedsCount(round)
+ }
+
+ // DKG operation is expensive.
+ g.contract.UseGas(100000)
+ return nil, nil
+}
+
func (g *GovernanceContract) updateConfiguration(config *params.DexconConfig) ([]byte, error) {
// Only owner can update configuration.
- if g.contract.Caller() != g.state.owner() {
+ if g.contract.Caller() != g.state.Owner() {
return nil, errExecutionReverted
}
@@ -1194,7 +1410,7 @@ func (g *GovernanceContract) updateConfiguration(config *params.DexconConfig) ([
func (g *GovernanceContract) stake(publicKey []byte) ([]byte, error) {
caller := g.contract.Caller()
- offset := g.state.offset(caller)
+ offset := g.state.Offset(caller)
// Can not stake if already staked.
if offset.Cmp(big.NewInt(0)) >= 0 {
@@ -1214,13 +1430,13 @@ func (g *GovernanceContract) stake(publicKey []byte) ([]byte, error) {
return nil, errExecutionReverted
}
- offset = g.state.nodesLength()
- g.state.pushNode(&nodeInfo{
- owner: caller,
- publicKey: publicKey,
- staked: g.contract.Value(),
+ offset = g.state.NodesLength()
+ g.state.PushNode(&nodeInfo{
+ Owner: caller,
+ PublicKey: publicKey,
+ Staked: g.contract.Value(),
})
- g.state.putOffset(caller, offset)
+ g.state.PutOffset(caller, offset)
g.contract.UseGas(21000)
return nil, nil
@@ -1228,34 +1444,34 @@ func (g *GovernanceContract) stake(publicKey []byte) ([]byte, error) {
func (g *GovernanceContract) unstake() ([]byte, error) {
caller := g.contract.Caller()
- offset := g.state.offset(caller)
+ offset := g.state.Offset(caller)
if offset.Cmp(big.NewInt(0)) < 0 {
return nil, errExecutionReverted
}
- node := g.state.node(offset)
- length := g.state.nodesLength()
+ node := g.state.Node(offset)
+ length := g.state.NodesLength()
lastIndex := new(big.Int).Sub(length, big.NewInt(1))
// Delete the node.
if offset != lastIndex {
- lastNode := g.state.node(lastIndex)
- g.state.updateNode(offset, lastNode)
- g.state.putOffset(lastNode.owner, offset)
- g.state.deleteOffset(caller)
+ lastNode := g.state.Node(lastIndex)
+ g.state.UpdateNode(offset, lastNode)
+ g.state.PutOffset(lastNode.Owner, offset)
+ g.state.DeleteOffset(caller)
}
// Return the staked fund.
// TODO(w): use OP_CALL so this show up is internal transaction.
- g.evm.Transfer(g.evm.StateDB, GovernanceContractAddress, caller, node.staked)
+ g.evm.Transfer(g.evm.StateDB, GovernanceContractAddress, caller, node.Staked)
g.contract.UseGas(21000)
return nil, nil
}
func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
- round := g.state.lenCRS()
- prevCRS := g.state.crs(round)
+ round := g.state.LenCRS()
+ prevCRS := g.state.CRS(round)
// round should be the next round number, abort otherwise.
if new(big.Int).Add(round, big.NewInt(1)).Cmp(round) != 0 {
@@ -1266,7 +1482,7 @@ func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
// Prepare DKGMasterPublicKeys.
// TODO(w): make sure DKGMasterPKs are unique.
var dkgMasterPKs []*coreTypes.DKGMasterPublicKey
- for _, pk := range g.state.dkgMasterPublicKeys(round) {
+ for _, pk := range g.state.DKGMasterPublicKeys(round) {
x := new(coreTypes.DKGMasterPublicKey)
if err := rlp.DecodeBytes(pk, x); err != nil {
panic(err)
@@ -1276,7 +1492,7 @@ func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
// Prepare DKGComplaints.
var dkgComplaints []*coreTypes.DKGComplaint
- for _, comp := range g.state.dkgComplaints(round) {
+ for _, comp := range g.state.DKGComplaints(round) {
x := new(coreTypes.DKGComplaint)
if err := rlp.DecodeBytes(comp, x); err != nil {
panic(err)
@@ -1284,7 +1500,7 @@ func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
dkgComplaints = append(dkgComplaints, x)
}
- threshold := int(g.state.dkgSetSize().Uint64() / 3)
+ threshold := int(g.state.DKGSetSize().Uint64() / 3)
dkgGPK, err := core.NewDKGGroupPublicKey(
round.Uint64(), dkgMasterPKs, dkgComplaints, threshold)
@@ -1304,8 +1520,8 @@ func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
newCRS := crypto.Keccak256(signedCRS)
crs := common.BytesToHash(newCRS)
- g.state.pushCRS(crs)
- g.state.emitCRSProposed(g.state.lenCRS(), crs)
+ g.state.PushCRS(crs)
+ g.state.emitCRSProposed(g.state.LenCRS(), crs)
// To encourage DKG set to propose the correct value, correctly submitting
// this should cause nothing.
@@ -1313,111 +1529,24 @@ func (g *GovernanceContract) proposeCRS(signedCRS []byte) ([]byte, error) {
return nil, nil
}
-func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
- caller := g.contract.Caller()
-
- // Finalized caller is not allowed to propose complaint.
- if g.state.dkgFinalized(round, caller) {
- g.penalize()
- return nil, errExecutionReverted
- }
-
- // Calculate 2f
- threshold := new(big.Int).Mul(
- big.NewInt(2),
- new(big.Int).Div(g.state.dkgSetSize(), big.NewInt(3)))
-
- // If 2f + 1 of DKG set is finalized, one can not propose complaint anymore.
- if g.state.dkgFinalizedsCount(round).Cmp(threshold) > 0 {
- return nil, errExecutionReverted
- }
-
- var dkgComplaint coreTypes.DKGComplaint
- if err := rlp.DecodeBytes(comp, &dkgComplaint); err != nil {
- g.penalize()
- return nil, errExecutionReverted
- }
- verified, _ := core.VerifyDKGComplaintSignature(&dkgComplaint)
- if !verified {
- g.penalize()
- return nil, errExecutionReverted
- }
-
- // Verify that the message is sent from the caller.
- signer := nodeIDToAddress(dkgComplaint.ProposerID)
- if signer != caller {
- g.penalize()
- return nil, errExecutionReverted
- }
-
- g.state.pushDKGComplaint(round, comp)
-
- // Set this to relatively high to prevent spamming
- g.contract.UseGas(10000000)
- return nil, nil
-}
-
-func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, pk []byte) ([]byte, error) {
- caller := g.contract.Caller()
- offset := g.state.offset(caller)
-
- // Can not add dkg mpk if not staked.
- if offset.Cmp(big.NewInt(0)) < 0 {
- return nil, errExecutionReverted
- }
-
- var dkgMasterPK coreTypes.DKGMasterPublicKey
- if err := rlp.DecodeBytes(pk, &dkgMasterPK); err != nil {
- g.penalize()
- return nil, errExecutionReverted
- }
- verified, _ := core.VerifyDKGMasterPublicKeySignature(&dkgMasterPK)
- if !verified {
- g.penalize()
- return nil, errExecutionReverted
- }
-
- // Verify that the message is sent from the caller.
- signer := nodeIDToAddress(dkgMasterPK.ProposerID)
- if signer != caller {
- g.penalize()
+func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte, error) {
+ // Only owner can update configuration.
+ if g.contract.Caller() != g.state.Owner() {
return nil, errExecutionReverted
}
-
- g.state.pushDKGMasterPublicKey(round, pk)
-
- // DKG operation is expensive.
- g.contract.UseGas(100000)
+ g.state.SetOwner(newOwner)
return nil, nil
}
-func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]byte, error) {
- caller := g.contract.Caller()
+func (g *GovernanceContract) snapshotRound(round, height *big.Int) ([]byte, error) {
+ // TODO(w): validate if this mapping is correct.
- var dkgFinalize coreTypes.DKGFinalize
- if err := rlp.DecodeBytes(finalize, &dkgFinalize); err != nil {
- g.penalize()
- return nil, errExecutionReverted
- }
- verified, _ := core.VerifyDKGFinalizeSignature(&dkgFinalize)
- if !verified {
- g.penalize()
+ // Only allow updating the next round.
+ nextRound := g.state.LenRoundHeight()
+ if round.Cmp(nextRound) != 0 {
return nil, errExecutionReverted
}
- // Verify that the message is sent from the caller.
- signer := nodeIDToAddress(dkgFinalize.ProposerID)
- if signer != caller {
- g.penalize()
- return nil, errExecutionReverted
- }
-
- if !g.state.dkgFinalized(round, caller) {
- g.state.putDKGFinalized(round, caller, true)
- g.state.incDKGFinalizedsCount(round)
- }
-
- // DKG operation is expensive.
- g.contract.UseGas(100000)
+ g.state.PushRoundHeight(height)
return nil, nil
}
diff --git a/dex/api_backend.go b/dex/api_backend.go
index 7f2677dc8..9e9765d1a 100644
--- a/dex/api_backend.go
+++ b/dex/api_backend.go
@@ -29,8 +29,8 @@ import (
"github.com/dexon-foundation/dexon/core/state"
"github.com/dexon-foundation/dexon/core/types"
"github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/dex/gasprice"
"github.com/dexon-foundation/dexon/eth/downloader"
- "github.com/dexon-foundation/dexon/eth/gasprice"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/event"
diff --git a/dex/backend.go b/dex/backend.go
index 619f0a2aa..67fc5fe25 100644
--- a/dex/backend.go
+++ b/dex/backend.go
@@ -147,7 +147,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Dexon, error) {
}
dex.txPool = core.NewTxPool(config.TxPool, dex.chainConfig, dex.blockchain)
- dex.APIBackend = &DexAPIBackend{dexon, nil}
+ dex.APIBackend = &DexAPIBackend{dex, nil}
gpoParams := config.GPO
//if gpoParams.Default == nil {
// gpoParams.Default = config.MinerGasPrice
diff --git a/dex/config.go b/dex/config.go
index 5a43496ab..f7937f390 100644
--- a/dex/config.go
+++ b/dex/config.go
@@ -25,8 +25,8 @@ import (
"github.com/dexon-foundation/dexon/consensus/dexcon"
"github.com/dexon-foundation/dexon/core"
+ "github.com/dexon-foundation/dexon/dex/gasprice"
"github.com/dexon-foundation/dexon/eth/downloader"
- "github.com/dexon-foundation/dexon/eth/gasprice"
)
// DefaultConfig contains default settings for use on the Ethereum main net.
diff --git a/dex/governance.go b/dex/governance.go
index f49355816..d2cfe05c6 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -1,10 +1,17 @@
package dex
import (
+ "context"
+ "math/big"
+ "time"
+
coreCommon "github.com/dexon-foundation/dexon-consensus-core/common"
- "github.com/dexon-foundation/dexon-consensus-core/core/crypto"
- "github.com/dexon-foundation/dexon-consensus-core/core/types"
+ coreCrypto "github.com/dexon-foundation/dexon-consensus-core/core/crypto"
+ "github.com/dexon-foundation/dexon-consensus-core/core/crypto/ecdsa"
+ coreTypes "github.com/dexon-foundation/dexon-consensus-core/core/types"
"github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/rlp"
+ "github.com/dexon-foundation/dexon/rpc"
)
type DexconGovernance struct {
@@ -19,21 +26,63 @@ func NewDexconGovernance(backend *DexAPIBackend) *DexconGovernance {
}
}
-// Configuration return the total ordering K constant.
-func (d *DexconGovernance) Configuration(round uint64) *types.Config {
- state, _, err := d.b.StateAndHeaderByNumber(ctx, blockNr)
+func (d *DexconGovernance) getRoundHeight(ctx context.Context, round uint64) (uint64, error) {
+ state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if state == nil || err != nil {
- return nil, err
+ return 0, err
}
-
s := vm.GovernanceStateHelper{state}
+ return s.RoundHeight(big.NewInt(int64(round))).Uint64(), nil
+}
+
+func (d *DexconGovernance) getGovState() *vm.GovernanceStateHelper {
+ ctx := context.Background()
+ state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
+ if state == nil || err != nil {
+ return nil
+ }
- return &types.Config{}
+ return &vm.GovernanceStateHelper{state}
+}
+
+func (d *DexconGovernance) getGovStateAtRound(round uint64) *vm.GovernanceStateHelper {
+ ctx := context.Background()
+ blockHeight, err := d.getRoundHeight(ctx, round)
+ if err != nil {
+ return nil
+ }
+
+ state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.BlockNumber(blockHeight))
+ if state == nil || err != nil {
+ return nil
+ }
+
+ return &vm.GovernanceStateHelper{state}
+}
+
+// Configuration return the total ordering K constant.
+func (d *DexconGovernance) Configuration(round uint64) *coreTypes.Config {
+ s := d.getGovStateAtRound(round)
+ c := s.Configuration()
+
+ return &coreTypes.Config{
+ NumChains: c.NumChains,
+ LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
+ LambdaDKG: time.Duration(c.LambdaDKG) * time.Millisecond,
+ K: c.K,
+ PhiRatio: c.PhiRatio,
+ NotarySetSize: c.NotarySetSize,
+ DKGSetSize: c.DKGSetSize,
+ RoundInterval: time.Duration(c.RoundInterval) * time.Millisecond,
+ MinBlockInterval: time.Duration(c.MinBlockInterval) * time.Millisecond,
+ MaxBlockInterval: time.Duration(c.MaxBlockInterval) * time.Millisecond,
+ }
}
// CRS returns the CRS for a given round.
func (d *DexconGovernance) CRS(round uint64) coreCommon.Hash {
- return coreCommon.Hash{}
+ s := d.getGovStateAtRound(round)
+ return coreCommon.Hash(s.CRS(big.NewInt(int64(round))))
}
// ProposeCRS send proposals of a new CRS
@@ -41,33 +90,60 @@ func (d *DexconGovernance) ProposeCRS(signedCRS []byte) {
}
// NodeSet returns the current notary set.
-func (d *DexconGovernance) NodeSet(round uint64) []crypto.PublicKey {
- return nil
+func (d *DexconGovernance) NodeSet(round uint64) []coreCrypto.PublicKey {
+ s := d.getGovStateAtRound(round)
+ var pks []coreCrypto.PublicKey
+
+ for _, n := range s.Nodes() {
+ pks = append(pks, ecdsa.NewPublicKeyFromByteSlice(n.PublicKey))
+ }
+ return pks
}
// AddDKGComplaint adds a DKGComplaint.
-func (d *DexconGovernance) AddDKGComplaint(round uint64, complaint *types.DKGComplaint) {
+func (d *DexconGovernance) AddDKGComplaint(round uint64, complaint *coreTypes.DKGComplaint) {
}
// DKGComplaints gets all the DKGComplaints of round.
-func (d *DexconGovernance) DKGComplaints(round uint64) []*types.DKGComplaint {
- return nil
+func (d *DexconGovernance) DKGComplaints(round uint64) []*coreTypes.DKGComplaint {
+ s := d.getGovState()
+ var dkgComplaints []*coreTypes.DKGComplaint
+ for _, pk := range s.DKGMasterPublicKeys(big.NewInt(int64(round))) {
+ x := new(coreTypes.DKGComplaint)
+ if err := rlp.DecodeBytes(pk, x); err != nil {
+ panic(err)
+ }
+ dkgComplaints = append(dkgComplaints, x)
+ }
+ return dkgComplaints
}
// AddDKGMasterPublicKey adds a DKGMasterPublicKey.
-func (d *DexconGovernance) AddDKGMasterPublicKey(round uint64, masterPublicKey *types.DKGMasterPublicKey) {
+func (d *DexconGovernance) AddDKGMasterPublicKey(round uint64, masterPublicKey *coreTypes.DKGMasterPublicKey) {
}
// DKGMasterPublicKeys gets all the DKGMasterPublicKey of round.
-func (d *DexconGovernance) DKGMasterPublicKeys(round uint64) []*types.DKGMasterPublicKey {
- return nil
+func (d *DexconGovernance) DKGMasterPublicKeys(round uint64) []*coreTypes.DKGMasterPublicKey {
+ s := d.getGovState()
+ var dkgMasterPKs []*coreTypes.DKGMasterPublicKey
+ for _, pk := range s.DKGMasterPublicKeys(big.NewInt(int64(round))) {
+ x := new(coreTypes.DKGMasterPublicKey)
+ if err := rlp.DecodeBytes(pk, x); err != nil {
+ panic(err)
+ }
+ dkgMasterPKs = append(dkgMasterPKs, x)
+ }
+ return dkgMasterPKs
}
// AddDKGFinalize adds a DKG finalize message.
-func (d *DexconGovernance) AddDKGFinalize(round uint64, final *types.DKGFinalize) {
+func (d *DexconGovernance) AddDKGFinalize(round uint64, final *coreTypes.DKGFinalize) {
}
// IsDKGFinal checks if DKG is final.
func (d *DexconGovernance) IsDKGFinal(round uint64) bool {
- return false
+ s := d.getGovStateAtRound(round)
+ threshold := 2*s.DKGSetSize().Uint64()/3 + 1
+ count := s.DKGFinalizedsCount(big.NewInt(int64(round))).Uint64()
+ return count >= threshold
}