mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
Latest changes
This commit is contained in:
parent
92e4d96935
commit
8ee5d4bf63
10 changed files with 90 additions and 102 deletions
|
|
@ -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)
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ type Header struct {
|
|||
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
|
||||
UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"`
|
||||
Validator common.Address `json:"validator" gencodec:"required"`
|
||||
LCPContext *LCPContextProto `json:"LCPContext" gencodec:"required"`
|
||||
LCPContext *LCPContextProto `json:"LCPContext" gencodec:"required"`
|
||||
Coinbase common.Address `json:"coinbase" gencodec:"required"`
|
||||
Root common.Hash `json:"stateRoot" gencodec:"required"`
|
||||
TxHash common.Hash `json:"transactionsRoot" gencodec:"required"`
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue