From 56680e215e7e27ab8896d782876ee64881cae6ff Mon Sep 17 00:00:00 2001 From: Wei-Ning Huang Date: Sun, 13 Jan 2019 16:21:17 +0800 Subject: consensus: implement DEXON cryptoeconomics v4.0 (#145) --- cmd/gdex/consolecmd_test.go | 2 +- consensus/dexcon/api.go | 26 ------- consensus/dexcon/dexcon.go | 67 ++++++++++++++---- consensus/dexcon/dexcon_test.go | 107 +++++++++++++++++++++++++++++ core/blockchain_test.go | 2 +- core/governance.go | 4 +- core/vm/governance.go | 102 ++++++++++++++++++++-------- core/vm/governance_abi.go | 60 +++++++++++----- core/vm/governance_test.go | 42 ++++++++++-- dex/app_test.go | 22 ++++-- dex/backend.go | 2 +- dex/governance.go | 4 +- params/config.go | 147 +++++++++++++++++++++------------------- params/gen_dexcon_config.go | 82 ++++++++++++---------- test/genesis.json | 14 ++-- test/keygen.go | 12 +--- test/run_test.sh | 24 +++---- 17 files changed, 479 insertions(+), 240 deletions(-) delete mode 100644 consensus/dexcon/api.go create mode 100644 consensus/dexcon/dexcon_test.go diff --git a/cmd/gdex/consolecmd_test.go b/cmd/gdex/consolecmd_test.go index 37f94cdc4..672735d2c 100644 --- a/cmd/gdex/consolecmd_test.go +++ b/cmd/gdex/consolecmd_test.go @@ -31,7 +31,7 @@ import ( ) const ( - ipcAPIs = "admin:1.0 debug:1.0 dexcon:1.0 eth:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0" + ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0" httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" ) diff --git a/consensus/dexcon/api.go b/consensus/dexcon/api.go deleted file mode 100644 index 6f314b96b..000000000 --- a/consensus/dexcon/api.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package dexcon - -// API exposes ethash related methods for the RPC interface. -type API struct { - dexcon *Dexcon -} - -func (api *API) Hello() error { - return nil -} diff --git a/consensus/dexcon/dexcon.go b/consensus/dexcon/dexcon.go index f0a133ccf..4480f64cb 100644 --- a/consensus/dexcon/dexcon.go +++ b/consensus/dexcon/dexcon.go @@ -23,17 +23,17 @@ import ( "github.com/dexon-foundation/dexon/consensus" "github.com/dexon-foundation/dexon/core/state" "github.com/dexon-foundation/dexon/core/types" - "github.com/dexon-foundation/dexon/params" + "github.com/dexon-foundation/dexon/core/vm" "github.com/dexon-foundation/dexon/rpc" ) -type ConfigurationFetcher interface { - DexconConfiguration(round uint64) *params.DexconConfig +type GovernanceStateFetcher interface { + GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateHelper } // Dexcon is a delegated proof-of-stake consensus engine. type Dexcon struct { - configFetcher ConfigurationFetcher + govStateFetcer GovernanceStateFetcher } // New creates a Clique proof-of-authority consensus engine with the initial @@ -42,11 +42,11 @@ func New() *Dexcon { return &Dexcon{} } -// SetConfigFetcher sets the config fetcher for Dexcon. The reason this is not +// SetGovStateFetcher sets the config fetcher for Dexcon. The reason this is not // passed in the New() method is to bypass cycle dependencies when initializing // dex backend. -func (d *Dexcon) SetConfigFetcher(fetcher ConfigurationFetcher) { - d.configFetcher = fetcher +func (d *Dexcon) SetGovStateFetcher(fetcher GovernanceStateFetcher) { + d.govStateFetcer = fetcher } // Author implements consensus.Engine, returning the Ethereum address recovered @@ -107,13 +107,55 @@ func (d *Dexcon) Prepare(chain consensus.ChainReader, header *types.Header) erro return nil } +func (d *Dexcon) calculateBlockReward(round int64, state *state.StateDB) *big.Int { + gs := d.govStateFetcer.GetGovStateHelperAtRound(uint64(round)) + config := gs.Configuration() + + gsCurrent := vm.GovernanceStateHelper{state} + configCurrent := gsCurrent.Configuration() + heightCurrent := gsCurrent.RoundHeight(big.NewInt(round)).Uint64() + + blocksPerRound := uint64(0) + + // The initial round, calculate an approximate number of round base on config. + if round == 0 || heightCurrent == 0 { + blocksPerRound = uint64(config.NumChains) * config.RoundInterval / config.MinBlockInterval + } else { + heightPrev := gsCurrent.RoundHeight(big.NewInt(round - 1)).Uint64() + blocksPerRound = heightCurrent - heightPrev + } + + // blockReard = miningVelocity * totalStaked * roundInterval / aYear / numBlocksInPrevRound + numerator, _ := new(big.Float).Mul( + new(big.Float).Mul( + big.NewFloat(float64(configCurrent.MiningVelocity)), + new(big.Float).SetInt(gs.TotalStaked())), + new(big.Float).SetInt(gs.RoundInterval())).Int(nil) + + reward := new(big.Int).Div(numerator, + new(big.Int).Mul( + big.NewInt(86400*1000*365), + big.NewInt(int64(blocksPerRound)))) + + return reward +} + // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given, and returns the final block. func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - config := d.configFetcher.DexconConfiguration(header.Round) - reward := new(big.Int).Div(config.BlockReward, big.NewInt(int64(config.NumChains))) + reward := d.calculateBlockReward(int64(header.Round), state) state.AddBalance(header.Coinbase, reward) + gs := vm.GovernanceStateHelper{state} + gs.IncTotalSupply(reward) + + config := gs.Configuration() + + // Check if halving checkpoint reached. + if gs.TotalSupply().Cmp(config.NextHalvingSupply) >= 0 { + gs.MiningHalved() + } + header.Reward = reward header.Root = state.IntermediateRoot(true) return types.NewBlock(header, txs, uncles, receipts), nil @@ -145,10 +187,5 @@ func (d *Dexcon) Close() error { // APIs implements consensus.Engine, returning the user facing RPC API to allow // controlling the signer voting. func (d *Dexcon) APIs(chain consensus.ChainReader) []rpc.API { - return []rpc.API{{ - Namespace: "dexcon", - Version: "1.0", - Service: &API{dexcon: d}, - Public: false, - }} + return []rpc.API{} } diff --git a/consensus/dexcon/dexcon_test.go b/consensus/dexcon/dexcon_test.go new file mode 100644 index 000000000..7ba1be876 --- /dev/null +++ b/consensus/dexcon/dexcon_test.go @@ -0,0 +1,107 @@ +// Copyright 2019 The dexon-consensus Authors +// This file is part of the dexon-consensus library. +// +// The dexon-consensus library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus library. If not, see +// . + +package dexcon + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/suite" + + "github.com/dexon-foundation/dexon/common" + "github.com/dexon-foundation/dexon/core/state" + "github.com/dexon-foundation/dexon/core/vm" + "github.com/dexon-foundation/dexon/crypto" + "github.com/dexon-foundation/dexon/ethdb" + "github.com/dexon-foundation/dexon/params" +) + +type GovStateFetcher struct { + statedb *state.StateDB +} + +func (g *GovStateFetcher) GetGovStateHelperAtRound(_ uint64) *vm.GovernanceStateHelper { + return &vm.GovernanceStateHelper{g.statedb} +} + +type DexconTestSuite struct { + suite.Suite + + config *params.DexconConfig + memDB *ethdb.MemDatabase + stateDB *state.StateDB + s *vm.GovernanceStateHelper +} + +func (d *DexconTestSuite) SetupTest() { + memDB := ethdb.NewMemDatabase() + stateDB, err := state.New(common.Hash{}, state.NewDatabase(memDB)) + if err != nil { + panic(err) + } + d.memDB = memDB + d.stateDB = stateDB + d.s = &vm.GovernanceStateHelper{stateDB} + + 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 + config.RoundInterval = 3600000 + config.NumChains = 6 + config.MinBlockInterval = 1000 + + d.config = config + + // Give governance contract balance so it will not be deleted because of being an empty state object. + stateDB.AddBalance(vm.GovernanceContractAddress, big.NewInt(1)) + + // Genesis CRS. + crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText)) + d.s.PushCRS(crs) + + // Round 0 height. + d.s.PushRoundHeight(big.NewInt(0)) + + // Governance configuration. + d.s.UpdateConfiguration(config) + + d.stateDB.Commit(true) +} + +func (d *DexconTestSuite) TestBlockRewardCalculation() { + consensus := New() + consensus.SetGovStateFetcher(&GovStateFetcher{d.stateDB}) + + d.s.IncTotalStaked(big.NewInt(1e18)) + + // blockReard = miningVelocity * totalStaked * roundInterval / aYear / numBlocksInPrevRound + // 0.1875 * 1e18 * 3600 * 1000 / (86400 * 1000 * 365 * 6 * 3600) = 990930999.4926434 + d.Require().Equal(big.NewInt(990930999), consensus.calculateBlockReward(0, d.stateDB)) + + // Round 1 + d.s.PushRoundHeight(big.NewInt(4000 * 6)) + + // 0.1875 * 1e18 * 3600 * 1000 / (86400 * 1000 * 365 * 6 * 4000) = 891837899 + d.Require().Equal(big.NewInt(891837899), consensus.calculateBlockReward(1, d.stateDB)) +} + +func TestDexcon(t *testing.T) { + suite.Run(t, new(DexconTestSuite)) +} 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 ¶ms.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 @@ -45,20 +45,6 @@ const GovernanceABIJSON = ` "stateMutability": "view", "type": "function" }, - { - "constant": true, - "inputs": [], - "name": "blockReward", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, { "constant": true, "inputs": [ @@ -171,6 +157,20 @@ const GovernanceABIJSON = ` "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "miningVelocity", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -385,6 +385,20 @@ const GovernanceABIJSON = ` "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "nextHalvingSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [], @@ -399,6 +413,20 @@ const GovernanceABIJSON = ` "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "lastHalvedAmount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [ @@ -780,10 +808,6 @@ const GovernanceABIJSON = ` "name": "LockupPeriod", "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)) } diff --git a/dex/app_test.go b/dex/app_test.go index f4cc2fd9a..c79dbc42c 100644 --- a/dex/app_test.go +++ b/dex/app_test.go @@ -494,9 +494,21 @@ func TestNumChainsChange(t *testing.T) { // Update config in round 1 and height 1. // Config will affect in round 3. input, err := abiObject.Pack("updateConfiguration", - new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), big.NewInt(2000), - big.NewInt(1e17), big.NewInt(9000000), big.NewInt(3), big.NewInt(500), big.NewInt(5000), - big.NewInt(1), big.NewInt(700000), big.NewInt(5), big.NewInt(5), big.NewInt(700000), big.NewInt(1000), + new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), + big.NewInt(2000), + big.NewInt(0.1875*1e8), + big.NewInt(1e18), + big.NewInt(1e18), + big.NewInt(9000000), + big.NewInt(3), + big.NewInt(500), + big.NewInt(5000), + big.NewInt(1), + big.NewInt(700000), + big.NewInt(5), + big.NewInt(5), + big.NewInt(700000), + big.NewInt(1000), []*big.Int{big.NewInt(1), big.NewInt(1), big.NewInt(1)}) if err != nil { t.Errorf("updateConfiguration abiObject pack error: %v", err) @@ -686,7 +698,7 @@ func newTestDexonWithGenesis(allocKey *ecdsa.PrivateKey) (*Dexon, error) { dex.APIBackend = &DexAPIBackend{dex, nil} dex.governance = NewDexconGovernance(dex.APIBackend, dex.chainConfig, config.PrivateKey) - engine.SetConfigFetcher(dex.governance) + engine.SetGovStateFetcher(dex.governance) dex.app = NewDexconApp(dex.txPool, dex.blockchain, dex.governance, db, &config) return dex, nil @@ -748,7 +760,7 @@ func prepareData(dex *Dexon, key *ecdsa.PrivateKey, startNonce, txNum int) ( func prepareConfirmedBlockWithTxAndData(dex *Dexon, key *ecdsa.PrivateKey, data [][]byte, round uint64) ( Block *coreTypes.Block, err error) { address := crypto.PubkeyToAddress(key.PublicKey) - numChains := dex.governance.GetConfigHelper(round).Configuration().NumChains + numChains := dex.governance.GetGovStateHelperAtRound(round).Configuration().NumChains chainID := new(big.Int).Mod(address.Big(), big.NewInt(int64(numChains))) for _, d := range data { diff --git a/dex/backend.go b/dex/backend.go index c7e0773ad..88cfa3033 100644 --- a/dex/backend.go +++ b/dex/backend.go @@ -160,7 +160,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Dexon, error) { dex.app = NewDexconApp(dex.txPool, dex.blockchain, dex.governance, chainDb, config) // Set config fetcher so engine can fetch current system configuration from state. - engine.SetConfigFetcher(dex.governance) + engine.SetGovStateFetcher(dex.governance) dMoment := time.Unix(config.DMoment, int64(0)) log.Info("DEXON Consensus DMoment", "time", dMoment) diff --git a/dex/governance.go b/dex/governance.go index ec029f2f1..0d5a7c926 100644 --- a/dex/governance.go +++ b/dex/governance.go @@ -68,7 +68,7 @@ func NewDexconGovernance(backend *DexAPIBackend, chainConfig *params.ChainConfig // DexconConfiguration return raw config in state. func (d *DexconGovernance) DexconConfiguration(round uint64) *params.DexconConfig { - return d.GetConfigHelper(round).Configuration() + return d.GetGovStateHelperAtRound(round).Configuration() } func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error { @@ -136,7 +136,7 @@ func (d *DexconGovernance) ProposeCRS(round uint64, signedCRS []byte) { // NodeSet returns the current node set. func (d *DexconGovernance) NodeSet(round uint64) []coreCrypto.PublicKey { - s := d.GetConfigHelper(round) + s := d.GetGovStateHelperAtRound(round) var pks []coreCrypto.PublicKey for _, n := range s.QualifiedNodes() { diff --git a/params/config.go b/params/config.go index c2d729c59..b63215c85 100644 --- a/params/config.go +++ b/params/config.go @@ -26,8 +26,8 @@ import ( // Genesis hashes to enforce below configs on. var ( - MainnetGenesisHash = common.HexToHash("0x4310c4984de8bf7ac1c509232d21511fae2cd73e8a1bb8365fe4e489042bc407") - TestnetGenesisHash = common.HexToHash("0x1fdd7ca7ccdd7c3a481f4162b8ca02a4db03859b4abaed96f7e259266d818a13") + MainnetGenesisHash = common.HexToHash("0xeffc8ddbc16ebd98411bb902290ba74a9cc699a4bd02652afecbf864ae542008") + TestnetGenesisHash = common.HexToHash("0xde641c0a52093329aaa5096ed19607243c98390285c5a4f4291c635b9f01301c") ) // TrustedCheckpoints associates each known checkpoint with the genesis hash of @@ -52,21 +52,23 @@ var ( ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), Dexcon: &DexconConfig{ - GenesisCRSText: "In DEXON, we trust.", - Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), - MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), - LockupPeriod: 86400 * 3 * 1000, - BlockReward: big.NewInt(1e18), - BlockGasLimit: 40000000, - NumChains: 4, - LambdaBA: 250, - LambdaDKG: 2500, - K: 0, - PhiRatio: 0.667, - NotarySetSize: 4, - DKGSetSize: 4, - RoundInterval: 600000, - MinBlockInterval: 900, + GenesisCRSText: "In DEXON, we trust.", + Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), + MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), + LockupPeriod: 86400 * 3 * 1000, + MiningVelocity: 0.1875, + NextHalvingSupply: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2.5e9)), + LastHalvedAmount: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1.5e9)), + BlockGasLimit: 40000000, + NumChains: 6, + LambdaBA: 250, + LambdaDKG: 2500, + K: 0, + PhiRatio: 0.667, + NotarySetSize: 4, + DKGSetSize: 4, + RoundInterval: 600000, + MinBlockInterval: 1000, FineValues: []*big.Int{ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), @@ -97,21 +99,23 @@ var ( ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), Dexcon: &DexconConfig{ - GenesisCRSText: "In DEXON, we trust.", - Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), - MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), - LockupPeriod: 86400 * 3 * 1000, - BlockReward: big.NewInt(1e18), - BlockGasLimit: 40000000, - NumChains: 6, - LambdaBA: 250, - LambdaDKG: 2500, - K: 0, - PhiRatio: 0.667, - NotarySetSize: 4, - DKGSetSize: 4, - RoundInterval: 600000, - MinBlockInterval: 900, + GenesisCRSText: "In DEXON, we trust.", + Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), + MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), + LockupPeriod: 86400 * 3 * 1000, + MiningVelocity: 0.1875, + NextHalvingSupply: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(6e6)), + LastHalvedAmount: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2e6)), + BlockGasLimit: 40000000, + NumChains: 6, + LambdaBA: 250, + LambdaDKG: 2500, + K: 0, + PhiRatio: 0.667, + NotarySetSize: 4, + DKGSetSize: 4, + RoundInterval: 600000, + MinBlockInterval: 1000, FineValues: []*big.Int{ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), @@ -133,21 +137,23 @@ var ( ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), Dexcon: &DexconConfig{ - GenesisCRSText: "In DEXON, we trust.", - Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), - MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), - LockupPeriod: 86400 * 3 * 1000, - BlockReward: big.NewInt(1e18), - BlockGasLimit: 40000000, - NumChains: 6, - LambdaBA: 400, - LambdaDKG: 10000, - K: 0, - PhiRatio: 0.667, - NotarySetSize: 21, - DKGSetSize: 13, - RoundInterval: 3600000, - MinBlockInterval: 900, + GenesisCRSText: "In DEXON, we trust.", + Owner: common.HexToAddress("BF8C48A620bacc46907f9B89732D25E47A2D7Cf7"), + MinStake: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e5)), + LockupPeriod: 86400 * 3 * 1000, + MiningVelocity: 0.1875, + NextHalvingSupply: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(6e6)), + LastHalvedAmount: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2e6)), + BlockGasLimit: 40000000, + NumChains: 6, + LambdaBA: 400, + LambdaDKG: 10000, + K: 0, + PhiRatio: 0.667, + NotarySetSize: 21, + DKGSetSize: 13, + RoundInterval: 3600000, + MinBlockInterval: 1000, FineValues: []*big.Int{ new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)), @@ -281,38 +287,43 @@ func (c *CliqueConfig) String() string { // DexconConfig is the consensus engine configs for DEXON consensus. type DexconConfig struct { - GenesisCRSText string `json:"genesisCRSText"` - Owner common.Address `json:"owner"` - MinStake *big.Int `json:"minStake"` - LockupPeriod uint64 `json:"lockupPeriod"` - BlockReward *big.Int `json:"blockReward"` - BlockGasLimit uint64 `json:"blockGasLimit"` - NumChains uint32 `json:"numChains"` - LambdaBA uint64 `json:"lambdaBA"` - LambdaDKG uint64 `json:"lambdaDKG"` - K uint32 `json:"k"` - PhiRatio float32 `json:"phiRatio"` - NotarySetSize uint32 `json:"notarySetSize"` - DKGSetSize uint32 `json:"dkgSetSize"` - RoundInterval uint64 `json:"roundInterval"` - MinBlockInterval uint64 `json:"minBlockInterval"` - FineValues []*big.Int `json:"fineValues"` + GenesisCRSText string `json:"genesisCRSText"` + Owner common.Address `json:"owner"` + MinStake *big.Int `json:"minStake"` + LockupPeriod uint64 `json:"lockupPeriod"` + MiningVelocity float32 `json:"miningVelocity"` + NextHalvingSupply *big.Int `json:"nextHalvingSupply"` + LastHalvedAmount *big.Int `json:"lastHalvedAmount"` + BlockGasLimit uint64 `json:"blockGasLimit"` + NumChains uint32 `json:"numChains"` + LambdaBA uint64 `json:"lambdaBA"` + LambdaDKG uint64 `json:"lambdaDKG"` + K uint32 `json:"k"` + PhiRatio float32 `json:"phiRatio"` + NotarySetSize uint32 `json:"notarySetSize"` + DKGSetSize uint32 `json:"dkgSetSize"` + RoundInterval uint64 `json:"roundInterval"` + MinBlockInterval uint64 `json:"minBlockInterval"` + FineValues []*big.Int `json:"fineValues"` } type dexconConfigSpecMarshaling struct { - MinStake *math.HexOrDecimal256 - BlockReward *math.HexOrDecimal256 - FineValues []*math.HexOrDecimal256 + MinStake *math.HexOrDecimal256 + NextHalvingSupply *math.HexOrDecimal256 + LastHalvedAmount *math.HexOrDecimal256 + FineValues []*math.HexOrDecimal256 } // String implements the stringer interface, returning the consensus engine details. func (d *DexconConfig) String() string { - return fmt.Sprintf("{GenesisCRSText: %v Owner: %v MinStake: %v LockupPeriod: %v BlockReward: %v BlockGasLimit: %v NumChains: %v LambdaBA: %v LambdaDKG: %v K: %v PhiRatio: %v NotarySetSize: %v DKGSetSize: %v RoundInterval: %v MinBlockInterval: %v FineValues: %v}", + return fmt.Sprintf("{GenesisCRSText: %v Owner: %v MinStake: %v LockupPeriod: %v MiningVelocity: %v NextHalvingSupply: %v LastHalvedAmount: %v BlockGasLimit: %v NumChains: %v LambdaBA: %v LambdaDKG: %v K: %v PhiRatio: %v NotarySetSize: %v DKGSetSize: %v RoundInterval: %v MinBlockInterval: %v FineValues: %v}", d.GenesisCRSText, d.Owner, d.MinStake, d.LockupPeriod, - d.BlockReward, + d.MiningVelocity, + d.NextHalvingSupply, + d.LastHalvedAmount, d.BlockGasLimit, d.NumChains, d.LambdaBA, diff --git a/params/gen_dexcon_config.go b/params/gen_dexcon_config.go index 4ec55c0c9..29ebf2eaf 100644 --- a/params/gen_dexcon_config.go +++ b/params/gen_dexcon_config.go @@ -15,29 +15,33 @@ var _ = (*dexconConfigSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (d DexconConfig) MarshalJSON() ([]byte, error) { type DexconConfig struct { - GenesisCRSText string `json:"genesisCRSText"` - Owner common.Address `json:"owner"` - MinStake *math.HexOrDecimal256 `json:"minStake"` - LockupPeriod uint64 `json:"lockupPeriod"` - BlockReward *math.HexOrDecimal256 `json:"blockReward"` - BlockGasLimit uint64 `json:"blockGasLimit"` - NumChains uint32 `json:"numChains"` - LambdaBA uint64 `json:"lambdaBA"` - LambdaDKG uint64 `json:"lambdaDKG"` - K uint32 `json:"k"` - PhiRatio float32 `json:"phiRatio"` - NotarySetSize uint32 `json:"notarySetSize"` - DKGSetSize uint32 `json:"dkgSetSize"` - RoundInterval uint64 `json:"roundInterval"` - MinBlockInterval uint64 `json:"minBlockInterval"` - FineValues []*math.HexOrDecimal256 `json:"fineValues"` + GenesisCRSText string `json:"genesisCRSText"` + Owner common.Address `json:"owner"` + MinStake *math.HexOrDecimal256 `json:"minStake"` + LockupPeriod uint64 `json:"lockupPeriod"` + MiningVelocity float32 `json:"miningVelocity"` + NextHalvingSupply *math.HexOrDecimal256 `json:"nextHalvingSupply"` + LastHalvedAmount *math.HexOrDecimal256 `json:"lastHalvedAmount"` + BlockGasLimit uint64 `json:"blockGasLimit"` + NumChains uint32 `json:"numChains"` + LambdaBA uint64 `json:"lambdaBA"` + LambdaDKG uint64 `json:"lambdaDKG"` + K uint32 `json:"k"` + PhiRatio float32 `json:"phiRatio"` + NotarySetSize uint32 `json:"notarySetSize"` + DKGSetSize uint32 `json:"dkgSetSize"` + RoundInterval uint64 `json:"roundInterval"` + MinBlockInterval uint64 `json:"minBlockInterval"` + FineValues []*math.HexOrDecimal256 `json:"fineValues"` } var enc DexconConfig enc.GenesisCRSText = d.GenesisCRSText enc.Owner = d.Owner enc.MinStake = (*math.HexOrDecimal256)(d.MinStake) enc.LockupPeriod = d.LockupPeriod - enc.BlockReward = (*math.HexOrDecimal256)(d.BlockReward) + enc.MiningVelocity = d.MiningVelocity + enc.NextHalvingSupply = (*math.HexOrDecimal256)(d.NextHalvingSupply) + enc.LastHalvedAmount = (*math.HexOrDecimal256)(d.LastHalvedAmount) enc.BlockGasLimit = d.BlockGasLimit enc.NumChains = d.NumChains enc.LambdaBA = d.LambdaBA @@ -60,22 +64,24 @@ func (d DexconConfig) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (d *DexconConfig) UnmarshalJSON(input []byte) error { type DexconConfig struct { - GenesisCRSText *string `json:"genesisCRSText"` - Owner *common.Address `json:"owner"` - MinStake *math.HexOrDecimal256 `json:"minStake"` - LockupPeriod *uint64 `json:"lockupPeriod"` - BlockReward *math.HexOrDecimal256 `json:"blockReward"` - BlockGasLimit *uint64 `json:"blockGasLimit"` - NumChains *uint32 `json:"numChains"` - LambdaBA *uint64 `json:"lambdaBA"` - LambdaDKG *uint64 `json:"lambdaDKG"` - K *uint32 `json:"k"` - PhiRatio *float32 `json:"phiRatio"` - NotarySetSize *uint32 `json:"notarySetSize"` - DKGSetSize *uint32 `json:"dkgSetSize"` - RoundInterval *uint64 `json:"roundInterval"` - MinBlockInterval *uint64 `json:"minBlockInterval"` - FineValues []*math.HexOrDecimal256 `json:"fineValues"` + GenesisCRSText *string `json:"genesisCRSText"` + Owner *common.Address `json:"owner"` + MinStake *math.HexOrDecimal256 `json:"minStake"` + LockupPeriod *uint64 `json:"lockupPeriod"` + MiningVelocity *float32 `json:"miningVelocity"` + NextHalvingSupply *math.HexOrDecimal256 `json:"nextHalvingSupply"` + LastHalvedAmount *math.HexOrDecimal256 `json:"lastHalvedAmount"` + BlockGasLimit *uint64 `json:"blockGasLimit"` + NumChains *uint32 `json:"numChains"` + LambdaBA *uint64 `json:"lambdaBA"` + LambdaDKG *uint64 `json:"lambdaDKG"` + K *uint32 `json:"k"` + PhiRatio *float32 `json:"phiRatio"` + NotarySetSize *uint32 `json:"notarySetSize"` + DKGSetSize *uint32 `json:"dkgSetSize"` + RoundInterval *uint64 `json:"roundInterval"` + MinBlockInterval *uint64 `json:"minBlockInterval"` + FineValues []*math.HexOrDecimal256 `json:"fineValues"` } var dec DexconConfig if err := json.Unmarshal(input, &dec); err != nil { @@ -93,8 +99,14 @@ func (d *DexconConfig) UnmarshalJSON(input []byte) error { if dec.LockupPeriod != nil { d.LockupPeriod = *dec.LockupPeriod } - if dec.BlockReward != nil { - d.BlockReward = (*big.Int)(dec.BlockReward) + if dec.MiningVelocity != nil { + d.MiningVelocity = *dec.MiningVelocity + } + if dec.NextHalvingSupply != nil { + d.NextHalvingSupply = (*big.Int)(dec.NextHalvingSupply) + } + if dec.LastHalvedAmount != nil { + d.LastHalvedAmount = (*big.Int)(dec.LastHalvedAmount) } if dec.BlockGasLimit != nil { d.BlockGasLimit = *dec.BlockGasLimit diff --git a/test/genesis.json b/test/genesis.json index c053120f5..ce3526883 100644 --- a/test/genesis.json +++ b/test/genesis.json @@ -1,7 +1,8 @@ { "config": { - "chainId": 238, + "chainId": 237, "homesteadBlock": 0, + "daoForkBlock": 0, "daoForkSupport": true, "eip150Block": 0, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -14,7 +15,9 @@ "owner": "0xbf8c48a620bacc46907f9b89732d25e47a2d7cf7", "minStake": "0x152d02c7e14af6800000", "lockupPeriod": 259200000, - "blockReward": "0xde0b6b3a7640000", + "miningVelocity": 0.1875, + "nextHalvingSupply": "0x813f3978f89409844000000", + "lastHalvedAmount": "0x4d8c55aefb8c05b5c000000", "blockGasLimit": 40000000, "numChains": 6, "lambdaBA": 250, @@ -24,7 +27,7 @@ "notarySetSize": 4, "dkgSetSize": 4, "roundInterval": 600000, - "minBlockInterval": 900, + "minBlockInterval": 1000, "fineValues": [ "0x21e19e0c9bab2400000", "0x21e19e0c9bab2400000", @@ -96,5 +99,8 @@ "url": "https://dexon.org" } } - } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" } diff --git a/test/keygen.go b/test/keygen.go index b98d70751..e7441e146 100644 --- a/test/keygen.go +++ b/test/keygen.go @@ -24,15 +24,7 @@ var preFundAddresss = []string{ } func main() { - data, err := ioutil.ReadFile(genesisFile) - if err != nil { - panic(err) - } - - genesis := new(core.Genesis) - if err := json.Unmarshal(data, &genesis); err != nil { - panic(err) - } + genesis := core.DefaultGenesisBlock() // Clear previous allocation. genesis.Alloc = make(map[common.Address]core.GenesisAccount) @@ -71,7 +63,7 @@ func main() { fmt.Printf("Created account %s\n", address.String()) } - data, err = json.MarshalIndent(genesis, "", " ") + data, err := json.MarshalIndent(genesis, "", " ") if err != nil { panic(err) } diff --git a/test/run_test.sh b/test/run_test.sh index a2280cc7d..ccbdbf9fc 100755 --- a/test/run_test.sh +++ b/test/run_test.sh @@ -1,17 +1,9 @@ #!/bin/bash -if [ "$1" != "--testnet" ] && [ "$1" != "--taipei" ]; then - echo 'invalid network specified' - exit 1 -fi - -NETWORK="${1}" - -if [ "$2" == "--local" ]; then - NETWORK="${NETWORK} --bootnodes enode://0478aa13c91aa0db8e93b668313b7eb0532fbdb24f64772375373b14dbe326c238ad09ab4469f6442c9a9753f1275aeec2e531912c14a958ed1feb4ae7e227ef@127.0.0.1:30301" - # Start bootnode. - bootnode -nodekey keystore/bootnode.key --verbosity=9 > bootnode.log 2>&1 & -fi +NETWORK="--bootnodes enode://0478aa13c91aa0db8e93b668313b7eb0532fbdb24f64772375373b14dbe326c238ad09ab4469f6442c9a9753f1275aeec2e531912c14a958ed1feb4ae7e227ef@127.0.0.1:30301" +GENESIS="genesis.json" +# Start bootnode. +bootnode -nodekey keystore/bootnode.key --verbosity=9 > bootnode.log 2>&1 & GDEX=../build/bin/gdex @@ -34,10 +26,10 @@ let dmoment=`date +%s`+7 # A standalone RPC server for accepting RPC requests. datadir=$PWD/Dexon.rpc rm -rf $datadir -$GDEX --datadir=$datadir init genesis.json +$GDEX --datadir=$datadir init ${GENESIS} $GDEX \ ${NETWORK} \ - --verbosity=4 \ + --verbosity=3 \ --gcmode=archive \ --datadir=$datadir --nodekey=keystore/rpc.key \ --rpc --rpcapi=eth,net,web3,debug \ @@ -52,11 +44,11 @@ $GDEX \ for i in $(seq 0 3); do datadir=$PWD/Dexon.$i rm -rf $datadir - $GDEX --datadir=$datadir init genesis.json + $GDEX --datadir=$datadir init ${GENESIS} $GDEX \ ${NETWORK} \ --bp \ - --verbosity=4 \ + --verbosity=3 \ --gcmode=archive \ --datadir=$datadir --nodekey=keystore/test$i.key \ --port=$((30305 + $i)) \ -- cgit