ADDED LCP engine

This commit is contained in:
pavelkrolevets 2018-08-21 12:50:03 +08:00
parent c9e3e998a8
commit 7d46b7f6ff
9 changed files with 73 additions and 99 deletions

View file

@ -34,7 +34,6 @@ import (
"github.com/pavelkrolevets/go-ethereum/common" "github.com/pavelkrolevets/go-ethereum/common"
"github.com/pavelkrolevets/go-ethereum/common/fdlimit" "github.com/pavelkrolevets/go-ethereum/common/fdlimit"
"github.com/pavelkrolevets/go-ethereum/consensus" "github.com/pavelkrolevets/go-ethereum/consensus"
"github.com/pavelkrolevets/go-ethereum/consensus/clique"
"github.com/pavelkrolevets/go-ethereum/consensus/ethash" "github.com/pavelkrolevets/go-ethereum/consensus/ethash"
"github.com/pavelkrolevets/go-ethereum/core" "github.com/pavelkrolevets/go-ethereum/core"
"github.com/pavelkrolevets/go-ethereum/core/state" "github.com/pavelkrolevets/go-ethereum/core/state"
@ -59,6 +58,7 @@ import (
"github.com/pavelkrolevets/go-ethereum/params" "github.com/pavelkrolevets/go-ethereum/params"
whisper "github.com/pavelkrolevets/go-ethereum/whisper/whisperv6" whisper "github.com/pavelkrolevets/go-ethereum/whisper/whisperv6"
"gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
"github.com/pavelkrolevets/go-ethereum/consensus/lcp"
) )
var ( var (
@ -1113,16 +1113,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if !ctx.GlobalIsSet(NetworkIdFlag.Name) { if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 3 cfg.NetworkId = 3
} }
cfg.Genesis = core.DefaultTestnetGenesisBlock()
case ctx.GlobalBool(RinkebyFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 4
}
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
case ctx.GlobalBool(DeveloperFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
}
// Create new developer account or reuse existing one // Create new developer account or reuse existing one
var ( var (
developer accounts.Account developer accounts.Account
@ -1140,11 +1131,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
Fatalf("Failed to unlock developer account: %v", err) Fatalf("Failed to unlock developer account: %v", err)
} }
log.Info("Using developer account", "address", developer.Address) log.Info("Using developer account", "address", developer.Address)
cfg.Genesis = core.DeveloperGenesisBlock(uint64(ctx.GlobalInt(DeveloperPeriodFlag.Name)), developer.Address)
if !ctx.GlobalIsSet(GasPriceFlag.Name) {
cfg.GasPrice = big.NewInt(1)
}
} }
// TODO(fjl): move trie cache generations into config // TODO(fjl): move trie cache generations into config
if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 { if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
@ -1260,14 +1246,6 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
func MakeGenesis(ctx *cli.Context) *core.Genesis { func MakeGenesis(ctx *cli.Context) *core.Genesis {
var genesis *core.Genesis var genesis *core.Genesis
switch {
case ctx.GlobalBool(TestnetFlag.Name):
genesis = core.DefaultTestnetGenesisBlock()
case ctx.GlobalBool(RinkebyFlag.Name):
genesis = core.DefaultRinkebyGenesisBlock()
case ctx.GlobalBool(DeveloperFlag.Name):
Fatalf("Developer chains are ephemeral")
}
return genesis return genesis
} }
@ -1281,8 +1259,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
Fatalf("%v", err) Fatalf("%v", err)
} }
var engine consensus.Engine var engine consensus.Engine
if config.Clique != nil { if config.LCP != nil {
engine = clique.New(config.Clique, chainDb) engine = lcp.New(config.LCP, chainDb)
} else { } else {
engine = ethash.NewFaker() engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) { if !ctx.GlobalBool(FakePoWFlag.Name) {

View file

@ -24,6 +24,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"github.com/pavelkrolevets/go-ethereum/trie" "github.com/pavelkrolevets/go-ethereum/trie"
"github.com/pavelkrolevets/go-ethereum/ethdb"
) )
const ( const (
@ -83,7 +84,7 @@ var (
type LCP struct { type LCP struct {
config *params.LcpConfig // Consensus engine configuration parameters config *params.LcpConfig // Consensus engine configuration parameters
db *trie.Database // Database to store and retrieve snapshots db ethdb.Database // Database to store and retrieve snapshots
signer common.Address signer common.Address
signFn SignerFn signFn SignerFn
@ -130,7 +131,7 @@ func sigHash(header *types.Header) (hash common.Hash) {
return hash return hash
} }
func New(config *params.LcpConfig, db *trie.Database) *LCP { func New(config *params.LcpConfig, db ethdb.Database) *LCP {
signatures, _ := lru.NewARC(inmemorySignatures) signatures, _ := lru.NewARC(inmemorySignatures)
return &LCP{ return &LCP{
config: config, config: config,
@ -315,8 +316,7 @@ func (d *LCP) updateConfirmedBlockHeader(chain consensus.ChainReader) error {
} }
func (s *LCP) loadConfirmedBlockHeader(chain consensus.ChainReader) (*types.Header, error) { func (s *LCP) loadConfirmedBlockHeader(chain consensus.ChainReader) (*types.Header, error) {
db := s.db.DiskDB() key, err:= s.db.Get(confirmedBlockHead)
key, err:=db.Get(confirmedBlockHead)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -328,9 +328,8 @@ func (s *LCP) loadConfirmedBlockHeader(chain consensus.ChainReader) (*types.Head
} }
// store inserts the snapshot into the database. // store inserts the snapshot into the database.
func (s *LCP) storeConfirmedBlockHeader(db *trie.Database) error { func (s *LCP) storeConfirmedBlockHeader(db ethdb.Database) error {
db_wr := s.db.DiskDBwrite() return db.Put(confirmedBlockHead, s.confirmedBlockHeader.Hash().Bytes())
return db_wr.Put(confirmedBlockHead, s.confirmedBlockHeader.Hash().Bytes())
} }
func (d *LCP) Prepare(chain consensus.ChainReader, header *types.Header) error { func (d *LCP) Prepare(chain consensus.ChainReader, header *types.Header) error {

View file

@ -52,7 +52,7 @@ func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *B
) )
// Initialize a fresh chain with only a genesis block // Initialize a fresh chain with only a genesis block
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}) blockchain, _ := NewBlockChain(db, nil, params.LcpChainConfig, engine, vm.Config{})
// Create and inject the requested chain // Create and inject the requested chain
if n == 0 { if n == 0 {
return db, blockchain, nil return db, blockchain, nil

View file

@ -346,8 +346,8 @@ func initGenesisLCPContext(g *Genesis, db ethdb.Database) *types.LCPContext {
if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.MaxValidators != 0 { if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.MaxValidators != 0 {
dc.SetMaxValidators(g.Config.LCP.MaxValidators) dc.SetMaxValidators(g.Config.LCP.MaxValidators)
} }
if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.Epoch != 0 { if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.EpochInterval != 0 {
dc.SetEpochInterval(g.Config.LCP.Epoch) dc.SetEpochInterval(g.Config.LCP.EpochInterval)
} }
return dc return dc
} }

View file

@ -30,16 +30,16 @@ import (
"github.com/pavelkrolevets/go-ethereum/params" "github.com/pavelkrolevets/go-ethereum/params"
) )
func TestDefaultGenesisBlock(t *testing.T) { //func TestDefaultGenesisBlock(t *testing.T) {
block := DefaultGenesisBlock().ToBlock(nil) // block := DefaultGenesisBlock().ToBlock(nil)
if block.Hash() != params.MainnetGenesisHash { // if block.Hash() != params.MainnetGenesisHash {
t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash) // t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash)
} // }
block = DefaultTestnetGenesisBlock().ToBlock(nil) // block = DefaultTestnetGenesisBlock().ToBlock(nil)
if block.Hash() != params.TestnetGenesisHash { // if block.Hash() != params.TestnetGenesisHash {
t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash(), params.TestnetGenesisHash) // t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash(), params.TestnetGenesisHash)
} // }
} //}
func TestSetupGenesis(t *testing.T) { func TestSetupGenesis(t *testing.T) {
var ( var (
@ -66,7 +66,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, new(Genesis)) return SetupGenesisBlock(db, new(Genesis))
}, },
wantErr: errGenesisNoConfig, wantErr: errGenesisNoConfig,
wantConfig: params.AllEthashProtocolChanges, wantConfig: params.LcpChainConfig,
}, },
{ {
name: "no block in DB, genesis == nil", name: "no block in DB, genesis == nil",
@ -74,7 +74,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, nil) return SetupGenesisBlock(db, nil)
}, },
wantHash: params.MainnetGenesisHash, wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig, wantConfig: params.LcpChainConfig,
}, },
{ {
name: "mainnet block in DB, genesis == nil", name: "mainnet block in DB, genesis == nil",
@ -83,7 +83,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, nil) return SetupGenesisBlock(db, nil)
}, },
wantHash: params.MainnetGenesisHash, wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig, wantConfig: params.LcpChainConfig,
}, },
{ {
name: "custom block in DB, genesis == nil", name: "custom block in DB, genesis == nil",

View file

@ -10,6 +10,7 @@ import (
"github.com/pavelkrolevets/go-ethereum/rlp" "github.com/pavelkrolevets/go-ethereum/rlp"
"github.com/pavelkrolevets/go-ethereum/trie" "github.com/pavelkrolevets/go-ethereum/trie"
"encoding/binary" "encoding/binary"
"github.com/pavelkrolevets/go-ethereum/ethdb"
) )
type LCPContext struct { type LCPContext struct {
@ -22,7 +23,7 @@ type LCPContext struct {
maxValidators *trie.Trie maxValidators *trie.Trie
epochInterval *trie.Trie epochInterval *trie.Trie
db *trie.Database db ethdb.Database
} }
var ( var (
@ -36,37 +37,45 @@ var (
epochIntervalPrefix = []byte("EpochInterval-") epochIntervalPrefix = []byte("EpochInterval-")
) )
func NewEpochTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewEpochTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, epochPrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, epochPrefix, dbd)
} }
func NewDelegateTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewDelegateTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, delegatePrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, delegatePrefix, dbd)
} }
func NewVoteTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewVoteTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, votePrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, votePrefix, dbd)
} }
func NewCandidateTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewCandidateTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, candidatePrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, candidatePrefix, dbd)
} }
func NewMintCntTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewMintCntTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, mintCntPrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, mintCntPrefix, dbd)
} }
func NewPeriodBlockTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewPeriodBlockTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, periodBlockPrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, periodBlockPrefix, dbd)
} }
func NewMaxValidatorsTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewMaxValidatorsTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, maxValidatorsPrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, maxValidatorsPrefix, dbd)
} }
func NewEpochIntervalTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) { func NewEpochIntervalTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, epochIntervalPrefix, db) dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, epochIntervalPrefix, dbd)
} }
func NewLCPContext(db *trie.Database) (*LCPContext, error) { func NewLCPContext(db ethdb.Database) (*LCPContext, error) {
epochTrie, err := NewEpochTrie(common.Hash{}, db) epochTrie, err := NewEpochTrie(common.Hash{}, db)
if err != nil { if err != nil {
return nil, err return nil, err
@ -113,7 +122,7 @@ func NewLCPContext(db *trie.Database) (*LCPContext, error) {
}, nil }, nil
} }
func NewLCPContextFromProto(db *trie.Database, ctxProto *LCPContextProto) (*LCPContext, error) { func NewLCPContextFromProto(db ethdb.Database, ctxProto *LCPContextProto) (*LCPContext, error) {
epochTrie, err := NewEpochTrie(ctxProto.EpochHash, db) epochTrie, err := NewEpochTrie(ctxProto.EpochHash, db)
if err != nil { if err != nil {
return nil, err return nil, err
@ -380,38 +389,38 @@ func (d *LCPContext) UnDelegate(delegatorAddr, candidateAddr common.Address) err
} }
return d.voteTrie.TryDelete(delegator) return d.voteTrie.TryDelete(delegator)
} }
//function to write tries to memory and then dump to a hard drive - new in 1.8 version //function to write tries to memory
func (d *LCPContext) CommitTo(onleaf trie.LeafCallback) (*LCPContextProto, error) { func (d *LCPContext) CommitTo(db ethdb.Database) (*LCPContextProto, error) {
epochRoot, err := d.epochTrie.Commit(onleaf) epochRoot, err := d.epochTrie.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
delegateRoot, err := d.delegateTrie.Commit(onleaf) delegateRoot, err := d.delegateTrie.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
voteRoot, err := d.voteTrie.Commit(onleaf) voteRoot, err := d.voteTrie.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
candidateRoot, err := d.candidateTrie.Commit(onleaf) candidateRoot, err := d.candidateTrie.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mintCntRoot, err := d.mintCntTrie.Commit(onleaf) mintCntRoot, err := d.mintCntTrie.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
blockPeriod, err := d.periodBlock.Commit(onleaf) blockPeriod, err := d.periodBlock.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
maxVal, err := d.maxValidators.Commit(onleaf) maxVal, err := d.maxValidators.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
epochInterv, err := d.epochInterval.Commit(onleaf) epochInterv, err := d.epochInterval.Commit(nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -435,7 +444,7 @@ func (d *LCPContext) MintCntTrie() *trie.Trie { return d.mintCntTrie
func (d *LCPContext) periodTrie() *trie.Trie { return d.periodBlock } func (d *LCPContext) periodTrie() *trie.Trie { return d.periodBlock }
func (d *LCPContext) maxValidatorTrie() *trie.Trie { return d.maxValidators } func (d *LCPContext) maxValidatorTrie() *trie.Trie { return d.maxValidators }
func (d *LCPContext) epochIntervalTrie() *trie.Trie { return d.epochInterval } func (d *LCPContext) epochIntervalTrie() *trie.Trie { return d.epochInterval }
func (d *LCPContext) DB() *trie.Database { return d.db } func (d *LCPContext) DB() ethdb.Database { return d.db }
func (dc *LCPContext) SetEpoch(epoch *trie.Trie) { dc.epochTrie = epoch } func (dc *LCPContext) SetEpoch(epoch *trie.Trie) { dc.epochTrie = epoch }
func (dc *LCPContext) SetDelegate(delegate *trie.Trie) { dc.delegateTrie = delegate } func (dc *LCPContext) SetDelegate(delegate *trie.Trie) { dc.delegateTrie = delegate }
func (dc *LCPContext) SetVote(vote *trie.Trie) { dc.voteTrie = vote } func (dc *LCPContext) SetVote(vote *trie.Trie) { dc.voteTrie = vote }

View file

@ -29,8 +29,8 @@ import (
"github.com/pavelkrolevets/go-ethereum/common" "github.com/pavelkrolevets/go-ethereum/common"
"github.com/pavelkrolevets/go-ethereum/common/hexutil" "github.com/pavelkrolevets/go-ethereum/common/hexutil"
"github.com/pavelkrolevets/go-ethereum/consensus" "github.com/pavelkrolevets/go-ethereum/consensus"
"github.com/pavelkrolevets/go-ethereum/consensus/clique"
"github.com/pavelkrolevets/go-ethereum/consensus/ethash" "github.com/pavelkrolevets/go-ethereum/consensus/ethash"
"github.com/pavelkrolevets/go-ethereum/consensus/lcp"
"github.com/pavelkrolevets/go-ethereum/core" "github.com/pavelkrolevets/go-ethereum/core"
"github.com/pavelkrolevets/go-ethereum/core/bloombits" "github.com/pavelkrolevets/go-ethereum/core/bloombits"
"github.com/pavelkrolevets/go-ethereum/core/rawdb" "github.com/pavelkrolevets/go-ethereum/core/rawdb"
@ -211,9 +211,9 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data
// CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service
func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine {
// If proof-of-authority is requested, set it up // If LCP is requested, set it up
if chainConfig.Clique != nil { if chainConfig.LCP != nil {
return clique.New(chainConfig.Clique, db) return lcp.New(chainConfig.LCP, db)
} }
// Otherwise assume proof-of-work // Otherwise assume proof-of-work
switch config.PowMode { switch config.PowMode {

View file

@ -265,7 +265,7 @@ func (self *worker) update() {
self.currentMu.Unlock() self.currentMu.Unlock()
} else { } else {
// If we're mining, but nothing is being processed, wake on new transactions // If we're mining, but nothing is being processed, wake on new transactions
if self.config.Clique != nil && self.config.Clique.Period == 0 { if self.config.LCP != nil && self.config.LCP.Period == 0 {
self.commitNewWork() self.commitNewWork()
} }
} }

View file

@ -57,13 +57,6 @@ type DatabaseReader interface {
// Has retrieves whether a key is present in the database. // Has retrieves whether a key is present in the database.
Has(key []byte) (bool, error) Has(key []byte) (bool, error)
} }
// DatabaseWriter wraps the Put method of a backing store for the trie.
type DatabaseWriter interface {
// Put stores the mapping key->value in the database.
// Implementations must not hold onto the value bytes, the trie
// will reuse the slice across calls to Put.
Put(key, value []byte) error
}
// Database is an intermediate write layer between the trie data structures and // Database is an intermediate write layer between the trie data structures and
// the disk database. The aim is to accumulate trie writes in-memory and only // the disk database. The aim is to accumulate trie writes in-memory and only
@ -282,11 +275,6 @@ func NewDatabase(diskdb ethdb.Database) *Database {
func (db *Database) DiskDB() DatabaseReader { func (db *Database) DiskDB() DatabaseReader {
return db.diskdb return db.diskdb
} }
// DiskDBwrite writes the persistent storage backing the trie database.
func (db *Database) DiskDBwrite() DatabaseWriter {
return db.diskdb
}
// InsertBlob writes a new reference tracked blob to the memory database if it's // InsertBlob writes a new reference tracked blob to the memory database if it's
// yet unknown. This method should only be used for non-trie nodes that require // yet unknown. This method should only be used for non-trie nodes that require
// reference counting, since trie nodes are garbage collected directly through // reference counting, since trie nodes are garbage collected directly through