aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-01-13 16:21:17 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:56 +0800
commit7c664ca090d90815db23644c209d4f5cdf0ff594 (patch)
tree79f192501314c5ae37f8cb6c45ac3ef759d01945 /core
parent7bf5e2205a49a500672ff7415921aa6659c46611 (diff)
downloaddexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar.gz
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar.bz2
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar.lz
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar.xz
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.tar.zst
dexon-7c664ca090d90815db23644c209d4f5cdf0ff594.zip
consensus: implement DEXON cryptoeconomics v4.0 (#145)
Diffstat (limited to 'core')
-rw-r--r--core/blockchain_test.go2
-rw-r--r--core/governance.go4
-rw-r--r--core/vm/governance.go102
-rw-r--r--core/vm/governance_abi.go60
-rw-r--r--core/vm/governance_test.go42
5 files changed, 153 insertions, 57 deletions
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index 6468e984d..a902f0032 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -1650,7 +1650,7 @@ func TestProcessPendingBlock(t *testing.T) {
}
engine := &dexconTest{
- blockReward: chainConfig.Dexcon.BlockReward,
+ blockReward: big.NewInt(1e18),
numChains: chainConfig.Dexcon.NumChains,
}
chain, err := NewBlockChain(db, nil, chainConfig, engine, vm.Config{}, nil)
diff --git a/core/governance.go b/core/governance.go
index 45594fb64..538cd2b96 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -74,7 +74,7 @@ func (g *Governance) getHelperAtRound(round uint64) *vm.GovernanceStateHelper {
return &vm.GovernanceStateHelper{StateDB: s}
}
-func (g *Governance) GetConfigHelper(round uint64) *vm.GovernanceStateHelper {
+func (g *Governance) GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateHelper {
if round < dexCore.ConfigRoundShift {
round = 0
} else {
@@ -88,7 +88,7 @@ func (g *Governance) GetRoundHeight(round uint64) uint64 {
}
func (g *Governance) Configuration(round uint64) *coreTypes.Config {
- configHelper := g.GetConfigHelper(round)
+ configHelper := g.GetGovStateHelperAtRound(round)
c := configHelper.Configuration()
return &coreTypes.Config{
NumChains: c.NumChains,
diff --git a/core/vm/governance.go b/core/vm/governance.go
index bebc26e03..e77519c58 100644
--- a/core/vm/governance.go
+++ b/core/vm/governance.go
@@ -242,12 +242,6 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (ret []by
return nil, errExecutionReverted
}
return res, nil
- case "blockReward":
- res, err := method.Outputs.Pack(g.state.BlockReward())
- if err != nil {
- return nil, errExecutionReverted
- }
- return res, nil
case "crs":
round := new(big.Int)
if err := method.Inputs.Unpack(&round, arguments); err != nil {
@@ -406,6 +400,12 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (ret []by
return nil, errExecutionReverted
}
return res, nil
+ case "lastHalvedAmount":
+ res, err := method.Outputs.Pack(g.state.LastHalvedAmount())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "lockupPeriod":
res, err := method.Outputs.Pack(g.state.LockupPeriod())
if err != nil {
@@ -418,12 +418,24 @@ func RunGovernanceContract(evm *EVM, input []byte, contract *Contract) (ret []by
return nil, errExecutionReverted
}
return res, nil
+ case "miningVelocity":
+ res, err := method.Outputs.Pack(g.state.MiningVelocity())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "minStake":
res, err := method.Outputs.Pack(g.state.MinStake())
if err != nil {
return nil, errExecutionReverted
}
return res, nil
+ case "nextHalvingSupply":
+ res, err := method.Outputs.Pack(g.state.NextHalvingSupply())
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "numChains":
res, err := method.Outputs.Pack(g.state.NumChains())
if err != nil {
@@ -533,7 +545,9 @@ const (
ownerLoc
minStakeLoc
lockupPeriodLoc
- blockRewardLoc
+ miningVelocityLoc
+ nextHalvingSupplyLoc
+ lastHalvedAmountLoc
blockGasLimitLoc
numChainsLoc
lambdaBALoc
@@ -1160,9 +1174,37 @@ func (s *GovernanceStateHelper) LockupPeriod() *big.Int {
return s.getStateBigInt(big.NewInt(lockupPeriodLoc))
}
-// uint256 public blockReward;
-func (s *GovernanceStateHelper) BlockReward() *big.Int {
- return s.getStateBigInt(big.NewInt(blockRewardLoc))
+// uint256 public miningVelocity;
+func (s *GovernanceStateHelper) MiningVelocity() *big.Int {
+ return s.getStateBigInt(big.NewInt(miningVelocityLoc))
+}
+func (s *GovernanceStateHelper) HalfMiningVelocity() {
+ s.setStateBigInt(big.NewInt(miningVelocityLoc),
+ new(big.Int).Div(s.MiningVelocity(), big.NewInt(2)))
+}
+
+// uint256 public nextHalvingSupply;
+func (s *GovernanceStateHelper) NextHalvingSupply() *big.Int {
+ return s.getStateBigInt(big.NewInt(nextHalvingSupplyLoc))
+}
+func (s *GovernanceStateHelper) 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 {
+ return s.getStateBigInt(big.NewInt(lastHalvedAmountLoc))
+}
+func (s *GovernanceStateHelper) HalfLastHalvedAmount() {
+ s.setStateBigInt(big.NewInt(lastHalvedAmountLoc),
+ new(big.Int).Div(s.LastHalvedAmount(), big.NewInt(2)))
+}
+
+func (s *GovernanceStateHelper) MiningHalved() {
+ s.HalfMiningVelocity()
+ s.HalfLastHalvedAmount()
+ s.IncNextHalvingSupply(s.LastHalvedAmount())
}
// uint256 public blockGasLimit;
@@ -1290,25 +1332,27 @@ func (s *GovernanceStateHelper) Stake(
s.IncTotalStaked(staked)
}
-const phiRatioMultiplier = 1000000.0
+const decimalMultiplier = 100000000.0
// Configuration returns the current configuration.
func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
return &params.DexconConfig{
- MinStake: s.getStateBigInt(big.NewInt(minStakeLoc)),
- LockupPeriod: s.getStateBigInt(big.NewInt(lockupPeriodLoc)).Uint64(),
- BlockReward: s.getStateBigInt(big.NewInt(blockRewardLoc)),
- BlockGasLimit: s.getStateBigInt(big.NewInt(blockGasLimitLoc)).Uint64(),
- NumChains: uint32(s.getStateBigInt(big.NewInt(numChainsLoc)).Uint64()),
- LambdaBA: s.getStateBigInt(big.NewInt(lambdaBALoc)).Uint64(),
- LambdaDKG: s.getStateBigInt(big.NewInt(lambdaDKGLoc)).Uint64(),
- K: uint32(s.getStateBigInt(big.NewInt(kLoc)).Uint64()),
- PhiRatio: float32(s.getStateBigInt(big.NewInt(phiRatioLoc)).Uint64()) / phiRatioMultiplier,
- NotarySetSize: uint32(s.getStateBigInt(big.NewInt(notarySetSizeLoc)).Uint64()),
- DKGSetSize: uint32(s.getStateBigInt(big.NewInt(dkgSetSizeLoc)).Uint64()),
- RoundInterval: s.getStateBigInt(big.NewInt(roundIntervalLoc)).Uint64(),
- MinBlockInterval: s.getStateBigInt(big.NewInt(minBlockIntervalLoc)).Uint64(),
- FineValues: s.FineValues(),
+ MinStake: s.getStateBigInt(big.NewInt(minStakeLoc)),
+ LockupPeriod: s.getStateBigInt(big.NewInt(lockupPeriodLoc)).Uint64(),
+ MiningVelocity: float32(s.getStateBigInt(big.NewInt(miningVelocityLoc)).Uint64()) / decimalMultiplier,
+ NextHalvingSupply: s.getStateBigInt(big.NewInt(nextHalvingSupplyLoc)),
+ LastHalvedAmount: s.getStateBigInt(big.NewInt(lastHalvedAmountLoc)),
+ BlockGasLimit: s.getStateBigInt(big.NewInt(blockGasLimitLoc)).Uint64(),
+ NumChains: uint32(s.getStateBigInt(big.NewInt(numChainsLoc)).Uint64()),
+ LambdaBA: s.getStateBigInt(big.NewInt(lambdaBALoc)).Uint64(),
+ LambdaDKG: s.getStateBigInt(big.NewInt(lambdaDKGLoc)).Uint64(),
+ K: uint32(s.getStateBigInt(big.NewInt(kLoc)).Uint64()),
+ PhiRatio: float32(s.getStateBigInt(big.NewInt(phiRatioLoc)).Uint64()) / decimalMultiplier,
+ NotarySetSize: uint32(s.getStateBigInt(big.NewInt(notarySetSizeLoc)).Uint64()),
+ DKGSetSize: uint32(s.getStateBigInt(big.NewInt(dkgSetSizeLoc)).Uint64()),
+ RoundInterval: s.getStateBigInt(big.NewInt(roundIntervalLoc)).Uint64(),
+ MinBlockInterval: s.getStateBigInt(big.NewInt(minBlockIntervalLoc)).Uint64(),
+ FineValues: s.FineValues(),
}
}
@@ -1316,13 +1360,15 @@ func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
func (s *GovernanceStateHelper) 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(blockRewardLoc), cfg.BlockReward)
+ s.setStateBigInt(big.NewInt(miningVelocityLoc), big.NewInt(int64(cfg.MiningVelocity*decimalMultiplier)))
+ s.setStateBigInt(big.NewInt(nextHalvingSupplyLoc), cfg.NextHalvingSupply)
+ s.setStateBigInt(big.NewInt(lastHalvedAmountLoc), cfg.LastHalvedAmount)
s.setStateBigInt(big.NewInt(blockGasLimitLoc), big.NewInt(int64(cfg.BlockGasLimit)))
s.setStateBigInt(big.NewInt(numChainsLoc), big.NewInt(int64(cfg.NumChains)))
s.setStateBigInt(big.NewInt(lambdaBALoc), big.NewInt(int64(cfg.LambdaBA)))
s.setStateBigInt(big.NewInt(lambdaDKGLoc), big.NewInt(int64(cfg.LambdaDKG)))
s.setStateBigInt(big.NewInt(kLoc), big.NewInt(int64(cfg.K)))
- s.setStateBigInt(big.NewInt(phiRatioLoc), big.NewInt(int64(cfg.PhiRatio*phiRatioMultiplier)))
+ s.setStateBigInt(big.NewInt(phiRatioLoc), big.NewInt(int64(cfg.PhiRatio*decimalMultiplier)))
s.setStateBigInt(big.NewInt(notarySetSizeLoc), big.NewInt(int64(cfg.NotarySetSize)))
s.setStateBigInt(big.NewInt(dkgSetSizeLoc), big.NewInt(int64(cfg.DKGSetSize)))
s.setStateBigInt(big.NewInt(roundIntervalLoc), big.NewInt(int64(cfg.RoundInterval)))
@@ -1333,7 +1379,6 @@ func (s *GovernanceStateHelper) UpdateConfiguration(cfg *params.DexconConfig) {
type rawConfigStruct struct {
MinStake *big.Int
LockupPeriod *big.Int
- BlockReward *big.Int
BlockGasLimit *big.Int
NumChains *big.Int
LambdaBA *big.Int
@@ -1351,7 +1396,6 @@ type rawConfigStruct struct {
func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
s.setStateBigInt(big.NewInt(minStakeLoc), cfg.MinStake)
s.setStateBigInt(big.NewInt(lockupPeriodLoc), cfg.LockupPeriod)
- s.setStateBigInt(big.NewInt(blockRewardLoc), cfg.BlockReward)
s.setStateBigInt(big.NewInt(blockGasLimitLoc), cfg.BlockGasLimit)
s.setStateBigInt(big.NewInt(numChainsLoc), cfg.NumChains)
s.setStateBigInt(big.NewInt(lambdaBALoc), cfg.LambdaBA)
diff --git a/core/vm/governance_abi.go b/core/vm/governance_abi.go
index 1b700ac32..f139ac7a8 100644
--- a/core/vm/governance_abi.go
+++ b/core/vm/governance_abi.go
@@ -47,20 +47,6 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [],
- "name": "blockReward",
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": true,
"inputs": [
{
"name": "",
@@ -174,6 +160,20 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
+ "name": "miningVelocity",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
"name": "lambdaBA",
"outputs": [
{
@@ -388,6 +388,20 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
+ "name": "nextHalvingSupply",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
+ "inputs": [],
"name": "owner",
"outputs": [
{
@@ -401,6 +415,20 @@ const GovernanceABIJSON = `
},
{
"constant": true,
+ "inputs": [],
+ "name": "lastHalvedAmount",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [
{
"name": "",
@@ -781,10 +809,6 @@ const GovernanceABIJSON = `
"type": "uint256"
},
{
- "name": "BlockReward",
- "type": "uint256"
- },
- {
"name": "BlockGasLimit",
"type": "uint256"
},
diff --git a/core/vm/governance_test.go b/core/vm/governance_test.go
index 8566d6537..55d4ebb8b 100644
--- a/core/vm/governance_test.go
+++ b/core/vm/governance_test.go
@@ -112,6 +112,9 @@ func (g *GovernanceContractTestSuite) SetupTest() {
config := params.TestnetChainConfig.Dexcon
config.LockupPeriod = 1000
+ config.NextHalvingSupply = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2.5e9))
+ config.LastHalvedAmount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1.5e9))
+ config.MiningVelocity = 0.1875
g.config = config
@@ -598,9 +601,18 @@ func (g *GovernanceContractTestSuite) TestUpdateConfiguration() {
_, addr := g.newPrefundAccount()
input, err := abiObject.Pack("updateConfiguration",
- new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), big.NewInt(1000),
- big.NewInt(1e18), big.NewInt(8000000), big.NewInt(6), big.NewInt(250), big.NewInt(2500),
- big.NewInt(0), big.NewInt(667000), big.NewInt(4), big.NewInt(4), big.NewInt(600000), big.NewInt(900),
+ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)),
+ big.NewInt(1000),
+ big.NewInt(8000000),
+ big.NewInt(6),
+ big.NewInt(250),
+ big.NewInt(2500),
+ big.NewInt(0),
+ big.NewInt(667000),
+ big.NewInt(4),
+ big.NewInt(4),
+ big.NewInt(600000),
+ big.NewInt(900),
[]*big.Int{big.NewInt(1), big.NewInt(1), big.NewInt(1)})
g.Require().NoError(err)
@@ -687,13 +699,13 @@ func (g *GovernanceContractTestSuite) TestConfigurationReading() {
g.Require().Equal(g.config.MinStake.String(), value.String())
// BlockReward.
- input, err = abiObject.Pack("blockReward")
+ input, err = abiObject.Pack("miningVelocity")
g.Require().NoError(err)
res, err = g.call(addr, input, big.NewInt(0))
g.Require().NoError(err)
- err = abiObject.Unpack(&value, "blockReward", res)
+ err = abiObject.Unpack(&value, "miningVelocity", res)
g.Require().NoError(err)
- g.Require().Equal(g.config.BlockReward.String(), value.String())
+ g.Require().Equal(g.config.MiningVelocity, float32(value.Uint64())/decimalMultiplier)
// BlockGasLimit.
input, err = abiObject.Pack("blockGasLimit")
@@ -747,7 +759,7 @@ func (g *GovernanceContractTestSuite) TestConfigurationReading() {
g.Require().NoError(err)
err = abiObject.Unpack(&value, "phiRatio", res)
g.Require().NoError(err)
- g.Require().Equal(g.config.PhiRatio, float32(value.Uint64())/phiRatioMultiplier)
+ g.Require().Equal(g.config.PhiRatio, float32(value.Uint64())/decimalMultiplier)
// NotarySetSize.
input, err = abiObject.Pack("notarySetSize")
@@ -1024,6 +1036,22 @@ func (g *GovernanceContractTestSuite) TestMiscVariableReading() {
g.Require().NoError(err)
}
+func (g *GovernanceContractTestSuite) TestHalvingCondition() {
+ // TotalSupply 2.5B reached
+ g.s.MiningHalved()
+ g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3.25e9)).String(),
+ g.s.NextHalvingSupply().String())
+ g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(0.75e9)).String(),
+ g.s.LastHalvedAmount().String())
+
+ // TotalSupply 3.25B reached
+ g.s.MiningHalved()
+ g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(3.625e9)).String(),
+ g.s.NextHalvingSupply().String())
+ g.Require().Equal(new(big.Int).Mul(big.NewInt(1e18), big.NewInt(0.375e9)).String(),
+ g.s.LastHalvedAmount().String())
+}
+
func TestGovernanceContract(t *testing.T) {
suite.Run(t, new(GovernanceContractTestSuite))
}