Compare commits
8 Commits
v1.1.1-bet
...
v1.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03f7b318d9 | ||
|
|
a3320d6f6e | ||
|
|
504424dc7c | ||
|
|
8d5f2ba90d | ||
|
|
29707b9252 | ||
|
|
6fcce0dce9 | ||
|
|
955c78bde0 | ||
|
|
3bd4e29954 |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,4 +1,16 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.1.1
|
||||||
|
IMPROVEMENT
|
||||||
|
* [\#355](https://github.com/binance-chain/bsc/pull/355) miner should propose block on a proper fork
|
||||||
|
|
||||||
|
BUGFIX
|
||||||
|
* [\#350](https://github.com/binance-chain/bsc/pull/350) flag: fix TriesInmemory specified but not work
|
||||||
|
* [\#358](https://github.com/binance-chain/bsc/pull/358) miner: fix null pending block
|
||||||
|
* [\#360](https://github.com/binance-chain/bsc/pull/360) pruner: fix state bloom sync permission in Windows
|
||||||
|
* [\#366](https://github.com/binance-chain/bsc/pull/366) fix double close channel of subfetcher
|
||||||
|
|
||||||
|
|
||||||
## v1.1.1-beta
|
## v1.1.1-beta
|
||||||
* [\#333](https://github.com/binance-chain/bsc/pull/333) improve block fetcher efficiency
|
* [\#333](https://github.com/binance-chain/bsc/pull/333) improve block fetcher efficiency
|
||||||
* [\#326](https://github.com/binance-chain/bsc/pull/326) eth/tracers: improve tracing performance
|
* [\#326](https://github.com/binance-chain/bsc/pull/326) eth/tracers: improve tracing performance
|
||||||
|
|||||||
@@ -1598,6 +1598,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
|||||||
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
|
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
|
||||||
cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
|
cfg.TrieDirtyCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
if ctx.GlobalIsSet(TriesInMemoryFlag.Name) {
|
||||||
|
cfg.TriesInMemory = ctx.GlobalUint64(TriesInMemoryFlag.Name)
|
||||||
|
}
|
||||||
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheSnapshotFlag.Name) {
|
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheSnapshotFlag.Name) {
|
||||||
cfg.SnapshotCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheSnapshotFlag.Name) / 100
|
cfg.SnapshotCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheSnapshotFlag.Name) / 100
|
||||||
}
|
}
|
||||||
@@ -1924,6 +1927,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
|
|||||||
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
|
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
|
||||||
cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
|
cache.TrieDirtyLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
if ctx.GlobalIsSet(TriesInMemoryFlag.Name) {
|
||||||
|
cache.TriesInMemory = ctx.GlobalUint64(TriesInMemoryFlag.Name)
|
||||||
|
}
|
||||||
vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
|
vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
|
||||||
|
|
||||||
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
|
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
|
||||||
|
|||||||
@@ -140,4 +140,5 @@ type PoSA interface {
|
|||||||
IsSystemTransaction(tx *types.Transaction, header *types.Header) (bool, error)
|
IsSystemTransaction(tx *types.Transaction, header *types.Header) (bool, error)
|
||||||
IsSystemContract(to *common.Address) bool
|
IsSystemContract(to *common.Address) bool
|
||||||
EnoughDistance(chain ChainReader, header *types.Header) bool
|
EnoughDistance(chain ChainReader, header *types.Header) bool
|
||||||
|
IsLocalBlock(header *types.Header) bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -882,6 +882,34 @@ func (p *Parlia) EnoughDistance(chain consensus.ChainReader, header *types.Heade
|
|||||||
return snap.enoughDistance(p.val, header)
|
return snap.enoughDistance(p.val, header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) IsLocalBlock(header *types.Header) bool {
|
||||||
|
return p.val == header.Coinbase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parlia) SignRecently(chain consensus.ChainReader, parent *types.Header) (bool, error) {
|
||||||
|
snap, err := p.snapshot(chain, parent.Number.Uint64(), parent.ParentHash, nil)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bail out if we're unauthorized to sign a block
|
||||||
|
if _, authorized := snap.Validators[p.val]; !authorized {
|
||||||
|
return true, errUnauthorizedValidator
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we're amongst the recent signers, wait for the next block
|
||||||
|
number := parent.Number.Uint64() + 1
|
||||||
|
for seen, recent := range snap.Recents {
|
||||||
|
if recent == p.val {
|
||||||
|
// Signer is among recents, only wait if the current block doesn't shift it out
|
||||||
|
if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
||||||
// that a new block should have based on the previous blocks in the chain and the
|
// that a new block should have based on the previous blocks in the chain and the
|
||||||
// current signer.
|
// current signer.
|
||||||
|
|||||||
@@ -217,6 +217,9 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
|||||||
if cacheConfig == nil {
|
if cacheConfig == nil {
|
||||||
cacheConfig = defaultCacheConfig
|
cacheConfig = defaultCacheConfig
|
||||||
}
|
}
|
||||||
|
if cacheConfig.TriesInMemory != 128 {
|
||||||
|
log.Warn("TriesInMemory isn't the default value(128), you need specify exact same TriesInMemory when prune data", "triesInMemory", cacheConfig.TriesInMemory)
|
||||||
|
}
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
bodyCache, _ := lru.New(bodyCacheLimit)
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
||||||
receiptsCache, _ := lru.New(receiptsCacheLimit)
|
receiptsCache, _ := lru.New(receiptsCacheLimit)
|
||||||
@@ -1578,7 +1581,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||||||
if !reorg && externTd.Cmp(localTd) == 0 {
|
if !reorg && externTd.Cmp(localTd) == 0 {
|
||||||
// Split same-difficulty blocks by number, then preferentially select
|
// Split same-difficulty blocks by number, then preferentially select
|
||||||
// the block generated by the local miner as the canonical block.
|
// the block generated by the local miner as the canonical block.
|
||||||
if block.NumberU64() < currentBlock.NumberU64() {
|
if block.NumberU64() < currentBlock.NumberU64() || block.Time() < currentBlock.Time() {
|
||||||
|
reorg = true
|
||||||
|
} else if p, ok := bc.engine.(consensus.PoSA); ok && p.IsLocalBlock(currentBlock.Header()) {
|
||||||
reorg = true
|
reorg = true
|
||||||
} else if block.NumberU64() == currentBlock.NumberU64() {
|
} else if block.NumberU64() == currentBlock.NumberU64() {
|
||||||
var currentPreserve, blockPreserve bool
|
var currentPreserve, blockPreserve bool
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func (bloom *stateBloom) Commit(filename, tempname string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Ensure the file is synced to disk
|
// Ensure the file is synced to disk
|
||||||
f, err := os.Open(tempname)
|
f, err := os.OpenFile(tempname, os.O_RDWR, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/metrics"
|
"github.com/ethereum/go-ethereum/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const abortChanSize = 64
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// triePrefetchMetricsPrefix is the prefix under which to publis the metrics.
|
// triePrefetchMetricsPrefix is the prefix under which to publis the metrics.
|
||||||
triePrefetchMetricsPrefix = "trie/prefetch/"
|
triePrefetchMetricsPrefix = "trie/prefetch/"
|
||||||
@@ -41,6 +43,9 @@ type triePrefetcher struct {
|
|||||||
fetches map[common.Hash]Trie // Partially or fully fetcher tries
|
fetches map[common.Hash]Trie // Partially or fully fetcher tries
|
||||||
fetchers map[common.Hash]*subfetcher // Subfetchers for each trie
|
fetchers map[common.Hash]*subfetcher // Subfetchers for each trie
|
||||||
|
|
||||||
|
abortChan chan *subfetcher
|
||||||
|
closeChan chan struct{}
|
||||||
|
|
||||||
deliveryMissMeter metrics.Meter
|
deliveryMissMeter metrics.Meter
|
||||||
accountLoadMeter metrics.Meter
|
accountLoadMeter metrics.Meter
|
||||||
accountDupMeter metrics.Meter
|
accountDupMeter metrics.Meter
|
||||||
@@ -59,6 +64,8 @@ func newTriePrefetcher(db Database, root common.Hash, namespace string) *triePre
|
|||||||
db: db,
|
db: db,
|
||||||
root: root,
|
root: root,
|
||||||
fetchers: make(map[common.Hash]*subfetcher), // Active prefetchers use the fetchers map
|
fetchers: make(map[common.Hash]*subfetcher), // Active prefetchers use the fetchers map
|
||||||
|
abortChan: make(chan *subfetcher, abortChanSize),
|
||||||
|
closeChan: make(chan struct{}),
|
||||||
|
|
||||||
deliveryMissMeter: metrics.GetOrRegisterMeter(prefix+"/deliverymiss", nil),
|
deliveryMissMeter: metrics.GetOrRegisterMeter(prefix+"/deliverymiss", nil),
|
||||||
accountLoadMeter: metrics.GetOrRegisterMeter(prefix+"/account/load", nil),
|
accountLoadMeter: metrics.GetOrRegisterMeter(prefix+"/account/load", nil),
|
||||||
@@ -70,14 +77,34 @@ func newTriePrefetcher(db Database, root common.Hash, namespace string) *triePre
|
|||||||
storageSkipMeter: metrics.GetOrRegisterMeter(prefix+"/storage/skip", nil),
|
storageSkipMeter: metrics.GetOrRegisterMeter(prefix+"/storage/skip", nil),
|
||||||
storageWasteMeter: metrics.GetOrRegisterMeter(prefix+"/storage/waste", nil),
|
storageWasteMeter: metrics.GetOrRegisterMeter(prefix+"/storage/waste", nil),
|
||||||
}
|
}
|
||||||
|
go p.abortLoop()
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *triePrefetcher) abortLoop() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case fetcher := <-p.abortChan:
|
||||||
|
fetcher.abort()
|
||||||
|
case <-p.closeChan:
|
||||||
|
// drain fetcher channel
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case fetcher := <-p.abortChan:
|
||||||
|
fetcher.abort()
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// close iterates over all the subfetchers, aborts any that were left spinning
|
// close iterates over all the subfetchers, aborts any that were left spinning
|
||||||
// and reports the stats to the metrics subsystem.
|
// and reports the stats to the metrics subsystem.
|
||||||
func (p *triePrefetcher) close() {
|
func (p *triePrefetcher) close() {
|
||||||
for _, fetcher := range p.fetchers {
|
for _, fetcher := range p.fetchers {
|
||||||
fetcher.abort() // safe to do multiple times
|
p.abortChan <- fetcher // safe to do multiple times
|
||||||
|
|
||||||
if metrics.Enabled {
|
if metrics.Enabled {
|
||||||
if fetcher.root == p.root {
|
if fetcher.root == p.root {
|
||||||
@@ -101,6 +128,7 @@ func (p *triePrefetcher) close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
close(p.closeChan)
|
||||||
// Clear out all fetchers (will crash on a second call, deliberate)
|
// Clear out all fetchers (will crash on a second call, deliberate)
|
||||||
p.fetchers = nil
|
p.fetchers = nil
|
||||||
}
|
}
|
||||||
@@ -174,7 +202,7 @@ func (p *triePrefetcher) trie(root common.Hash) Trie {
|
|||||||
}
|
}
|
||||||
// Interrupt the prefetcher if it's by any chance still running and return
|
// Interrupt the prefetcher if it's by any chance still running and return
|
||||||
// a copy of any pre-loaded trie.
|
// a copy of any pre-loaded trie.
|
||||||
fetcher.abort() // safe to do multiple times
|
p.abortChan <- fetcher // safe to do multiple times
|
||||||
|
|
||||||
trie := fetcher.peek()
|
trie := fetcher.peek()
|
||||||
if trie == nil {
|
if trie == nil {
|
||||||
|
|||||||
@@ -184,8 +184,11 @@ func (miner *Miner) SetRecommitInterval(interval time.Duration) {
|
|||||||
// Pending returns the currently pending block and associated state.
|
// Pending returns the currently pending block and associated state.
|
||||||
func (miner *Miner) Pending() (*types.Block, *state.StateDB) {
|
func (miner *Miner) Pending() (*types.Block, *state.StateDB) {
|
||||||
if miner.worker.isRunning() {
|
if miner.worker.isRunning() {
|
||||||
return miner.worker.pending()
|
pendingBlock, pendingState := miner.worker.pending()
|
||||||
} else {
|
if pendingState != nil && pendingBlock != nil {
|
||||||
|
return pendingBlock, pendingState
|
||||||
|
}
|
||||||
|
}
|
||||||
// fallback to latest block
|
// fallback to latest block
|
||||||
block := miner.worker.chain.CurrentBlock()
|
block := miner.worker.chain.CurrentBlock()
|
||||||
if block == nil {
|
if block == nil {
|
||||||
@@ -197,7 +200,6 @@ func (miner *Miner) Pending() (*types.Block, *state.StateDB) {
|
|||||||
}
|
}
|
||||||
return block, stateDb
|
return block, stateDb
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// PendingBlock returns the currently pending block.
|
// PendingBlock returns the currently pending block.
|
||||||
//
|
//
|
||||||
@@ -206,12 +208,14 @@ func (miner *Miner) Pending() (*types.Block, *state.StateDB) {
|
|||||||
// change between multiple method calls
|
// change between multiple method calls
|
||||||
func (miner *Miner) PendingBlock() *types.Block {
|
func (miner *Miner) PendingBlock() *types.Block {
|
||||||
if miner.worker.isRunning() {
|
if miner.worker.isRunning() {
|
||||||
return miner.worker.pendingBlock()
|
pendingBlock := miner.worker.pendingBlock()
|
||||||
} else {
|
if pendingBlock != nil {
|
||||||
|
return pendingBlock
|
||||||
|
}
|
||||||
|
}
|
||||||
// fallback to latest block
|
// fallback to latest block
|
||||||
return miner.worker.chain.CurrentBlock()
|
return miner.worker.chain.CurrentBlock()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (miner *Miner) SetEtherbase(addr common.Address) {
|
func (miner *Miner) SetEtherbase(addr common.Address) {
|
||||||
miner.coinbase = addr
|
miner.coinbase = addr
|
||||||
|
|||||||
@@ -389,6 +389,17 @@ func (w *worker) newWorkLoop(recommit time.Duration) {
|
|||||||
}
|
}
|
||||||
clearPending(head.Block.NumberU64())
|
clearPending(head.Block.NumberU64())
|
||||||
timestamp = time.Now().Unix()
|
timestamp = time.Now().Unix()
|
||||||
|
if p, ok := w.engine.(*parlia.Parlia); ok {
|
||||||
|
signedRecent, err := p.SignRecently(w.chain, head.Block.Header())
|
||||||
|
if err != nil {
|
||||||
|
log.Info("Not allowed to propose block", "err", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if signedRecent {
|
||||||
|
log.Info("Signed recently, must wait")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
commit(true, commitInterruptNewHead)
|
commit(true, commitInterruptNewHead)
|
||||||
|
|
||||||
case <-timer.C:
|
case <-timer.C:
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const (
|
|||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 1 // Minor version component of the current release
|
VersionMinor = 1 // Minor version component of the current release
|
||||||
VersionPatch = 1 // Patch version component of the current release
|
VersionPatch = 1 // Patch version component of the current release
|
||||||
VersionMeta = "beta" // Version metadata to append to the version string
|
VersionMeta = "" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version holds the textual version string.
|
// Version holds the textual version string.
|
||||||
|
|||||||
Reference in New Issue
Block a user