@ -2,12 +2,10 @@ package ethchain
import (
"bytes"
"math"
"math/big"
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/eth-go/ethwire"
)
var chainlogger = ethlog . NewLogger ( "CHAIN" )
@ -110,99 +108,6 @@ func (bc *BlockChain) CalculateBlockTD(block *Block) *big.Int {
return blockDiff
}
func ( bc * BlockChain ) FindCanonicalChainFromMsg ( msg * ethwire . Msg , commonBlockHash [ ] byte ) bool {
var blocks [ ] * Block
for i := 0 ; i < ( msg . Data . Len ( ) - 1 ) ; i ++ {
block := NewBlockFromRlpValue ( msg . Data . Get ( i ) )
blocks = append ( blocks , block )
}
return bc . FindCanonicalChain ( blocks , commonBlockHash )
}
// Is tasked by finding the CanonicalChain and resetting the chain if we are not the Conical one
// Return true if we are the using the canonical chain false if not
func ( bc * BlockChain ) FindCanonicalChain ( blocks [ ] * Block , commonBlockHash [ ] byte ) bool {
// 1. Calculate TD of the current chain
// 2. Calculate TD of the new chain
// Reset state to the correct one
chainDifficulty := new ( big . Int )
// Calculate the entire chain until the block we both have
// Start with the newest block we got, all the way back to the common block we both know
for _ , block := range blocks {
if bytes . Compare ( block . Hash ( ) , commonBlockHash ) == 0 {
chainlogger . Infoln ( "We have found the common parent block, breaking" )
break
}
chainDifficulty . Add ( chainDifficulty , bc . CalculateBlockTD ( block ) )
}
chainlogger . Infoln ( "Incoming chain difficulty:" , chainDifficulty )
curChainDifficulty := new ( big . Int )
block := bc . CurrentBlock
for i := 0 ; block != nil ; block = bc . GetBlock ( block . PrevHash ) {
i ++
if bytes . Compare ( block . Hash ( ) , commonBlockHash ) == 0 {
chainlogger . Infoln ( "Found the common parent block" )
break
}
anOtherBlock := bc . GetBlock ( block . PrevHash )
if anOtherBlock == nil {
// We do not want to count the genesis block for difficulty since that's not being sent
chainlogger . Infoln ( "Found genesis block. Stop" )
break
}
curChainDifficulty . Add ( curChainDifficulty , bc . CalculateBlockTD ( block ) )
}
chainlogger . Infoln ( "Current chain difficulty:" , curChainDifficulty )
if chainDifficulty . Cmp ( curChainDifficulty ) == 1 {
chainlogger . Infof ( "Resetting to block %x. Changing chain." )
bc . ResetTillBlockHash ( commonBlockHash )
return false
} else {
chainlogger . Infoln ( "Current chain is longest chain. Ignoring incoming chain." )
return true
}
}
func ( bc * BlockChain ) ResetTillBlockHash ( hash [ ] byte ) error {
lastBlock := bc . CurrentBlock
var returnTo * Block
// Reset to Genesis if that's all the origin there is.
if bytes . Compare ( hash , bc . genesisBlock . Hash ( ) ) == 0 {
returnTo = bc . genesisBlock
bc . CurrentBlock = bc . genesisBlock
bc . LastBlockHash = bc . genesisBlock . Hash ( )
bc . LastBlockNumber = 1
} else {
returnTo = bc . GetBlock ( hash )
bc . CurrentBlock = returnTo
bc . LastBlockHash = returnTo . Hash ( )
bc . LastBlockNumber = returnTo . Number . Uint64 ( )
}
// Manually reset the last sync block
err := ethutil . Config . Db . Delete ( lastBlock . Hash ( ) )
if err != nil {
return err
}
var block * Block
for ; block != nil ; block = bc . GetBlock ( block . PrevHash ) {
if bytes . Compare ( block . Hash ( ) , hash ) == 0 {
chainlogger . Infoln ( "We have arrived at the the common parent block, breaking" )
break
}
err = ethutil . Config . Db . Delete ( block . Hash ( ) )
if err != nil {
return err
}
}
chainlogger . Infoln ( "Split chain deleted and reverted to common parent block." )
return nil
}
func ( bc * BlockChain ) GenesisBlock ( ) * Block {
return bc . genesisBlock
@ -228,66 +133,6 @@ func (self *BlockChain) GetChainHashesFromHash(hash []byte, max uint64) (chain [
return
}
// Get chain return blocks from hash up to max in RLP format
func ( bc * BlockChain ) GetChainFromHash ( hash [ ] byte , max uint64 ) [ ] interface { } {
var chain [ ] interface { }
// Get the current hash to start with
currentHash := bc . CurrentBlock . Hash ( )
// Get the last number on the block chain
lastNumber := bc . CurrentBlock . Number . Uint64 ( )
// Get the parents number
parentNumber := bc . GetBlock ( hash ) . Number . Uint64 ( )
// Get the min amount. We might not have max amount of blocks
count := uint64 ( math . Min ( float64 ( lastNumber - parentNumber ) , float64 ( max ) ) )
startNumber := parentNumber + count
num := lastNumber
for num > startNumber {
num --
block := bc . GetBlock ( currentHash )
if block == nil {
break
}
currentHash = block . PrevHash
}
for i := uint64 ( 0 ) ; bytes . Compare ( currentHash , hash ) != 0 && num >= parentNumber && i < count ; i ++ {
// Get the block of the chain
block := bc . GetBlock ( currentHash )
if block == nil {
chainlogger . Debugf ( "Unexpected error during GetChainFromHash: Unable to find %x\n" , currentHash )
break
}
currentHash = block . PrevHash
chain = append ( chain , block . Value ( ) . Val )
num --
}
return chain
}
func ( bc * BlockChain ) GetChain ( hash [ ] byte , amount int ) [ ] * Block {
genHash := bc . genesisBlock . Hash ( )
block := bc . GetBlock ( hash )
var blocks [ ] * Block
for i := 0 ; i < amount && block != nil ; block = bc . GetBlock ( block . PrevHash ) {
blocks = append ( [ ] * Block { block } , blocks ... )
if bytes . Compare ( genHash , block . Hash ( ) ) == 0 {
break
}
i ++
}
return blocks
}
func AddTestNetFunds ( block * Block ) {
for _ , addr := range [ ] string {
"51ba59315b3a95761d0863b05ccc7a7f54703d99" ,