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/fdlimit"
"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/core"
"github.com/pavelkrolevets/go-ethereum/core/state"
@ -59,6 +58,7 @@ import (
"github.com/pavelkrolevets/go-ethereum/params"
whisper "github.com/pavelkrolevets/go-ethereum/whisper/whisperv6"
"gopkg.in/urfave/cli.v1"
"github.com/pavelkrolevets/go-ethereum/consensus/lcp"
)
var (
@ -1113,16 +1113,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
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
var (
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)
}
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
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 {
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
}
@ -1281,8 +1259,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
Fatalf("%v", err)
}
var engine consensus.Engine
if config.Clique != nil {
engine = clique.New(config.Clique, chainDb)
if config.LCP != nil {
engine = lcp.New(config.LCP, chainDb)
} else {
engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {

View file

@ -24,6 +24,7 @@ import (
"encoding/binary"
"fmt"
"github.com/pavelkrolevets/go-ethereum/trie"
"github.com/pavelkrolevets/go-ethereum/ethdb"
)
const (
@ -83,7 +84,7 @@ var (
type LCP struct {
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
signFn SignerFn
@ -130,7 +131,7 @@ func sigHash(header *types.Header) (hash common.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)
return &LCP{
config: config,
@ -315,8 +316,7 @@ func (d *LCP) updateConfirmedBlockHeader(chain consensus.ChainReader) error {
}
func (s *LCP) loadConfirmedBlockHeader(chain consensus.ChainReader) (*types.Header, error) {
db := s.db.DiskDB()
key, err:=db.Get(confirmedBlockHead)
key, err:= s.db.Get(confirmedBlockHead)
if err != nil {
return nil, err
}
@ -328,9 +328,8 @@ func (s *LCP) loadConfirmedBlockHeader(chain consensus.ChainReader) (*types.Head
}
// store inserts the snapshot into the database.
func (s *LCP) storeConfirmedBlockHeader(db *trie.Database) error {
db_wr := s.db.DiskDBwrite()
return db_wr.Put(confirmedBlockHead, s.confirmedBlockHeader.Hash().Bytes())
func (s *LCP) storeConfirmedBlockHeader(db ethdb.Database) error {
return db.Put(confirmedBlockHead, s.confirmedBlockHeader.Hash().Bytes())
}
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
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
blockchain, _ := NewBlockChain(db, nil, params.LcpChainConfig, engine, vm.Config{})
// Create and inject the requested chain
if n == 0 {
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 {
dc.SetMaxValidators(g.Config.LCP.MaxValidators)
}
if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.Epoch != 0 {
dc.SetEpochInterval(g.Config.LCP.Epoch)
if g.Config != nil && g.Config.LCP != nil && g.Config.LCP.EpochInterval != 0 {
dc.SetEpochInterval(g.Config.LCP.EpochInterval)
}
return dc
}

View file

@ -30,16 +30,16 @@ import (
"github.com/pavelkrolevets/go-ethereum/params"
)
func TestDefaultGenesisBlock(t *testing.T) {
block := DefaultGenesisBlock().ToBlock(nil)
if block.Hash() != params.MainnetGenesisHash {
t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash)
}
block = DefaultTestnetGenesisBlock().ToBlock(nil)
if block.Hash() != params.TestnetGenesisHash {
t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash(), params.TestnetGenesisHash)
}
}
//func TestDefaultGenesisBlock(t *testing.T) {
// block := DefaultGenesisBlock().ToBlock(nil)
// if block.Hash() != params.MainnetGenesisHash {
// t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash)
// }
// block = DefaultTestnetGenesisBlock().ToBlock(nil)
// if block.Hash() != params.TestnetGenesisHash {
// t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash(), params.TestnetGenesisHash)
// }
//}
func TestSetupGenesis(t *testing.T) {
var (
@ -66,7 +66,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, new(Genesis))
},
wantErr: errGenesisNoConfig,
wantConfig: params.AllEthashProtocolChanges,
wantConfig: params.LcpChainConfig,
},
{
name: "no block in DB, genesis == nil",
@ -74,7 +74,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, nil)
},
wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig,
wantConfig: params.LcpChainConfig,
},
{
name: "mainnet block in DB, genesis == nil",
@ -83,7 +83,7 @@ func TestSetupGenesis(t *testing.T) {
return SetupGenesisBlock(db, nil)
},
wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig,
wantConfig: params.LcpChainConfig,
},
{
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/trie"
"encoding/binary"
"github.com/pavelkrolevets/go-ethereum/ethdb"
)
type LCPContext struct {
@ -22,7 +23,7 @@ type LCPContext struct {
maxValidators *trie.Trie
epochInterval *trie.Trie
db *trie.Database
db ethdb.Database
}
var (
@ -36,37 +37,45 @@ var (
epochIntervalPrefix = []byte("EpochInterval-")
)
func NewEpochTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, epochPrefix, db)
func NewEpochTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, epochPrefix, dbd)
}
func NewDelegateTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, delegatePrefix, db)
func NewDelegateTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, delegatePrefix, dbd)
}
func NewVoteTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, votePrefix, db)
func NewVoteTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, votePrefix, dbd)
}
func NewCandidateTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, candidatePrefix, db)
func NewCandidateTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, candidatePrefix, dbd)
}
func NewMintCntTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, mintCntPrefix, db)
func NewMintCntTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, mintCntPrefix, dbd)
}
func NewPeriodBlockTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, periodBlockPrefix, db)
func NewPeriodBlockTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, periodBlockPrefix, dbd)
}
func NewMaxValidatorsTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, maxValidatorsPrefix, db)
func NewMaxValidatorsTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
dbd := trie.NewDatabase(db)
return trie.NewTrieWithPrefix(root, maxValidatorsPrefix, dbd)
}
func NewEpochIntervalTrie(root common.Hash, db *trie.Database) (*trie.Trie, error) {
return trie.NewTrieWithPrefix(root, epochIntervalPrefix, db)
func NewEpochIntervalTrie(root common.Hash, db ethdb.Database) (*trie.Trie, error) {
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)
if err != nil {
return nil, err
@ -113,7 +122,7 @@ func NewLCPContext(db *trie.Database) (*LCPContext, error) {
}, 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)
if err != nil {
return nil, err
@ -380,38 +389,38 @@ func (d *LCPContext) UnDelegate(delegatorAddr, candidateAddr common.Address) err
}
return d.voteTrie.TryDelete(delegator)
}
//function to write tries to memory and then dump to a hard drive - new in 1.8 version
func (d *LCPContext) CommitTo(onleaf trie.LeafCallback) (*LCPContextProto, error) {
epochRoot, err := d.epochTrie.Commit(onleaf)
//function to write tries to memory
func (d *LCPContext) CommitTo(db ethdb.Database) (*LCPContextProto, error) {
epochRoot, err := d.epochTrie.Commit(nil)
if err != nil {
return nil, err
}
delegateRoot, err := d.delegateTrie.Commit(onleaf)
delegateRoot, err := d.delegateTrie.Commit(nil)
if err != nil {
return nil, err
}
voteRoot, err := d.voteTrie.Commit(onleaf)
voteRoot, err := d.voteTrie.Commit(nil)
if err != nil {
return nil, err
}
candidateRoot, err := d.candidateTrie.Commit(onleaf)
candidateRoot, err := d.candidateTrie.Commit(nil)
if err != nil {
return nil, err
}
mintCntRoot, err := d.mintCntTrie.Commit(onleaf)
mintCntRoot, err := d.mintCntTrie.Commit(nil)
if err != nil {
return nil, err
}
blockPeriod, err := d.periodBlock.Commit(onleaf)
blockPeriod, err := d.periodBlock.Commit(nil)
if err != nil {
return nil, err
}
maxVal, err := d.maxValidators.Commit(onleaf)
maxVal, err := d.maxValidators.Commit(nil)
if err != nil {
return nil, err
}
epochInterv, err := d.epochInterval.Commit(onleaf)
epochInterv, err := d.epochInterval.Commit(nil)
if err != nil {
return nil, err
}
@ -432,10 +441,10 @@ func (d *LCPContext) DelegateTrie() *trie.Trie { return d.delegateTrie
func (d *LCPContext) VoteTrie() *trie.Trie { return d.voteTrie }
func (d *LCPContext) EpochTrie() *trie.Trie { return d.epochTrie }
func (d *LCPContext) MintCntTrie() *trie.Trie { return d.mintCntTrie }
func (d *LCPContext) periodTrie() *trie.Trie { return d.periodBlock }
func (d *LCPContext) maxValidatorTrie() *trie.Trie { return d.maxValidators }
func (d *LCPContext) epochIntervalTrie() *trie.Trie { return d.epochInterval }
func (d *LCPContext) DB() *trie.Database { return d.db }
func (d *LCPContext) periodTrie() *trie.Trie { return d.periodBlock }
func (d *LCPContext) maxValidatorTrie() *trie.Trie { return d.maxValidators }
func (d *LCPContext) epochIntervalTrie() *trie.Trie { return d.epochInterval }
func (d *LCPContext) DB() ethdb.Database { return d.db }
func (dc *LCPContext) SetEpoch(epoch *trie.Trie) { dc.epochTrie = epoch }
func (dc *LCPContext) SetDelegate(delegate *trie.Trie) { dc.delegateTrie = delegate }
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/hexutil"
"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/lcp"
"github.com/pavelkrolevets/go-ethereum/core"
"github.com/pavelkrolevets/go-ethereum/core/bloombits"
"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
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 chainConfig.Clique != nil {
return clique.New(chainConfig.Clique, db)
// If LCP is requested, set it up
if chainConfig.LCP != nil {
return lcp.New(chainConfig.LCP, db)
}
// Otherwise assume proof-of-work
switch config.PowMode {

View file

@ -265,7 +265,7 @@ func (self *worker) update() {
self.currentMu.Unlock()
} else {
// 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()
}
}

View file

@ -57,13 +57,6 @@ type DatabaseReader interface {
// Has retrieves whether a key is present in the database.
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
// 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 {
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
// yet unknown. This method should only be used for non-trie nodes that require
// reference counting, since trie nodes are garbage collected directly through