Skip to content

Commit 2cea410

Browse files
committed
Merge pull request #1282 from obscuren/state-cleanup
core/state: cleanup & optimisations
2 parents 53a6145 + 430bcdb commit 2cea410

File tree

14 files changed

+176
-197
lines changed

14 files changed

+176
-197
lines changed

common/types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
6262
return reflect.ValueOf(h)
6363
}
6464

65+
func EmptyHash(h Hash) bool {
66+
return h == Hash{}
67+
}
68+
6569
/////////// Address
6670
func BytesToAddress(b []byte) Address {
6771
var a Address

core/block_processor.go

Lines changed: 65 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
185185
state := state.New(parent.Root(), sm.db)
186186

187187
// Block validation
188-
if err = sm.ValidateHeader(block.Header(), parent.Header(), false); err != nil {
188+
if err = ValidateHeader(sm.Pow, block.Header(), parent.Header(), false); err != nil {
189189
return
190190
}
191191

@@ -246,12 +246,6 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
246246
return
247247
}
248248

249-
// store the receipts
250-
err = putReceipts(sm.extraDb, block.Hash(), receipts)
251-
if err != nil {
252-
return nil, err
253-
}
254-
255249
// Sync the current block's state to the database
256250
state.Sync()
257251

@@ -260,76 +254,12 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (logs st
260254
putTx(sm.extraDb, tx, block, uint64(i))
261255
}
262256

263-
receiptsRlp := receipts.RlpEncode()
264-
/*if len(receipts) > 0 {
265-
glog.V(logger.Info).Infof("Saving %v receipts, rlp len is %v\n", len(receipts), len(receiptsRlp))
266-
}*/
267-
sm.extraDb.Put(append(receiptsPre, block.Hash().Bytes()...), receiptsRlp)
257+
// store the receipts
258+
putReceipts(sm.extraDb, block.Hash(), receipts)
268259

269260
return state.Logs(), nil
270261
}
271262

272-
// See YP section 4.3.4. "Block Header Validity"
273-
// Validates a block. Returns an error if the block is invalid.
274-
func (sm *BlockProcessor) ValidateHeader(block, parent *types.Header, checkPow bool) error {
275-
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
276-
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
277-
}
278-
279-
expd := CalcDifficulty(block, parent)
280-
if expd.Cmp(block.Difficulty) != 0 {
281-
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
282-
}
283-
284-
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
285-
a.Abs(a)
286-
b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor)
287-
if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) {
288-
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
289-
}
290-
291-
if int64(block.Time) > time.Now().Unix() {
292-
return BlockFutureErr
293-
}
294-
295-
if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 {
296-
return BlockNumberErr
297-
}
298-
299-
if block.Time <= parent.Time {
300-
return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time)
301-
}
302-
303-
if checkPow {
304-
// Verify the nonce of the block. Return an error if it's not valid
305-
if !sm.Pow.Verify(types.NewBlockWithHeader(block)) {
306-
return ValidationError("Block's nonce is invalid (= %x)", block.Nonce)
307-
}
308-
}
309-
310-
return nil
311-
}
312-
313-
func AccumulateRewards(statedb *state.StateDB, block *types.Block) {
314-
reward := new(big.Int).Set(BlockReward)
315-
316-
for _, uncle := range block.Uncles() {
317-
num := new(big.Int).Add(big.NewInt(8), uncle.Number)
318-
num.Sub(num, block.Number())
319-
320-
r := new(big.Int)
321-
r.Mul(BlockReward, num)
322-
r.Div(r, big.NewInt(8))
323-
324-
statedb.AddBalance(uncle.Coinbase, r)
325-
326-
reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
327-
}
328-
329-
// Get the account associated with the coinbase
330-
statedb.AddBalance(block.Header().Coinbase, reward)
331-
}
332-
333263
func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *types.Block) error {
334264
ancestors := set.New()
335265
uncles := set.New()
@@ -367,7 +297,7 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
367297
return UncleError("uncle[%d](%x)'s parent is not ancestor (%x)", i, hash[:4], uncle.ParentHash[0:4])
368298
}
369299

370-
if err := sm.ValidateHeader(uncle, ancestorHeaders[uncle.ParentHash], true); err != nil {
300+
if err := ValidateHeader(sm.Pow, uncle, ancestorHeaders[uncle.ParentHash], true); err != nil {
371301
return ValidationError(fmt.Sprintf("uncle[%d](%x) header invalid: %v", i, hash[:4], err))
372302
}
373303
}
@@ -404,6 +334,67 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro
404334
return state.Logs(), nil
405335
}
406336

337+
// See YP section 4.3.4. "Block Header Validity"
338+
// Validates a block. Returns an error if the block is invalid.
339+
func ValidateHeader(pow pow.PoW, block, parent *types.Header, checkPow bool) error {
340+
if big.NewInt(int64(len(block.Extra))).Cmp(params.MaximumExtraDataSize) == 1 {
341+
return fmt.Errorf("Block extra data too long (%d)", len(block.Extra))
342+
}
343+
344+
expd := CalcDifficulty(block, parent)
345+
if expd.Cmp(block.Difficulty) != 0 {
346+
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd)
347+
}
348+
349+
a := new(big.Int).Sub(block.GasLimit, parent.GasLimit)
350+
a.Abs(a)
351+
b := new(big.Int).Div(parent.GasLimit, params.GasLimitBoundDivisor)
352+
if !(a.Cmp(b) < 0) || (block.GasLimit.Cmp(params.MinGasLimit) == -1) {
353+
return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b)
354+
}
355+
356+
if int64(block.Time) > time.Now().Unix() {
357+
return BlockFutureErr
358+
}
359+
360+
if new(big.Int).Sub(block.Number, parent.Number).Cmp(big.NewInt(1)) != 0 {
361+
return BlockNumberErr
362+
}
363+
364+
if block.Time <= parent.Time {
365+
return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time)
366+
}
367+
368+
if checkPow {
369+
// Verify the nonce of the block. Return an error if it's not valid
370+
if !pow.Verify(types.NewBlockWithHeader(block)) {
371+
return ValidationError("Block's nonce is invalid (= %x)", block.Nonce)
372+
}
373+
}
374+
375+
return nil
376+
}
377+
378+
func AccumulateRewards(statedb *state.StateDB, block *types.Block) {
379+
reward := new(big.Int).Set(BlockReward)
380+
381+
for _, uncle := range block.Uncles() {
382+
num := new(big.Int).Add(big.NewInt(8), uncle.Number)
383+
num.Sub(num, block.Number())
384+
385+
r := new(big.Int)
386+
r.Mul(BlockReward, num)
387+
r.Div(r, big.NewInt(8))
388+
389+
statedb.AddBalance(uncle.Coinbase, r)
390+
391+
reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
392+
}
393+
394+
// Get the account associated with the coinbase
395+
statedb.AddBalance(block.Header().Coinbase, reward)
396+
}
397+
407398
func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) {
408399
var rdata []byte
409400
rdata, err = db.Get(append(receiptsPre, bhash[:]...))

core/block_processor_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,20 @@ func proc() (*BlockProcessor, *ChainManager) {
2626
}
2727

2828
func TestNumber(t *testing.T) {
29-
bp, chain := proc()
29+
_, chain := proc()
3030
block1 := chain.NewBlock(common.Address{})
3131
block1.Header().Number = big.NewInt(3)
3232
block1.Header().Time--
3333

34-
err := bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false)
34+
pow := ezp.New()
35+
36+
err := ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false)
3537
if err != BlockNumberErr {
3638
t.Errorf("expected block number error %v", err)
3739
}
3840

3941
block1 = chain.NewBlock(common.Address{})
40-
err = bp.ValidateHeader(block1.Header(), chain.Genesis().Header(), false)
42+
err = ValidateHeader(pow, block1.Header(), chain.Genesis().Header(), false)
4143
if err == BlockNumberErr {
4244
t.Errorf("didn't expect block number error")
4345
}

core/state/dump.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (self *StateDB) RawDump() World {
3434
account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: common.Bytes2Hex(stateObject.Root()), CodeHash: common.Bytes2Hex(stateObject.codeHash)}
3535
account.Storage = make(map[string]string)
3636

37-
storageIt := stateObject.State.trie.Iterator()
37+
storageIt := stateObject.trie.Iterator()
3838
for storageIt.Next() {
3939
account.Storage[common.Bytes2Hex(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value)
4040
}
@@ -54,8 +54,8 @@ func (self *StateDB) Dump() []byte {
5454

5555
// Debug stuff
5656
func (self *StateObject) CreateOutputForDiff() {
57-
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.nonce)
58-
it := self.State.trie.Iterator()
57+
fmt.Printf("%x %x %x %x\n", self.Address(), self.Root(), self.balance.Bytes(), self.nonce)
58+
it := self.trie.Iterator()
5959
for it.Next() {
6060
fmt.Printf("%x %x\n", it.Key, it.Value)
6161
}

0 commit comments

Comments
 (0)