block_manager.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. package core
  2. import (
  3. "bytes"
  4. "container/list"
  5. "errors"
  6. "fmt"
  7. "math/big"
  8. "sync"
  9. "time"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. "github.com/ethereum/go-ethereum/crypto"
  12. "github.com/ethereum/go-ethereum/ethutil"
  13. "github.com/ethereum/go-ethereum/event"
  14. "github.com/ethereum/go-ethereum/logger"
  15. "github.com/ethereum/go-ethereum/state"
  16. "github.com/ethereum/go-ethereum/wire"
  17. )
  18. var statelogger = logger.NewLogger("BLOCK")
  19. type Peer interface {
  20. Inbound() bool
  21. LastSend() time.Time
  22. LastPong() int64
  23. Host() []byte
  24. Port() uint16
  25. Version() string
  26. PingTime() string
  27. Connected() *int32
  28. Caps() *ethutil.Value
  29. }
  30. type EthManager interface {
  31. BlockManager() *BlockManager
  32. ChainManager() *ChainManager
  33. TxPool() *TxPool
  34. Broadcast(msgType wire.MsgType, data []interface{})
  35. PeerCount() int
  36. IsMining() bool
  37. IsListening() bool
  38. Peers() *list.List
  39. KeyManager() *crypto.KeyManager
  40. ClientIdentity() wire.ClientIdentity
  41. Db() ethutil.Database
  42. EventMux() *event.TypeMux
  43. }
  44. type BlockManager struct {
  45. // Mutex for locking the block processor. Blocks can only be handled one at a time
  46. mutex sync.Mutex
  47. // Canonical block chain
  48. bc *ChainManager
  49. // non-persistent key/value memory storage
  50. mem map[string]*big.Int
  51. // Proof of work used for validating
  52. Pow PoW
  53. // The ethereum manager interface
  54. eth EthManager
  55. // The managed states
  56. // Transiently state. The trans state isn't ever saved, validated and
  57. // it could be used for setting account nonces without effecting
  58. // the main states.
  59. transState *state.State
  60. // Mining state. The mining state is used purely and solely by the mining
  61. // operation.
  62. miningState *state.State
  63. // The last attempted block is mainly used for debugging purposes
  64. // This does not have to be a valid block and will be set during
  65. // 'Process' & canonical validation.
  66. lastAttemptedBlock *types.Block
  67. events event.Subscription
  68. }
  69. func NewBlockManager(ethereum EthManager) *BlockManager {
  70. sm := &BlockManager{
  71. mem: make(map[string]*big.Int),
  72. Pow: &EasyPow{},
  73. eth: ethereum,
  74. bc: ethereum.ChainManager(),
  75. }
  76. sm.transState = ethereum.ChainManager().CurrentBlock.State().Copy()
  77. sm.miningState = ethereum.ChainManager().CurrentBlock.State().Copy()
  78. return sm
  79. }
  80. func (self *BlockManager) Start() {
  81. statelogger.Debugln("Starting block manager")
  82. }
  83. func (self *BlockManager) Stop() {
  84. statelogger.Debugln("Stopping state manager")
  85. }
  86. func (sm *BlockManager) CurrentState() *state.State {
  87. return sm.eth.ChainManager().CurrentBlock.State()
  88. }
  89. func (sm *BlockManager) TransState() *state.State {
  90. return sm.transState
  91. }
  92. func (sm *BlockManager) MiningState() *state.State {
  93. return sm.miningState
  94. }
  95. func (sm *BlockManager) NewMiningState() *state.State {
  96. sm.miningState = sm.eth.ChainManager().CurrentBlock.State().Copy()
  97. return sm.miningState
  98. }
  99. func (sm *BlockManager) ChainManager() *ChainManager {
  100. return sm.bc
  101. }
  102. func (sm *BlockManager) TransitionState(statedb *state.State, parent, block *types.Block) (receipts types.Receipts, err error) {
  103. coinbase := statedb.GetOrNewStateObject(block.Coinbase)
  104. coinbase.SetGasPool(block.CalcGasLimit(parent))
  105. // Process the transactions on to current block
  106. receipts, _, _, _, err = sm.ProcessTransactions(coinbase, statedb, block, parent, block.Transactions())
  107. if err != nil {
  108. return nil, err
  109. }
  110. return receipts, nil
  111. }
  112. func (self *BlockManager) ProcessTransactions(coinbase *state.StateObject, state *state.State, block, parent *types.Block, txs types.Transactions) (types.Receipts, types.Transactions, types.Transactions, types.Transactions, error) {
  113. var (
  114. receipts types.Receipts
  115. handled, unhandled types.Transactions
  116. erroneous types.Transactions
  117. totalUsedGas = big.NewInt(0)
  118. err error
  119. cumulativeSum = new(big.Int)
  120. )
  121. done:
  122. for i, tx := range txs {
  123. // If we are mining this block and validating we want to set the logs back to 0
  124. state.EmptyLogs()
  125. txGas := new(big.Int).Set(tx.Gas)
  126. cb := state.GetStateObject(coinbase.Address())
  127. st := NewStateTransition(cb, tx, state, block)
  128. err = st.TransitionState()
  129. if err != nil {
  130. statelogger.Infoln(err)
  131. switch {
  132. case IsNonceErr(err):
  133. err = nil // ignore error
  134. continue
  135. case IsGasLimitErr(err):
  136. unhandled = txs[i:]
  137. break done
  138. default:
  139. statelogger.Infoln(err)
  140. erroneous = append(erroneous, tx)
  141. err = nil
  142. continue
  143. }
  144. }
  145. txGas.Sub(txGas, st.gas)
  146. cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice))
  147. // Update the state with pending changes
  148. state.Update(txGas)
  149. cumulative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, txGas))
  150. receipt := types.NewReceipt(state.Root(), cumulative)
  151. receipt.SetLogs(state.Logs())
  152. receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
  153. // Notify all subscribers
  154. go self.eth.EventMux().Post(TxPostEvent{tx})
  155. receipts = append(receipts, receipt)
  156. handled = append(handled, tx)
  157. if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
  158. state.CreateOutputForDiff()
  159. }
  160. }
  161. block.Reward = cumulativeSum
  162. block.GasUsed = totalUsedGas
  163. return receipts, handled, unhandled, erroneous, err
  164. }
  165. func (sm *BlockManager) Process(block *types.Block) (td *big.Int, msgs state.Messages, err error) {
  166. // Processing a blocks may never happen simultaneously
  167. sm.mutex.Lock()
  168. defer sm.mutex.Unlock()
  169. if sm.bc.HasBlock(block.Hash()) {
  170. return nil, nil, &KnownBlockError{block.Number, block.Hash()}
  171. }
  172. if !sm.bc.HasBlock(block.PrevHash) {
  173. return nil, nil, ParentError(block.PrevHash)
  174. }
  175. parent := sm.bc.GetBlock(block.PrevHash)
  176. return sm.ProcessWithParent(block, parent)
  177. }
  178. func (sm *BlockManager) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
  179. sm.lastAttemptedBlock = block
  180. state := parent.State().Copy()
  181. // Defer the Undo on the Trie. If the block processing happened
  182. // we don't want to undo but since undo only happens on dirty
  183. // nodes this won't happen because Commit would have been called
  184. // before that.
  185. defer state.Reset()
  186. if ethutil.Config.Diff && ethutil.Config.DiffType == "all" {
  187. fmt.Printf("## %x %x ##\n", block.Hash(), block.Number)
  188. }
  189. _, err = sm.TransitionState(state, parent, block)
  190. if err != nil {
  191. return
  192. }
  193. txSha := types.DeriveSha(block.Transactions())
  194. if bytes.Compare(txSha, block.TxSha) != 0 {
  195. err = fmt.Errorf("validating transaction root. received=%x got=%x", block.TxSha, txSha)
  196. return
  197. }
  198. /*
  199. receiptSha := types.DeriveSha(receipts)
  200. if bytes.Compare(receiptSha, block.ReceiptSha) != 0 {
  201. err = fmt.Errorf("validating receipt root. received=%x got=%x", block.ReceiptSha, receiptSha)
  202. return
  203. }
  204. */
  205. // Block validation
  206. if err = sm.ValidateBlock(block, parent); err != nil {
  207. return
  208. }
  209. if err = sm.AccumelateRewards(state, block, parent); err != nil {
  210. return
  211. }
  212. /*
  213. //block.receipts = receipts // although this isn't necessary it be in the future
  214. rbloom := types.CreateBloom(receipts)
  215. if bytes.Compare(rbloom, block.LogsBloom) != 0 {
  216. err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
  217. return
  218. }
  219. */
  220. state.Update(ethutil.Big0)
  221. if !block.State().Cmp(state) {
  222. err = fmt.Errorf("invalid merkle root. received=%x got=%x", block.Root(), state.Root())
  223. return
  224. }
  225. // Calculate the new total difficulty and sync back to the db
  226. if td, ok := sm.CalculateTD(block); ok {
  227. // Sync the current block's state to the database and cancelling out the deferred Undo
  228. state.Sync()
  229. messages := state.Manifest().Messages
  230. state.Manifest().Reset()
  231. chainlogger.Infof("Processed block #%d (%x...)\n", block.Number, block.Hash()[0:4])
  232. sm.transState = state.Copy()
  233. sm.eth.TxPool().RemoveSet(block.Transactions())
  234. return td, messages, nil
  235. } else {
  236. return nil, nil, errors.New("total diff failed")
  237. }
  238. }
  239. func (sm *BlockManager) CalculateTD(block *types.Block) (*big.Int, bool) {
  240. uncleDiff := new(big.Int)
  241. for _, uncle := range block.Uncles {
  242. uncleDiff = uncleDiff.Add(uncleDiff, uncle.Difficulty)
  243. }
  244. // TD(genesis_block) = 0 and TD(B) = TD(B.parent) + sum(u.difficulty for u in B.uncles) + B.difficulty
  245. td := new(big.Int)
  246. td = td.Add(sm.bc.TD, uncleDiff)
  247. td = td.Add(td, block.Difficulty)
  248. // The new TD will only be accepted if the new difficulty is
  249. // is greater than the previous.
  250. if td.Cmp(sm.bc.TD) > 0 {
  251. return td, true
  252. }
  253. return nil, false
  254. }
  255. // Validates the current block. Returns an error if the block was invalid,
  256. // an uncle or anything that isn't on the current block chain.
  257. // Validation validates easy over difficult (dagger takes longer time = difficult)
  258. func (sm *BlockManager) ValidateBlock(block, parent *types.Block) error {
  259. expd := CalcDifficulty(block, parent)
  260. if expd.Cmp(block.Difficulty) < 0 {
  261. return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
  262. }
  263. diff := block.Time - parent.Time
  264. if diff < 0 {
  265. return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time)
  266. }
  267. /* XXX
  268. // New blocks must be within the 15 minute range of the last block.
  269. if diff > int64(15*time.Minute) {
  270. return ValidationError("Block is too far in the future of last block (> 15 minutes)")
  271. }
  272. */
  273. // Verify the nonce of the block. Return an error if it's not valid
  274. if !sm.Pow.Verify(block.HashNoNonce(), block.Difficulty, block.Nonce) {
  275. return ValidationError("Block's nonce is invalid (= %v)", ethutil.Bytes2Hex(block.Nonce))
  276. }
  277. return nil
  278. }
  279. func (sm *BlockManager) AccumelateRewards(statedb *state.State, block, parent *types.Block) error {
  280. reward := new(big.Int).Set(BlockReward)
  281. knownUncles := ethutil.Set(parent.Uncles)
  282. nonces := ethutil.NewSet(block.Nonce)
  283. for _, uncle := range block.Uncles {
  284. if nonces.Include(uncle.Nonce) {
  285. // Error not unique
  286. return UncleError("Uncle not unique")
  287. }
  288. uncleParent := sm.bc.GetBlock(uncle.PrevHash)
  289. if uncleParent == nil {
  290. return UncleError(fmt.Sprintf("Uncle's parent unknown (%x)", uncle.PrevHash[0:4]))
  291. }
  292. if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
  293. return UncleError("Uncle too old")
  294. }
  295. if knownUncles.Include(uncle.Hash()) {
  296. return UncleError("Uncle in chain")
  297. }
  298. nonces.Insert(uncle.Nonce)
  299. r := new(big.Int)
  300. r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
  301. uncleAccount := statedb.GetAccount(uncle.Coinbase)
  302. uncleAccount.AddAmount(r)
  303. reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
  304. }
  305. // Get the account associated with the coinbase
  306. account := statedb.GetAccount(block.Coinbase)
  307. // Reward amount of ether to the coinbase address
  308. account.AddAmount(reward)
  309. statedb.Manifest().AddMessage(&state.Message{
  310. To: block.Coinbase, From: block.Coinbase,
  311. Input: nil,
  312. Origin: nil,
  313. Block: block.Hash(), Timestamp: block.Time, Coinbase: block.Coinbase, Number: block.Number,
  314. Value: new(big.Int).Add(reward, block.Reward),
  315. })
  316. return nil
  317. }
  318. func (sm *BlockManager) GetMessages(block *types.Block) (messages []*state.Message, err error) {
  319. if !sm.bc.HasBlock(block.PrevHash) {
  320. return nil, ParentError(block.PrevHash)
  321. }
  322. sm.lastAttemptedBlock = block
  323. var (
  324. parent = sm.bc.GetBlock(block.PrevHash)
  325. state = parent.State().Copy()
  326. )
  327. defer state.Reset()
  328. sm.TransitionState(state, parent, block)
  329. sm.AccumelateRewards(state, block, parent)
  330. return state.Manifest().Messages, nil
  331. }