| 
									
										
										
										
											2014-12-04 10:28:02 +01:00
										 |  |  | package core | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-01-08 16:45:51 +01:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	"path" | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/ethdb" | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/ethutil" | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | func init() { | 
					
						
							|  |  |  | 	runtime.GOMAXPROCS(runtime.NumCPU()) | 
					
						
							|  |  |  | 	ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH") | 
					
						
							| 
									
										
										
										
											2015-01-02 11:16:30 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | func loadChain(fn string, t *testing.T) (types.Blocks, error) { | 
					
						
							| 
									
										
										
										
											2015-01-02 13:00:25 +01:00
										 |  |  | 	fh, err := os.OpenFile(path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm) | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	defer fh.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var chain types.Blocks | 
					
						
							|  |  |  | 	if err := rlp.Decode(fh, &chain); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	return chain, nil | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *testing.T) { | 
					
						
							|  |  |  | 	err := chainMan.InsertChain(chain) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println(err) | 
					
						
							|  |  |  | 		t.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-01-02 11:16:30 +01:00
										 |  |  | 	done <- true | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestChainInsertions(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-01-24 18:40:03 +01:00
										 |  |  | 	t.Skip() // travil fails. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	db, _ := ethdb.NewMemDatabase() | 
					
						
							| 
									
										
										
										
											2015-01-02 11:16:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 	chain1, err := loadChain("valid1", t) | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println(err) | 
					
						
							|  |  |  | 		t.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 	chain2, err := loadChain("valid2", t) | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println(err) | 
					
						
							|  |  |  | 		t.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	var eventMux event.TypeMux | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	chainMan := NewChainManager(db, &eventMux) | 
					
						
							| 
									
										
										
										
											2015-01-02 12:26:55 +01:00
										 |  |  | 	txPool := NewTxPool(&eventMux) | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux) | 
					
						
							| 
									
										
										
										
											2014-12-18 13:12:54 +01:00
										 |  |  | 	chainMan.SetProcessor(blockMan) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const max = 2 | 
					
						
							|  |  |  | 	done := make(chan bool, max) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go insertChain(done, chainMan, chain1, t) | 
					
						
							|  |  |  | 	go insertChain(done, chainMan, chain2, t) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < max; i++ { | 
					
						
							|  |  |  | 		<-done | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 16:45:51 +01:00
										 |  |  | 	if bytes.Equal(chain2[len(chain2)-1].Hash(), chainMan.CurrentBlock().Hash()) { | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 		t.Error("chain2 is canonical and shouldn't be") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 16:45:51 +01:00
										 |  |  | 	if !bytes.Equal(chain1[len(chain1)-1].Hash(), chainMan.CurrentBlock().Hash()) { | 
					
						
							| 
									
										
										
										
											2014-12-30 13:32:01 +01:00
										 |  |  | 		t.Error("chain1 isn't canonical and should be") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-12-17 12:57:35 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestChainMultipleInsertions(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-01-24 18:40:03 +01:00
										 |  |  | 	t.Skip() // travil fails. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	db, _ := ethdb.NewMemDatabase() | 
					
						
							| 
									
										
										
										
											2015-01-02 11:16:30 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 	const max = 4 | 
					
						
							|  |  |  | 	chains := make([]types.Blocks, max) | 
					
						
							|  |  |  | 	var longest int | 
					
						
							|  |  |  | 	for i := 0; i < max; i++ { | 
					
						
							|  |  |  | 		var err error | 
					
						
							|  |  |  | 		name := "valid" + strconv.Itoa(i+1) | 
					
						
							|  |  |  | 		chains[i], err = loadChain(name, t) | 
					
						
							|  |  |  | 		if len(chains[i]) >= len(chains[longest]) { | 
					
						
							|  |  |  | 			longest = i | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		fmt.Println("loaded", name, "with a length of", len(chains[i])) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			fmt.Println(err) | 
					
						
							|  |  |  | 			t.FailNow() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var eventMux event.TypeMux | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	chainMan := NewChainManager(db, &eventMux) | 
					
						
							| 
									
										
										
										
											2015-01-02 12:26:55 +01:00
										 |  |  | 	txPool := NewTxPool(&eventMux) | 
					
						
							| 
									
										
										
										
											2015-01-07 13:17:48 +01:00
										 |  |  | 	blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux) | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 	chainMan.SetProcessor(blockMan) | 
					
						
							|  |  |  | 	done := make(chan bool, max) | 
					
						
							|  |  |  | 	for i, chain := range chains { | 
					
						
							| 
									
										
										
										
											2015-01-02 11:16:30 +01:00
										 |  |  | 		// XXX the go routine would otherwise reference the same (chain[3]) variable and fail | 
					
						
							|  |  |  | 		i := i | 
					
						
							|  |  |  | 		chain := chain | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 		go func() { | 
					
						
							|  |  |  | 			insertChain(done, chainMan, chain, t) | 
					
						
							|  |  |  | 			fmt.Println(i, "done") | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < max; i++ { | 
					
						
							|  |  |  | 		<-done | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 16:48:39 +01:00
										 |  |  | 	if !bytes.Equal(chains[longest][len(chains[longest])-1].Hash(), chainMan.CurrentBlock().Hash()) { | 
					
						
							| 
									
										
										
										
											2014-12-30 15:42:26 +01:00
										 |  |  | 		t.Error("Invalid canonical chain") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-12 10:19:27 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestGetAncestors(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2015-01-24 18:46:35 +01:00
										 |  |  | 	t.Skip() // travil fails. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-12 10:19:27 +01:00
										 |  |  | 	db, _ := ethdb.NewMemDatabase() | 
					
						
							|  |  |  | 	var eventMux event.TypeMux | 
					
						
							|  |  |  | 	chainMan := NewChainManager(db, &eventMux) | 
					
						
							|  |  |  | 	chain, err := loadChain("valid1", t) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println(err) | 
					
						
							|  |  |  | 		t.FailNow() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, block := range chain { | 
					
						
							|  |  |  | 		chainMan.write(block) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ancestors := chainMan.GetAncestors(chain[len(chain)-1], 4) | 
					
						
							|  |  |  | 	fmt.Println(ancestors) | 
					
						
							|  |  |  | } |