From 7d46b7f6ff877ba3526cae033df4d005db5dbd2d Mon Sep 17 00:00:00 2001 From: pavelkrolevets Date: Tue, 21 Aug 2018 12:50:03 +0800 Subject: [PATCH] ADDED LCP engine --- cmd/utils/flags.go | 30 +++------------- consensus/lcp/lcp.go | 13 ++++--- core/blockchain_test.go | 2 +- core/genesis.go | 4 +-- core/genesis_test.go | 26 +++++++------- core/types/lcp_context.go | 75 ++++++++++++++++++++++----------------- eth/backend.go | 8 ++--- miner/worker.go | 2 +- trie/database.go | 12 ------- 9 files changed, 73 insertions(+), 99 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 8725a28737..f422ed922c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -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) { diff --git a/consensus/lcp/lcp.go b/consensus/lcp/lcp.go index c7c7688a15..bc59933bda 100644 --- a/consensus/lcp/lcp.go +++ b/consensus/lcp/lcp.go @@ -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 { diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 5806d078b0..a5fc6e073a 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -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 diff --git a/core/genesis.go b/core/genesis.go index dcf0e7eccc..e7f593306a 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -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 } diff --git a/core/genesis_test.go b/core/genesis_test.go index 523bd18b1a..cd4900054b 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -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", diff --git a/core/types/lcp_context.go b/core/types/lcp_context.go index 06652c9b80..79f1ab3296 100644 --- a/core/types/lcp_context.go +++ b/core/types/lcp_context.go @@ -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 } diff --git a/eth/backend.go b/eth/backend.go index 22c453f05c..8b90e957ca 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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 { diff --git a/miner/worker.go b/miner/worker.go index 2d5cb5d71b..0f605bed6d 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -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() } } diff --git a/trie/database.go b/trie/database.go index bd30223730..7cb4083263 100644 --- a/trie/database.go +++ b/trie/database.go @@ -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