diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index 525c7bea9343..864e5e1cd087 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -144,6 +144,7 @@ var ( rpcFlags = []cli.Flag{ utils.RPCEnabledFlag, + utils.RPCGlobalGasCapFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, utils.RPCHttpWriteTimeoutFlag, diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index a49da82bb581..b724155162a5 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -144,6 +144,7 @@ var AppHelpFlagGroups = []flagGroup{ Name: "API AND CONSOLE", Flags: []cli.Flag{ utils.RPCEnabledFlag, + utils.RPCGlobalGasCapFlag, utils.RPCListenAddrFlag, utils.RPCPortFlag, utils.RPCHttpWriteTimeoutFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 38ce46222e1f..272ecbef57ec 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -374,7 +374,7 @@ var ( Usage: "Record information useful for VM and contract debugging", } RPCGlobalGasCapFlag = cli.Uint64Flag{ - Name: "rpc.gascap", + Name: "rpc-gascap", Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", Value: ethconfig.Defaults.RPCGasCap, } @@ -1242,6 +1242,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.GlobalIsSet(DocRootFlag.Name) { cfg.DocRoot = ctx.GlobalString(DocRootFlag.Name) } + if ctx.GlobalIsSet(RPCGlobalGasCapFlag.Name) { + cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCapFlag.Name) + } if ctx.GlobalIsSet(RPCGlobalTxFeeCap.Name) { cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCap.Name) } diff --git a/consensus/XDPoS/api.go b/consensus/XDPoS/api.go index fd06703128b3..af8ab44ee290 100644 --- a/consensus/XDPoS/api.go +++ b/consensus/XDPoS/api.go @@ -344,3 +344,23 @@ func (api *API) GetEpochNumbersBetween(begin, end *rpc.BlockNumber) ([]uint64, e } return epochSwitchNumbers, nil } + +/* +An API exclusively for V2 consensus, designed to assist in getting rewards of the epoch number. +Given the epoch number, search the epoch switch block. +*/ +func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo, error) { + thisEpoch, nextEpoch, err := api.XDPoS.EngineV2.GetBlockByEpochNumber(api.chain, epochNumber) + if err != nil { + return nil, err + } + info := &utils.EpochNumInfo{ + EpochBlockHash: thisEpoch.Hash, + EpochRound: thisEpoch.Round, + EpochFirstBlockNumber: thisEpoch.Number, + } + if nextEpoch != nil { + info.EpochLastBlockNumber = new(big.Int).Sub(nextEpoch.Number, big.NewInt(1)) + } + return info, nil +} diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index c2235f5d32a9..5646465e5d7a 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -654,6 +654,10 @@ func (x *XDPoS_v2) VoteHandler(chain consensus.ChainReader, voteMsg *types.Vote) 3. Broadcast(Not part of consensus) */ func (x *XDPoS_v2) VerifyTimeoutMessage(chain consensus.ChainReader, timeoutMsg *types.Timeout) (bool, error) { + if timeoutMsg.Round < x.currentRound { + log.Debug("[VerifyTimeoutMessage] Disqualified timeout message as the proposed round does not match currentRound", "timeoutHash", timeoutMsg.Hash(), "timeoutRound", timeoutMsg.Round, "currentRound", x.currentRound) + return false, nil + } snap, err := x.getSnapshot(chain, timeoutMsg.GapNumber, true) if err != nil || snap == nil { log.Error("[VerifyTimeoutMessage] Fail to get snapshot when verifying timeout message!", "messageGapNumber", timeoutMsg.GapNumber, "err", err) diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index abb35bde0926..2df90ab1a076 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -175,6 +175,10 @@ func (x *XDPoS_v2) GetEpochSwitchInfoBetween(chain consensus.ChainReader, begin, return nil, err } iteratorHeader = nil + // V2 switch epoch switch info has nil parent + if epochSwitchInfo.EpochSwitchParentBlockInfo == nil { + break + } iteratorHash = epochSwitchInfo.EpochSwitchParentBlockInfo.Hash iteratorNum = epochSwitchInfo.EpochSwitchBlockInfo.Number if iteratorNum.Cmp(begin.Number) >= 0 { diff --git a/consensus/XDPoS/engines/engine_v2/forensics.go b/consensus/XDPoS/engines/engine_v2/forensics.go index 45f88097d6b3..b3198bd71c42 100644 --- a/consensus/XDPoS/engines/engine_v2/forensics.go +++ b/consensus/XDPoS/engines/engine_v2/forensics.go @@ -87,6 +87,7 @@ Forensics runs in a seperate go routine as its no system critical Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow */ func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error { + return nil log.Debug("Received a QC in forensics", "QC", incomingQC) // Clone the values to a temporary variable highestCommittedQCs := f.HighestCommittedQCs @@ -394,6 +395,7 @@ Forensics runs in a seperate go routine as its no system critical Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/99516417/Vote+Equivocation+detection+specification */ func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine *XDPoS_v2, incomingVote *types.Vote) error { + return nil log.Debug("Received a vote in forensics", "vote", incomingVote) // Clone the values to a temporary variable highestCommittedQCs := f.HighestCommittedQCs @@ -484,6 +486,7 @@ func (f *Forensics) isVoteBlamed(chain consensus.ChainReader, highestCommittedQC } func (f *Forensics) DetectEquivocationInVotePool(vote *types.Vote, votePool *utils.Pool) { + return poolKey := vote.PoolKey() votePoolKeys := votePool.PoolObjKeysList() signer, err := GetVoteSignerAddresses(vote) diff --git a/consensus/XDPoS/engines/engine_v2/utils.go b/consensus/XDPoS/engines/engine_v2/utils.go index 20198816280b..c2e17b7e71dd 100644 --- a/consensus/XDPoS/engines/engine_v2/utils.go +++ b/consensus/XDPoS/engines/engine_v2/utils.go @@ -3,6 +3,7 @@ package engine_v2 import ( "errors" "fmt" + "math/big" "github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/common" @@ -218,3 +219,44 @@ func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *t return missedRoundsMetadata, nil } + +func (x *XDPoS_v2) GetBlockByEpochNumber(chain consensus.ChainReader, targetEpochNum uint64) (*types.BlockInfo, *types.BlockInfo, error) { + currentHeader := chain.CurrentHeader() + epochSwitchInfo, err := x.getEpochSwitchInfo(chain, currentHeader, currentHeader.Hash()) + if err != nil { + return nil, nil, err + } + epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(epochSwitchInfo.EpochSwitchBlockInfo.Round)/x.config.Epoch + // since below function GetEpochSwitchInfoBetween(chain, start, end) return nil if start == end, we early return the result + if targetEpochNum == epochNum { + return epochSwitchInfo.EpochSwitchBlockInfo, nil, nil + } + if targetEpochNum > epochNum { + return nil, nil, errors.New("input epoch number > current epoch number") + } + if targetEpochNum < x.config.V2.SwitchBlock.Uint64()/x.config.Epoch { + return nil, nil, errors.New("input epoch number < v2 begin epoch number") + } + epoch := big.NewInt(int64(x.config.Epoch)) + estblockNumDiff := new(big.Int).Mul(epoch, big.NewInt(int64(epochNum-targetEpochNum))) + estBlockNum := new(big.Int).Sub(epochSwitchInfo.EpochSwitchBlockInfo.Number, estblockNumDiff) + if estBlockNum.Cmp(x.config.V2.SwitchBlock) == -1 { + estBlockNum.Set(x.config.V2.SwitchBlock) + } + estBlockHeader := chain.GetHeaderByNumber(estBlockNum.Uint64()) + epochSwitchInfos, err := x.GetEpochSwitchInfoBetween(chain, estBlockHeader, currentHeader) + if err != nil { + return nil, nil, err + } + for i, info := range epochSwitchInfos { + epochNum := x.config.V2.SwitchBlock.Uint64()/x.config.Epoch + uint64(info.EpochSwitchBlockInfo.Round)/x.config.Epoch + if epochNum == targetEpochNum { + if i < len(epochSwitchInfos)-1 { + nextEpoch := epochSwitchInfos[i+1].EpochSwitchBlockInfo + return info.EpochSwitchBlockInfo, nextEpoch, nil + } + return info.EpochSwitchBlockInfo, nil, nil + } + } + return nil, nil, errors.New("input epoch number not found (all rounds in this epoch are missed, which is very rare)") +} diff --git a/consensus/XDPoS/utils/types.go b/consensus/XDPoS/utils/types.go index 897e984b4811..b5d116834110 100644 --- a/consensus/XDPoS/utils/types.go +++ b/consensus/XDPoS/utils/types.go @@ -71,3 +71,11 @@ type PublicApiMissedRoundsMetadata struct { EpochBlockNumber *big.Int MissedRounds []MissedRoundInfo } + +// Given an epoch number, this struct records the epoch switch block (first block in epoch) infos such as block number +type EpochNumInfo struct { + EpochBlockHash common.Hash `json:"hash"` + EpochRound types.Round `json:"round"` + EpochFirstBlockNumber *big.Int `json:"firstBlock"` + EpochLastBlockNumber *big.Int `json:"lastBlock"` +} diff --git a/consensus/tests/engine_v2_tests/api_test.go b/consensus/tests/engine_v2_tests/api_test.go index 185f9a40ccd2..723ed33090aa 100644 --- a/consensus/tests/engine_v2_tests/api_test.go +++ b/consensus/tests/engine_v2_tests/api_test.go @@ -168,3 +168,70 @@ func TestGetEpochNumbersBetween(t *testing.T) { assert.Nil(t, numbers) assert.EqualError(t, err, "illegal begin block number") } +func TestGetBlockByEpochNumber(t *testing.T) { + blockchain, _, currentBlock, signer, signFn := PrepareXDCTestBlockChainWithPenaltyForV2Engine(t, 1802, params.TestXDPoSMockChainConfig) + + blockCoinBase := "0x111000000000000000000000000000000123" + largeRound := int64(1802) + newBlock := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, int(currentBlock.NumberU64())+1, largeRound, blockCoinBase, signer, signFn, nil, nil, currentBlock.Header().Root.Hex()) + err := blockchain.InsertBlock(newBlock) + assert.Nil(t, err) + largeRound2 := int64(3603) + newBlock2 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, newBlock, int(newBlock.NumberU64())+1, largeRound2, blockCoinBase, signer, signFn, nil, nil, newBlock.Header().Root.Hex()) + err = blockchain.InsertBlock(newBlock2) + assert.Nil(t, err) + + // block num, round, epoch is as follows + // 900,0,1 (v2 switch block, not v2 epoch switch block) + // 901,1,1 (1st epoch switch block) + // 902,2,1 + // ... + // 1800,900,2 (2nd epoch switch block) + // 1801,901,2 + // 1802,902,2 + // 1803,1802,3 (epoch switch) + // epoch 4 has no block + // 1804,3603,5 (epoch switch) + engine := blockchain.Engine().(*XDPoS.XDPoS) + + // init the snapshot, otherwise getEpochSwitchInfo would return error + checkpointHeader := blockchain.GetHeaderByNumber(blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() + 1) + err = engine.Initial(blockchain, checkpointHeader) + assert.Nil(t, err) + + info, err := engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(0) + assert.NotNil(t, err) + assert.Nil(t, info) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(1) + assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(901)) + assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1799)) + assert.Equal(t, info.EpochRound, types.Round(1)) + assert.Nil(t, err) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(2) + assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(1800)) + assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1802)) + assert.Equal(t, info.EpochRound, types.Round(900)) + assert.Nil(t, err) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(3) + assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(1803)) + assert.Equal(t, info.EpochLastBlockNumber.Int64(), int64(1803)) + assert.Equal(t, info.EpochRound, types.Round(largeRound)) + assert.Nil(t, err) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(4) + assert.NotNil(t, err) + assert.Nil(t, info) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(5) + assert.Equal(t, info.EpochRound, types.Round(largeRound2)) + assert.Equal(t, info.EpochFirstBlockNumber.Int64(), int64(1804)) + assert.Nil(t, info.EpochLastBlockNumber) + assert.Nil(t, err) + + info, err = engine.APIs(blockchain)[0].Service.(*XDPoS.API).GetBlockInfoByEpochNum(6) + assert.NotNil(t, err) + assert.Nil(t, info) +} diff --git a/consensus/tests/engine_v2_tests/forensics_test.go b/consensus/tests/engine_v2_tests/forensics_test.go index 10f031aa8992..dd9ad913db01 100644 --- a/consensus/tests/engine_v2_tests/forensics_test.go +++ b/consensus/tests/engine_v2_tests/forensics_test.go @@ -17,6 +17,8 @@ import ( ) func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2 @@ -92,6 +94,8 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) { } func TestSetCommittedQCsInOrder(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil) forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker() @@ -118,6 +122,8 @@ func TestSetCommittedQCsInOrder(t *testing.T) { // Happty path func TestForensicsMonitoring(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil) forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker() var decodedCurrentblockExtraField types.ExtraFields_v2 @@ -140,6 +146,7 @@ func TestForensicsMonitoring(t *testing.T) { } func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") var numOfForks = new(int) *numOfForks = 10 var forkRoundDifference = new(int) @@ -199,6 +206,8 @@ func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) { } func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + var numOfForks = new(int) *numOfForks = 10 var forkRoundDifference = new(int) @@ -260,6 +269,8 @@ func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) { // "prone to attack" test where the "across epoch" field is true func TestForensicsAcrossEpoch(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + var numOfForks = new(int) *numOfForks = 10 var forkRoundDifference = new(int) @@ -322,6 +333,8 @@ func TestForensicsAcrossEpoch(t *testing.T) { } func TestVoteEquivocationSameRound(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + var numOfForks = new(int) *numOfForks = 1 blockchain, _, currentBlock, signer, signFn, currentForkBlock := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks}) @@ -388,6 +401,8 @@ func TestVoteEquivocationSameRound(t *testing.T) { } func TestVoteEquivocationDifferentRound(t *testing.T) { + t.Skip("Skipping this test for now as we disable forensics") + var numOfForks = new(int) *numOfForks = 10 var forkRoundDifference = new(int) diff --git a/eth/api_backend.go b/eth/api_backend.go index f9a585ba5e7f..f5e2ead83d56 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -442,11 +442,11 @@ func (b *EthApiBackend) GetVotersRewards(masternodeAddr common.Address) map[comm // calculate for 2 epochs ago currentCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, block.Number()) if err != nil { - log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for current checkpoint block", "block", block) + log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for current checkpoint block", "block", block.Number(), "err", err) } lastCheckpointNumber, _, err := engine.GetCurrentEpochSwitchBlock(chain, big.NewInt(int64(currentCheckpointNumber-1))) if err != nil { - log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for last checkpoint block", "block", block) + log.Error("[GetVotersRewards] Fail to get GetCurrentEpochSwitchBlock for last checkpoint block", "block", block.Number(), "err", err) } lastCheckpointBlock := chain.GetBlockByNumber(lastCheckpointNumber) diff --git a/eth/bft/bft_handler.go b/eth/bft/bft_handler.go index cb39dc31a15f..44d7c9b42378 100644 --- a/eth/bft/bft_handler.go +++ b/eth/bft/bft_handler.go @@ -11,7 +11,7 @@ import ( const maxBlockDist = 7 // Maximum allowed backward distance from the chain head, 7 is just a magic number indicate very close block -//Define Boradcast Group functions +// Define Boradcast Group functions type broadcastVoteFn func(*types.Vote) type broadcastTimeoutFn func(*types.Timeout) type broadcastSyncInfoFn func(*types.SyncInfo) @@ -93,9 +93,8 @@ func (b *Bfter) Vote(peer string, vote *types.Vote) error { return err } - b.broadcastCh <- vote - if verified { + b.broadcastCh <- vote err = b.consensus.voteHandler(b.blockChainReader, vote) if err != nil { if _, ok := err.(*utils.ErrIncomingMessageRoundTooFarFromCurrentRound); ok { @@ -126,8 +125,8 @@ func (b *Bfter) Timeout(peer string, timeout *types.Timeout) error { return err } - b.broadcastCh <- timeout if verified { + b.broadcastCh <- timeout err = b.consensus.timeoutHandler(b.blockChainReader, timeout) if err != nil { if _, ok := err.(*utils.ErrIncomingMessageRoundNotEqualCurrentRound); ok { @@ -156,9 +155,9 @@ func (b *Bfter) SyncInfo(peer string, syncInfo *types.SyncInfo) error { return err } - b.broadcastCh <- syncInfo // Process only if verified and qualified if verified { + b.broadcastCh <- syncInfo err = b.consensus.syncInfoHandler(b.blockChainReader, syncInfo) if err != nil { log.Error("handle BFT SyncInfo", "error", err) diff --git a/eth/bft/bft_handler_test.go b/eth/bft/bft_handler_test.go index 11d052ba3f72..865a58173016 100644 --- a/eth/bft/bft_handler_test.go +++ b/eth/bft/bft_handler_test.go @@ -144,7 +144,7 @@ func TestBoardcastButNotProcessDisqualifiedVotes(t *testing.T) { tester.bfter.Vote(peerID, &vote) time.Sleep(50 * time.Millisecond) - if int(handlerCounter) != targetVotes || int(broadcastCounter) != 1 { + if int(handlerCounter) != targetVotes || int(broadcastCounter) != 0 { t.Fatalf("count mismatch: have %v on handler, %v on broadcast, want %v", handlerCounter, broadcastCounter, targetVotes) } } @@ -171,7 +171,7 @@ func TestBoardcastButNotProcessDisqualifiedTimeout(t *testing.T) { tester.bfter.Timeout(peerID, &timeout) time.Sleep(50 * time.Millisecond) - if int(handlerCounter) != targetTimeout || int(broadcastCounter) != 1 { + if int(handlerCounter) != targetTimeout || int(broadcastCounter) != 0 { t.Fatalf("count mismatch: have %v on handler, %v on broadcast, want %v", handlerCounter, broadcastCounter, targetTimeout) } } @@ -198,7 +198,7 @@ func TestBoardcastButNotProcessDisqualifiedSyncInfo(t *testing.T) { tester.bfter.SyncInfo(peerID, &syncInfo) time.Sleep(50 * time.Millisecond) - if int(handlerCounter) != targetSyncInfo || int(broadcastCounter) != 1 { + if int(handlerCounter) != targetSyncInfo || int(broadcastCounter) != 0 { t.Fatalf("count mismatch: have %v on handler, %v on broadcast, want %v", handlerCounter, broadcastCounter, targetSyncInfo) } } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 73cc4e7cddbe..efdd2197d92e 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -69,7 +69,7 @@ var Defaults = Config{ GasPrice: big.NewInt(0.25 * params.Shannon), TxPool: core.DefaultTxPoolConfig, - RPCGasCap: 25000000, + RPCGasCap: 50000000, GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether } diff --git a/eth/peer.go b/eth/peer.go index 8035f2a9f06b..eb7730b99a1e 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -37,13 +37,13 @@ var ( ) const ( - maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) - maxKnownOrderTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) - maxKnownLendingTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) - maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS) - maxKnownVote = 1024 // Maximum transactions hashes to keep in the known list (prevent DOS) - maxKnownTimeout = 1024 // Maximum transactions hashes to keep in the known list (prevent DOS) - maxKnownSyncInfo = 1024 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownOrderTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownLendingTxs = 32768 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownBlocks = 1024 // Maximum block hashes to keep in the known list (prevent DOS) + maxKnownVote = 131072 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownTimeout = 131072 // Maximum transactions hashes to keep in the known list (prevent DOS) + maxKnownSyncInfo = 131072 // Maximum transactions hashes to keep in the known list (prevent DOS) handshakeTimeout = 5 * time.Second ) diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 3b4ff0412248..16a87c9810c1 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -106,7 +106,7 @@ var Flags = []cli.Flag{ //blockprofilerateFlag, cpuprofileFlag, //traceFlag, - //periodicProfilingFlag, + periodicProfilingFlag, debugDataDirFlag, } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 62e0f101ece4..96d422ec7596 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -877,7 +877,7 @@ func (s *PublicBlockChainAPI) GetCandidateStatus(ctx context.Context, coinbaseAd epochConfig := s.b.ChainConfig().XDPoS.Epoch // checkpoint block - checkpointNumber, epochNumber = s.GetPreviousCheckpointFromEpoch(ctx, epoch) + checkpointNumber, epochNumber = s.GetCheckpointFromEpoch(ctx, epoch) result[fieldEpoch] = epochNumber.Int64() block, err = s.b.BlockByNumber(ctx, checkpointNumber) @@ -1036,7 +1036,7 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch } epochConfig := s.b.ChainConfig().XDPoS.Epoch - checkpointNumber, epochNumber = s.GetPreviousCheckpointFromEpoch(ctx, epoch) + checkpointNumber, epochNumber = s.GetCheckpointFromEpoch(ctx, epoch) result[fieldEpoch] = epochNumber.Int64() block, err = s.b.BlockByNumber(ctx, checkpointNumber) @@ -1184,25 +1184,31 @@ func (s *PublicBlockChainAPI) GetCandidates(ctx context.Context, epoch rpc.Epoch return result, nil } -// GetPreviousCheckpointFromEpoch returns header of the previous checkpoint -func (s *PublicBlockChainAPI) GetPreviousCheckpointFromEpoch(ctx context.Context, epochNum rpc.EpochNumber) (rpc.BlockNumber, rpc.EpochNumber) { +// GetCheckpointFromEpoch returns header of the previous checkpoint +func (s *PublicBlockChainAPI) GetCheckpointFromEpoch(ctx context.Context, epochNum rpc.EpochNumber) (rpc.BlockNumber, rpc.EpochNumber) { var checkpointNumber uint64 epoch := s.b.ChainConfig().XDPoS.Epoch if epochNum == rpc.LatestEpochNumber { - blockNumer := s.b.CurrentBlock().Number().Uint64() - diff := blockNumer % epoch - // checkpoint number - checkpointNumber = blockNumer - diff - epochNum = rpc.EpochNumber(checkpointNumber / epoch) - if diff > 0 { - epochNum += 1 + blockNumer := s.b.CurrentBlock().Number() + if engine, ok := s.b.GetEngine().(*XDPoS.XDPoS); ok { + var err error + var currentEpoch uint64 + checkpointNumber, currentEpoch, err = engine.GetCurrentEpochSwitchBlock(s.chainReader, blockNumer) + if err != nil { + log.Error("[GetCheckpointFromEpoch] Fail to get GetCurrentEpochSwitchBlock for current checkpoint block", "block", blockNumer, "err", err) + return 0, epochNum + } + + epochNum = rpc.EpochNumber(currentEpoch) } } else if epochNum < 2 { checkpointNumber = 0 } else { + // TODO this checkpointNumber needs to be recalculated for v2 blocks checkpointNumber = epoch * (uint64(epochNum) - 1) } + return rpc.BlockNumber(checkpointNumber), epochNum } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 688f8df33af1..1921ad609961 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -168,6 +168,11 @@ web3._extend({ params: 2, inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter, web3._extend.formatters.inputBlockNumberFormatter] }), + new web3._extend.Method({ + name: 'getBlockInfoByEpochNum', + call: 'XDPoS_getBlockInfoByEpochNum', + params: 1, + }), ], properties: [ new web3._extend.Property({ diff --git a/params/config.go b/params/config.go index a4dcdbe7508e..a7ac5ff3a4dc 100644 --- a/params/config.go +++ b/params/config.go @@ -56,6 +56,30 @@ var ( TimeoutPeriod: 600, MinePeriod: 2, }, + 8000: { + MaxMasternodes: 108, + SwitchRound: 8000, + CertThreshold: 0.667, + TimeoutSyncThreshold: 2, + TimeoutPeriod: 60, + MinePeriod: 2, + }, + 220000: { + MaxMasternodes: 108, + SwitchRound: 220000, + CertThreshold: 0.667, + TimeoutSyncThreshold: 2, + TimeoutPeriod: 30, + MinePeriod: 2, + }, + 460000: { + MaxMasternodes: 108, + SwitchRound: 460000, + CertThreshold: 0.667, + TimeoutSyncThreshold: 2, + TimeoutPeriod: 20, + MinePeriod: 2, + }, } TestnetV2Configs = map[uint64]*V2Config{ diff --git a/params/version.go b/params/version.go index c60b07776e4f..0162660a4c65 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 2 // Major version component of the current release - VersionMinor = 3 // Minor version component of the current release - VersionPatch = 1 // Patch version component of the current release - VersionMeta = "beta1" // Version metadata to append to the version string + VersionMajor = 2 // Major version component of the current release + VersionMinor = 3 // Minor version component of the current release + VersionPatch = 0 // Patch version component of the current release + VersionMeta = "stable" // Version metadata to append to the version string ) // Version holds the textual version string.