Skip to content

Commit

Permalink
cmd, core, eth, common: genesis preparation
Browse files Browse the repository at this point in the history
Implemented the --genesis flag thru which we can set a custom genesis
block, including the official Ethereum genesis block.
  • Loading branch information
obscuren committed Jul 22, 2015
1 parent 4ca3d49 commit 487b3b0
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 138 deletions.
6 changes: 4 additions & 2 deletions cmd/geth/js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/rpc/comms"
)
Expand Down Expand Up @@ -89,9 +90,9 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
t.Fatal(err)
}

// set up mock genesis with balance on the testAddress
core.GenesisAccounts = []byte(testGenesis)
db, _ := ethdb.NewMemDatabase()

core.WriteGenesisBlockForTesting(db, common.HexToAddress(testAddress), common.String2Big(testBalance))
ks := crypto.NewKeyStorePlain(filepath.Join(tmp, "keystore"))
am := accounts.NewManager(ks)
conf := &eth.Config{
Expand All @@ -102,6 +103,7 @@ func testREPL(t *testing.T, config func(*eth.Config)) (string, *testjethre, *eth
Name: "test",
SolcPath: testSolcPath,
PowTest: true,
NewDB: func(path string) (common.Database, error) { return db, nil },
}
if config != nil {
config(conf)
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Conso
utils.UnlockedAccountFlag,
utils.PasswordFileFlag,
utils.GenesisNonceFlag,
utils.GenesisFileFlag,
utils.BootnodesFlag,
utils.DataDirFlag,
utils.BlockchainVersionFlag,
Expand Down
9 changes: 7 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ var (
Usage: "Sets the genesis nonce",
Value: 42,
}
GenesisFileFlag = cli.StringFlag{
Name: "genesis",
Usage: "Inserts/Overwrites the genesis block (json format)",
}
IdentityFlag = cli.StringFlag{
Name: "identity",
Usage: "Custom node name",
Expand Down Expand Up @@ -378,6 +382,7 @@ func MakeEthConfig(clientID, version string, ctx *cli.Context) *eth.Config {
Name: common.MakeName(clientID, version),
DataDir: ctx.GlobalString(DataDirFlag.Name),
GenesisNonce: ctx.GlobalInt(GenesisNonceFlag.Name),
GenesisFile: ctx.GlobalString(GenesisFileFlag.Name),
BlockChainVersion: ctx.GlobalInt(BlockchainVersionFlag.Name),
SkipBcVersionCheck: false,
NetworkId: ctx.GlobalInt(NetworkIdFlag.Name),
Expand Down Expand Up @@ -434,8 +439,8 @@ func MakeChain(ctx *cli.Context) (chain *core.ChainManager, blockDB, stateDB, ex

eventMux := new(event.TypeMux)
pow := ethash.New()
genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
chain, err = core.NewChainManager(genesis, blockDB, stateDB, extraDB, pow, eventMux)
//genesis := core.GenesisBlock(uint64(ctx.GlobalInt(GenesisNonceFlag.Name)), blockDB)
chain, err = core.NewChainManager(blockDB, stateDB, extraDB, pow, eventMux)
if err != nil {
Fatalf("Could not start chainmanager: %v", err)
}
Expand Down
8 changes: 5 additions & 3 deletions common/natspec/natspec_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethdb"
xe "github.com/ethereum/go-ethereum/xeth"
)

Expand Down Expand Up @@ -128,12 +129,12 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
if err != nil {
panic(err)
}

testAddress := strings.TrimPrefix(testAccount.Address.Hex(), "0x")

db, _ := ethdb.NewMemDatabase()
// set up mock genesis with balance on the testAddress
core.GenesisAccounts = []byte(`{
"` + testAddress + `": {"balance": "` + testBalance + `"}
}`)
core.WriteGenesisBlockForTesting(db, common.HexToAddress(testAddress), common.String2Big(testBalance))

// only use minimalistic stack with no networking
ethereum, err = eth.New(&eth.Config{
Expand All @@ -142,6 +143,7 @@ func testEth(t *testing.T) (ethereum *eth.Ethereum, err error) {
MaxPeers: 0,
PowTest: true,
Etherbase: common.HexToAddress(testAddress),
NewDB: func(path string) (common.Database, error) { return db, nil },
})

if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,13 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {

// Generate a chain of b.N blocks using the supplied block
// generator function.
genesis := GenesisBlockForTesting(db, benchRootAddr, benchRootFunds)
genesis := WriteGenesisBlockForTesting(db, benchRootAddr, benchRootFunds)
chain := GenerateChain(genesis, db, b.N, gen)

// Time the insertion of the new chain.
// State and blocks are stored in the same DB.
evmux := new(event.TypeMux)
chainman, _ := NewChainManager(genesis, db, db, db, FakePow{}, evmux)
chainman, _ := NewChainManager(db, db, db, FakePow{}, evmux)
chainman.SetProcessor(NewBlockProcessor(db, db, FakePow{}, chainman, evmux))
defer chainman.Stop()
b.ReportAllocs()
Expand Down
4 changes: 2 additions & 2 deletions core/block_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ func proc() (*BlockProcessor, *ChainManager) {
db, _ := ethdb.NewMemDatabase()
var mux event.TypeMux

genesis := GenesisBlock(0, db)
chainMan, err := NewChainManager(genesis, db, db, db, thePow(), &mux)
WriteTestNetGenesisBlock(db, db, 0)
chainMan, err := NewChainManager(db, db, db, thePow(), &mux)
if err != nil {
fmt.Println(err)
}
Expand Down
4 changes: 3 additions & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header {
// InsertChain on the result of makeChain.
func newCanonical(n int, db common.Database) (*BlockProcessor, error) {
evmux := &event.TypeMux{}
chainman, _ := NewChainManager(GenesisBlock(0, db), db, db, db, FakePow{}, evmux)

WriteTestNetGenesisBlock(db, db, 0)
chainman, _ := NewChainManager(db, db, db, FakePow{}, evmux)
bman := NewBlockProcessor(db, db, FakePow{}, chainman, evmux)
bman.bc.SetProcessor(bman)
parent := bman.bc.CurrentBlock()
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func ExampleGenerateChain() {
)

// Ensure that key1 has some funds in the genesis block.
genesis := GenesisBlockForTesting(db, addr1, big.NewInt(1000000))
genesis := WriteGenesisBlockForTesting(db, addr1, big.NewInt(1000000))

// This call generates a chain of 5 blocks. The function runs for
// each block and adds different features to gen based on the
Expand Down Expand Up @@ -74,7 +74,7 @@ func ExampleGenerateChain() {

// Import the chain. This runs all block validation rules.
evmux := &event.TypeMux{}
chainman, _ := NewChainManager(genesis, db, db, db, FakePow{}, evmux)
chainman, _ := NewChainManager(db, db, db, FakePow{}, evmux)
chainman.SetProcessor(NewBlockProcessor(db, db, FakePow{}, chainman, evmux))
if i, err := chainman.InsertChain(chain); err != nil {
fmt.Printf("insert error (block %d): %v\n", i, err)
Expand Down
85 changes: 45 additions & 40 deletions core/chain_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package core

import (
"errors"
"fmt"
"io"
"math/big"
Expand All @@ -34,18 +35,16 @@ import (
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"github.com/hashicorp/golang-lru"
)

var (
chainlogger = logger.NewLogger("CHAIN")
jsonlogger = logger.NewJsonLogger()

blockHashPre = []byte("block-hash-")
blockNumPre = []byte("block-num-")

blockInsertTimer = metrics.NewTimer("chain/inserts")

ErrNoGenesis = errors.New("Genesis not found in chain")
)

const (
Expand Down Expand Up @@ -88,25 +87,32 @@ type ChainManager struct {
pow pow.PoW
}

func NewChainManager(genesis *types.Block, blockDb, stateDb, extraDb common.Database, pow pow.PoW, mux *event.TypeMux) (*ChainManager, error) {
func NewChainManager(blockDb, stateDb, extraDb common.Database, pow pow.PoW, mux *event.TypeMux) (*ChainManager, error) {
cache, _ := lru.New(blockCacheLimit)
bc := &ChainManager{
blockDb: blockDb,
stateDb: stateDb,
extraDb: extraDb,
genesisBlock: GenesisBlock(42, stateDb),
eventMux: mux,
quit: make(chan struct{}),
cache: cache,
pow: pow,
}
// Check the genesis block given to the chain manager. If the genesis block mismatches block number 0
// throw an error. If no block or the same block's found continue.
if g := bc.GetBlockByNumber(0); g != nil && g.Hash() != genesis.Hash() {
return nil, fmt.Errorf("Genesis mismatch. Maybe different nonce (%d vs %d)? %x / %x", g.Nonce(), genesis.Nonce(), g.Hash().Bytes()[:4], genesis.Hash().Bytes()[:4])
}
bc.genesisBlock = genesis
bc.setLastState()
blockDb: blockDb,
stateDb: stateDb,
extraDb: extraDb,
eventMux: mux,
quit: make(chan struct{}),
cache: cache,
pow: pow,
}

bc.genesisBlock = bc.GetBlockByNumber(0)
if bc.genesisBlock == nil {
// XXX Uncomment me before Frontier
//return nil, ErrNoGenesis
genesis, err := WriteTestNetGenesisBlock(bc.stateDb, bc.blockDb, 42)
if err != nil {
glog.Fatalln("genisis err", err)
}
bc.genesisBlock = genesis
}

if err := bc.setLastState(); err != nil {
return nil, err
}

// Check the current state of the block hashes and make sure that we do not have any of the bad blocks in our chain
for hash, _ := range BadHashes {
Expand Down Expand Up @@ -226,7 +232,7 @@ func (bc *ChainManager) recover() bool {
return false
}

func (bc *ChainManager) setLastState() {
func (bc *ChainManager) setLastState() error {
data, _ := bc.blockDb.Get([]byte("LastBlock"))
if len(data) != 0 {
block := bc.GetBlock(common.BytesToHash(data))
Expand All @@ -250,6 +256,8 @@ func (bc *ChainManager) setLastState() {
if glog.V(logger.Info) {
glog.Infof("Last block (#%v) %x TD=%v\n", bc.currentBlock.Number(), bc.currentBlock.Hash(), bc.td)
}

return nil
}

func (bc *ChainManager) makeCache() {
Expand All @@ -272,7 +280,11 @@ func (bc *ChainManager) Reset() {
bc.cache, _ = lru.New(blockCacheLimit)

// Prepare the genesis block
bc.write(bc.genesisBlock)
err := WriteBlock(bc.blockDb, bc.genesisBlock)
if err != nil {
glog.Fatalln("db err:", err)
}

bc.insert(bc.genesisBlock)
bc.currentBlock = bc.genesisBlock
bc.makeCache()
Expand All @@ -295,7 +307,12 @@ func (bc *ChainManager) ResetWithGenesisBlock(gb *types.Block) {
// Prepare the genesis block
gb.Td = gb.Difficulty()
bc.genesisBlock = gb
bc.write(bc.genesisBlock)

err := WriteBlock(bc.blockDb, bc.genesisBlock)
if err != nil {
glog.Fatalln("db err:", err)
}

bc.insert(bc.genesisBlock)
bc.currentBlock = bc.genesisBlock
bc.makeCache()
Expand Down Expand Up @@ -357,21 +374,6 @@ func (bc *ChainManager) insert(block *types.Block) {
bc.lastBlockHash = block.Hash()
}

func (bc *ChainManager) write(block *types.Block) {
tstart := time.Now()

enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block))
key := append(blockHashPre, block.Hash().Bytes()...)
err := bc.blockDb.Put(key, enc)
if err != nil {
glog.Fatal("db write fail:", err)
}

if glog.V(logger.Debug) {
glog.Infof("wrote block #%v %s. Took %v\n", block.Number(), common.PP(block.Hash().Bytes()), time.Since(tstart))
}
}

// Accessors
func (bc *ChainManager) Genesis() *types.Block {
return bc.genesisBlock
Expand Down Expand Up @@ -535,7 +537,10 @@ func (self *ChainManager) WriteBlock(block *types.Block, queued bool) (status wr
status = SideStatTy
}

self.write(block)
err = WriteBlock(self.blockDb, block)
if err != nil {
glog.Fatalln("db err:", err)
}
// Delete from future blocks
self.futureBlocks.Remove(block.Hash())

Expand Down
Loading

0 comments on commit 487b3b0

Please sign in to comment.