MCPcopy Create free account
hub / github.com/CPChain/chain / InsertChain

Method InsertChain

core/blockchain.go:1182–1255  ·  view source on GitHub ↗

InsertChain attempts to insert the given batch of blocks in to the canonical chain or, otherwise, create a fork. If an error is returned it will return the index number of the failing block as well an error describing what went wrong. After insertion is done, all accumulated events will be fired.

(chain types.Blocks)

Source from the content-addressed store, hash-verified

1180//
1181// After insertion is done, all accumulated events will be fired.
1182func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
1183 bc.insertChainProtectLock.Lock()
1184 defer bc.insertChainProtectLock.Unlock()
1185
1186 // do not stop blockchain if the insertion is not finished
1187 bc.wg.Add(1)
1188 defer bc.wg.Done()
1189
1190 if len(chain) == 0 {
1191 return 0, nil
1192 }
1193
1194 var (
1195 last = chain[len(chain)-1].NumberU64()
1196 current = bc.CurrentBlock().NumberU64()
1197 )
1198
1199 // if the last block is already in local chain, return early
1200 if last <= current {
1201 return len(chain), nil
1202 }
1203
1204 // find the first block that is not in local chain
1205 var outset int
1206 for index, block := range chain {
1207 if block.NumberU64() > current {
1208 outset = index
1209 break
1210 }
1211 }
1212
1213 // remove useless prefix
1214 chain = chain[outset:]
1215
1216 if bc.mux != nil {
1217 bc.mux.Post(InsertionStartEvent{})
1218 log.Debug("posted InsertionStartEvent when inserting blocks")
1219
1220 defer func() {
1221 bc.mux.Post(InsertionDoneEvent{})
1222 log.Debug("posted InsertionDoneEvent when inserted blocks")
1223 }()
1224 }
1225
1226 _, headN := bc.KnownHead()
1227
1228 // if the first item in the chain is in range (head-pivot, head), insert one by one.
1229 if headN < configs.DefaultFullSyncPivot || chain[len(chain)-1].NumberU64() > headN-configs.DefaultFullSyncPivot {
1230
1231 rN, rErr := 0, error(nil)
1232
1233 for iter := 0; iter < len(chain); iter++ {
1234 n, events, logs, err := bc.insertChain(chain[iter : iter+1])
1235
1236 rN, rErr = rN+n, err
1237
1238 bc.CommitStateDB()
1239 bc.PostChainEvents(events, logs)

Callers 15

TestHeaderVerificationFunction · 0.95
ExampleGenerateChainFunction · 0.95
benchInsertChainFunction · 0.95
procFutureBlocksMethod · 0.95
procUnknownAncestorsMethod · 0.95
newCanonicalFunction · 0.95
TestChainTxReorgsFunction · 0.95
TestLogReorgsFunction · 0.95
TestReorgSideEventFunction · 0.95
TestTrieForkGCFunction · 0.95
TestLargeReorgTrieGCFunction · 0.95

Calls 10

CurrentBlockMethod · 0.95
KnownHeadMethod · 0.95
insertChainMethod · 0.95
CommitStateDBMethod · 0.95
PostChainEventsMethod · 0.95
LockMethod · 0.80
UnlockMethod · 0.80
NumberU64Method · 0.80
DebugMethod · 0.80
AddMethod · 0.65

Tested by 15

TestHeaderVerificationFunction · 0.76
ExampleGenerateChainFunction · 0.76
benchInsertChainFunction · 0.76
newCanonicalFunction · 0.76
TestChainTxReorgsFunction · 0.76
TestLogReorgsFunction · 0.76
TestReorgSideEventFunction · 0.76
TestTrieForkGCFunction · 0.76
TestLargeReorgTrieGCFunction · 0.76
newBlockchainWithDbFunction · 0.76