diff options
Diffstat (limited to 'eth')
-rw-r--r-- | eth/api.go | 83 | ||||
-rw-r--r-- | eth/backend.go | 20 | ||||
-rw-r--r-- | eth/config.go | 39 | ||||
-rw-r--r-- | eth/downloader/downloader.go | 14 | ||||
-rw-r--r-- | eth/downloader/fakepeer.go | 2 | ||||
-rw-r--r-- | eth/downloader/peer.go | 2 | ||||
-rw-r--r-- | eth/filters/filter.go | 3 | ||||
-rw-r--r-- | eth/gen_config.go | 51 |
8 files changed, 144 insertions, 70 deletions
diff --git a/eth/api.go b/eth/api.go index e91f51bb9..12448a6a1 100644 --- a/eth/api.go +++ b/eth/api.go @@ -636,3 +636,86 @@ func storageRangeAt(st state.Trie, start []byte, maxResult int) StorageRangeResu } return result } + +// GetModifiedAccountsByumber returns all accounts that have changed between the +// two blocks specified. A change is defined as a difference in nonce, balance, +// code hash, or storage hash. +// +// With one parameter, returns the list of accounts modified in the specified block. +func (api *PrivateDebugAPI) GetModifiedAccountsByNumber(startNum uint64, endNum *uint64) ([]common.Address, error) { + var startBlock, endBlock *types.Block + + startBlock = api.eth.blockchain.GetBlockByNumber(startNum) + if startBlock == nil { + return nil, fmt.Errorf("start block %x not found", startNum) + } + + if endNum == nil { + endBlock = startBlock + startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash()) + if startBlock == nil { + return nil, fmt.Errorf("block %x has no parent", endBlock.Number()) + } + } else { + endBlock = api.eth.blockchain.GetBlockByNumber(*endNum) + if endBlock == nil { + return nil, fmt.Errorf("end block %d not found", *endNum) + } + } + return api.getModifiedAccounts(startBlock, endBlock) +} + +// GetModifiedAccountsByHash returns all accounts that have changed between the +// two blocks specified. A change is defined as a difference in nonce, balance, +// code hash, or storage hash. +// +// With one parameter, returns the list of accounts modified in the specified block. +func (api *PrivateDebugAPI) GetModifiedAccountsByHash(startHash common.Hash, endHash *common.Hash) ([]common.Address, error) { + var startBlock, endBlock *types.Block + startBlock = api.eth.blockchain.GetBlockByHash(startHash) + if startBlock == nil { + return nil, fmt.Errorf("start block %x not found", startHash) + } + + if endHash == nil { + endBlock = startBlock + startBlock = api.eth.blockchain.GetBlockByHash(startBlock.ParentHash()) + if startBlock == nil { + return nil, fmt.Errorf("block %x has no parent", endBlock.Number()) + } + } else { + endBlock = api.eth.blockchain.GetBlockByHash(*endHash) + if endBlock == nil { + return nil, fmt.Errorf("end block %x not found", *endHash) + } + } + return api.getModifiedAccounts(startBlock, endBlock) +} + +func (api *PrivateDebugAPI) getModifiedAccounts(startBlock, endBlock *types.Block) ([]common.Address, error) { + if startBlock.Number().Uint64() >= endBlock.Number().Uint64() { + return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startBlock.Number().Uint64(), endBlock.Number().Uint64()) + } + + oldTrie, err := trie.NewSecure(startBlock.Root(), api.eth.chainDb, 0) + if err != nil { + return nil, err + } + newTrie, err := trie.NewSecure(endBlock.Root(), api.eth.chainDb, 0) + if err != nil { + return nil, err + } + + diff, _ := trie.NewDifferenceIterator(oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{})) + iter := trie.NewIterator(diff) + + var dirty []common.Address + for iter.Next() { + key := newTrie.GetKey(iter.Key) + if key == nil { + return nil, fmt.Errorf("no preimage found for hash %x", iter.Key) + } + dirty = append(dirty, common.BytesToAddress(key)) + } + return dirty, nil +} diff --git a/eth/backend.go b/eth/backend.go index 1cd9e8fff..e7f0f57dd 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -125,7 +125,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { chainConfig: chainConfig, eventMux: ctx.EventMux, accountManager: ctx.AccountManager, - engine: CreateConsensusEngine(ctx, config, chainConfig, chainDb), + engine: CreateConsensusEngine(ctx, &config.Ethash, chainConfig, chainDb), shutdownChan: make(chan bool), stopDbUpgrade: stopDbUpgrade, networkId: config.NetworkId, @@ -209,25 +209,31 @@ 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 *Config, chainConfig *params.ChainConfig, db ethdb.Database) consensus.Engine { +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) } // Otherwise assume proof-of-work switch { - case config.PowFake: + case config.PowMode == ethash.ModeFake: log.Warn("Ethash used in fake mode") return ethash.NewFaker() - case config.PowTest: + case config.PowMode == ethash.ModeTest: log.Warn("Ethash used in test mode") return ethash.NewTester() - case config.PowShared: + case config.PowMode == ethash.ModeShared: log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - engine := ethash.New(ctx.ResolvePath(config.EthashCacheDir), config.EthashCachesInMem, config.EthashCachesOnDisk, - config.EthashDatasetDir, config.EthashDatasetsInMem, config.EthashDatasetsOnDisk) + engine := ethash.New(ethash.Config{ + CacheDir: ctx.ResolvePath(config.CacheDir), + CachesInMem: config.CachesInMem, + CachesOnDisk: config.CachesOnDisk, + DatasetDir: config.DatasetDir, + DatasetsInMem: config.DatasetsInMem, + DatasetsOnDisk: config.DatasetsOnDisk, + }) engine.SetThreads(-1) // Disable CPU mining return engine } diff --git a/eth/config.go b/eth/config.go index 7bcfd403e..383cd6783 100644 --- a/eth/config.go +++ b/eth/config.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -33,16 +34,18 @@ import ( // DefaultConfig contains default settings for use on the Ethereum main net. var DefaultConfig = Config{ - SyncMode: downloader.FastSync, - EthashCacheDir: "ethash", - EthashCachesInMem: 2, - EthashCachesOnDisk: 3, - EthashDatasetsInMem: 1, - EthashDatasetsOnDisk: 2, - NetworkId: 1, - LightPeers: 20, - DatabaseCache: 128, - GasPrice: big.NewInt(18 * params.Shannon), + SyncMode: downloader.FastSync, + Ethash: ethash.Config{ + CacheDir: "ethash", + CachesInMem: 2, + CachesOnDisk: 3, + DatasetsInMem: 1, + DatasetsOnDisk: 2, + }, + NetworkId: 1, + LightPeers: 20, + DatabaseCache: 128, + GasPrice: big.NewInt(18 * params.Shannon), TxPool: core.DefaultTxPoolConfig, GPO: gasprice.Config{ @@ -59,9 +62,9 @@ func init() { } } if runtime.GOOS == "windows" { - DefaultConfig.EthashDatasetDir = filepath.Join(home, "AppData", "Ethash") + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, "AppData", "Ethash") } else { - DefaultConfig.EthashDatasetDir = filepath.Join(home, ".ethash") + DefaultConfig.Ethash.DatasetDir = filepath.Join(home, ".ethash") } } @@ -92,12 +95,7 @@ type Config struct { GasPrice *big.Int // Ethash options - EthashCacheDir string - EthashCachesInMem int - EthashCachesOnDisk int - EthashDatasetDir string - EthashDatasetsInMem int - EthashDatasetsOnDisk int + Ethash ethash.Config // Transaction pool options TxPool core.TxPoolConfig @@ -109,10 +107,7 @@ type Config struct { EnablePreimageRecording bool // Miscellaneous options - DocRoot string `toml:"-"` - PowFake bool `toml:"-"` - PowTest bool `toml:"-"` - PowShared bool `toml:"-"` + DocRoot string `toml:"-"` } type configMarshaling struct { diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 5782d4cf5..b338129e0 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -333,7 +333,7 @@ func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode } // synchronise will select the peer and use it for synchronising. If an empty string is given -// it will use the best peer possible and synchronize if it's TD is higher than our own. If any of the +// it will use the best peer possible and synchronize if its TD is higher than our own. If any of the // checks fail an error will be returned. This method is synchronous func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode SyncMode) error { // Mock out the synchronisation if testing @@ -708,7 +708,7 @@ func (d *Downloader) findAncestor(p *peerConnection, height uint64) (uint64, err ttl := d.requestTTL() timeout := time.After(ttl) - go p.peer.RequestHeadersByNumber(uint64(check), 1, 0, false) + go p.peer.RequestHeadersByNumber(check, 1, 0, false) // Wait until a reply arrives to this request for arrived := false; !arrived; { @@ -1003,8 +1003,8 @@ func (d *Downloader) fetchParts(errCancel error, deliveryCh chan dataPack, deliv return errCancel case packet := <-deliveryCh: - // If the peer was previously banned and failed to deliver it's pack - // in a reasonable time frame, ignore it's message. + // If the peer was previously banned and failed to deliver its pack + // in a reasonable time frame, ignore its message. if peer := d.peers.Peer(packet.PeerId()); peer != nil { // Deliver the received chunk of data and check chain validity accepted, err := deliver(packet) @@ -1205,8 +1205,8 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error { case <-d.cancelCh: } } - // If no headers were retrieved at all, the peer violated it's TD promise that it had a - // better chain compared to ours. The only exception is if it's promised blocks were + // If no headers were retrieved at all, the peer violated its TD promise that it had a + // better chain compared to ours. The only exception is if its promised blocks were // already imported by other means (e.g. fecher): // // R <remote peer>, L <local node>: Both at block 10 @@ -1518,7 +1518,7 @@ func (d *Downloader) deliver(id string, destCh chan dataPack, packet dataPack, i func (d *Downloader) qosTuner() { for { // Retrieve the current median RTT and integrate into the previoust target RTT - rtt := time.Duration(float64(1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT())) + rtt := time.Duration((1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT())) atomic.StoreUint64(&d.rttEstimate, uint64(rtt)) // A new RTT cycle passed, increase our confidence in the estimated RTT diff --git a/eth/downloader/fakepeer.go b/eth/downloader/fakepeer.go index ebdb9c334..b45acff7d 100644 --- a/eth/downloader/fakepeer.go +++ b/eth/downloader/fakepeer.go @@ -62,7 +62,7 @@ func (p *FakePeer) RequestHeadersByHash(hash common.Hash, amount int, skip int, number := origin.Number.Uint64() headers = append(headers, origin) if reverse { - for i := 0; i < int(skip)+1; i++ { + for i := 0; i <= skip; i++ { if header := p.hc.GetHeader(hash, number); header != nil { hash = header.ParentHash number-- diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go index e638744ea..a4aa86114 100644 --- a/eth/downloader/peer.go +++ b/eth/downloader/peer.go @@ -548,7 +548,7 @@ func (ps *peerSet) idlePeers(minProtocol, maxProtocol int, idleCheck func(*peerC return idle, total } -// medianRTT returns the median RTT of te peerset, considering only the tuning +// medianRTT returns the median RTT of the peerset, considering only the tuning // peers if there are more peers available. func (ps *peerSet) medianRTT() time.Duration { // Gather all the currnetly measured round trip times diff --git a/eth/filters/filter.go b/eth/filters/filter.go index d16af84ee..43d7e2a81 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -158,6 +158,7 @@ func (f *Filter) indexedLogs(ctx context.Context, end uint64) ([]*types.Log, err return logs, err } f.begin = int64(number) + 1 + // Retrieve the suggested block and pull any truly matching logs header, err := f.backend.HeaderByNumber(ctx, rpc.BlockNumber(number)) if header == nil || err != nil { @@ -206,7 +207,7 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) (logs [ } var unfiltered []*types.Log for _, receipt := range receipts { - unfiltered = append(unfiltered, ([]*types.Log)(receipt.Logs)...) + unfiltered = append(unfiltered, receipt.Logs...) } logs = filterLogs(unfiltered, nil, nil, f.addresses, f.topics) if len(logs) > 0 { diff --git a/eth/gen_config.go b/eth/gen_config.go index 4a4cd7b9c..e2d50e1f6 100644 --- a/eth/gen_config.go +++ b/eth/gen_config.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -36,10 +37,8 @@ func (c Config) MarshalTOML() (interface{}, error) { TxPool core.TxPoolConfig GPO gasprice.Config EnablePreimageRecording bool - DocRoot string `toml:"-"` - PowFake bool `toml:"-"` - PowTest bool `toml:"-"` - PowShared bool `toml:"-"` + DocRoot string `toml:"-"` + PowMode ethash.Mode `toml:"-"` } var enc Config enc.Genesis = c.Genesis @@ -54,19 +53,17 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.MinerThreads = c.MinerThreads enc.ExtraData = c.ExtraData enc.GasPrice = c.GasPrice - enc.EthashCacheDir = c.EthashCacheDir - enc.EthashCachesInMem = c.EthashCachesInMem - enc.EthashCachesOnDisk = c.EthashCachesOnDisk - enc.EthashDatasetDir = c.EthashDatasetDir - enc.EthashDatasetsInMem = c.EthashDatasetsInMem - enc.EthashDatasetsOnDisk = c.EthashDatasetsOnDisk + enc.EthashCacheDir = c.Ethash.CacheDir + enc.EthashCachesInMem = c.Ethash.CachesInMem + enc.EthashCachesOnDisk = c.Ethash.CachesOnDisk + enc.EthashDatasetDir = c.Ethash.DatasetDir + enc.EthashDatasetsInMem = c.Ethash.DatasetsInMem + enc.EthashDatasetsOnDisk = c.Ethash.DatasetsOnDisk enc.TxPool = c.TxPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot - enc.PowFake = c.PowFake - enc.PowTest = c.PowTest - enc.PowShared = c.PowShared + enc.PowMode = c.Ethash.PowMode return &enc, nil } @@ -94,10 +91,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { TxPool *core.TxPoolConfig GPO *gasprice.Config EnablePreimageRecording *bool - DocRoot *string `toml:"-"` - PowFake *bool `toml:"-"` - PowTest *bool `toml:"-"` - PowShared *bool `toml:"-"` + DocRoot *string `toml:"-"` + PowMode *ethash.Mode `toml:"-"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -140,22 +135,22 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.GasPrice = dec.GasPrice } if dec.EthashCacheDir != nil { - c.EthashCacheDir = *dec.EthashCacheDir + c.Ethash.CacheDir = *dec.EthashCacheDir } if dec.EthashCachesInMem != nil { - c.EthashCachesInMem = *dec.EthashCachesInMem + c.Ethash.CachesInMem = *dec.EthashCachesInMem } if dec.EthashCachesOnDisk != nil { - c.EthashCachesOnDisk = *dec.EthashCachesOnDisk + c.Ethash.CachesOnDisk = *dec.EthashCachesOnDisk } if dec.EthashDatasetDir != nil { - c.EthashDatasetDir = *dec.EthashDatasetDir + c.Ethash.DatasetDir = *dec.EthashDatasetDir } if dec.EthashDatasetsInMem != nil { - c.EthashDatasetsInMem = *dec.EthashDatasetsInMem + c.Ethash.DatasetsInMem = *dec.EthashDatasetsInMem } if dec.EthashDatasetsOnDisk != nil { - c.EthashDatasetsOnDisk = *dec.EthashDatasetsOnDisk + c.Ethash.DatasetsOnDisk = *dec.EthashDatasetsOnDisk } if dec.TxPool != nil { c.TxPool = *dec.TxPool @@ -169,14 +164,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.DocRoot != nil { c.DocRoot = *dec.DocRoot } - if dec.PowFake != nil { - c.PowFake = *dec.PowFake - } - if dec.PowTest != nil { - c.PowTest = *dec.PowTest - } - if dec.PowShared != nil { - c.PowShared = *dec.PowShared + if dec.PowMode != nil { + c.Ethash.PowMode = *dec.PowMode } return nil } |