aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
Diffstat (limited to 'eth')
-rw-r--r--eth/api.go33
-rw-r--r--eth/backend.go11
-rw-r--r--eth/downloader/downloader.go36
-rw-r--r--eth/downloader/downloader_test.go5
-rw-r--r--eth/downloader/queue.go4
-rw-r--r--eth/handler_test.go2
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)
}
}