aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm')
-rw-r--r--core/vm/evm.go1
-rw-r--r--core/vm/oracle_contract_abi.go171
-rw-r--r--core/vm/oracle_contracts.go603
-rw-r--r--core/vm/oracle_contracts_test.go171
4 files changed, 464 insertions, 482 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 422d52ccb..6b2844020 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -101,6 +101,7 @@ type Context struct {
Time *big.Int // Provides information for TIME
Randomness []byte // Provides information for RAND
Difficulty *big.Int // Provides information for DIFFICULTY
+ Round *big.Int // Current round number.
RandCallIndex uint64 // Number of times opRand is called
}
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index ff4a94b29..43055bc4a 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -47,29 +47,6 @@ const GovernanceABIJSON = `
},
{
"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": "notarySetSize",
"outputs": [
@@ -223,14 +200,26 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
+ "type": "address"
+ },
+ {
+ "name": "",
"type": "uint256"
}
],
- "name": "crs",
+ "name": "delegators",
"outputs": [
{
- "name": "",
- "type": "bytes32"
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "undelegated_at",
+ "type": "uint256"
}
],
"payable": false,
@@ -242,14 +231,14 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "uint256"
+ "type": "address"
}
],
- "name": "dkgMPKReadysCount",
+ "name": "dkgFinalizeds",
"outputs": [
{
"name": "",
- "type": "uint256"
+ "type": "bool"
}
],
"payable": false,
@@ -258,21 +247,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- },
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "dkgMPKReadys",
+ "inputs": [],
+ "name": "blockGasLimit",
"outputs": [
{
"name": "",
- "type": "bool"
+ "type": "uint256"
}
],
"payable": false,
@@ -284,26 +264,14 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "address"
- },
- {
- "name": "",
- "type": "uint256"
+ "type": "bytes32"
}
],
- "name": "delegators",
+ "name": "nodesOffsetByID",
"outputs": [
{
- "name": "owner",
- "type": "address"
- },
- {
- "name": "value",
- "type": "uint256"
- },
- {
- "name": "undelegated_at",
- "type": "uint256"
+ "name": "",
+ "type": "int256"
}
],
"payable": false,
@@ -313,7 +281,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "blockGasLimit",
+ "name": "totalStaked",
"outputs": [
{
"name": "",
@@ -329,10 +297,10 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "bytes32"
+ "type": "address"
}
],
- "name": "nodesOffsetByID",
+ "name": "nodesOffsetByAddress",
"outputs": [
{
"name": "",
@@ -346,11 +314,11 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "totalStaked",
+ "name": "crs",
"outputs": [
{
"name": "",
- "type": "uint256"
+ "type": "bytes32"
}
],
"payable": false,
@@ -359,17 +327,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "nodesOffsetByAddress",
+ "inputs": [],
+ "name": "roundLength",
"outputs": [
{
"name": "",
- "type": "int256"
+ "type": "uint256"
}
],
"payable": false,
@@ -379,7 +342,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "roundLength",
+ "name": "nextHalvingSupply",
"outputs": [
{
"name": "",
@@ -392,14 +355,19 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [],
- "name": "nextHalvingSupply",
- "outputs": [
+ "inputs": [
{
"name": "",
"type": "uint256"
}
],
+ "name": "dkgComplaints",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
"payable": false,
"stateMutability": "view",
"type": "function"
@@ -420,6 +388,25 @@ const GovernanceABIJSON = `
},
{
"constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "dkgMPKReadys",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [],
"name": "lastHalvedAmount",
"outputs": [
@@ -506,7 +493,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "minBlockInterval",
+ "name": "dkgMPKReadysCount",
"outputs": [
{
"name": "",
@@ -519,21 +506,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- },
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "dkgMasterPublicKeys",
+ "inputs": [],
+ "name": "minBlockInterval",
"outputs": [
{
"name": "",
- "type": "bytes"
+ "type": "uint256"
}
],
"payable": false,
@@ -546,17 +524,13 @@ const GovernanceABIJSON = `
{
"name": "",
"type": "uint256"
- },
- {
- "name": "",
- "type": "address"
}
],
- "name": "dkgFinalizeds",
+ "name": "dkgMasterPublicKeys",
"outputs": [
{
"name": "",
- "type": "bool"
+ "type": "bytes"
}
],
"payable": false,
@@ -580,7 +554,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "lockupPeriod",
+ "name": "dkgFinalizedsCount",
"outputs": [
{
"name": "",
@@ -593,13 +567,8 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "dkgFinalizedsCount",
+ "inputs": [],
+ "name": "lockupPeriod",
"outputs": [
{
"name": "",
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index aa93c97fb..fcdc1d0a2 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -20,6 +20,7 @@ package vm
import (
"bytes"
"errors"
+ "fmt"
"math/big"
"sort"
@@ -31,7 +32,7 @@ import (
"github.com/dexon-foundation/dexon/rlp"
coreCommon "github.com/dexon-foundation/dexon-consensus/common"
- "github.com/dexon-foundation/dexon-consensus/core"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreUtils "github.com/dexon-foundation/dexon-consensus/core/utils"
@@ -60,7 +61,9 @@ const (
nodesOffsetByIDLoc
delegatorsLoc
delegatorsOffsetLoc
+ crsRoundLoc
crsLoc
+ dkgRoundLoc
dkgMasterPublicKeysLoc
dkgComplaintsLoc
dkgReadyLoc
@@ -96,36 +99,36 @@ func publicKeyToNodeID(pkBytes []byte) (Bytes32, error) {
}
// State manipulation helper fro the governance contract.
-type GovernanceStateHelper struct {
+type GovernanceState struct {
StateDB StateDB
}
-func (s *GovernanceStateHelper) getState(loc common.Hash) common.Hash {
+func (s *GovernanceState) getState(loc common.Hash) common.Hash {
return s.StateDB.GetState(GovernanceContractAddress, loc)
}
-func (s *GovernanceStateHelper) setState(loc common.Hash, val common.Hash) {
+func (s *GovernanceState) setState(loc common.Hash, val common.Hash) {
s.StateDB.SetState(GovernanceContractAddress, loc, val)
}
-func (s *GovernanceStateHelper) getStateBigInt(loc *big.Int) *big.Int {
+func (s *GovernanceState) getStateBigInt(loc *big.Int) *big.Int {
res := s.StateDB.GetState(GovernanceContractAddress, common.BigToHash(loc))
return new(big.Int).SetBytes(res.Bytes())
}
-func (s *GovernanceStateHelper) setStateBigInt(loc *big.Int, val *big.Int) {
+func (s *GovernanceState) setStateBigInt(loc *big.Int, val *big.Int) {
s.setState(common.BigToHash(loc), common.BigToHash(val))
}
-func (s *GovernanceStateHelper) getSlotLoc(loc *big.Int) *big.Int {
+func (s *GovernanceState) getSlotLoc(loc *big.Int) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(common.BigToHash(loc).Bytes()))
}
-func (s *GovernanceStateHelper) getMapLoc(pos *big.Int, key []byte) *big.Int {
+func (s *GovernanceState) getMapLoc(pos *big.Int, key []byte) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(key, common.BigToHash(pos).Bytes()))
}
-func (s *GovernanceStateHelper) readBytes(loc *big.Int) []byte {
+func (s *GovernanceState) readBytes(loc *big.Int) []byte {
// Length of the dynamic array (bytes).
rawLength := s.getStateBigInt(loc)
lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
@@ -158,7 +161,7 @@ func (s *GovernanceStateHelper) readBytes(loc *big.Int) []byte {
return data
}
-func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
+func (s *GovernanceState) writeBytes(loc *big.Int, data []byte) {
length := int64(len(data))
if length == 0 {
@@ -204,7 +207,7 @@ func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
}
}
-func (s *GovernanceStateHelper) eraseBytes(loc *big.Int) {
+func (s *GovernanceState) eraseBytes(loc *big.Int) {
// Length of the dynamic array (bytes).
rawLength := s.getStateBigInt(loc)
lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
@@ -227,10 +230,7 @@ func (s *GovernanceStateHelper) eraseBytes(loc *big.Int) {
s.setStateBigInt(loc, big.NewInt(0))
}
-func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) read1DByteArray(loc *big.Int) [][]byte {
arrayLength := s.getStateBigInt(loc)
dataLoc := s.getSlotLoc(loc)
@@ -243,11 +243,7 @@ func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
return data
}
-func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []byte) {
- // Find the loc of the last element.
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) appendTo1DByteArray(loc *big.Int, data []byte) {
// Increase length by 1.
arrayLength := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(arrayLength, big.NewInt(1)))
@@ -258,10 +254,7 @@ func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []
s.writeBytes(elementLoc, data)
}
-func (s *GovernanceStateHelper) erase2DByteArray(pos, index *big.Int) {
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) erase1DByteArray(loc *big.Int) {
arrayLength := s.getStateBigInt(loc)
dataLoc := s.getSlotLoc(loc)
@@ -273,12 +266,12 @@ func (s *GovernanceStateHelper) erase2DByteArray(pos, index *big.Int) {
}
// uint256[] public roundHeight;
-func (s *GovernanceStateHelper) RoundHeight(round *big.Int) *big.Int {
+func (s *GovernanceState) 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) {
+func (s *GovernanceState) 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)))
@@ -290,24 +283,24 @@ func (s *GovernanceStateHelper) PushRoundHeight(height *big.Int) {
}
// uint256 public totalSupply;
-func (s *GovernanceStateHelper) TotalSupply() *big.Int {
+func (s *GovernanceState) TotalSupply() *big.Int {
return s.getStateBigInt(big.NewInt(totalSupplyLoc))
}
-func (s *GovernanceStateHelper) IncTotalSupply(amount *big.Int) {
+func (s *GovernanceState) IncTotalSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalSupplyLoc), new(big.Int).Add(s.TotalSupply(), amount))
}
-func (s *GovernanceStateHelper) DecTotalSupply(amount *big.Int) {
+func (s *GovernanceState) DecTotalSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalSupplyLoc), new(big.Int).Sub(s.TotalSupply(), amount))
}
// uint256 public totalStaked;
-func (s *GovernanceStateHelper) TotalStaked() *big.Int {
+func (s *GovernanceState) TotalStaked() *big.Int {
return s.getStateBigInt(big.NewInt(totalStakedLoc))
}
-func (s *GovernanceStateHelper) IncTotalStaked(amount *big.Int) {
+func (s *GovernanceState) IncTotalStaked(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalStakedLoc), new(big.Int).Add(s.TotalStaked(), amount))
}
-func (s *GovernanceStateHelper) DecTotalStaked(amount *big.Int) {
+func (s *GovernanceState) DecTotalStaked(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalStakedLoc), new(big.Int).Sub(s.TotalStaked(), amount))
}
@@ -337,10 +330,10 @@ type nodeInfo struct {
const nodeStructSize = 8
-func (s *GovernanceStateHelper) LenNodes() *big.Int {
+func (s *GovernanceState) LenNodes() *big.Int {
return s.getStateBigInt(big.NewInt(nodesLoc))
}
-func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo {
+func (s *GovernanceState) Node(index *big.Int) *nodeInfo {
node := new(nodeInfo)
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
@@ -381,14 +374,14 @@ func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo {
return node
}
-func (s *GovernanceStateHelper) PushNode(n *nodeInfo) {
+func (s *GovernanceState) PushNode(n *nodeInfo) {
// Increase length by 1.
arrayLength := s.LenNodes()
s.setStateBigInt(big.NewInt(nodesLoc), new(big.Int).Add(arrayLength, big.NewInt(1)))
s.UpdateNode(arrayLength, n)
}
-func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) {
+func (s *GovernanceState) 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(nodeStructSize)))
@@ -425,7 +418,7 @@ func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) {
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7))
s.writeBytes(loc, []byte(n.Url))
}
-func (s *GovernanceStateHelper) PopLastNode() {
+func (s *GovernanceState) PopLastNode() {
// Decrease length by 1.
arrayLength := s.LenNodes()
newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1))
@@ -436,14 +429,14 @@ func (s *GovernanceStateHelper) PopLastNode() {
Fined: big.NewInt(0),
})
}
-func (s *GovernanceStateHelper) Nodes() []*nodeInfo {
+func (s *GovernanceState) Nodes() []*nodeInfo {
var nodes []*nodeInfo
for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
nodes = append(nodes, s.Node(big.NewInt(i)))
}
return nodes
}
-func (s *GovernanceStateHelper) QualifiedNodes() []*nodeInfo {
+func (s *GovernanceState) QualifiedNodes() []*nodeInfo {
var nodes []*nodeInfo
for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
node := s.Node(big.NewInt(i))
@@ -455,34 +448,34 @@ func (s *GovernanceStateHelper) QualifiedNodes() []*nodeInfo {
}
// mapping(address => uint256) public nodeOffsetByAddress;
-func (s *GovernanceStateHelper) NodesOffsetByAddress(addr common.Address) *big.Int {
+func (s *GovernanceState) NodesOffsetByAddress(addr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutNodesOffsetByAddress(addr common.Address, offset *big.Int) {
+func (s *GovernanceState) PutNodesOffsetByAddress(addr common.Address, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteNodesOffsetByAddress(addr common.Address) {
+func (s *GovernanceState) DeleteNodesOffsetByAddress(addr common.Address) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
// mapping(address => uint256) public nodeOffsetByID;
-func (s *GovernanceStateHelper) NodesOffsetByID(id Bytes32) *big.Int {
+func (s *GovernanceState) NodesOffsetByID(id Bytes32) *big.Int {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutNodesOffsetByID(id Bytes32, offset *big.Int) {
+func (s *GovernanceState) PutNodesOffsetByID(id Bytes32, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteNodesOffsetByID(id Bytes32) {
+func (s *GovernanceState) DeleteNodesOffsetByID(id Bytes32) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
s.setStateBigInt(loc, big.NewInt(0))
}
-func (s *GovernanceStateHelper) PutNodeOffsets(n *nodeInfo, offset *big.Int) error {
+func (s *GovernanceState) PutNodeOffsets(n *nodeInfo, offset *big.Int) error {
id, err := publicKeyToNodeID(n.PublicKey)
if err != nil {
return err
@@ -508,11 +501,11 @@ type delegatorInfo struct {
const delegatorStructSize = 3
// mapping(address => Delegator[]) public delegators;
-func (s *GovernanceStateHelper) LenDelegators(nodeAddr common.Address) *big.Int {
+func (s *GovernanceState) LenDelegators(nodeAddr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
return s.getStateBigInt(loc)
}
-func (s *GovernanceStateHelper) Delegator(nodeAddr common.Address, offset *big.Int) *delegatorInfo {
+func (s *GovernanceState) Delegator(nodeAddr common.Address, offset *big.Int) *delegatorInfo {
delegator := new(delegatorInfo)
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
@@ -533,7 +526,7 @@ func (s *GovernanceStateHelper) Delegator(nodeAddr common.Address, offset *big.I
return delegator
}
-func (s *GovernanceStateHelper) PushDelegator(nodeAddr common.Address, delegator *delegatorInfo) {
+func (s *GovernanceState) PushDelegator(nodeAddr common.Address, delegator *delegatorInfo) {
// Increase length by 1.
arrayLength := s.LenDelegators(nodeAddr)
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
@@ -541,7 +534,7 @@ func (s *GovernanceStateHelper) PushDelegator(nodeAddr common.Address, delegator
s.UpdateDelegator(nodeAddr, arrayLength, delegator)
}
-func (s *GovernanceStateHelper) UpdateDelegator(nodeAddr common.Address, offset *big.Int, delegator *delegatorInfo) {
+func (s *GovernanceState) UpdateDelegator(nodeAddr common.Address, offset *big.Int, delegator *delegatorInfo) {
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
arrayBaseLoc := s.getSlotLoc(loc)
elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(big.NewInt(delegatorStructSize), offset))
@@ -558,7 +551,7 @@ func (s *GovernanceStateHelper) UpdateDelegator(nodeAddr common.Address, offset
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2))
s.setStateBigInt(loc, delegator.UndelegatedAt)
}
-func (s *GovernanceStateHelper) PopLastDelegator(nodeAddr common.Address) {
+func (s *GovernanceState) PopLastDelegator(nodeAddr common.Address) {
// Decrease length by 1.
arrayLength := s.LenDelegators(nodeAddr)
newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1))
@@ -572,67 +565,55 @@ func (s *GovernanceStateHelper) PopLastDelegator(nodeAddr common.Address) {
}
// mapping(address => mapping(address => uint256)) delegatorsOffset;
-func (s *GovernanceStateHelper) DelegatorsOffset(nodeAddr, delegatorAddr common.Address) *big.Int {
+func (s *GovernanceState) DelegatorsOffset(nodeAddr, delegatorAddr common.Address) *big.Int {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutDelegatorOffset(nodeAddr, delegatorAddr common.Address, offset *big.Int) {
+func (s *GovernanceState) PutDelegatorOffset(nodeAddr, delegatorAddr common.Address, offset *big.Int) {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteDelegatorsOffset(nodeAddr, delegatorAddr common.Address) {
+func (s *GovernanceState) DeleteDelegatorsOffset(nodeAddr, delegatorAddr common.Address) {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
-// bytes32[] public crs;
-func (s *GovernanceStateHelper) LenCRS() *big.Int {
- return s.getStateBigInt(big.NewInt(crsLoc))
+// uint256 public crsRound;
+func (s *GovernanceState) CRSRound() *big.Int {
+ return s.getStateBigInt(big.NewInt(crsRoundLoc))
}
-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 *GovernanceState) SetCRSRound(round *big.Int) {
+ s.setStateBigInt(big.NewInt(crsRoundLoc), round)
}
-func (s *GovernanceStateHelper) CurrentCRS() common.Hash {
- return s.CRS(new(big.Int).Sub(s.LenCRS(), big.NewInt(1)))
-}
-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)))
-
- baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
- loc := new(big.Int).Add(baseLoc, length)
- s.setState(common.BigToHash(loc), crs)
+// bytes32 public crs;
+func (s *GovernanceState) CRS() common.Hash {
+ return s.getState(common.BigToHash(big.NewInt(crsLoc)))
+}
+func (s *GovernanceState) SetCRS(crs common.Hash) {
+ s.setState(common.BigToHash(big.NewInt(crsLoc)), crs)
}
-func (s *GovernanceStateHelper) PopCRS() {
- // decrease length by 1.
- length := s.getStateBigInt(big.NewInt(crsLoc))
- s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Sub(length, big.NewInt(1)))
-
- baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
- loc := new(big.Int).Add(baseLoc, length)
- s.setState(common.BigToHash(loc), common.Hash{})
+// uint256 public dkgRound;
+func (s *GovernanceState) DKGRound() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgRoundLoc))
}
-func (s *GovernanceStateHelper) Round() *big.Int {
- return new(big.Int).Sub(s.getStateBigInt(big.NewInt(crsLoc)), big.NewInt(1))
+func (s *GovernanceState) SetDKGRound(round *big.Int) {
+ s.setStateBigInt(big.NewInt(dkgRoundLoc), round)
}
-// bytes[][] public dkgMasterPublicKeys;
-func (s *GovernanceStateHelper) DKGMasterPublicKeys(round *big.Int) [][]byte {
- return s.read2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
+// bytes[] public dkgMasterPublicKeys;
+func (s *GovernanceState) DKGMasterPublicKeys() [][]byte {
+ return s.read1DByteArray(big.NewInt(dkgMasterPublicKeysLoc))
}
-func (s *GovernanceStateHelper) PushDKGMasterPublicKey(round *big.Int, mpk []byte) {
- s.appendTo2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round, mpk)
+func (s *GovernanceState) PushDKGMasterPublicKey(mpk []byte) {
+ s.appendTo1DByteArray(big.NewInt(dkgMasterPublicKeysLoc), mpk)
}
-func (s *GovernanceStateHelper) UniqueDKGMasterPublicKeys(round *big.Int) []*dkgTypes.MasterPublicKey {
+func (s *GovernanceState) UniqueDKGMasterPublicKeys() []*dkgTypes.MasterPublicKey {
// Prepare DKGMasterPublicKeys.
var dkgMasterPKs []*dkgTypes.MasterPublicKey
existence := make(map[coreTypes.NodeID]struct{})
- for _, mpk := range s.DKGMasterPublicKeys(round) {
+ for _, mpk := range s.DKGMasterPublicKeys() {
x := new(dkgTypes.MasterPublicKey)
if err := rlp.DecodeBytes(mpk, x); err != nil {
panic(err)
@@ -647,10 +628,10 @@ func (s *GovernanceStateHelper) UniqueDKGMasterPublicKeys(round *big.Int) []*dkg
}
return dkgMasterPKs
}
-func (s *GovernanceStateHelper) GetDKGMasterPublicKeyByProposerID(
- round *big.Int, proposerID coreTypes.NodeID) (*dkgTypes.MasterPublicKey, error) {
+func (s *GovernanceState) GetDKGMasterPublicKeyByProposerID(
+ proposerID coreTypes.NodeID) (*dkgTypes.MasterPublicKey, error) {
- for _, mpk := range s.DKGMasterPublicKeys(round) {
+ for _, mpk := range s.DKGMasterPublicKeys() {
x := new(dkgTypes.MasterPublicKey)
if err := rlp.DecodeBytes(mpk, x); err != nil {
panic(err)
@@ -661,199 +642,189 @@ func (s *GovernanceStateHelper) GetDKGMasterPublicKeyByProposerID(
}
return nil, errors.New("not found")
}
-func (s *GovernanceStateHelper) ClearDKGMasterPublicKeys(round *big.Int) {
- s.erase2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
+func (s *GovernanceState) ClearDKGMasterPublicKeys() {
+ s.erase1DByteArray(big.NewInt(dkgMasterPublicKeysLoc))
}
-// bytes[][] public dkgComplaints;
-func (s *GovernanceStateHelper) DKGComplaints(round *big.Int) [][]byte {
- return s.read2DByteArray(big.NewInt(dkgComplaintsLoc), round)
+// bytes[] public dkgComplaints;
+func (s *GovernanceState) DKGComplaints() [][]byte {
+ return s.read1DByteArray(big.NewInt(dkgComplaintsLoc))
}
-func (s *GovernanceStateHelper) PushDKGComplaint(round *big.Int, complaint []byte) {
- s.appendTo2DByteArray(big.NewInt(dkgComplaintsLoc), round, complaint)
+func (s *GovernanceState) PushDKGComplaint(complaint []byte) {
+ s.appendTo1DByteArray(big.NewInt(dkgComplaintsLoc), complaint)
}
-func (s *GovernanceStateHelper) ClearDKGComplaints(round *big.Int) {
- s.erase2DByteArray(big.NewInt(dkgComplaintsLoc), round)
+func (s *GovernanceState) ClearDKGComplaints() {
+ s.erase1DByteArray(big.NewInt(dkgComplaintsLoc))
}
-// mapping(address => bool)[] public dkgReady;
-func (s *GovernanceStateHelper) DKGMPKReady(round *big.Int, addr common.Address) bool {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadyLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+// mapping(address => bool) public dkgReady;
+func (s *GovernanceState) DKGMPKReady(addr common.Address) bool {
+ mapLoc := s.getMapLoc(big.NewInt(dkgReadyLoc), addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *GovernanceStateHelper) PutDKGMPKReady(round *big.Int, addr common.Address, ready bool) {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadyLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+func (s *GovernanceState) PutDKGMPKReady(addr common.Address, ready bool) {
+ mapLoc := s.getMapLoc(big.NewInt(dkgReadyLoc), addr.Bytes())
res := big.NewInt(0)
if ready {
res = big.NewInt(1)
}
s.setStateBigInt(mapLoc, res)
}
-func (s *GovernanceStateHelper) ClearDKGMPKReady(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+func (s *GovernanceState) ClearDKGMPKReady(dkgSet map[coreTypes.NodeID]struct{}) {
for id := range dkgSet {
offset := s.NodesOffsetByID(Bytes32(id.Hash))
if offset.Cmp(big.NewInt(0)) < 0 {
panic(errors.New("DKG node does not exist"))
}
node := s.Node(offset)
- s.PutDKGMPKReady(round, node.Owner, false)
+ s.PutDKGMPKReady(node.Owner, false)
}
}
-// uint256[] public dkgReadysCount;
-func (s *GovernanceStateHelper) DKGMPKReadysCount(round *big.Int) *big.Int {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- return s.getStateBigInt(loc)
+// uint256 public dkgReadysCount;
+func (s *GovernanceState) DKGMPKReadysCount() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgReadysCountLoc))
}
-func (s *GovernanceStateHelper) IncDKGMPKReadysCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- count := s.getStateBigInt(loc)
- s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
+func (s *GovernanceState) IncDKGMPKReadysCount() {
+ s.setStateBigInt(big.NewInt(dkgReadysCountLoc),
+ new(big.Int).Add(s.getStateBigInt(big.NewInt(dkgReadysCountLoc)), big.NewInt(1)))
}
-func (s *GovernanceStateHelper) ResetDKGMPKReadysCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- s.setStateBigInt(loc, big.NewInt(0))
+func (s *GovernanceState) ResetDKGMPKReadysCount() {
+ s.setStateBigInt(big.NewInt(dkgReadysCountLoc), big.NewInt(0))
}
-// mapping(address => bool)[] public dkgFinalized;
-func (s *GovernanceStateHelper) DKGFinalized(round *big.Int, addr common.Address) bool {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+// mapping(address => bool) public dkgFinalized;
+func (s *GovernanceState) DKGFinalized(addr common.Address) bool {
+ mapLoc := s.getMapLoc(big.NewInt(dkgFinalizedLoc), addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *GovernanceStateHelper) PutDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+func (s *GovernanceState) PutDKGFinalized(addr common.Address, finalized bool) {
+ mapLoc := s.getMapLoc(big.NewInt(dkgFinalizedLoc), addr.Bytes())
res := big.NewInt(0)
if finalized {
res = big.NewInt(1)
}
s.setStateBigInt(mapLoc, res)
}
-func (s *GovernanceStateHelper) ClearDKGFinalized(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+func (s *GovernanceState) ClearDKGFinalized(dkgSet map[coreTypes.NodeID]struct{}) {
for id := range dkgSet {
offset := s.NodesOffsetByID(Bytes32(id.Hash))
if offset.Cmp(big.NewInt(0)) < 0 {
panic(errors.New("DKG node does not exist"))
}
node := s.Node(offset)
- s.PutDKGFinalized(round, node.Owner, false)
+ s.PutDKGFinalized(node.Owner, false)
}
}
-// uint256[] public dkgFinalizedsCount;
-func (s *GovernanceStateHelper) DKGFinalizedsCount(round *big.Int) *big.Int {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
- return s.getStateBigInt(loc)
+// uint256 public dkgFinalizedsCount;
+func (s *GovernanceState) DKGFinalizedsCount() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgFinalizedsCountLoc))
}
-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)))
+func (s *GovernanceState) IncDKGFinalizedsCount() {
+ s.setStateBigInt(big.NewInt(dkgFinalizedsCountLoc),
+ new(big.Int).Add(s.getStateBigInt(big.NewInt(dkgFinalizedsCountLoc)), big.NewInt(1)))
}
-func (s *GovernanceStateHelper) ResetDKGFinalizedsCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
- s.setStateBigInt(loc, big.NewInt(0))
+func (s *GovernanceState) ResetDKGFinalizedsCount() {
+ s.setStateBigInt(big.NewInt(dkgFinalizedsCountLoc), big.NewInt(0))
}
// address public owner;
-func (s *GovernanceStateHelper) Owner() common.Address {
+func (s *GovernanceState) Owner() common.Address {
val := s.getState(common.BigToHash(big.NewInt(ownerLoc)))
return common.BytesToAddress(val.Bytes())
}
-func (s *GovernanceStateHelper) SetOwner(newOwner common.Address) {
+func (s *GovernanceState) SetOwner(newOwner common.Address) {
s.setState(common.BigToHash(big.NewInt(ownerLoc)), newOwner.Hash())
}
// uint256 public minStake;
-func (s *GovernanceStateHelper) MinStake() *big.Int {
+func (s *GovernanceState) MinStake() *big.Int {
return s.getStateBigInt(big.NewInt(minStakeLoc))
}
// uint256 public lockupPeriod;
-func (s *GovernanceStateHelper) LockupPeriod() *big.Int {
+func (s *GovernanceState) LockupPeriod() *big.Int {
return s.getStateBigInt(big.NewInt(lockupPeriodLoc))
}
// uint256 public miningVelocity;
-func (s *GovernanceStateHelper) MiningVelocity() *big.Int {
+func (s *GovernanceState) MiningVelocity() *big.Int {
return s.getStateBigInt(big.NewInt(miningVelocityLoc))
}
-func (s *GovernanceStateHelper) HalfMiningVelocity() {
+func (s *GovernanceState) HalfMiningVelocity() {
s.setStateBigInt(big.NewInt(miningVelocityLoc),
new(big.Int).Div(s.MiningVelocity(), big.NewInt(2)))
}
// uint256 public nextHalvingSupply;
-func (s *GovernanceStateHelper) NextHalvingSupply() *big.Int {
+func (s *GovernanceState) NextHalvingSupply() *big.Int {
return s.getStateBigInt(big.NewInt(nextHalvingSupplyLoc))
}
-func (s *GovernanceStateHelper) IncNextHalvingSupply(amount *big.Int) {
+func (s *GovernanceState) IncNextHalvingSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(nextHalvingSupplyLoc),
new(big.Int).Add(s.NextHalvingSupply(), amount))
}
// uint256 public lastHalvedAmount;
-func (s *GovernanceStateHelper) LastHalvedAmount() *big.Int {
+func (s *GovernanceState) LastHalvedAmount() *big.Int {
return s.getStateBigInt(big.NewInt(lastHalvedAmountLoc))
}
-func (s *GovernanceStateHelper) HalfLastHalvedAmount() {
+func (s *GovernanceState) HalfLastHalvedAmount() {
s.setStateBigInt(big.NewInt(lastHalvedAmountLoc),
new(big.Int).Div(s.LastHalvedAmount(), big.NewInt(2)))
}
-func (s *GovernanceStateHelper) MiningHalved() {
+func (s *GovernanceState) MiningHalved() {
s.HalfMiningVelocity()
s.HalfLastHalvedAmount()
s.IncNextHalvingSupply(s.LastHalvedAmount())
}
// uint256 public blockGasLimit;
-func (s *GovernanceStateHelper) BlockGasLimit() *big.Int {
+func (s *GovernanceState) BlockGasLimit() *big.Int {
return s.getStateBigInt(big.NewInt(blockGasLimitLoc))
}
-func (s *GovernanceStateHelper) SetBlockGasLimit(reward *big.Int) {
+func (s *GovernanceState) SetBlockGasLimit(reward *big.Int) {
s.setStateBigInt(big.NewInt(blockGasLimitLoc), reward)
}
// uint256 public lambdaBA;
-func (s *GovernanceStateHelper) LambdaBA() *big.Int {
+func (s *GovernanceState) LambdaBA() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaBALoc))
}
// uint256 public lambdaDKG;
-func (s *GovernanceStateHelper) LambdaDKG() *big.Int {
+func (s *GovernanceState) LambdaDKG() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaDKGLoc))
}
// uint256 public notarySetSize;
-func (s *GovernanceStateHelper) NotarySetSize() *big.Int {
+func (s *GovernanceState) NotarySetSize() *big.Int {
return s.getStateBigInt(big.NewInt(notarySetSizeLoc))
}
// uint256 public dkgSetSize;
-func (s *GovernanceStateHelper) DKGSetSize() *big.Int {
+func (s *GovernanceState) DKGSetSize() *big.Int {
return s.getStateBigInt(big.NewInt(dkgSetSizeLoc))
}
// uint256 public roundLength;
-func (s *GovernanceStateHelper) RoundLength() *big.Int {
+func (s *GovernanceState) RoundLength() *big.Int {
return s.getStateBigInt(big.NewInt(roundLengthLoc))
}
// uint256 public minBlockInterval;
-func (s *GovernanceStateHelper) MinBlockInterval() *big.Int {
+func (s *GovernanceState) MinBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(minBlockIntervalLoc))
}
// uint256[] public fineValues;
-func (s *GovernanceStateHelper) FineValue(index *big.Int) *big.Int {
+func (s *GovernanceState) FineValue(index *big.Int) *big.Int {
arrayBaseLoc := s.getSlotLoc(big.NewInt(fineValuesLoc))
return s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, index))
}
-func (s *GovernanceStateHelper) FineValues() []*big.Int {
+func (s *GovernanceState) FineValues() []*big.Int {
len := s.getStateBigInt(big.NewInt(fineValuesLoc))
result := make([]*big.Int, len.Uint64())
for i := 0; i < int(len.Uint64()); i++ {
@@ -861,7 +832,7 @@ func (s *GovernanceStateHelper) FineValues() []*big.Int {
}
return result
}
-func (s *GovernanceStateHelper) SetFineValues(values []*big.Int) {
+func (s *GovernanceState) SetFineValues(values []*big.Int) {
s.setStateBigInt(big.NewInt(fineValuesLoc), big.NewInt(int64(len(values))))
arrayBaseLoc := s.getSlotLoc(big.NewInt(fineValuesLoc))
@@ -871,11 +842,11 @@ func (s *GovernanceStateHelper) SetFineValues(values []*big.Int) {
}
// mapping(bytes32 => bool) public fineRdecords;
-func (s *GovernanceStateHelper) FineRecords(recordHash Bytes32) bool {
+func (s *GovernanceState) FineRecords(recordHash Bytes32) bool {
loc := s.getMapLoc(big.NewInt(finedRecordsLoc), recordHash[:])
return s.getStateBigInt(loc).Cmp(big.NewInt(0)) > 0
}
-func (s *GovernanceStateHelper) SetFineRecords(recordHash Bytes32, status bool) {
+func (s *GovernanceState) SetFineRecords(recordHash Bytes32, status bool) {
loc := s.getMapLoc(big.NewInt(finedRecordsLoc), recordHash[:])
value := int64(0)
if status {
@@ -885,23 +856,50 @@ func (s *GovernanceStateHelper) SetFineRecords(recordHash Bytes32, status bool)
}
// uint256[] public DKGResetCount;
-func (s *GovernanceStateHelper) DKGResetCount(round *big.Int) *big.Int {
+func (s *GovernanceState) DKGResetCount(round *big.Int) *big.Int {
arrayBaseLoc := s.getSlotLoc(big.NewInt(dkgResetCountLoc))
return s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, round))
}
-func (s *GovernanceStateHelper) IncDKGResetCount(round *big.Int) {
+func (s *GovernanceState) IncDKGResetCount(round *big.Int) {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgResetCountLoc)), round)
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
// uint256 public minGasPrice;
-func (s *GovernanceStateHelper) MinGasPrice() *big.Int {
+func (s *GovernanceState) MinGasPrice() *big.Int {
return s.getStateBigInt(big.NewInt(minGasPriceLoc))
}
+// Initialize initializes governance contract state.
+func (s *GovernanceState) Initialize(config *params.DexconConfig, totalSupply *big.Int) {
+ if config.NextHalvingSupply.Cmp(totalSupply) <= 0 {
+ panic(fmt.Sprintf("invalid genesis found, totalSupply: %s, nextHavlingSupply: %s",
+ totalSupply, config.NextHalvingSupply))
+ }
+
+ // Genesis CRS.
+ crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
+ s.SetCRS(crs)
+
+ // Round 0 height.
+ s.PushRoundHeight(big.NewInt(0))
+
+ // Owner.
+ s.SetOwner(config.Owner)
+
+ // Governance configuration.
+ s.UpdateConfiguration(config)
+
+ // Set totalSupply.
+ s.IncTotalSupply(totalSupply)
+
+ // Set DKGRound.
+ s.SetDKGRound(big.NewInt(int64(dexCore.DKGDelayRound)))
+}
+
// Stake is a helper function for creating genesis state.
-func (s *GovernanceStateHelper) Stake(
+func (s *GovernanceState) Stake(
addr common.Address, publicKey []byte, staked *big.Int,
name, email, location, url string) {
offset := s.LenNodes()
@@ -939,7 +937,7 @@ func (s *GovernanceStateHelper) Stake(
const decimalMultiplier = 100000000.0
// Configuration returns the current configuration.
-func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
+func (s *GovernanceState) Configuration() *params.DexconConfig {
return &params.DexconConfig{
MinStake: s.getStateBigInt(big.NewInt(minStakeLoc)),
LockupPeriod: s.getStateBigInt(big.NewInt(lockupPeriodLoc)).Uint64(),
@@ -959,7 +957,7 @@ func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
}
// UpdateConfiguration updates system configuration.
-func (s *GovernanceStateHelper) UpdateConfiguration(cfg *params.DexconConfig) {
+func (s *GovernanceState) UpdateConfiguration(cfg *params.DexconConfig) {
s.setStateBigInt(big.NewInt(minStakeLoc), cfg.MinStake)
s.setStateBigInt(big.NewInt(lockupPeriodLoc), big.NewInt(int64(cfg.LockupPeriod)))
s.setStateBigInt(big.NewInt(miningVelocityLoc), big.NewInt(int64(cfg.MiningVelocity*decimalMultiplier)))
@@ -991,7 +989,7 @@ type rawConfigStruct struct {
}
// UpdateConfigurationRaw updates system configuration.
-func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
+func (s *GovernanceState) UpdateConfigurationRaw(cfg *rawConfigStruct) {
s.setStateBigInt(big.NewInt(minStakeLoc), cfg.MinStake)
s.setStateBigInt(big.NewInt(lockupPeriodLoc), cfg.LockupPeriod)
s.setStateBigInt(big.NewInt(blockGasLimitLoc), cfg.BlockGasLimit)
@@ -1006,7 +1004,7 @@ func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
}
// event ConfigurationChanged();
-func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
+func (s *GovernanceState) emitConfigurationChangedEvent() {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["ConfigurationChanged"].Id()},
@@ -1015,7 +1013,7 @@ func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
}
// event CRSProposed(uint256 round, bytes32 crs);
-func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
+func (s *GovernanceState) emitCRSProposed(round *big.Int, crs common.Hash) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["CRSProposed"].Id(), common.BigToHash(round)},
@@ -1024,7 +1022,7 @@ func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash)
}
// event Staked(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
+func (s *GovernanceState) emitStaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Staked"].Id(), nodeAddr.Hash()},
@@ -1033,7 +1031,7 @@ func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
}
// event Unstaked(address indexed NodeAddress);
-func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
+func (s *GovernanceState) emitUnstaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Unstaked"].Id(), nodeAddr.Hash()},
@@ -1042,7 +1040,7 @@ func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
}
// event NodeRemoved(address indexed NodeAddress);
-func (s *GovernanceStateHelper) emitNodeRemoved(nodeAddr common.Address) {
+func (s *GovernanceState) emitNodeRemoved(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["NodeRemoved"].Id(), nodeAddr.Hash()},
@@ -1051,7 +1049,7 @@ func (s *GovernanceStateHelper) emitNodeRemoved(nodeAddr common.Address) {
}
// event Delegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1060,7 +1058,7 @@ func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Add
}
// event Undelegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1069,7 +1067,7 @@ func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.A
}
// event Withdrawn(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1078,7 +1076,7 @@ func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, delegator
}
// event ForkReported(address indexed NodeAddress, address indexed Type, bytes Arg1, bytes Arg2);
-func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, reportType *big.Int, arg1, arg2 []byte) {
+func (s *GovernanceState) emitForkReported(nodeAddr common.Address, reportType *big.Int, arg1, arg2 []byte) {
t, err := abi.NewType("bytes", nil)
if err != nil {
@@ -1110,7 +1108,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report
}
// event Fined(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitFined(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Fined"].Id(), nodeAddr.Hash()},
@@ -1119,7 +1117,7 @@ func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.I
}
// event FinePaid(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitFinePaid(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["FinePaid"].Id(), nodeAddr.Hash()},
@@ -1128,7 +1126,7 @@ func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *bi
}
// event DKGReset(uint256 indexed Round, uint256 BlockHeight);
-func (s *GovernanceStateHelper) emitDKGReset(round *big.Int, blockHeight *big.Int) {
+func (s *GovernanceState) emitDKGReset(round *big.Int, blockHeight *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["DKGReset"].Id(), common.BigToHash(round)},
@@ -1136,25 +1134,28 @@ func (s *GovernanceStateHelper) emitDKGReset(round *big.Int, blockHeight *big.In
})
}
-func getConfigState(evm *EVM, round *big.Int) (*GovernanceStateHelper, error) {
- configRound := big.NewInt(0)
- if round.Uint64() > core.ConfigRoundShift {
- configRound = new(big.Int).Sub(round, big.NewInt(int64(core.ConfigRoundShift)))
- }
-
- gs := &GovernanceStateHelper{evm.StateDB}
- height := gs.RoundHeight(configRound).Uint64()
- if round.Uint64() > core.ConfigRoundShift {
+func getRoundState(evm *EVM, round *big.Int) (*GovernanceState, error) {
+ gs := &GovernanceState{evm.StateDB}
+ height := gs.RoundHeight(round).Uint64()
+ if round.Uint64() > dexCore.ConfigRoundShift {
if height == 0 {
return nil, errExecutionReverted
}
}
statedb, err := evm.StateAtNumber(height)
- return &GovernanceStateHelper{statedb}, err
+ return &GovernanceState{statedb}, err
+}
+
+func getConfigState(evm *EVM, round *big.Int) (*GovernanceState, error) {
+ configRound := big.NewInt(0)
+ if round.Uint64() > dexCore.ConfigRoundShift {
+ configRound = new(big.Int).Sub(round, big.NewInt(int64(dexCore.ConfigRoundShift)))
+ }
+ return getRoundState(evm, configRound)
}
type coreDKGUtils interface {
- SetState(GovernanceStateHelper)
+ SetState(GovernanceState)
NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error)
}
type tsigVerifierIntf interface {
@@ -1164,28 +1165,27 @@ type tsigVerifierIntf interface {
// GovernanceContract represents the governance contract of DEXCON.
type GovernanceContract struct {
evm *EVM
- state GovernanceStateHelper
+ state GovernanceState
contract *Contract
coreDKGUtils coreDKGUtils
}
// defaultCoreDKGUtils implements coreDKGUtils.
type defaultCoreDKGUtils struct {
- state GovernanceStateHelper
+ state GovernanceState
}
-func (c *defaultCoreDKGUtils) SetState(state GovernanceStateHelper) {
+func (c *defaultCoreDKGUtils) SetState(state GovernanceState) {
c.state = state
}
-func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int,
- threshold int) (tsigVerifierIntf, error) {
+func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int, threshold int) (tsigVerifierIntf, error) {
// Prepare DKGMasterPublicKeys.
- mpks := c.state.UniqueDKGMasterPublicKeys(round)
+ mpks := c.state.UniqueDKGMasterPublicKeys()
// Prepare DKGComplaints.
var complaints []*dkgTypes.Complaint
- for _, comp := range c.state.DKGComplaints(round) {
+ for _, comp := range c.state.DKGComplaints() {
x := new(dkgTypes.Complaint)
if err := rlp.DecodeBytes(comp, x); err != nil {
panic(err)
@@ -1193,7 +1193,7 @@ func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int,
complaints = append(complaints, x)
}
- return core.NewDKGGroupPublicKey(round.Uint64(), mpks, complaints, threshold)
+ return dexCore.NewDKGGroupPublicKey(round.Uint64(), mpks, complaints, threshold)
}
func (g *GovernanceContract) Address() common.Address {
@@ -1229,7 +1229,7 @@ func (g *GovernanceContract) configDKGSetSize(round *big.Int) *big.Int {
return s.DKGSetSize()
}
func (g *GovernanceContract) getDKGSet(round *big.Int) map[coreTypes.NodeID]struct{} {
- target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CRS(round)))
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CRS()))
ns := coreTypes.NewNodeSet()
state, err := getConfigState(g.evm, round)
@@ -1252,15 +1252,21 @@ func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) b
return ok
}
-func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
+func (g *GovernanceContract) clearDKG() {
+ dkgSet := g.getDKGSet(g.evm.Round)
+ g.state.ClearDKGMasterPublicKeys()
+ g.state.ClearDKGComplaints()
+ g.state.ClearDKGMPKReady(dkgSet)
+ g.state.ResetDKGMPKReadysCount()
+ g.state.ClearDKGFinalized(dkgSet)
+ g.state.ResetDKGFinalizedsCount()
+}
+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) {
+ if g.state.DKGFinalized(caller) {
return g.penalize()
}
@@ -1270,7 +1276,7 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
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 {
+ if g.state.DKGFinalizedsCount().Cmp(threshold) > 0 {
return nil, errExecutionReverted
}
@@ -1289,8 +1295,7 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
return g.penalize()
}
- mpk, err := g.state.GetDKGMasterPublicKeyByProposerID(
- round, dkgComplaint.PrivateShare.ProposerID)
+ mpk, err := g.state.GetDKGMasterPublicKeyByProposerID(dkgComplaint.PrivateShare.ProposerID)
if err != nil {
return g.penalize()
}
@@ -1315,28 +1320,35 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
}
}
- g.state.PushDKGComplaint(round, comp)
+ g.state.PushDKGComplaint(comp)
// Set this to relatively high to prevent spamming
return g.useGas(5000000)
}
func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) ([]byte, error) {
- // Can only add DKG master public key of current and next round.
- if round.Cmp(new(big.Int).Add(g.state.Round(), big.NewInt(1))) > 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
offset := g.state.NodesOffsetByAddress(caller)
+ if g.evm.Round.Uint64() > 0 {
+ if round.Uint64() != g.evm.Round.Uint64()+1 {
+ return nil, errExecutionReverted
+ }
+
+ if g.state.DKGRound().Cmp(g.evm.Round) == 0 {
+ // Clear DKG states for next round.
+ g.clearDKG()
+ g.state.SetDKGRound(round)
+ }
+ }
+
// Can not add dkg mpk if not staked.
if offset.Cmp(big.NewInt(0)) < 0 {
return nil, errExecutionReverted
}
// MPKReady caller is not allowed to propose mpk.
- if g.state.DKGMPKReady(round, caller) {
+ if g.state.DKGMPKReady(caller) {
return g.penalize()
}
@@ -1346,7 +1358,7 @@ func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) (
new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
// If 2f + 1 of DKG set is mpk ready, one can not propose mpk anymore.
- if g.state.DKGMPKReadysCount(round).Cmp(threshold) > 0 {
+ if g.state.DKGMPKReadysCount().Cmp(threshold) > 0 {
return nil, errExecutionReverted
}
@@ -1365,16 +1377,12 @@ func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) (
return g.penalize()
}
- g.state.PushDKGMasterPublicKey(round, mpk)
+ g.state.PushDKGMasterPublicKey(mpk)
return g.useGas(100000)
}
func (g *GovernanceContract) addDKGMPKReady(round *big.Int, ready []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
var dkgReady dkgTypes.MPKReady
@@ -1392,18 +1400,14 @@ func (g *GovernanceContract) addDKGMPKReady(round *big.Int, ready []byte) ([]byt
return g.penalize()
}
- if !g.state.DKGMPKReady(round, caller) {
- g.state.PutDKGMPKReady(round, caller, true)
- g.state.IncDKGMPKReadysCount(round)
+ if !g.state.DKGMPKReady(caller) {
+ g.state.PutDKGMPKReady(caller, true)
+ g.state.IncDKGMPKReadysCount()
}
return g.useGas(100000)
}
func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
var dkgFinalize dkgTypes.Finalize
@@ -1421,9 +1425,9 @@ func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]
return g.penalize()
}
- if !g.state.DKGFinalized(round, caller) {
- g.state.PutDKGFinalized(round, caller, true)
- g.state.IncDKGFinalizedsCount(round)
+ if !g.state.DKGFinalized(caller) {
+ g.state.PutDKGFinalized(caller, true)
+ g.state.IncDKGFinalizedsCount()
}
return g.useGas(100000)
@@ -1688,18 +1692,22 @@ func (g *GovernanceContract) payFine(nodeAddr common.Address) ([]byte, error) {
}
func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([]byte, error) {
- round := g.state.Round()
-
- if nextRound.Cmp(round) <= 0 {
+ if nextRound.Uint64() != g.evm.Round.Uint64()+1 ||
+ g.state.CRSRound().Uint64() == nextRound.Uint64() {
return nil, errExecutionReverted
}
- prevCRS := g.state.CRS(round)
+ prevCRS := g.state.CRS()
- threshold := int(g.state.DKGSetSize().Uint64()/3 + 1)
+ // CRS(n) = hash(CRS(n-1)) if n <= core.DKGRoundDelay
+ if g.evm.Round.Uint64() == dexCore.DKGDelayRound {
+ for i := uint64(0); i < dexCore.DKGDelayRound; i++ {
+ prevCRS = crypto.Keccak256Hash(prevCRS[:])
+ }
+ }
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
- round, threshold)
+ threshold := int(g.state.DKGSetSize().Uint64()/3 + 1)
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(nextRound, threshold)
if err != nil {
return nil, errExecutionReverted
}
@@ -1712,10 +1720,10 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
}
// Save new CRS into state and increase round.
- newCRS := crypto.Keccak256(signedCRS)
- crs := common.BytesToHash(newCRS)
+ crs := crypto.Keccak256Hash(signedCRS)
- g.state.PushCRS(crs)
+ g.state.SetCRS(crs)
+ g.state.SetCRSRound(nextRound)
g.state.emitCRSProposed(nextRound, crs)
// To encourage DKG set to propose the correct value, correctly submitting
@@ -1811,23 +1819,24 @@ func (g *GovernanceContract) report(reportType *big.Int, arg1, arg2 []byte) ([]b
}
func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
- // Check if current block over 80% of current round.
- round := g.state.Round()
+ round := g.evm.Round
+ nextRound := new(big.Int).Add(round, big.NewInt(1))
+
resetCount := g.state.DKGResetCount(round)
+
// Just restart DEXON if failed at round 0.
if round.Cmp(big.NewInt(0)) == 0 {
return nil, errExecutionReverted
}
- // target = 80 + 100 * DKGResetCount
+ // Extend the the current round.
+ // target = (80 + 100 * DKGResetCount)%
target := new(big.Int).Add(
big.NewInt(80),
new(big.Int).Mul(big.NewInt(100), resetCount))
- // Round() is increased if CRS is signed. But we want to extend round r-1 now.
- curRound := new(big.Int).Sub(round, big.NewInt(1))
- roundHeight := g.state.RoundHeight(curRound)
- gs, err := getConfigState(g.evm, curRound)
+ roundHeight := g.state.RoundHeight(round)
+ gs, err := getConfigState(g.evm, round)
if err != nil {
return nil, err
}
@@ -1838,6 +1847,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
targetBlockNum.Quo(targetBlockNum, big.NewInt(100))
targetBlockNum.Add(targetBlockNum, roundHeight)
+ // Check if current block over 80% of current round.
blockHeight := g.evm.Context.BlockNumber
if blockHeight.Cmp(targetBlockNum) < 0 {
return nil, errExecutionReverted
@@ -1850,35 +1860,30 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
// If 2f + 1 of DKG set is finalized, check if DKG succeeded.
- if g.state.DKGFinalizedsCount(round).Cmp(threshold) > 0 {
- _, err := g.coreDKGUtils.NewGroupPublicKey(
- round, int(threshold.Int64()))
+ if g.state.DKGFinalizedsCount().Cmp(threshold) > 0 {
+ _, err := g.coreDKGUtils.NewGroupPublicKey(nextRound, int(threshold.Int64()))
// DKG success.
if err == nil {
return nil, errExecutionReverted
}
switch err {
- case core.ErrNotReachThreshold, core.ErrInvalidThreshold:
+ case dexCore.ErrNotReachThreshold, dexCore.ErrInvalidThreshold:
default:
return nil, errExecutionReverted
}
}
- // Clear dkg states for next round.
- dkgSet := g.getDKGSet(round)
- g.state.ClearDKGMasterPublicKeys(round)
- g.state.ClearDKGComplaints(round)
- g.state.ClearDKGMPKReady(round, dkgSet)
- g.state.ResetDKGMPKReadysCount(round)
- g.state.ClearDKGFinalized(round, dkgSet)
- g.state.ResetDKGFinalizedsCount(round)
+
// Update CRS.
- prevCRS := g.state.CRS(curRound)
+ headState, err := getRoundState(g.evm, round)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ prevCRS := headState.CRS()
for i := uint64(0); i < resetCount.Uint64()+1; i++ {
prevCRS = crypto.Keccak256Hash(prevCRS[:])
}
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
- curRound, int(config.DKGSetSize/3+1))
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(round, int(config.DKGSetSize/3+1))
if err != nil {
return nil, errExecutionReverted
}
@@ -1890,16 +1895,22 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
return g.penalize()
}
+ newRound := new(big.Int).Add(g.evm.Round, big.NewInt(1))
+
+ // Clear DKG states for next round.
+ g.clearDKG()
+ g.state.SetDKGRound(newRound)
+
// Save new CRS into state and increase round.
newCRS := crypto.Keccak256(newSignedCRS)
crs := common.BytesToHash(newCRS)
- g.state.PopCRS()
- g.state.PushCRS(crs)
- g.state.emitCRSProposed(round, crs)
+ g.state.SetCRS(crs)
+ g.state.SetCRSRound(newRound)
+ g.state.emitCRSProposed(newRound, crs)
// Increase reset count.
- g.state.IncDKGResetCount(round)
+ g.state.IncDKGResetCount(new(big.Int).Add(round, big.NewInt(1)))
g.state.emitDKGReset(round, blockHeight)
return nil, nil
@@ -1913,7 +1924,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
// Initialize contract state.
g.evm = evm
- g.state = GovernanceStateHelper{evm.StateDB}
+ g.state = GovernanceState{evm.StateDB}
g.contract = contract
g.coreDKGUtils.SetState(g.state)
@@ -2068,11 +2079,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
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))
+ res, err := method.Outputs.Pack(g.state.CRS())
if err != nil {
return nil, errExecutionReverted
}
@@ -2101,12 +2108,11 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
return res, nil
case "dkgComplaints":
- round, index := new(big.Int), new(big.Int)
- args := []interface{}{&round, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
return nil, errExecutionReverted
}
- complaints := g.state.DKGComplaints(round)
+ complaints := g.state.DKGComplaints()
if int(index.Uint64()) >= len(complaints) {
return nil, errExecutionReverted
}
@@ -2117,23 +2123,18 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
return res, nil
case "dkgReadys":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ addr := common.Address{}
+ if err := method.Inputs.Unpack(&addr, arguments); err != nil {
return nil, errExecutionReverted
}
- ready := g.state.DKGMPKReady(round, addr)
+ ready := g.state.DKGMPKReady(addr)
res, err := method.Outputs.Pack(ready)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "dkgReadysCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGMPKReadysCount(round)
+ count := g.state.DKGMPKReadysCount()
res, err := method.Outputs.Pack(count)
if err != nil {
return nil, errExecutionReverted
@@ -2141,35 +2142,29 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return res, nil
case "dkgFinalizeds":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ addr := common.Address{}
+ if err := method.Inputs.Unpack(&addr, arguments); err != nil {
return nil, errExecutionReverted
}
- finalized := g.state.DKGFinalized(round, addr)
+ finalized := g.state.DKGFinalized(addr)
res, err := method.Outputs.Pack(finalized)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "dkgFinalizedsCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGFinalizedsCount(round)
+ count := g.state.DKGFinalizedsCount()
res, err := method.Outputs.Pack(count)
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 {
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
return nil, errExecutionReverted
}
- mpks := g.state.DKGMasterPublicKeys(round)
+ mpks := g.state.DKGMasterPublicKeys()
if int(index.Uint64()) >= len(mpks) {
return nil, errExecutionReverted
}
@@ -2442,7 +2437,6 @@ func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) {
if err != nil {
return nil, err
}
-
data := append(method.Id(), res...)
return data, nil
}
@@ -2464,7 +2458,6 @@ func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) {
if err != nil {
return nil, err
}
-
data := append(method.Id(), res...)
return data, nil
}
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index 4980d4b77..c96256e5d 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -27,6 +27,7 @@ import (
"time"
coreCommon "github.com/dexon-foundation/dexon-consensus/common"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreEcdsa "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
@@ -57,22 +58,22 @@ func randomBytes(minLength, maxLength int32) []byte {
return b
}
-type GovernanceStateHelperTestSuite struct {
+type GovernanceStateTestSuite struct {
suite.Suite
- s *GovernanceStateHelper
+ s *GovernanceState
}
-func (g *GovernanceStateHelperTestSuite) SetupTest() {
+func (g *GovernanceStateTestSuite) SetupTest() {
db := state.NewDatabase(ethdb.NewMemDatabase())
statedb, err := state.New(common.Hash{}, db)
if err != nil {
panic(err)
}
- g.s = &GovernanceStateHelper{statedb}
+ g.s = &GovernanceState{statedb}
}
-func (g *GovernanceStateHelperTestSuite) TestReadWriteEraseBytes() {
+func (g *GovernanceStateTestSuite) TestReadWriteEraseBytes() {
for i := 0; i < 100; i++ {
// Short bytes.
loc := big.NewInt(rand.Int63())
@@ -96,30 +97,27 @@ func (g *GovernanceStateHelperTestSuite) TestReadWriteEraseBytes() {
}
}
-func (g *GovernanceStateHelperTestSuite) TestReadWriteErase2DArray() {
- for i := 0; i < 50; i++ {
- loc := big.NewInt(rand.Int63())
- for j := 0; j < 50; j++ {
- idx := big.NewInt(int64(j))
- data := make([][]byte, 30)
- for key := range data {
- data[key] = randomBytes(3, 32)
- g.s.appendTo2DByteArray(loc, idx, data[key])
- }
- read := g.s.read2DByteArray(loc, idx)
- g.Require().Len(read, len(data))
- for key := range data {
- g.Require().Equal(0, bytes.Compare(data[key], read[key]))
- }
- g.s.erase2DByteArray(loc, idx)
- read = g.s.read2DByteArray(loc, idx)
- g.Require().Len(read, 0)
+func (g *GovernanceStateTestSuite) TestReadWriteErase1DArray() {
+ for j := 0; j < 50; j++ {
+ idx := big.NewInt(int64(j))
+ data := make([][]byte, 30)
+ for key := range data {
+ data[key] = randomBytes(3, 32)
+ g.s.appendTo1DByteArray(idx, data[key])
}
+ read := g.s.read1DByteArray(idx)
+ g.Require().Len(read, len(data))
+ for key := range data {
+ g.Require().Equal(0, bytes.Compare(data[key], read[key]))
+ }
+ g.s.erase1DByteArray(idx)
+ read = g.s.read1DByteArray(idx)
+ g.Require().Len(read, 0)
}
}
-func TestGovernanceStateHelper(t *testing.T) {
- suite.Run(t, new(GovernanceStateHelperTestSuite))
+func TestGovernanceState(t *testing.T) {
+ suite.Run(t, new(GovernanceStateTestSuite))
}
type OracleContractsTestSuite struct {
@@ -129,7 +127,7 @@ type OracleContractsTestSuite struct {
config *params.DexconConfig
memDB *ethdb.MemDatabase
stateDB *state.StateDB
- s *GovernanceStateHelper
+ s *GovernanceState
}
func (g *OracleContractsTestSuite) SetupTest() {
@@ -140,7 +138,7 @@ func (g *OracleContractsTestSuite) SetupTest() {
}
g.memDB = memDB
g.stateDB = stateDB
- g.s = &GovernanceStateHelper{stateDB}
+ g.s = &GovernanceState{stateDB}
config := params.TestnetChainConfig.Dexcon
config.LockupPeriod = 1000
@@ -156,7 +154,7 @@ func (g *OracleContractsTestSuite) SetupTest() {
// Genesis CRS.
crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
- g.s.PushCRS(crs)
+ g.s.SetCRS(crs)
// Round 0 height.
g.s.PushRoundHeight(big.NewInt(0))
@@ -671,7 +669,7 @@ func (g *OracleContractsTestSuite) TestConfigurationReading() {
_, addr := g.newPrefundAccount()
// CRS.
- input, err := GovernanceABI.ABI.Pack("crs", big.NewInt(0))
+ input, err := GovernanceABI.ABI.Pack("crs")
g.Require().NoError(err)
res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
@@ -1082,7 +1080,7 @@ type testCoreMock struct {
tsigReturn bool
}
-func (m *testCoreMock) SetState(GovernanceStateHelper) {}
+func (m *testCoreMock) SetState(GovernanceState) {}
func (m *testCoreMock) NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error) {
if m.newDKGGPKError != nil {
@@ -1106,7 +1104,8 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
- input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1",
+ "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
_, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
@@ -1114,10 +1113,29 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
g.Require().Len(g.s.QualifiedNodes(), int(g.config.DKGSetSize))
addrs := make(map[int][]common.Address)
- addDKG := func(round int, final bool) {
+ dkgSets := make(map[int]map[coreTypes.NodeID]struct{})
+ addDKG := func(round int, final, proposeCRS bool) {
+ if proposeCRS && uint64(round) > dexCore.DKGDelayRound {
+ // ProposeCRS and clear DKG state.
+ input, err := GovernanceABI.ABI.Pack(
+ "proposeCRS", big.NewInt(int64(round)), randomBytes(32, 32))
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addrs[round-1][0], input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ // Clear DKG states for next round.
+ dkgSet := dkgSets[round-1]
+ g.s.ClearDKGMasterPublicKeys()
+ g.s.ClearDKGComplaints()
+ g.s.ClearDKGMPKReady(dkgSet)
+ g.s.ResetDKGMPKReadysCount()
+ g.s.ClearDKGFinalized(dkgSet)
+ g.s.ResetDKGFinalizedsCount()
+ g.s.SetDKGRound(big.NewInt(int64(round)))
+ }
+
addrs[round] = []common.Address{}
- r := big.NewInt(int64(round))
- target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.s.CRS(r)))
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.s.CRS()))
ns := coreTypes.NewNodeSet()
for _, x := range g.s.QualifiedNodes() {
@@ -1129,6 +1147,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
}
dkgSet := ns.GetSubSet(int(g.s.DKGSetSize().Uint64()), target)
g.Require().Len(dkgSet, int(g.config.DKGSetSize))
+ dkgSets[round] = dkgSet
for id := range dkgSet {
offset := g.s.NodesOffsetByID(Bytes32(id.Hash))
@@ -1137,66 +1156,69 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
}
node := g.s.Node(offset)
// Prepare MPK.
- g.s.PushDKGMasterPublicKey(r, randomBytes(32, 64))
+ g.s.PushDKGMasterPublicKey(randomBytes(32, 64))
// Prepare Complaint.
- g.s.PushDKGComplaint(r, randomBytes(32, 64))
+ g.s.PushDKGComplaint(randomBytes(32, 64))
addr := node.Owner
addrs[round] = append(addrs[round], addr)
// Prepare MPK Ready.
- g.s.PutDKGMPKReady(r, addr, true)
- g.s.IncDKGMPKReadysCount(r)
+ g.s.PutDKGMPKReady(addr, true)
+ g.s.IncDKGMPKReadysCount()
if final {
// Prepare Finalized.
- g.s.PutDKGFinalized(r, addr, true)
- g.s.IncDKGFinalizedsCount(r)
+ g.s.PutDKGFinalized(addr, true)
+ g.s.IncDKGFinalizedsCount()
}
}
dkgSetSize := len(dkgSet)
- g.Require().Len(g.s.DKGMasterPublicKeys(r), dkgSetSize)
- g.Require().Len(g.s.DKGComplaints(r), dkgSetSize)
- g.Require().Equal(0, g.s.DKGMPKReadysCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ g.Require().Len(g.s.DKGMasterPublicKeys(), dkgSetSize)
+ g.Require().Len(g.s.DKGComplaints(), dkgSetSize)
+ g.Require().Equal(int64(dkgSetSize), g.s.DKGMPKReadysCount().Int64())
for _, addr := range addrs[round] {
- g.Require().True(g.s.DKGMPKReady(r, addr))
+ g.Require().True(g.s.DKGMPKReady(addr))
}
+
if final {
- g.Require().Equal(0, g.s.DKGFinalizedsCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ g.Require().Equal(int64(dkgSetSize), g.s.DKGFinalizedsCount().Int64())
for _, addr := range addrs[round] {
- g.Require().True(g.s.DKGFinalized(r, addr))
+ g.Require().True(g.s.DKGFinalized(addr))
}
}
+
}
+ mock := &testCoreMock{
+ tsigReturn: true,
+ }
+ OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = mock
+
// Fill data for previous rounds.
roundHeight := int64(g.config.RoundLength)
- round := 3
+ round := int(dexCore.DKGDelayRound) + 3
for i := 0; i <= round; i++ {
- // Prepare CRS.
- crs := common.BytesToHash(randomBytes(common.HashLength, common.HashLength))
- g.s.PushCRS(crs)
+ g.context.Round = big.NewInt(int64(i))
+
// Prepare Round Height
if i != 0 {
g.s.PushRoundHeight(big.NewInt(int64(i) * roundHeight))
}
- g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(i+2))))
- g.Require().Equal(crs, g.s.CurrentCRS())
- }
- for i := 0; i <= round; i++ {
- addDKG(i, true)
- }
- mock := &testCoreMock{
- tsigReturn: true,
+ addDKG(i+1, true, true)
}
- OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = mock
+
+ round++
+ g.s.PushRoundHeight(big.NewInt(int64(round) * roundHeight))
+ g.context.Round = big.NewInt(int64(round))
+ addDKG(round+1, false, true)
repeat := 3
for r := 0; r < repeat; r++ {
- addDKG(round+1, false)
// Add one finalized for test.
roundPlusOne := big.NewInt(int64(round + 1))
- g.s.PutDKGFinalized(roundPlusOne, addrs[round+1][0], true)
- g.s.IncDKGFinalizedsCount(roundPlusOne)
+ g.s.PutDKGFinalized(addrs[round+1][0], true)
+ g.s.IncDKGFinalizedsCount()
- g.context.BlockNumber = big.NewInt(roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
+ g.context.BlockNumber = big.NewInt(
+ roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
_, addr := g.newPrefundAccount()
newCRS := randomBytes(common.HashLength, common.HashLength)
input, err := GovernanceABI.ABI.Pack("resetDKG", newCRS)
@@ -1206,29 +1228,26 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
// Test if CRS is reset.
newCRSHash := crypto.Keccak256Hash(newCRS)
- g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(round+2))))
- g.Require().Equal(newCRSHash, g.s.CurrentCRS())
- g.Require().Equal(newCRSHash, g.s.CRS(big.NewInt(int64(round+1))))
+ g.Require().Equal(newCRSHash, g.s.CRS())
// Test if MPK is purged.
- g.Require().Len(g.s.DKGMasterPublicKeys(big.NewInt(int64(round+1))), 0)
+ g.Require().Len(g.s.DKGMasterPublicKeys(), 0)
// Test if MPKReady is purged.
- g.Require().Equal(0,
- g.s.DKGMPKReadysCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ g.Require().Equal(int64(0), g.s.DKGMPKReadysCount().Int64())
for _, addr := range addrs[round+1] {
- g.Require().False(g.s.DKGMPKReady(big.NewInt(int64(round+1)), addr))
+ g.Require().False(g.s.DKGMPKReady(addr))
}
// Test if Complaint is purged.
- g.Require().Len(g.s.DKGComplaints(big.NewInt(int64(round+1))), 0)
+ g.Require().Len(g.s.DKGComplaints(), 0)
// Test if Finalized is purged.
- g.Require().Equal(0,
- g.s.DKGFinalizedsCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ g.Require().Equal(int64(0), g.s.DKGFinalizedsCount().Int64())
for _, addr := range addrs[round+1] {
- g.Require().False(g.s.DKGFinalized(big.NewInt(int64(round+1)), addr))
+ g.Require().False(g.s.DKGFinalized(addr))
}
- g.Require().Equal(0,
- g.s.DKGResetCount(roundPlusOne).Cmp(big.NewInt(int64(r+1))))
+ g.Require().Equal(int64(r+1), g.s.DKGResetCount(roundPlusOne).Int64())
+
+ addDKG(round+1, false, false)
}
}