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
import (
"io/ioutil"
"math/big"
"os"
"path/filepath"
"testing"
"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)
@ -80,73 +72,73 @@ var daoProForkGenesis = `{
var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
var daoGenesisForkBlock = big.NewInt(314)
// 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.
func TestDAOForkBlockNewChain(t *testing.T) {
for i, arg := range []struct {
genesis string
expectBlock *big.Int
expectVote bool
}{
// Test DAO Default Mainnet
{"", params.MainnetChainConfig.DAOForkBlock, true},
// test DAO Init Old Privnet
{daoOldGenesis, nil, false},
// test DAO Default No Fork Privnet
{daoNoForkGenesis, daoGenesisForkBlock, false},
// test DAO Default Pro Fork Privnet
{daoProForkGenesis, daoGenesisForkBlock, true},
} {
testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote)
}
}
func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) {
// Create a temporary data directory to use and inspect later
datadir := tmpdir(t)
defer os.RemoveAll(datadir)
// Start a Geth instance with the requested flags set and immediately terminate
if genesis != "" {
json := filepath.Join(datadir, "genesis.json")
if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
t.Fatalf("test %d: failed to write genesis file: %v", test, err)
}
runGeth(t, "--datadir", datadir, "init", json).WaitExit()
} else {
// Force chain initialization
args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
geth.WaitExit()
}
// Retrieve the DAO config flag from the database
path := filepath.Join(datadir, "geth", "chaindata")
db, err := ethdb.NewLDBDatabase(path, 0, 0)
if err != nil {
t.Fatalf("test %d: failed to open test database: %v", test, err)
}
defer db.Close()
genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
if genesis != "" {
genesisHash = daoGenesisHash
}
config := rawdb.ReadChainConfig(db, genesisHash)
if config == nil {
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).
}
// Validate the DAO hard-fork block number against the expected value
if config.DAOForkBlock == nil {
if expectBlock != nil {
t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock)
}
} else if expectBlock == nil {
t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock)
} else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock)
}
if config.DAOForkSupport != expectVote {
t.Errorf("test %d: dao hard-fork support mismatch: have %v, want %v", test, config.DAOForkSupport, expectVote)
}
}
//// 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.
//func TestDAOForkBlockNewChain(t *testing.T) {
// for i, arg := range []struct {
// genesis string
// expectBlock *big.Int
// expectVote bool
// }{
// // Test DAO Default Mainnet
// {"", params.LcpConfig.DAOForkBlock, true},
// // test DAO Init Old Privnet
// {daoOldGenesis, nil, false},
// // test DAO Default No Fork Privnet
// {daoNoForkGenesis, daoGenesisForkBlock, false},
// // test DAO Default Pro Fork Privnet
// {daoProForkGenesis, daoGenesisForkBlock, true},
// } {
// testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote)
// }
//}
//
//func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) {
// // Create a temporary data directory to use and inspect later
// datadir := tmpdir(t)
// defer os.RemoveAll(datadir)
//
// // Start a Geth instance with the requested flags set and immediately terminate
// if genesis != "" {
// json := filepath.Join(datadir, "genesis.json")
// if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
// t.Fatalf("test %d: failed to write genesis file: %v", test, err)
// }
// runGeth(t, "--datadir", datadir, "init", json).WaitExit()
// } else {
// // Force chain initialization
// args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
// geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
// geth.WaitExit()
// }
// // Retrieve the DAO config flag from the database
// path := filepath.Join(datadir, "geth", "chaindata")
// db, err := ethdb.NewLDBDatabase(path, 0, 0)
// if err != nil {
// t.Fatalf("test %d: failed to open test database: %v", test, err)
// }
// defer db.Close()
//
// genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
// if genesis != "" {
// genesisHash = daoGenesisHash
// }
// config := rawdb.ReadChainConfig(db, genesisHash)
// if config == nil {
// 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).
// }
// // Validate the DAO hard-fork block number against the expected value
// if config.DAOForkBlock == nil {
// if expectBlock != nil {
// t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock)
// }
// } else if expectBlock == nil {
// t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock)
// } else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
// t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock)
// }
// if 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"
"fmt"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"runtime"
@ -34,7 +33,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/ethash"
"github.com/pavelkrolevets/go-ethereum/core"
"github.com/pavelkrolevets/go-ethereum/core/state"
"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
if config.LCP != nil {
engine = lcp.New(config.LCP, chainDb)
} else {
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,
})
}
} else {fmt.Println("No engine defined!!!")
}
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
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
// consensus rules that happen at finalization (e.g. block rewards).
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 place on top.
@ -97,7 +97,7 @@ type Engine interface {
// APIs returns the RPC APIs this consensus engine provides.
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
}

View file

@ -128,11 +128,12 @@ func sigHash(header *types.Header) (hash common.Hash) {
func New(config *params.LcpConfig, db ethdb.Database) *LCP {
signatures, _ := lru.NewARC(inmemorySignatures)
return &LCP{
Lcp := &LCP{
config: config,
db: db,
signatures: signatures,
}
return Lcp
}
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))
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)
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
root, err := statedb.Commit(config.IsEIP158(b.header.Number))
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...)
}
// 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
}

View file

@ -235,6 +235,7 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data
return db, nil
}
// APIs return the collection of RPC services the ethereum package offers.
// NOTE, some of these services probably need to be moved to somewhere else.
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/discv5"
"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 {
@ -102,7 +103,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
peers: peers,
reqDist: newRequestDistributor(peers, quitSync),
accountManager: ctx.AccountManager,
engine: eth.CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb),
engine: lcp.New(chainConfig.LCP, chainDb),
shutdownChan: make(chan bool),
networkId: config.NetworkId,
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
// 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)
} else {
// 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)
// 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)
return
}