Latest changes

This commit is contained in:
pavelkrolevets 2018-08-28 11:12:32 +08:00
parent 92e4d96935
commit 8ee5d4bf63
10 changed files with 90 additions and 102 deletions

View file

@ -17,16 +17,8 @@
package main package main
import ( import (
"io/ioutil"
"math/big" "math/big"
"os"
"path/filepath"
"testing"
"github.com/pavelkrolevets/go-ethereum/common" "github.com/pavelkrolevets/go-ethereum/common"
"github.com/pavelkrolevets/go-ethereum/core/rawdb"
"github.com/pavelkrolevets/go-ethereum/ethdb"
"github.com/pavelkrolevets/go-ethereum/params"
) )
// Genesis block for nodes which don't care about the DAO fork (i.e. not configured) // Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
@ -80,73 +72,73 @@ var daoProForkGenesis = `{
var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0") var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
var daoGenesisForkBlock = big.NewInt(314) var daoGenesisForkBlock = big.NewInt(314)
// TestDAOForkBlockNewChain tests that the DAO hard-fork number and the nodes support/opposition is correctly //// TestDAOForkBlockNewChain tests that the DAO hard-fork number and the nodes support/opposition is correctly
// set in the database after various initialization procedures and invocations. //// set in the database after various initialization procedures and invocations.
func TestDAOForkBlockNewChain(t *testing.T) { //func TestDAOForkBlockNewChain(t *testing.T) {
for i, arg := range []struct { // for i, arg := range []struct {
genesis string // genesis string
expectBlock *big.Int // expectBlock *big.Int
expectVote bool // expectVote bool
}{ // }{
// Test DAO Default Mainnet // // Test DAO Default Mainnet
{"", params.MainnetChainConfig.DAOForkBlock, true}, // {"", params.LcpConfig.DAOForkBlock, true},
// test DAO Init Old Privnet // // test DAO Init Old Privnet
{daoOldGenesis, nil, false}, // {daoOldGenesis, nil, false},
// test DAO Default No Fork Privnet // // test DAO Default No Fork Privnet
{daoNoForkGenesis, daoGenesisForkBlock, false}, // {daoNoForkGenesis, daoGenesisForkBlock, false},
// test DAO Default Pro Fork Privnet // // test DAO Default Pro Fork Privnet
{daoProForkGenesis, daoGenesisForkBlock, true}, // {daoProForkGenesis, daoGenesisForkBlock, true},
} { // } {
testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote) // testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote)
} // }
} //}
//
func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) { //func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) {
// Create a temporary data directory to use and inspect later // // Create a temporary data directory to use and inspect later
datadir := tmpdir(t) // datadir := tmpdir(t)
defer os.RemoveAll(datadir) // defer os.RemoveAll(datadir)
//
// Start a Geth instance with the requested flags set and immediately terminate // // Start a Geth instance with the requested flags set and immediately terminate
if genesis != "" { // if genesis != "" {
json := filepath.Join(datadir, "genesis.json") // json := filepath.Join(datadir, "genesis.json")
if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil { // if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
t.Fatalf("test %d: failed to write genesis file: %v", test, err) // t.Fatalf("test %d: failed to write genesis file: %v", test, err)
} // }
runGeth(t, "--datadir", datadir, "init", json).WaitExit() // runGeth(t, "--datadir", datadir, "init", json).WaitExit()
} else { // } else {
// Force chain initialization // // Force chain initialization
args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir} // args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...) // geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
geth.WaitExit() // geth.WaitExit()
} // }
// Retrieve the DAO config flag from the database // // Retrieve the DAO config flag from the database
path := filepath.Join(datadir, "geth", "chaindata") // path := filepath.Join(datadir, "geth", "chaindata")
db, err := ethdb.NewLDBDatabase(path, 0, 0) // db, err := ethdb.NewLDBDatabase(path, 0, 0)
if err != nil { // if err != nil {
t.Fatalf("test %d: failed to open test database: %v", test, err) // t.Fatalf("test %d: failed to open test database: %v", test, err)
} // }
defer db.Close() // defer db.Close()
//
genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") // genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
if genesis != "" { // if genesis != "" {
genesisHash = daoGenesisHash // genesisHash = daoGenesisHash
} // }
config := rawdb.ReadChainConfig(db, genesisHash) // config := rawdb.ReadChainConfig(db, genesisHash)
if config == nil { // if config == nil {
t.Errorf("test %d: failed to retrieve chain config: %v", test, err) // t.Errorf("test %d: failed to retrieve chain config: %v", test, err)
return // we want to return here, the other checks can't make it past this point (nil panic). // return // we want to return here, the other checks can't make it past this point (nil panic).
} // }
// Validate the DAO hard-fork block number against the expected value // // Validate the DAO hard-fork block number against the expected value
if config.DAOForkBlock == nil { // if config.DAOForkBlock == nil {
if expectBlock != nil { // if expectBlock != nil {
t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock) // t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock)
} // }
} else if expectBlock == nil { // } else if expectBlock == nil {
t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock) // t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock)
} else if config.DAOForkBlock.Cmp(expectBlock) != 0 { // } else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock) // t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock)
} // }
if config.DAOForkSupport != expectVote { // if config.DAOForkSupport != expectVote {
t.Errorf("test %d: dao hard-fork support mismatch: have %v, want %v", test, config.DAOForkSupport, expectVote) // t.Errorf("test %d: dao hard-fork support mismatch: have %v, want %v", test, config.DAOForkSupport, expectVote)
} // }
} //}

View file

@ -21,7 +21,6 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/big"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -34,7 +33,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/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"
"github.com/pavelkrolevets/go-ethereum/core/vm" "github.com/pavelkrolevets/go-ethereum/core/vm"
@ -1261,19 +1259,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
var engine consensus.Engine var engine consensus.Engine
if config.LCP != nil { if config.LCP != nil {
engine = lcp.New(config.LCP, chainDb) engine = lcp.New(config.LCP, chainDb)
} else { } else {fmt.Println("No engine defined!!!")
engine = ethash.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {
engine = ethash.New(ethash.Config{
CacheDir: stack.ResolvePath(eth.DefaultConfig.Ethash.CacheDir),
CachesInMem: eth.DefaultConfig.Ethash.CachesInMem,
CachesOnDisk: eth.DefaultConfig.Ethash.CachesOnDisk,
DatasetDir: stack.ResolvePath(eth.DefaultConfig.Ethash.DatasetDir),
DatasetsInMem: eth.DefaultConfig.Ethash.DatasetsInMem,
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
})
}
} }
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" { if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name) Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
} }

View file

@ -84,7 +84,7 @@ type Engine interface {
// Note: The block header and state database might be updated to reflect any // Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards). // consensus rules that happen at finalization (e.g. block rewards).
Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt, LcpContext *types.LCPContext) (*types.Block, error) uncles []*types.Header, receipts []*types.Receipt, dposContext *types.LCPContext ) (*types.Block, error)
// Seal generates a new block for the given input block with the local miner's // Seal generates a new block for the given input block with the local miner's
// seal place on top. // seal place on top.
@ -97,7 +97,7 @@ type Engine interface {
// APIs returns the RPC APIs this consensus engine provides. // APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainReader) []rpc.API APIs(chain ChainReader) []rpc.API
// Close terminates any background threads maintained by the consensus engine. //// Close terminates any background threads maintained by the consensus engine.
Close() error Close() error
} }

View file

@ -128,11 +128,12 @@ func sigHash(header *types.Header) (hash common.Hash) {
func New(config *params.LcpConfig, db ethdb.Database) *LCP { func New(config *params.LcpConfig, db ethdb.Database) *LCP {
signatures, _ := lru.NewARC(inmemorySignatures) signatures, _ := lru.NewARC(inmemorySignatures)
return &LCP{ Lcp := &LCP{
config: config, config: config,
db: db, db: db,
signatures: signatures, signatures: signatures,
} }
return Lcp
} }
func (d *LCP) Author(header *types.Header) (common.Address, error) { func (d *LCP) Author(header *types.Header) (common.Address, error) {
@ -526,3 +527,8 @@ func updateMintCnt(parentBlockTime, currentBlockTime int64, validator common.Add
binary.BigEndian.PutUint64(newCntBytes, uint64(cnt)) binary.BigEndian.PutUint64(newCntBytes, uint64(cnt))
dposContext.MintCntTrie().TryUpdate(append(newEpochBytes, validator.Bytes()...), newCntBytes) dposContext.MintCntTrie().TryUpdate(append(newEpochBytes, validator.Bytes()...), newCntBytes)
} }
// Close implements consensus.Engine. It's a noop for clique as there is are no background threads.
func (c *LCP) Close() error {
return nil
}

View file

@ -198,7 +198,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
} }
lcp.AccumulateRewards(config, statedb, b.header, b.uncles) lcp.AccumulateRewards(config, statedb, b.header, b.uncles)
if b.engine != nil { if b.engine != nil {
block, _ := b.engine.Finalize(b.chainReader, b.header, statedb, b.txs, b.uncles, b.receipts, b.header.LCPContext) block, _ := b.engine.Finalize(b.chainReader, b.header, statedb, b.txs, b.uncles, b.receipts, parent.LCPContext)
// Write state changes to db // Write state changes to db
root, err := statedb.Commit(config.IsEIP158(b.header.Number)) root, err := statedb.Commit(config.IsEIP158(b.header.Number))
if err != nil { if err != nil {

View file

@ -77,7 +77,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
allLogs = append(allLogs, receipt.Logs...) allLogs = append(allLogs, receipt.Logs...)
} }
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards) // Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles(), receipts, block.LCPContext)
return receipts, allLogs, *usedGas, nil return receipts, allLogs, *usedGas, nil
} }

View file

@ -235,6 +235,7 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data
return db, nil return db, nil
} }
// APIs return the collection of RPC services the ethereum package offers. // APIs return the collection of RPC services the ethereum package offers.
// NOTE, some of these services probably need to be moved to somewhere else. // NOTE, some of these services probably need to be moved to somewhere else.
func (s *Ethereum) APIs() []rpc.API { func (s *Ethereum) APIs() []rpc.API {

View file

@ -43,7 +43,8 @@ import (
"github.com/pavelkrolevets/go-ethereum/p2p" "github.com/pavelkrolevets/go-ethereum/p2p"
"github.com/pavelkrolevets/go-ethereum/p2p/discv5" "github.com/pavelkrolevets/go-ethereum/p2p/discv5"
"github.com/pavelkrolevets/go-ethereum/params" "github.com/pavelkrolevets/go-ethereum/params"
rpc "github.com/pavelkrolevets/go-ethereum/rpc" "github.com/pavelkrolevets/go-ethereum/rpc"
"github.com/pavelkrolevets/go-ethereum/consensus/lcp"
) )
type LightEthereum struct { type LightEthereum struct {
@ -102,7 +103,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
peers: peers, peers: peers,
reqDist: newRequestDistributor(peers, quitSync), reqDist: newRequestDistributor(peers, quitSync),
accountManager: ctx.AccountManager, accountManager: ctx.AccountManager,
engine: eth.CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), engine: lcp.New(chainConfig.LCP, chainDb),
shutdownChan: make(chan bool), shutdownChan: make(chan bool),
networkId: config.NetworkId, networkId: config.NetworkId,
bloomRequests: make(chan chan *bloombits.Retrieval), bloomRequests: make(chan chan *bloombits.Retrieval),

View file

@ -462,7 +462,7 @@ func (self *worker) commitNewWork() {
// Create an empty block based on temporary copied state for sealing in advance without waiting block // Create an empty block based on temporary copied state for sealing in advance without waiting block
// execution finished. // execution finished.
if work.Block, err = self.engine.Finalize(self.chain, header, work.state.Copy(), nil, uncles, nil); err != nil { if work.Block, err = self.engine.Finalize(self.chain, header, work.state.Copy(), nil, uncles, nil, work.LCPContext); err != nil {
log.Error("Failed to finalize block for temporary sealing", "err", err) log.Error("Failed to finalize block for temporary sealing", "err", err)
} else { } else {
// Push empty work in advance without applying pending transaction. // Push empty work in advance without applying pending transaction.
@ -484,7 +484,7 @@ func (self *worker) commitNewWork() {
work.commitTransactions(self.mux, txs, self.chain, self.coinbase) work.commitTransactions(self.mux, txs, self.chain, self.coinbase)
// Create the full block to seal with the consensus engine // Create the full block to seal with the consensus engine
if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil { if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts, work.LCPContext); err != nil {
log.Error("Failed to finalize block for sealing", "err", err) log.Error("Failed to finalize block for sealing", "err", err)
return return
} }