diff options
Diffstat (limited to 'eth')
-rw-r--r-- | eth/api.go | 33 | ||||
-rw-r--r-- | eth/backend.go | 11 | ||||
-rw-r--r-- | eth/downloader/downloader.go | 36 | ||||
-rw-r--r-- | eth/downloader/downloader_test.go | 5 | ||||
-rw-r--r-- | eth/downloader/queue.go | 4 | ||||
-rw-r--r-- | eth/handler_test.go | 2 |
6 files changed, 65 insertions, 26 deletions
diff --git a/eth/api.go b/eth/api.go index 4b26396aa..38b67a07a 100644 --- a/eth/api.go +++ b/eth/api.go @@ -610,13 +610,14 @@ type callmsg struct { } // accessor boilerplate to implement core.Message -func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } -func (m callmsg) Nonce() uint64 { return m.from.Nonce() } -func (m callmsg) To() *common.Address { return m.to } -func (m callmsg) GasPrice() *big.Int { return m.gasPrice } -func (m callmsg) Gas() *big.Int { return m.gas } -func (m callmsg) Value() *big.Int { return m.value } -func (m callmsg) Data() []byte { return m.data } +func (m callmsg) From() (common.Address, error) { return m.from.Address(), nil } +func (m callmsg) FromFrontier() (common.Address, error) { return m.from.Address(), nil } +func (m callmsg) Nonce() uint64 { return m.from.Nonce() } +func (m callmsg) To() *common.Address { return m.to } +func (m callmsg) GasPrice() *big.Int { return m.gasPrice } +func (m callmsg) Gas() *big.Int { return m.gas } +func (m callmsg) Value() *big.Int { return m.value } +func (m callmsg) Data() []byte { return m.data } type CallArgs struct { From common.Address `json:"from"` @@ -762,7 +763,7 @@ type RPCTransaction struct { // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { - from, _ := tx.From() + from, _ := tx.FromFrontier() return &RPCTransaction{ From: from, @@ -780,7 +781,7 @@ func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransaction, error) { if txIndex >= 0 && txIndex < len(b.Transactions()) { tx := b.Transactions()[txIndex] - from, err := tx.From() + from, err := tx.FromFrontier() if err != nil { return nil, err } @@ -970,7 +971,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (ma return nil, nil } - from, err := tx.From() + from, err := tx.FromFrontier() if err != nil { glog.V(logger.Debug).Infof("%v\n", err) return nil, nil @@ -1084,7 +1085,7 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(encodedTx string) (string, } if tx.To() == nil { - from, err := tx.From() + from, err := tx.FromFrontier() if err != nil { return "", err } @@ -1186,7 +1187,7 @@ type SignTransactionResult struct { } func newTx(t *types.Transaction) *Tx { - from, _ := t.From() + from, _ := t.FromFrontier() return &Tx{ tx: t, To: t.To(), @@ -1259,7 +1260,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err pending := s.txPool.GetTransactions() transactions := make([]*RPCTransaction, 0) for _, tx := range pending { - if from, _ := tx.From(); accountSet.Has(from) { + if from, _ := tx.FromFrontier(); accountSet.Has(from) { transactions = append(transactions, newRPCPendingTransaction(tx)) } } @@ -1294,7 +1295,7 @@ func (s *PublicTransactionPoolAPI) NewPendingTransactions() (rpc.Subscription, e } tx := transaction.(core.TxPreEvent) - if from, err := tx.Tx.From(); err == nil { + if from, err := tx.Tx.FromFrontier(); err == nil { if accountSet.Has(from) { return tx.Tx.Hash() } @@ -1311,7 +1312,7 @@ func (s *PublicTransactionPoolAPI) Resend(tx *Tx, gasPrice, gasLimit *rpc.HexNum pending := s.txPool.GetTransactions() for _, p := range pending { - if pFrom, err := p.From(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() { + if pFrom, err := p.FromFrontier(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() { if gasPrice == nil { gasPrice = rpc.NewHexNumber(tx.tx.GasPrice()) } @@ -1585,7 +1586,7 @@ func (s *PrivateDebugAPI) doReplayTransaction(txHash common.Hash) ([]vm.StructLo return nil, nil, nil, err } - txFrom, err := tx.From() + txFrom, err := tx.FromFrontier() if err != nil { return nil, nil, nil, fmt.Errorf("Unable to create transaction sender") diff --git a/eth/backend.go b/eth/backend.go index 2f0bc3ee5..f62ee976d 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -74,6 +74,7 @@ type Config struct { DocRoot string AutoDAG bool PowTest bool + PowShared bool ExtraData []byte AccountManager *accounts.Manager @@ -211,14 +212,18 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { GpobaseCorrectionFactor: config.GpobaseCorrectionFactor, httpclient: httpclient.New(config.DocRoot), } - - if config.PowTest { + switch { + case config.PowTest: glog.V(logger.Info).Infof("ethash used in test mode") eth.pow, err = ethash.NewForTesting() if err != nil { return nil, err } - } else { + case config.PowShared: + glog.V(logger.Info).Infof("ethash used in shared mode") + eth.pow = ethash.NewShared() + + default: eth.pow = ethash.New() } //genesis := core.GenesisBlock(uint64(config.GenesisNonce), stateDb) diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 6dad6a2cd..143d8bde7 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -571,8 +571,14 @@ func (d *Downloader) findAncestor61(p *peer) (uint64, error) { // Check if a common ancestor was found finished = true for i := len(hashes) - 1; i >= 0; i-- { + // Skip any headers that underflow/overflow our requested set + header := d.getHeader(hashes[i]) + if header == nil || header.Number.Int64() < from || header.Number.Uint64() > head { + continue + } + // Otherwise check if we already know the header or not if d.hasBlockAndState(hashes[i]) { - number, hash = uint64(from)+uint64(i), hashes[i] + number, hash = header.Number.Uint64(), header.Hash() break } } @@ -990,12 +996,28 @@ func (d *Downloader) findAncestor(p *peer) (uint64, error) { // Make sure the peer actually gave something valid headers := packet.(*headerPack).headers if len(headers) == 0 { - glog.V(logger.Debug).Infof("%v: empty head header set", p) + glog.V(logger.Warn).Infof("%v: empty head header set", p) return 0, errEmptyHeaderSet } + // Make sure the peer's reply conforms to the request + for i := 0; i < len(headers); i++ { + if number := headers[i].Number.Int64(); number != from+int64(i) { + glog.V(logger.Warn).Infof("%v: head header set (item %d) broke chain ordering: requested %d, got %d", p, i, from+int64(i), number) + return 0, errInvalidChain + } + if i > 0 && headers[i-1].Hash() != headers[i].ParentHash { + glog.V(logger.Warn).Infof("%v: head header set (item %d) broke chain ancestry: expected [%x], got [%x]", p, i, headers[i-1].Hash().Bytes()[:4], headers[i].ParentHash[:4]) + return 0, errInvalidChain + } + } // Check if a common ancestor was found finished = true for i := len(headers) - 1; i >= 0; i-- { + // Skip any headers that underflow/overflow our requested set + if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > head { + continue + } + // Otherwise check if we already know the header or not if (d.mode != LightSync && d.hasBlockAndState(headers[i].Hash())) || (d.mode == LightSync && d.hasHeader(headers[i].Hash())) { number, hash = headers[i].Number.Uint64(), headers[i].Hash() break @@ -1206,6 +1228,10 @@ func (d *Downloader) fetchHeaders(p *peer, td *big.Int, from uint64) error { frequency = 1 } if n, err := d.insertHeaders(headers, frequency); err != nil { + // If some headers were inserted, add them too to the rollback list + if n > 0 { + rollback = append(rollback, headers[:n]...) + } glog.V(logger.Debug).Infof("%v: invalid header #%d [%x…]: %v", p, headers[n].Number, headers[n].Hash().Bytes()[:4], err) return errInvalidChain } @@ -1223,7 +1249,7 @@ func (d *Downloader) fetchHeaders(p *peer, td *big.Int, from uint64) error { } } // Notify the content fetchers of new headers, but stop if queue is full - cont := d.queue.PendingBlocks() < maxQueuedHeaders || d.queue.PendingReceipts() < maxQueuedHeaders + cont := d.queue.PendingBlocks() < maxQueuedHeaders && d.queue.PendingReceipts() < maxQueuedHeaders for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh, d.stateWakeCh} { if cont { // We still have headers to fetch, send continuation wake signal (potential) @@ -1237,9 +1263,11 @@ func (d *Downloader) fetchHeaders(p *peer, td *big.Int, from uint64) error { case ch <- false: case <-d.cancelCh: } - return nil } } + if !cont { + return nil + } // Queue not yet full, fetch the next batch from += uint64(len(headers)) getHeaders(from) diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 993190c38..ff57fe167 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -43,6 +43,11 @@ var ( genesis = core.GenesisBlockForTesting(testdb, testAddress, big.NewInt(1000000000)) ) +// Reduce the block cache limit, otherwise the tests will be very heavy. +func init() { + blockCacheLimit = 1024 +} + // makeChain creates a chain of n blocks starting at and including parent. // the returned hash chain is ordered head->parent. In addition, every 3rd block // contains a transaction and every 5th an uncle to allow testing correct block diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 9d0f2914d..bc9428ecf 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -39,7 +39,7 @@ import ( ) var ( - blockCacheLimit = 1024 // Maximum number of blocks to cache before throttling the download + blockCacheLimit = 8192 // Maximum number of blocks to cache before throttling the download maxInFlightStates = 4096 // Maximum number of state downloads to allow concurrently ) @@ -977,7 +977,7 @@ func (q *queue) DeliverNodeData(id string, data [][]byte, callback func(error, i process := []trie.SyncResult{} for _, blob := range data { // Skip any state trie entires that were not requested - hash := common.BytesToHash(crypto.Sha3(blob)) + hash := common.BytesToHash(crypto.Keccak256(blob)) if _, ok := request.Hashes[hash]; !ok { errs = append(errs, fmt.Errorf("non-requested state data %x", hash)) continue diff --git a/eth/handler_test.go b/eth/handler_test.go index 148d56cc6..e5974c23c 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -481,7 +481,7 @@ func testGetNodeData(t *testing.T, protocol int) { } // Verify that all hashes correspond to the requested data, and reconstruct a state tree for i, want := range hashes { - if hash := crypto.Sha3Hash(data[i]); hash != want { + if hash := crypto.Keccak256Hash(data[i]); hash != want { fmt.Errorf("data hash mismatch: have %x, want %x", hash, want) } } |