Skip to content

Commit 1aaab76

Browse files
committed
verify task get difflayer cache synchronously
Signed-off-by: kyrie-yl <[email protected]>
1 parent 7b070c0 commit 1aaab76

File tree

3 files changed

+64
-30
lines changed

3 files changed

+64
-30
lines changed

core/block_validator.go

-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"github.com/ethereum/go-ethereum/consensus"
2424
"github.com/ethereum/go-ethereum/core/state"
2525
"github.com/ethereum/go-ethereum/core/types"
26-
"github.com/ethereum/go-ethereum/log"
2726
"github.com/ethereum/go-ethereum/params"
2827
"github.com/ethereum/go-ethereum/trie"
2928
)
@@ -49,7 +48,6 @@ func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engin
4948
bc: blockchain,
5049
}
5150
if mode.NeedRemoteVerify() {
52-
log.Info("this node is a fast node with remote state verifier.")
5351
validator.remoteValidator = NewVerifyManager(blockchain, peers, mode == InsecureVerify)
5452
go validator.remoteValidator.mainLoop()
5553
}
@@ -92,13 +90,6 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
9290
}
9391
return nil
9492
},
95-
// for fast node which verify trie from remote verify peers, a block's H-11 ancestor should have been verify.
96-
func() error {
97-
if v.remoteValidator != nil && !v.remoteValidator.AncestorVerified(header) {
98-
return fmt.Errorf("block's ancessor %x has not been verified", block.Hash())
99-
}
100-
return nil
101-
},
10293
}
10394
validateRes := make(chan error, len(validateFuns))
10495
for _, f := range validateFuns {

core/blockchain.go

+28-1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ type BlockChain struct {
203203
chainFeed event.Feed
204204
chainSideFeed event.Feed
205205
chainHeadFeed event.Feed
206+
chainBlockFeed event.Feed
206207
logsFeed event.Feed
207208
blockProcFeed event.Feed
208209
scope event.SubscriptionScope
@@ -226,6 +227,7 @@ type BlockChain struct {
226227
// trusted diff layers
227228
diffLayerCache *lru.Cache // Cache for the diffLayers
228229
diffLayerRLPCache *lru.Cache // Cache for the rlp encoded diffLayers
230+
diffLayerChanCache *lru.Cache // Cache for
229231
diffQueue *prque.Prque // A Priority queue to store recent diff layer
230232
diffQueueBuffer chan *types.DiffLayer
231233
diffLayerFreezerBlockLimit uint64
@@ -277,6 +279,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
277279
futureBlocks, _ := lru.New(maxFutureBlocks)
278280
diffLayerCache, _ := lru.New(diffLayerCacheLimit)
279281
diffLayerRLPCache, _ := lru.New(diffLayerRLPCacheLimit)
282+
diffLayerChanCache, _ := lru.New(diffLayerCacheLimit)
280283

281284
bc := &BlockChain{
282285
chainConfig: chainConfig,
@@ -299,6 +302,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
299302
badBlockCache: badBlockCache,
300303
diffLayerCache: diffLayerCache,
301304
diffLayerRLPCache: diffLayerRLPCache,
305+
diffLayerChanCache: diffLayerChanCache,
302306
txLookupCache: txLookupCache,
303307
futureBlocks: futureBlocks,
304308
engine: engine,
@@ -520,7 +524,13 @@ func (bc *BlockChain) cacheDiffLayer(diffLayer *types.DiffLayer, sorted bool) {
520524
if bc.diffLayerCache.Len() >= diffLayerCacheLimit {
521525
bc.diffLayerCache.RemoveOldest()
522526
}
527+
528+
//json.MarshalIndent()
523529
bc.diffLayerCache.Add(diffLayer.BlockHash, diffLayer)
530+
if cached, ok := bc.diffLayerChanCache.Get(diffLayer.BlockHash); ok {
531+
diffLayerCh := cached.(chan struct{})
532+
close(diffLayerCh)
533+
}
524534
if bc.db.DiffStore() != nil {
525535
// push to priority queue before persisting
526536
bc.diffQueueBuffer <- diffLayer
@@ -1816,6 +1826,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
18161826
diffLayer.BlockHash = block.Hash()
18171827
diffLayer.Number = block.NumberU64()
18181828

1829+
diffLayerCh := make(chan struct{})
1830+
bc.diffLayerChanCache.Add(diffLayer.BlockHash, diffLayerCh)
1831+
18191832
go bc.cacheDiffLayer(diffLayer, false)
18201833
}
18211834

@@ -2072,6 +2085,15 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
20722085
}()
20732086

20742087
for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() {
2088+
if bc.validator.RemoteVerifyManager() != nil {
2089+
for !bc.Validator().RemoteVerifyManager().AncestorVerified(block.Header()) {
2090+
if bc.insertStopped() {
2091+
break
2092+
}
2093+
log.Info("block ancestor has not been verified", "number", block.Number(), "hash", block.Hash())
2094+
time.Sleep(100 * time.Millisecond)
2095+
}
2096+
}
20752097
// If the chain is terminating, stop processing blocks
20762098
if bc.insertStopped() {
20772099
log.Debug("Abort during block processing")
@@ -2231,6 +2253,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
22312253
stats.processed++
22322254
stats.usedGas += usedGas
22332255

2256+
bc.chainBlockFeed.Send(ChainHeadEvent{block})
22342257
dirty, _ := bc.stateCache.TrieDB().Size()
22352258
stats.report(chain, it.index, dirty)
22362259
}
@@ -3101,6 +3124,10 @@ func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Su
31013124
return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
31023125
}
31033126

3127+
func (bc *BlockChain) SubscribeChainBlockEvent(ch chan<- ChainHeadEvent) event.Subscription {
3128+
return bc.scope.Track(bc.chainBlockFeed.Subscribe(ch))
3129+
}
3130+
31043131
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
31053132
func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
31063133
return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
@@ -3278,7 +3305,7 @@ func CalculateDiffHash(d *types.DiffLayer) (common.Hash, error) {
32783305
BlockHash: d.BlockHash,
32793306
Receipts: make([]*types.ReceiptForStorage, 0),
32803307
Number: d.Number,
3281-
Codes: d.Codes,
3308+
//Codes: d.Codes,
32823309
Destructs: d.Destructs,
32833310
Accounts: d.Accounts,
32843311
Storages: d.Storages,

core/remote_state_verifier.go

+36-20
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type remoteVerifyManager struct {
4545
allowInsecure bool
4646

4747
// Subscription
48-
chainHeadCh chan ChainHeadEvent
48+
chainBlockCh chan ChainHeadEvent
4949
chainHeadSub event.Subscription
5050

5151
// Channels
@@ -62,11 +62,11 @@ func NewVerifyManager(blockchain *BlockChain, peers verifyPeers, allowInsecure b
6262
verifiedCache: verifiedCache,
6363
allowInsecure: allowInsecure,
6464

65-
chainHeadCh: make(chan ChainHeadEvent, chainHeadChanSize),
65+
chainBlockCh: make(chan ChainHeadEvent, chainHeadChanSize),
6666
verifyCh: make(chan common.Hash, maxForkHeight),
6767
messageCh: make(chan verifyMessage),
6868
}
69-
vm.chainHeadSub = blockchain.SubscribeChainHeadEvent(vm.chainHeadCh)
69+
vm.chainHeadSub = blockchain.SubscribeChainBlockEvent(vm.chainBlockCh)
7070
return vm
7171
}
7272

@@ -81,7 +81,7 @@ func (vm *remoteVerifyManager) mainLoop() {
8181
defer pruneTicker.Stop()
8282
for {
8383
select {
84-
case h := <-vm.chainHeadCh:
84+
case h := <-vm.chainBlockCh:
8585
vm.NewBlockVerifyTask(h.Block.Header())
8686
case hash := <-vm.verifyCh:
8787
vm.cacheBlockVerified(hash)
@@ -121,6 +121,11 @@ func (vm *remoteVerifyManager) mainLoop() {
121121

122122
func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) {
123123
for i := 0; header != nil && i <= maxForkHeight; i++ {
124+
// if is genesis block, mark it as verified and break.
125+
if header.Number.Uint64() == 0 {
126+
vm.cacheBlockVerified(header.Hash())
127+
break
128+
}
124129
func(hash common.Hash) {
125130
// if verified cache record that this block has been verified, skip.
126131
if _, ok := vm.verifiedCache.Get(hash); ok {
@@ -130,17 +135,32 @@ func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) {
130135
if _, ok := vm.tasks[hash]; ok {
131136
return
132137
}
133-
diffLayer := vm.bc.GetTrustedDiffLayer(hash)
138+
139+
if header.TxHash == types.EmptyRootHash {
140+
log.Debug("this is an empty block:", "block", hash, "number", header.Number)
141+
vm.cacheBlockVerified(hash)
142+
return
143+
}
144+
145+
var diffLayer *types.DiffLayer
146+
if cached, ok := vm.bc.diffLayerChanCache.Get(hash); ok {
147+
diffLayerCh := cached.(chan struct{})
148+
<-diffLayerCh
149+
vm.bc.diffLayerChanCache.Remove(hash)
150+
diffLayer = vm.bc.GetTrustedDiffLayer(hash)
151+
}
134152
// if this block has no diff, there is no need to verify it.
135153
var err error
136154
if diffLayer == nil {
137-
if diffLayer, err = vm.bc.GenerateDiffLayer(hash); err != nil {
138-
log.Error("failed to get diff layer", "block", hash, "number", header.Number, "error", err)
139-
return
140-
} else if diffLayer == nil {
141-
log.Info("this is an empty block:", "block", hash, "number", header.Number)
142-
return
143-
}
155+
log.Info("block's trusted diffLayer is nil", "hash", hash, "number", header.Number)
156+
//if diffLayer, err = vm.bc.GenerateDiffLayer(hash); err != nil {
157+
// log.Error("failed to get diff layer", "block", hash, "number", header.Number, "error", err)
158+
// return
159+
//} else if diffLayer == nil {
160+
// log.Info("this is an empty block:", "block", hash, "number", header.Number)
161+
// vm.cacheBlockVerified(hash)
162+
// return
163+
//}
144164
}
145165
diffHash, err := CalculateDiffHash(diffLayer)
146166
if err != nil {
@@ -170,11 +190,7 @@ func (vm *remoteVerifyManager) AncestorVerified(header *types.Header) bool {
170190
if header == nil {
171191
return true
172192
}
173-
// check whether H-11 block is a empty block.
174-
if header.TxHash == types.EmptyRootHash {
175-
parent := vm.bc.GetHeaderByHash(header.ParentHash)
176-
return parent == nil || header.Root == parent.Root
177-
}
193+
178194
hash := header.Hash()
179195
_, exist := vm.verifiedCache.Get(hash)
180196
return exist
@@ -203,7 +219,7 @@ type verifyTask struct {
203219
candidatePeers verifyPeers
204220
badPeers map[string]struct{}
205221
startAt time.Time
206-
allowInsecure bool
222+
allowInsecure bool
207223

208224
messageCh chan verifyMessage
209225
terminalCh chan struct{}
@@ -236,13 +252,13 @@ func (vt *verifyTask) Start(verifyCh chan common.Hash) {
236252
case types.StatusFullVerified:
237253
vt.compareRootHashAndMark(msg, verifyCh)
238254
case types.StatusPartiallyVerified:
239-
log.Warn("block %s , num= %s is insecure verified", msg.verifyResult.BlockHash, msg.verifyResult.BlockNumber)
255+
log.Warn("block is insecure verified", "hash", msg.verifyResult.BlockHash, "number", msg.verifyResult.BlockNumber)
240256
if vt.allowInsecure {
241257
vt.compareRootHashAndMark(msg, verifyCh)
242258
}
243259
case types.StatusDiffHashMismatch, types.StatusImpossibleFork, types.StatusUnexpectedError:
244260
vt.badPeers[msg.peerId] = struct{}{}
245-
log.Info("peer %s is not available: code %d, msg %s,", msg.peerId, msg.verifyResult.Status.Code, msg.verifyResult.Status.Msg)
261+
log.Info("peer is not available", "hash", msg.verifyResult.BlockHash, "number", msg.verifyResult.BlockNumber, "peer", msg.peerId, "reason", msg.verifyResult.Status.Msg)
246262
case types.StatusBlockTooNew, types.StatusBlockNewer, types.StatusPossibleFork:
247263
log.Info("return msg from peer %s for block %s is %s", msg.peerId, msg.verifyResult.BlockHash, msg.verifyResult.Status.Msg)
248264
}

0 commit comments

Comments
 (0)