Skip to content

Commit b3a701d

Browse files
committed
refactor block remote validation code
1 parent f8c6a4a commit b3a701d

File tree

5 files changed

+40
-11
lines changed

5 files changed

+40
-11
lines changed

core/block_validator.go

+7
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,13 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
9494
}
9595
return nil
9696
},
97+
func() error {
98+
if v.remoteValidator != nil && !v.remoteValidator.AncestorVerified(block.Header()) {
99+
return fmt.Errorf("%w, number: %s, hash: %s", ErrAncestorHasNotBeenVerified, block.Number(), block.Hash())
100+
}
101+
102+
return nil
103+
},
97104
}
98105
validateRes := make(chan error, len(validateFuns))
99106
for _, f := range validateFuns {

core/blockchain.go

-9
Original file line numberDiff line numberDiff line change
@@ -2092,15 +2092,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, er
20922092
}()
20932093

20942094
for ; block != nil && err == nil || err == ErrKnownBlock; block, err = it.next() {
2095-
if bc.validator.RemoteVerifyManager() != nil {
2096-
for !bc.Validator().RemoteVerifyManager().AncestorVerified(block.Header()) {
2097-
if bc.insertStopped() {
2098-
break
2099-
}
2100-
log.Info("block ancestor has not been verified", "number", block.Number(), "hash", block.Hash())
2101-
time.Sleep(100 * time.Millisecond)
2102-
}
2103-
}
21042095
// If the chain is terminating, stop processing blocks
21052096
if bc.insertStopped() {
21062097
log.Debug("Abort during block processing")

core/error.go

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ var (
3535
// ErrDiffLayerNotFound is returned when diff layer not found.
3636
ErrDiffLayerNotFound = errors.New("diff layer not found")
3737

38+
// ErrDiffLayerNotFound is returned when block - 11 has not been verified by the remote verifier.
39+
ErrAncestorHasNotBeenVerified = errors.New("block ancestor has not been verified")
40+
3841
// ErrCurrentBlockNotFound is returned when current block not found.
3942
ErrCurrentBlockNotFound = errors.New("current block not found")
4043

core/remote_state_verifier.go

+26-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"math/big"
66
"math/rand"
7+
"sync"
78
"time"
89

910
lru "github.com/hashicorp/golang-lru"
@@ -40,6 +41,7 @@ var (
4041

4142
type remoteVerifyManager struct {
4243
bc *BlockChain
44+
taskLock sync.RWMutex
4345
tasks map[common.Hash]*verifyTask
4446
peers verifyPeers
4547
verifiedCache *lru.Cache
@@ -109,14 +111,17 @@ func (vm *remoteVerifyManager) mainLoop() {
109111
vm.NewBlockVerifyTask(h.Block.Header())
110112
case hash := <-vm.verifyCh:
111113
vm.cacheBlockVerified(hash)
114+
vm.taskLock.Lock()
112115
if task, ok := vm.tasks[hash]; ok {
113116
delete(vm.tasks, hash)
114117
verifyTaskCounter.Dec(1)
115118
verifyTaskSucceedMeter.Mark(1)
116119
verifyTaskExecutionTimer.Update(time.Since(task.startAt))
117120
close(task.terminalCh)
118121
}
122+
vm.taskLock.Unlock()
119123
case <-pruneTicker.C:
124+
vm.taskLock.Lock()
120125
for hash, task := range vm.tasks {
121126
if vm.bc.CurrentHeader().Number.Cmp(task.blockHeader.Number) == 1 &&
122127
vm.bc.CurrentHeader().Number.Uint64()-task.blockHeader.Number.Uint64() > pruneHeightDiff {
@@ -126,16 +131,21 @@ func (vm *remoteVerifyManager) mainLoop() {
126131
close(task.terminalCh)
127132
}
128133
}
134+
vm.taskLock.Unlock()
129135
case message := <-vm.messageCh:
136+
vm.taskLock.RLock()
130137
if vt, ok := vm.tasks[message.verifyResult.BlockHash]; ok {
131138
vt.messageCh <- message
132139
}
140+
vm.taskLock.RUnlock()
133141

134142
// System stopped
135143
case <-vm.bc.quit:
144+
vm.taskLock.RLock()
136145
for _, task := range vm.tasks {
137146
close(task.terminalCh)
138147
}
148+
vm.taskLock.RUnlock()
139149
return
140150
case <-vm.chainHeadSub.Err():
141151
return
@@ -156,7 +166,10 @@ func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) {
156166
return
157167
}
158168
// if there already has a verify task for this block, skip.
159-
if _, ok := vm.tasks[hash]; ok {
169+
vm.taskLock.RLock()
170+
_, ok := vm.tasks[hash]
171+
vm.taskLock.RUnlock()
172+
if ok {
160173
return
161174
}
162175

@@ -184,7 +197,9 @@ func (vm *remoteVerifyManager) NewBlockVerifyTask(header *types.Header) {
184197
return
185198
}
186199
verifyTask := NewVerifyTask(diffHash, header, vm.peers, vm.verifyCh, vm.allowInsecure)
200+
vm.taskLock.Lock()
187201
vm.tasks[hash] = verifyTask
202+
vm.taskLock.Unlock()
188203
verifyTaskCounter.Inc(1)
189204
}(header.Hash())
190205
header = vm.bc.GetHeaderByHash(header.ParentHash)
@@ -208,7 +223,16 @@ func (vm *remoteVerifyManager) AncestorVerified(header *types.Header) bool {
208223
}
209224

210225
hash := header.Hash()
211-
_, exist := vm.verifiedCache.Get(hash)
226+
227+
// Check if the task is complete
228+
vm.taskLock.RLock()
229+
task, exist := vm.tasks[hash]
230+
vm.taskLock.RUnlock()
231+
if exist {
232+
<-task.terminalCh
233+
}
234+
235+
_, exist = vm.verifiedCache.Get(hash)
212236
return exist
213237
}
214238

eth/downloader/downloader.go

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727

2828
"github.com/ethereum/go-ethereum"
2929
"github.com/ethereum/go-ethereum/common"
30+
"github.com/ethereum/go-ethereum/core"
3031
"github.com/ethereum/go-ethereum/core/rawdb"
3132
"github.com/ethereum/go-ethereum/core/state/snapshot"
3233
"github.com/ethereum/go-ethereum/core/types"
@@ -1812,6 +1813,9 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
18121813
// of the blocks delivered from the downloader, and the indexing will be off.
18131814
log.Debug("Downloaded item processing failed on sidechain import", "index", index, "err", err)
18141815
}
1816+
if errors.Is(err, core.ErrAncestorHasNotBeenVerified) {
1817+
return err
1818+
}
18151819
return fmt.Errorf("%w: %v", errInvalidChain, err)
18161820
}
18171821
return nil

0 commit comments

Comments
 (0)