Пример #1
0
// reportBlock reports the given block and error using the canonical block
// reporting tool. Reporting the block to the service is handled in a separate
// goroutine.
func reportBlock(block *types.Block, err error) {
	if glog.V(logger.Error) {
		glog.Errorf("Bad block #%v (%s)\n", block.Number(), block.Hash().Hex())
		glog.Errorf("    %v", err)
	}
	go ReportBlock(block, err)
}
Пример #2
0
func NewStateObjectFromBytes(address common.Address, data []byte, db ethdb.Database) *StateObject {
	var extobject struct {
		Nonce    uint64
		Balance  *big.Int
		Root     common.Hash
		CodeHash []byte
	}
	err := rlp.Decode(bytes.NewReader(data), &extobject)
	if err != nil {
		glog.Errorf("can't decode state object %x: %v", address, err)
		return nil
	}
	trie, err := trie.NewSecure(extobject.Root, db)
	if err != nil {
		// TODO: bubble this up or panic
		glog.Errorf("can't create account trie with root %x: %v", extobject.Root[:], err)
		return nil
	}

	object := &StateObject{address: address, db: db}
	object.nonce = extobject.Nonce
	object.balance = extobject.Balance
	object.codeHash = extobject.CodeHash
	object.trie = trie
	object.storage = make(map[string]common.Hash)
	object.code, _ = db.Get(extobject.CodeHash)
	return object
}
Пример #3
0
// Get returns the value for key stored in the trie.
// The value bytes must not be modified by the caller.
func (t *SecureTrie) Get(key []byte) []byte {
	res, err := t.TryGet(key)
	if err != nil && glog.V(logger.Error) {
		glog.Errorf("Unhandled trie error: %v", err)
	}
	return res
}
Пример #4
0
func (self *Iterator) key(node interface{}) []byte {
	switch node := node.(type) {
	case shortNode:
		// Leaf node
		k := remTerm(node.Key)
		if vnode, ok := node.Val.(valueNode); ok {
			self.Value = vnode
			return k
		}
		return append(k, self.key(node.Val)...)
	case fullNode:
		if node.Children[16] != nil {
			self.Value = node.Children[16].(valueNode)
			return []byte{16}
		}
		for i := 0; i < 16; i++ {
			k := self.key(node.Children[i])
			if k != nil {
				return append([]byte{byte(i)}, k...)
			}
		}
	case hashNode:
		rn, err := self.trie.resolveHash(node, nil, nil)
		if err != nil && glog.V(logger.Error) {
			glog.Errorf("Unhandled trie error: %v", err)
		}
		return self.key(rn)
	}
	return nil
}
Пример #5
0
// checkQueue moves transactions that have become processable to main pool.
func (pool *TxPool) checkQueue() {
	// init delayed since tx pool could have been started before any state sync
	if pool.pendingState == nil {
		pool.resetState()
	}

	var addq txQueue
	for address, txs := range pool.queue {
		// guessed nonce is the nonce currently kept by the tx pool (pending state)
		guessedNonce := pool.pendingState.GetNonce(address)
		// true nonce is the nonce known by the last state
		currentState, err := pool.currentState()
		if err != nil {
			glog.Errorf("could not get current state: %v", err)
			return
		}
		trueNonce := currentState.GetNonce(address)
		addq := addq[:0]
		for hash, tx := range txs {
			if tx.Nonce() < trueNonce {
				// Drop queued transactions whose nonce is lower than
				// the account nonce because they have been processed.
				delete(txs, hash)
			} else {
				// Collect the remaining transactions for the next pass.
				addq = append(addq, txQueueEntry{hash, address, tx})
			}
		}
		// Find the next consecutive nonce range starting at the
		// current account nonce.
		sort.Sort(addq)
		for i, e := range addq {
			// start deleting the transactions from the queue if they exceed the limit
			if i > maxQueued {
				delete(pool.queue[address], e.hash)
				continue
			}

			if e.Nonce() > guessedNonce {
				if len(addq)-i > maxQueued {
					if glog.V(logger.Debug) {
						glog.Infof("Queued tx limit exceeded for %s. Tx %s removed\n", common.PP(address[:]), common.PP(e.hash[:]))
					}
					for j := i + maxQueued; j < len(addq); j++ {
						delete(txs, addq[j].hash)
					}
				}
				break
			}
			delete(txs, e.hash)
			pool.addTx(e.hash, address, e.Transaction)
		}
		// Delete the entire queue entry if it became empty.
		if len(txs) == 0 {
			delete(pool.queue, address)
		}
	}
}
Пример #6
0
// Prove constructs a merkle proof for key. The result contains all
// encoded nodes on the path to the value at key. The value itself is
// also included in the last node and can be retrieved by verifying
// the proof.
//
// If the trie does not contain a value for key, the returned proof
// contains all nodes of the longest existing prefix of the key
// (at least the root node), ending with the node that proves the
// absence of the key.
func (t *Trie) Prove(key []byte) []rlp.RawValue {
	// Collect all nodes on the path to key.
	key = compactHexDecode(key)
	nodes := []node{}
	tn := t.root
	for len(key) > 0 && tn != nil {
		switch n := tn.(type) {
		case shortNode:
			if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) {
				// The trie doesn't contain the key.
				tn = nil
			} else {
				tn = n.Val
				key = key[len(n.Key):]
			}
			nodes = append(nodes, n)
		case fullNode:
			tn = n[key[0]]
			key = key[1:]
			nodes = append(nodes, n)
		case hashNode:
			var err error
			tn, err = t.resolveHash(n, nil, nil)
			if err != nil {
				if glog.V(logger.Error) {
					glog.Errorf("Unhandled trie error: %v", err)
				}
				return nil
			}
		default:
			panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
		}
	}
	if t.hasher == nil {
		t.hasher = newHasher()
	}
	proof := make([]rlp.RawValue, 0, len(nodes))
	for i, n := range nodes {
		// Don't bother checking for errors here since hasher panics
		// if encoding doesn't work and we're not writing to any database.
		n, _ = t.hasher.replaceChildren(n, nil)
		hn, _ := t.hasher.store(n, nil, false)
		if _, ok := hn.(hashNode); ok || i == 0 {
			// If the node's database encoding is a hash (or is the
			// root node), it becomes a proof element.
			enc, _ := rlp.EncodeToBytes(n)
			proof = append(proof, enc)
		}
	}
	return proof
}
Пример #7
0
// Create a new state from a given trie
func New(root common.Hash, db ethdb.Database) (*StateDB, error) {
	tr, err := trie.NewSecure(root, db)
	if err != nil {
		glog.Errorf("can't create state trie with root %x: %v", root[:], err)
		return nil, err
	}
	return &StateDB{
		db:           db,
		trie:         tr,
		stateObjects: make(map[string]*StateObject),
		refund:       new(big.Int),
		logs:         make(map[common.Hash]vm.Logs),
	}, nil
}
Пример #8
0
func handle(id int, conn net.Conn, api shared.EthereumApi, c codec.Codec) {
	codec := c.New(conn)

	defer func() {
		if r := recover(); r != nil {
			glog.Errorf("panic: %v\n", r)
		}
		codec.Close()
	}()

	for {
		requests, isBatch, err := codec.ReadRequest()
		if err == io.EOF {
			return
		} else if err != nil {
			glog.V(logger.Debug).Infof("Closed IPC Conn %06d recv err - %v\n", id, err)
			return
		}

		if isBatch {
			responses := make([]*interface{}, len(requests))
			responseCount := 0
			for _, req := range requests {
				res, err := api.Execute(req)
				if req.Id != nil {
					rpcResponse := shared.NewRpcResponse(req.Id, req.Jsonrpc, res, err)
					responses[responseCount] = rpcResponse
					responseCount += 1
				}
			}

			err = codec.WriteResponse(responses[:responseCount])
			if err != nil {
				glog.V(logger.Debug).Infof("Closed IPC Conn %06d send err - %v\n", id, err)
				return
			}
		} else {
			var rpcResponse interface{}
			res, err := api.Execute(requests[0])

			rpcResponse = shared.NewRpcResponse(requests[0].Id, requests[0].Jsonrpc, res, err)
			err = codec.WriteResponse(rpcResponse)
			if err != nil {
				glog.V(logger.Debug).Infof("Closed IPC Conn %06d send err - %v\n", id, err)
				return
			}
		}
	}
}
Пример #9
0
// reload caches addresses of existing accounts.
// Callers must hold ac.mu.
func (ac *addrCache) reload() {
	accounts, err := ac.scan()
	if err != nil && glog.V(logger.Debug) {
		glog.Errorf("can't load keys: %v", err)
	}
	ac.all = accounts
	sort.Sort(ac.all)
	for k := range ac.byAddr {
		delete(ac.byAddr, k)
	}
	for _, a := range accounts {
		ac.byAddr[a.Address] = append(ac.byAddr[a.Address], a)
	}
	glog.V(logger.Debug).Infof("reloaded keys, cache has %d accounts", len(ac.all))
}
Пример #10
0
// reads the next node record from the iterator, skipping over other
// database entries.
func nextNode(it iterator.Iterator) *Node {
	for end := false; !end; end = !it.Next() {
		id, field := splitKey(it.Key())
		if field != nodeDBDiscoverRoot {
			continue
		}
		var n Node
		if err := rlp.DecodeBytes(it.Value(), &n); err != nil {
			if glog.V(logger.Warn) {
				glog.Errorf("invalid node %x: %v", id, err)
			}
			continue
		}
		return &n
	}
	return nil
}
Пример #11
0
func (self *LDBDatabase) Close() {
	// Stop the metrics collection to avoid internal database races
	self.quitLock.Lock()
	defer self.quitLock.Unlock()

	if self.quitChan != nil {
		errc := make(chan error)
		self.quitChan <- errc
		if err := <-errc; err != nil {
			glog.V(logger.Error).Infof("metrics failure in '%s': %v\n", self.fn, err)
		}
	}
	err := self.db.Close()
	if glog.V(logger.Error) {
		if err == nil {
			glog.Infoln("closed db:", self.fn)
		} else {
			glog.Errorf("error closing db %s: %v", self.fn, err)
		}
	}
}
Пример #12
0
func (t *Trie) resolveHash(n hashNode) node {
	if v, ok := globalCache.Get(n); ok {
		return v
	}
	enc, err := t.db.Get(n)
	if err != nil || enc == nil {
		// TODO: This needs to be improved to properly distinguish errors.
		// Disk I/O errors shouldn't produce nil (and cause a
		// consensus failure or weird crash), but it is unclear how
		// they could be handled because the entire stack above the trie isn't
		// prepared to cope with missing state nodes.
		if glog.V(logger.Error) {
			glog.Errorf("Dangling hash node ref %x: %v", n, err)
		}
		return nil
	}
	dec := mustDecodeNode(n, enc)
	if dec != nil {
		globalCache.Put(n, dec)
	}
	return dec
}
Пример #13
0
// Retrieve a state object given my the address. Nil if not found
func (self *StateDB) GetStateObject(addr common.Address) (stateObject *StateObject) {
	stateObject = self.stateObjects[addr.Str()]
	if stateObject != nil {
		if stateObject.deleted {
			stateObject = nil
		}

		return stateObject
	}

	data := self.trie.Get(addr[:])
	if len(data) == 0 {
		return nil
	}
	stateObject, err := DecodeObject(addr, self.db, data)
	if err != nil {
		glog.Errorf("can't decode object at %x: %v", addr[:], err)
		return nil
	}
	self.SetStateObject(stateObject)
	return stateObject
}
Пример #14
0
// checkQueue moves transactions that have become processable to main pool.
func (pool *TxPool) checkQueue() {
	// init delayed since tx pool could have been started before any state sync
	if pool.pendingState == nil {
		pool.resetState()
	}

	var promote txQueue
	for address, txs := range pool.queue {
		currentState, err := pool.currentState()
		if err != nil {
			glog.Errorf("could not get current state: %v", err)
			return
		}
		balance := currentState.GetBalance(address)

		var (
			guessedNonce = pool.pendingState.GetNonce(address) // nonce currently kept by the tx pool (pending state)
			trueNonce    = currentState.GetNonce(address)      // nonce known by the last state
		)
		promote = promote[:0]
		for hash, tx := range txs {
			// Drop processed or out of fund transactions
			if tx.Nonce() < trueNonce || balance.Cmp(tx.Cost()) < 0 {
				if glog.V(logger.Core) {
					glog.Infof("removed tx (%v) from pool queue: low tx nonce or out of funds\n", tx)
				}
				delete(txs, hash)
				continue
			}
			// Collect the remaining transactions for the next pass.
			promote = append(promote, txQueueEntry{hash, address, tx})
		}
		// Find the next consecutive nonce range starting at the current account nonce,
		// pushing the guessed nonce forward if we add consecutive transactions.
		sort.Sort(promote)
		for i, entry := range promote {
			// If we reached a gap in the nonces, enforce transaction limit and stop
			if entry.Nonce() > guessedNonce {
				if len(promote)-i > maxQueued {
					if glog.V(logger.Debug) {
						glog.Infof("Queued tx limit exceeded for %s. Tx %s removed\n", common.PP(address[:]), common.PP(entry.hash[:]))
					}
					for _, drop := range promote[i+maxQueued:] {
						delete(txs, drop.hash)
					}
				}
				break
			}
			// Otherwise promote the transaction and move the guess nonce if needed
			pool.addTx(entry.hash, address, entry.Transaction)
			delete(txs, entry.hash)

			if entry.Nonce() == guessedNonce {
				guessedNonce++
			}
		}
		// Delete the entire queue entry if it became empty.
		if len(txs) == 0 {
			delete(pool.queue, address)
		}
	}
}
Пример #15
0
// Delete removes any existing value for key from the trie.
func (t *SecureTrie) Delete(key []byte) {
	if err := t.TryDelete(key); err != nil && glog.V(logger.Error) {
		glog.Errorf("Unhandled trie error: %v", err)
	}
}
Пример #16
0
func (self *Iterator) next(node interface{}, key []byte, isIterStart bool) []byte {
	if node == nil {
		return nil
	}

	switch node := node.(type) {
	case fullNode:
		if len(key) > 0 {
			k := self.next(node.Children[key[0]], key[1:], isIterStart)
			if k != nil {
				return append([]byte{key[0]}, k...)
			}
		}

		var r byte
		if len(key) > 0 {
			r = key[0] + 1
		}

		for i := r; i < 16; i++ {
			k := self.key(node.Children[i])
			if k != nil {
				return append([]byte{i}, k...)
			}
		}

	case shortNode:
		k := remTerm(node.Key)
		if vnode, ok := node.Val.(valueNode); ok {
			switch bytes.Compare([]byte(k), key) {
			case 0:
				if isIterStart {
					self.Value = vnode
					return k
				}
			case 1:
				self.Value = vnode
				return k
			}
		} else {
			cnode := node.Val

			var ret []byte
			skey := key[len(k):]
			if bytes.HasPrefix(key, k) {
				ret = self.next(cnode, skey, isIterStart)
			} else if bytes.Compare(k, key[:len(k)]) > 0 {
				return self.key(node)
			}

			if ret != nil {
				return append(k, ret...)
			}
		}

	case hashNode:
		rn, err := self.trie.resolveHash(node, nil, nil)
		if err != nil && glog.V(logger.Error) {
			glog.Errorf("Unhandled trie error: %v", err)
		}
		return self.next(rn, key, isIterStart)
	}
	return nil
}
Пример #17
0
// Update associates key with value in the trie. Subsequent calls to
// Get will return value. If value has length zero, any existing value
// is deleted from the trie and calls to Get will return nil.
//
// The value bytes must not be modified by the caller while they are
// stored in the trie.
func (t *SecureTrie) Update(key, value []byte) {
	if err := t.TryUpdate(key, value); err != nil && glog.V(logger.Error) {
		glog.Errorf("Unhandled trie error: %v", err)
	}
}