aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-11-17 13:18:34 +0800
committerWei-Ning Huang <w@dexon.org>2019-03-12 12:19:09 +0800
commit0e3b223de19e1975453206d8a0d326b575cb0afe (patch)
tree5b845b41416efafa814c47769a198c0e1dc0edae
parent4246c8733870b92a8090bff1b3dc0c1159c535ad (diff)
downloaddexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar.gz
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar.bz2
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar.lz
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar.xz
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.tar.zst
dexon-0e3b223de19e1975453206d8a0d326b575cb0afe.zip
core: more fix on light node synchronization (#32)
Fix gas calculation in governance contract. Correctly register round height when processing pending blocks. We should register the mapping when we get the pending block instead of waiting for block confirmation.
-rw-r--r--core/blockchain.go21
-rw-r--r--core/genesis.go4
-rw-r--r--core/vm/governance.go92
-rw-r--r--dex/config.go4
-rw-r--r--dex/governance.go11
-rw-r--r--test/genesis.json2
6 files changed, 58 insertions, 76 deletions
diff --git a/core/blockchain.go b/core/blockchain.go
index 5a75afaf2..482cd94f0 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -1596,7 +1596,7 @@ func (bc *BlockChain) processPendingBlock(
return nil, nil, nil, err
}
- // Iterate over and process the individual transactions
+ // Iterate over and process the individual transactions.
for i, tx := range block.Transactions() {
pendingState.Prepare(tx.Hash(), block.Hash(), i)
receipt, _, err := ApplyTransaction(bc.chainConfig, bc, nil, gp, pendingState, header, tx, usedGas, bc.vmConfig)
@@ -1613,19 +1613,23 @@ func (bc *BlockChain) processPendingBlock(
return nil, nil, nil, fmt.Errorf("finalize error: %v", err)
}
+ if _, ok := bc.GetRoundHeight(newPendingBlock.Round()); !ok {
+ bc.storeRoundHeight(newPendingBlock.Round(), newPendingBlock.NumberU64())
+ }
+
proctime := time.Since(bstart)
- // commit state to refresh stateCache
+ // Commit state to refresh stateCache.
_, err = pendingState.Commit(true)
if err != nil {
return nil, nil, nil, fmt.Errorf("pendingState commit error: %v", err)
}
- // add into pending blocks
+ // Add into pending blocks.
bc.addPendingBlock(newPendingBlock, receipts)
events = append(events, BlockConfirmedEvent{newPendingBlock})
- // start insert available pending blocks into db
+ // Start insert available pending blocks into db
for pendingHeight := bc.CurrentBlock().NumberU64() + 1; pendingHeight <= witness.Height; pendingHeight++ {
pendingIns, exist := bc.pendingBlocks[pendingHeight]
if !exist {
@@ -1646,8 +1650,9 @@ func (bc *BlockChain) processPendingBlock(
switch status {
case CanonStatTy:
- log.Debug("Inserted new block", "number", pendingIns.block.Number(), "hash", pendingIns.block.Hash(), "uncles", len(pendingIns.block.Uncles()),
- "txs", len(pendingIns.block.Transactions()), "gas", pendingIns.block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
+ log.Debug("Inserted new block", "number", pendingIns.block.Number(), "hash", pendingIns.block.Hash(),
+ "uncles", len(pendingIns.block.Uncles()), "txs", len(pendingIns.block.Transactions()),
+ "gas", pendingIns.block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(bstart)))
var allLogs []*types.Log
for _, r := range pendingIns.receipts {
@@ -1671,10 +1676,6 @@ func (bc *BlockChain) processPendingBlock(
cache, _ := bc.stateCache.TrieDB().Size()
stats.report([]*types.Block{pendingIns.block}, 0, cache)
-
- if _, ok := bc.GetRoundHeight(pendingIns.block.Round()); !ok {
- bc.storeRoundHeight(pendingIns.block.Round(), pendingHeight)
- }
}
// Append a single chain head event if we've progressed the chain
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
diff --git a/core/genesis.go b/core/genesis.go
index 8b5588a0f..440ff1a64 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -387,7 +387,7 @@ func DefaultGenesisBlock() *Genesis {
Timestamp: 1540024964,
Nonce: 0x42,
ExtraData: hexutil.MustDecode("0x5765692d4e696e6720536f6e696320426f6a696520323031382d31302d32302e"),
- GasLimit: 8000000,
+ GasLimit: 80000000,
Difficulty: big.NewInt(1),
Alloc: decodePrealloc(mainnetAllocData),
}
@@ -399,7 +399,7 @@ func DefaultTestnetGenesisBlock() *Genesis {
Config: params.TestnetChainConfig,
Nonce: 0x42,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
- GasLimit: 8000000,
+ GasLimit: 80000000,
Difficulty: big.NewInt(1),
Alloc: decodePrealloc(testnetAllocData),
}
diff --git a/core/vm/governance.go b/core/vm/governance.go
index cbc7f458f..b6a5038c5 100644
--- a/core/vm/governance.go
+++ b/core/vm/governance.go
@@ -1498,8 +1498,16 @@ func newGovernanceContract(evm *EVM, contract *Contract) *GovernanceContract {
}
}
-func (g *GovernanceContract) penalize() {
- g.contract.UseGas(g.contract.Gas)
+func (g *GovernanceContract) UseGas(gas uint64) ([]byte, error) {
+ if !g.contract.UseGas(gas) {
+ return nil, ErrOutOfGas
+ }
+ return nil, nil
+}
+
+func (g *GovernanceContract) penalize() ([]byte, error) {
+ g.UseGas(g.contract.Gas)
+ return nil, errExecutionReverted
}
func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) bool {
@@ -1532,16 +1540,14 @@ func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) b
func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
if round.Cmp(g.state.Round()) != 0 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
caller := g.contract.Caller()
// Finalized caller is not allowed to propose complaint.
if g.state.DKGFinalized(round, caller) {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// Calculate 2f
@@ -1556,34 +1562,29 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
var dkgComplaint dkgTypes.Complaint
if err := rlp.DecodeBytes(comp, &dkgComplaint); err != nil {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// DKGComplaint must belongs to someone in DKG set.
if !g.inDKGSet(round, dkgComplaint.ProposerID) {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
verified, _ := core.VerifyDKGComplaintSignature(&dkgComplaint)
if !verified {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
g.state.PushDKGComplaint(round, comp)
// Set this to relatively high to prevent spamming
- g.contract.UseGas(10000000)
- return nil, nil
+ 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 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
caller := g.contract.Caller()
@@ -1596,53 +1597,44 @@ func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) (
var dkgMasterPK dkgTypes.MasterPublicKey
if err := rlp.DecodeBytes(mpk, &dkgMasterPK); err != nil {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// DKGMasterPublicKey must belongs to someone in DKG set.
if !g.inDKGSet(round, dkgMasterPK.ProposerID) {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
verified, _ := core.VerifyDKGMasterPublicKeySignature(&dkgMasterPK)
if !verified {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
g.state.PushDKGMasterPublicKey(round, mpk)
- // DKG operation is expensive.
- g.contract.UseGas(100000)
- return nil, nil
+ return g.UseGas(100000)
}
func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]byte, error) {
if round.Cmp(g.state.Round()) != 0 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
caller := g.contract.Caller()
var dkgFinalize dkgTypes.Finalize
if err := rlp.DecodeBytes(finalize, &dkgFinalize); err != nil {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// DKGFInalize must belongs to someone in DKG set.
if !g.inDKGSet(round, dkgFinalize.ProposerID) {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
verified, _ := core.VerifyDKGFinalizeSignature(&dkgFinalize)
if !verified {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
if !g.state.DKGFinalized(round, caller) {
@@ -1650,9 +1642,7 @@ func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]
g.state.IncDKGFinalizedsCount(round)
}
- // DKG operation is expensive.
- g.contract.UseGas(100000)
- return nil, nil
+ return g.UseGas(100000)
}
func (g *GovernanceContract) updateConfiguration(config *params.DexconConfig) ([]byte, error) {
@@ -1671,8 +1661,7 @@ func (g *GovernanceContract) stake(
// Reject invalid inputs.
if len(name) >= 32 || len(email) >= 32 || len(location) >= 32 || len(url) >= 128 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
caller := g.contract.Caller()
@@ -1680,14 +1669,12 @@ func (g *GovernanceContract) stake(
// Need to stake at least minStake.
if g.contract.Value().Cmp(g.state.MinStake()) < 0 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// Can not stake if already staked.
if offset.Cmp(big.NewInt(0)) >= 0 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
offset = g.state.NodesLength()
@@ -1702,8 +1689,7 @@ func (g *GovernanceContract) stake(
})
g.state.PutOffset(caller, offset)
- g.contract.UseGas(21000)
- return nil, nil
+ return g.UseGas(0)
}
func (g *GovernanceContract) unstake() ([]byte, error) {
@@ -1729,8 +1715,7 @@ func (g *GovernanceContract) unstake() ([]byte, error) {
// TODO(w): add this to debug trace so it shows up as internal transaction.
g.evm.Transfer(g.evm.StateDB, GovernanceContractAddress, caller, node.Staked)
- g.contract.UseGas(21000)
- return nil, nil
+ return g.UseGas(0)
}
func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([]byte, error) {
@@ -1781,8 +1766,7 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
Signature: signedCRS,
}
if !dkgGPK.VerifySignature(coreCommon.Hash(prevCRS), signature) {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
// Save new CRS into state and increase round.
@@ -1794,8 +1778,7 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
// To encourage DKG set to propose the correct value, correctly submitting
// this should cause nothing.
- g.contract.UseGas(0)
- return nil, nil
+ return g.UseGas(0)
}
func (g *GovernanceContract) transferOwnership(newOwner common.Address) ([]byte, error) {
@@ -1812,20 +1795,19 @@ func (g *GovernanceContract) snapshotRound(round, height *big.Int) ([]byte, erro
if g.evm.IsBlockProposer() {
realHeight, ok := g.evm.Context.GetRoundHeight(round.Uint64())
if !ok {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
if height.Cmp(new(big.Int).SetUint64(realHeight)) != 0 {
- g.penalize()
- return nil, errExecutionReverted
+ return g.penalize()
}
}
// Only allow updating the next round.
nextRound := g.state.LenRoundHeight()
if round.Cmp(nextRound) != 0 {
- g.penalize()
+ // No need to penalize, since the only possibility at this point is the
+ // round height is already snapshoted.
return nil, errExecutionReverted
}
diff --git a/dex/config.go b/dex/config.go
index e78a698a9..438e959e3 100644
--- a/dex/config.go
+++ b/dex/config.go
@@ -48,8 +48,8 @@ var DefaultConfig = Config{
},
BlockProposerEnabled: false,
DefaultGasPrice: big.NewInt(params.GWei),
- GasFloor: 8000000,
- GasCeil: 8000000,
+ GasFloor: 80000000,
+ GasCeil: 80000000,
GasLimitTolerance: 1000000,
}
diff --git a/dex/governance.go b/dex/governance.go
index 0251d2afd..f555b3508 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -79,6 +79,7 @@ func (d *DexconGovernance) getGovStateAtRound(round uint64) *vm.GovernanceStateH
state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.BlockNumber(blockHeight))
if state == nil || err != nil {
+ log.Error("Failed to retrieve governance state", "round", round, "height", blockHeight)
return nil
}
return &vm.GovernanceStateHelper{state}
@@ -119,17 +120,15 @@ func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
return err
}
- log.Info("sendGovTx", "nonce", nonce)
-
- // Increase gasPrice to 5 times of suggested gas price to make sure it will
+ // Increase gasPrice to 10 times of suggested gas price to make sure it will
// be included in time.
- gasPrice = new(big.Int).Mul(gasPrice, big.NewInt(5))
+ gasPrice = new(big.Int).Mul(gasPrice, big.NewInt(10))
tx := types.NewTransaction(
nonce,
vm.GovernanceContractAddress,
big.NewInt(0),
- uint64(2000000),
+ uint64(10000000),
gasPrice,
data)
@@ -140,7 +139,7 @@ func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
return err
}
- log.Info("Send governance transaction", "fullhash", tx.Hash().Hex())
+ log.Info("Send governance transaction", "fullhash", tx.Hash().Hex(), "nonce", nonce)
return d.b.SendTx(ctx, tx)
}
diff --git a/test/genesis.json b/test/genesis.json
index cf61e2d45..c4e110e84 100644
--- a/test/genesis.json
+++ b/test/genesis.json
@@ -29,7 +29,7 @@
"nonce": "0x42",
"timestamp": "0x0",
"extraData": "0x3535353535353535353535353535353535353535353535353535353535353535",
- "gasLimit": "0x7a1200",
+ "gasLimit": "0x4c4b400",
"difficulty": "0x1",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x0000000000000000000000000000000000000000",