@ -144,7 +144,12 @@ func (dl *downloadTester) HasFastBlock(hash common.Hash, number uint64) bool {
func ( dl * downloadTester ) GetHeaderByHash ( hash common . Hash ) * types . Header {
dl . lock . RLock ( )
defer dl . lock . RUnlock ( )
return dl . getHeaderByHash ( hash )
}
// getHeaderByHash returns the header if found either within ancients or own blocks)
// This method assumes that the caller holds at least the read-lock (dl.lock)
func ( dl * downloadTester ) getHeaderByHash ( hash common . Hash ) * types . Header {
header := dl . ancientHeaders [ hash ]
if header != nil {
return header
@ -232,6 +237,13 @@ func (dl *downloadTester) GetTd(hash common.Hash, number uint64) *big.Int {
dl . lock . RLock ( )
defer dl . lock . RUnlock ( )
return dl . getTd ( hash )
}
// getTd retrieves the block's total difficulty if found either within
// ancients or own blocks).
// This method assumes that the caller holds at least the read-lock (dl.lock)
func ( dl * downloadTester ) getTd ( hash common . Hash ) * big . Int {
if td := dl . ancientChainTd [ hash ] ; td != nil {
return td
}
@ -243,8 +255,8 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
dl . lock . Lock ( )
defer dl . lock . Unlock ( )
// Do a quick check, as the blockchain.InsertHeaderChain doesn't insert anything in case of errors
if _ , ok := dl . ownHeaders [ headers [ 0 ] . ParentHash ] ; ! ok {
return 0 , errors . New ( "InsertHeaderChain: unknown parent at first position" )
if dl . getHeaderByHash ( headers [ 0 ] . ParentHash ) == nil {
return 0 , fmt . Errorf ( "InsertHeaderChain: unknown parent at first position, parent of number %d " , headers [ 0 ] . Number )
}
var hashes [ ] common . Hash
for i := 1 ; i < len ( headers ) ; i ++ {
@ -258,16 +270,18 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
// Do a full insert if pre-checks passed
for i , header := range headers {
hash := hashes [ i ]
if _ , ok := dl . ownHeaders [ hash ] ; ok {
if dl . getHeaderByHash ( hash ) != nil {
continue
}
if _ , ok := dl . ownHeaders [ header . ParentHash ] ; ! ok {
if dl . getHeaderByHash ( header . ParentHash ) == nil {
// This _should_ be impossible, due to precheck and induction
return i , fmt . Errorf ( "InsertHeaderChain: unknown parent at position %d" , i )
}
dl . ownHashes = append ( dl . ownHashes , hash )
dl . ownHeaders [ hash ] = header
dl . ownChainTd [ hash ] = new ( big . Int ) . Add ( dl . ownChainTd [ header . ParentHash ] , header . Difficulty )
td := dl . getTd ( header . ParentHash )
dl . ownChainTd [ hash ] = new ( big . Int ) . Add ( td , header . Difficulty )
}
return len ( headers ) , nil
}
@ -276,7 +290,6 @@ func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq i
func ( dl * downloadTester ) InsertChain ( blocks types . Blocks ) ( i int , err error ) {
dl . lock . Lock ( )
defer dl . lock . Unlock ( )
for i , block := range blocks {
if parent , ok := dl . ownBlocks [ block . ParentHash ( ) ] ; ! ok {
return i , fmt . Errorf ( "InsertChain: unknown parent at position %d / %d" , i , len ( blocks ) )
@ -290,7 +303,9 @@ func (dl *downloadTester) InsertChain(blocks types.Blocks) (i int, err error) {
dl . ownBlocks [ block . Hash ( ) ] = block
dl . ownReceipts [ block . Hash ( ) ] = make ( types . Receipts , 0 )
dl . stateDb . Put ( block . Root ( ) . Bytes ( ) , [ ] byte { 0x00 } )
dl . ownChainTd [ block . Hash ( ) ] = new ( big . Int ) . Add ( dl . ownChainTd [ block . ParentHash ( ) ] , block . Difficulty ( ) )
td := dl . getTd ( block . ParentHash ( ) )
dl . ownChainTd [ block . Hash ( ) ] = new ( big . Int ) . Add ( td , block . Difficulty ( ) )
}
return len ( blocks ) , nil
}
@ -316,7 +331,6 @@ func (dl *downloadTester) InsertReceiptChain(blocks types.Blocks, receipts []typ
// Migrate from active db to ancient db
dl . ancientHeaders [ blocks [ i ] . Hash ( ) ] = blocks [ i ] . Header ( )
dl . ancientChainTd [ blocks [ i ] . Hash ( ) ] = new ( big . Int ) . Add ( dl . ancientChainTd [ blocks [ i ] . ParentHash ( ) ] , blocks [ i ] . Difficulty ( ) )
delete ( dl . ownHeaders , blocks [ i ] . Hash ( ) )
delete ( dl . ownChainTd , blocks [ i ] . Hash ( ) )
} else {