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)
This commit is contained in:
Jeffrey Wilcke 2016-05-26 01:48:38 +02:00
parent 19a0f9f958
commit dae51d9a84
2 changed files with 72 additions and 6 deletions

View file

@ -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
}

37
core/generator.go Normal file
View file

@ -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
}