From dae51d9a84c677e012a1a8785de096a57a616a8e Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Thu, 26 May 2016 01:48:38 +0200 Subject: [PATCH] core: basic interface for new blocks Added Unsealed, mutable block and sealed, immutable blocks which will help in the generation of new blocks and chains. Unsealed blocks are generated from Forks, modified and sealed: block := fork.NewUnsealedBlock(...) block.ApplyTransactions(txs) sealedBlock := Seal(sealer, block) --- core/fork.go | 41 +++++++++++++++++++++++++++++++++++------ core/generator.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 core/generator.go diff --git a/core/fork.go b/core/fork.go index b39df90c65..49da794fb2 100644 --- a/core/fork.go +++ b/core/fork.go @@ -19,6 +19,7 @@ package core import ( "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -91,7 +92,7 @@ type ChainFork struct { tx ethdb.Transaction // current operating transaction reader BlockReader // block reader utility interface - origin common.Hash // origin notes the start of the fork + origin *types.Block // origin notes the start of the fork currentBlock *types.Block // the current block within this transaction changes []Changes // changes @@ -103,7 +104,6 @@ func Fork(blockReader BlockReader, origin common.Hash) (*ChainFork, error) { fork := &ChainFork{ db: blockReader.Db(), reader: blockReader, - origin: origin, } // open a new leveldb transaction tx, err := fork.db.OpenTransaction() @@ -113,10 +113,7 @@ func Fork(blockReader BlockReader, origin common.Hash) (*ChainFork, error) { fork.tx = tx // get the origin block from which this fork originates - if block := blockReader.GetBlock(origin); block != nil { - // Block found, set as the current head - fork.currentBlock = block - } else { + if fork.origin = blockReader.GetBlock(origin); fork.origin == nil { return nil, fmt.Errorf("core/fork: no block found with hash: %x", origin) } @@ -202,3 +199,35 @@ func (fork *ChainFork) CommitToDb() error { func (fork *ChainFork) ApplyTo(resolver ChainResolver) error { return resolver.Resolve(fork.tx, fork.changes) } + +// NewUnsealedBlock creates a new unsealed block using the last block in the fork +// as its parent. +func (fork *ChainFork) NewUnsealedBlock(coinbase common.Address, extra []byte) *UnsealedBlock { + var ( + parent types.Header + unsealedBlock = new(UnsealedBlock) + ) + + if len(fork.changes) == 0 { + parent = *fork.origin.Header() + } else { + parent = fork.changes[len(fork.changes)-1].header + } + + tstamp := time.Now().Unix() + if parent.Time.Cmp(new(big.Int).SetInt64(tstamp)) >= 0 { + tstamp = parent.Time.Int64() + 1 + } + + unsealedBlock.header = types.Header{ + ParentHash: parent.Hash(), + Number: new(big.Int).Add(parent.Number, common.Big1), + Difficulty: CalcDifficulty(nil, uint64(tstamp), parent.Time.Uint64(), parent.Number, parent.Difficulty), + GasLimit: CalcGasLimit(types.NewBlockWithHeader(&parent)), + GasUsed: new(big.Int), + Coinbase: coinbase, + Extra: extra, + Time: big.NewInt(tstamp), + } + return unsealedBlock +} diff --git a/core/generator.go b/core/generator.go new file mode 100644 index 0000000000..a772220626 --- /dev/null +++ b/core/generator.go @@ -0,0 +1,37 @@ +package core + +import "github.com/ethereum/go-ethereum/core/types" + +// UnsealedBlock is a not-yet finalised block to which you can +// keep applying transactions until the gas-limit is met. +type UnsealedBlock struct { + header types.Header // block header + transactions types.Transactions // transactions previously applied + uncles []types.Header // uncles previously applied + + gasPool *GasPool // gas pool for this block +} + +// ApplyTransactions applies the given txs to the unsealed block and an error +// if unsuccessful. +func (b *UnsealedBlock) ApplyTransactions(txs types.Transactions) error { + return nil +} + +// ApplyUncles applies the given uncles to the unsealed block and an error +// if unsuccessful. +func (b *UnsealedBlock) ApplyUncles(uncles []types.Header) error { + return nil +} + +// SealedBlock is a finalised, immutable block. +type SealedBlock struct{} + +// Sealer seals a block. +type Sealer interface{} + +// Seal seals a block with the given Sealer and returns a new SealedBlock +// and/or an error. +func Seal(sealer Sealer, block UnsealedBlock) (*SealedBlock, error) { + return nil, nil +}