Added chain tests & minor fixes

* Fork tests (equal and larger chains)
* `chain.link` fields are now exported
* moved debug function from state to dump.go
This commit is contained in:
obscuren 2014-11-19 12:25:52 +01:00
parent 437d79f094
commit 14e2e488fd
6 changed files with 2751 additions and 740 deletions

@ -191,8 +191,8 @@ func (self *ChainManager) GetBlock(hash []byte) *types.Block {
if self.workingChain != nil { if self.workingChain != nil {
// Check the temp chain // Check the temp chain
for e := self.workingChain.Front(); e != nil; e = e.Next() { for e := self.workingChain.Front(); e != nil; e = e.Next() {
if bytes.Compare(e.Value.(*link).block.Hash(), hash) == 0 { if bytes.Compare(e.Value.(*link).Block.Hash(), hash) == 0 {
return e.Value.(*link).block return e.Value.(*link).Block
} }
} }
} }
@ -275,15 +275,15 @@ func (self *ChainManager) InsertChain(chain *BlockChain, call func(*types.Block,
for e := chain.Front(); e != nil; e = e.Next() { for e := chain.Front(); e != nil; e = e.Next() {
link := e.Value.(*link) link := e.Value.(*link)
self.add(link.block) self.add(link.Block)
self.SetTotalDifficulty(link.td) self.SetTotalDifficulty(link.Td)
call(link.block, link.messages) call(link.Block, link.Messages)
} }
b, e := chain.Front(), chain.Back() b, e := chain.Front(), chain.Back()
if b != nil && e != nil { if b != nil && e != nil {
front, back := b.Value.(*link).block, e.Value.(*link).block front, back := b.Value.(*link).Block, e.Value.(*link).Block
chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4]) chainlogger.Infof("Imported %d blocks. #%v (%x) / %#v (%x)", chain.Len(), front.Number, front.Hash()[0:4], back.Number, back.Hash()[0:4])
} }
} }
@ -295,7 +295,7 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
for e := chain.Front(); e != nil; e = e.Next() { for e := chain.Front(); e != nil; e = e.Next() {
var ( var (
l = e.Value.(*link) l = e.Value.(*link)
block = l.block block = l.Block
parent = self.GetBlock(block.PrevHash) parent = self.GetBlock(block.PrevHash)
) )
@ -314,8 +314,8 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
err = fmt.Errorf("incoming chain failed %v\n", err) err = fmt.Errorf("incoming chain failed %v\n", err)
return return
} }
l.td = td l.Td = td
l.messages = messages l.Messages = messages
} }
if td.Cmp(self.TD) <= 0 { if td.Cmp(self.TD) <= 0 {
@ -329,9 +329,9 @@ func (self *ChainManager) TestChain(chain *BlockChain) (td *big.Int, err error)
} }
type link struct { type link struct {
block *types.Block Block *types.Block
messages state.Messages Messages state.Messages
td *big.Int Td *big.Int
} }
type BlockChain struct { type BlockChain struct {
@ -351,7 +351,7 @@ func NewChain(blocks types.Blocks) *BlockChain {
func (self *BlockChain) RlpEncode() []byte { func (self *BlockChain) RlpEncode() []byte {
dat := make([]interface{}, 0) dat := make([]interface{}, 0)
for e := self.Front(); e != nil; e = e.Next() { for e := self.Front(); e != nil; e = e.Next() {
dat = append(dat, e.Value.(*link).block.RlpData()) dat = append(dat, e.Value.(*link).Block.RlpData())
} }
return ethutil.Encode(dat) return ethutil.Encode(dat)

@ -1 +1,116 @@
package chain package chain
import (
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/chain/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
)
var TD *big.Int
func init() {
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db, _ = ethdb.NewMemDatabase()
}
type fakeproc struct {
}
func (self fakeproc) ProcessWithParent(a, b *types.Block) (*big.Int, state.Messages, error) {
TD = new(big.Int).Add(TD, big.NewInt(1))
return TD, nil, nil
}
func makechain(cman *ChainManager, max int) *BlockChain {
blocks := make(types.Blocks, max)
for i := 0; i < max; i++ {
addr := ethutil.LeftPadBytes([]byte{byte(i)}, 20)
block := cman.NewBlock(addr)
if i != 0 {
cman.CurrentBlock = blocks[i-1]
}
blocks[i] = block
}
return NewChain(blocks)
}
func TestLongerFork(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chainA := makechain(cman, 5)
TD = big.NewInt(1)
chainB := makechain(cman, 10)
td, err := cman.TestChain(chainA)
if err != nil {
t.Error("unable to create new TD from chainA:", err)
}
cman.TD = td
_, err = cman.TestChain(chainB)
if err != nil {
t.Error("expected chainB not to give errors:", err)
}
}
func TestEqualFork(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chainA := makechain(cman, 5)
TD = big.NewInt(2)
chainB := makechain(cman, 5)
td, err := cman.TestChain(chainA)
if err != nil {
t.Error("unable to create new TD from chainA:", err)
}
cman.TD = td
_, err = cman.TestChain(chainB)
if err != nil {
t.Error("expected chainB not to give errors:", err)
}
}
func TestBrokenChain(t *testing.T) {
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chain := makechain(cman, 5)
chain.Remove(chain.Front())
_, err := cman.TestChain(chain)
if err == nil {
t.Error("expected broken chain to return error")
}
}
func BenchmarkChainTesting(b *testing.B) {
const chainlen = 1000
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db, _ = ethdb.NewMemDatabase()
cman := NewChainManager()
cman.SetProcessor(fakeproc{})
TD = big.NewInt(1)
chain := makechain(cman, chainlen)
stime := time.Now()
cman.TestChain(chain)
fmt.Println(chainlen, "took", time.Since(stime))
}

@ -1,40 +0,0 @@
mode: count
github.com/ethereum/go-ethereum/event/event.go:41.66,45.17 4 1005
github.com/ethereum/go-ethereum/event/event.go:63.2,63.12 1 1004
github.com/ethereum/go-ethereum/event/event.go:45.17,47.3 1 1
github.com/ethereum/go-ethereum/event/event.go:47.3,48.22 1 1004
github.com/ethereum/go-ethereum/event/event.go:51.3,51.27 1 1004
github.com/ethereum/go-ethereum/event/event.go:48.22,50.4 1 5
github.com/ethereum/go-ethereum/event/event.go:51.27,54.32 3 1006
github.com/ethereum/go-ethereum/event/event.go:57.4,60.25 4 1005
github.com/ethereum/go-ethereum/event/event.go:54.32,56.5 1 1
github.com/ethereum/go-ethereum/event/event.go:68.48,71.17 3 3513
github.com/ethereum/go-ethereum/event/event.go:75.2,77.27 3 3511
github.com/ethereum/go-ethereum/event/event.go:80.2,80.12 1 3509
github.com/ethereum/go-ethereum/event/event.go:71.17,74.3 2 2
github.com/ethereum/go-ethereum/event/event.go:77.27,79.3 1 2576
github.com/ethereum/go-ethereum/event/event.go:86.28,88.32 2 5
github.com/ethereum/go-ethereum/event/event.go:93.2,95.20 3 5
github.com/ethereum/go-ethereum/event/event.go:88.32,89.28 1 3
github.com/ethereum/go-ethereum/event/event.go:89.28,91.4 1 3
github.com/ethereum/go-ethereum/event/event.go:98.36,100.34 2 1001
github.com/ethereum/go-ethereum/event/event.go:109.2,109.22 1 1001
github.com/ethereum/go-ethereum/event/event.go:100.34,101.37 1 1001
github.com/ethereum/go-ethereum/event/event.go:101.37,102.22 1 1001
github.com/ethereum/go-ethereum/event/event.go:102.22,104.5 1 2
github.com/ethereum/go-ethereum/event/event.go:104.5,106.5 1 999
github.com/ethereum/go-ethereum/event/event.go:112.46,113.26 1 2007
github.com/ethereum/go-ethereum/event/event.go:118.2,118.11 1 1005
github.com/ethereum/go-ethereum/event/event.go:113.26,114.16 1 181499
github.com/ethereum/go-ethereum/event/event.go:114.16,116.4 1 1002
github.com/ethereum/go-ethereum/event/event.go:121.52,126.2 4 999
github.com/ethereum/go-ethereum/event/event.go:142.35,150.2 2 1005
github.com/ethereum/go-ethereum/event/event.go:152.44,154.2 1 1003
github.com/ethereum/go-ethereum/event/event.go:156.32,159.2 2 1001
github.com/ethereum/go-ethereum/event/event.go:161.30,164.14 3 1004
github.com/ethereum/go-ethereum/event/event.go:167.2,173.19 6 1003
github.com/ethereum/go-ethereum/event/event.go:164.14,166.3 1 1
github.com/ethereum/go-ethereum/event/event.go:176.42,178.9 2 2575
github.com/ethereum/go-ethereum/event/event.go:182.2,182.20 1 2575
github.com/ethereum/go-ethereum/event/event.go:179.2,179.21 0 1004
github.com/ethereum/go-ethereum/event/event.go:180.2,180.19 0 1571

File diff suppressed because it is too large Load Diff

@ -46,3 +46,11 @@ func (self *State) Dump() []byte {
return json return json
} }
// Debug stuff
func (self *StateObject) CreateOutputForDiff() {
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce)
self.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("%x %x\n", addr, value.Bytes())
})
}

@ -287,14 +287,6 @@ func (self *StateObject) Root() []byte {
return self.State.Trie.GetRoot() return self.State.Trie.GetRoot()
} }
// Debug stuff
func (self *StateObject) CreateOutputForDiff() {
fmt.Printf("%x %x %x %x\n", self.Address(), self.State.Root(), self.balance.Bytes(), self.Nonce)
self.EachStorage(func(addr string, value *ethutil.Value) {
fmt.Printf("%x %x\n", addr, value.Bytes())
})
}
// //
// Encoding // Encoding
// //