Beispiel #1
0
func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake, error) {
	msg, err := rw.ReadMsg()
	if err != nil {
		return nil, err
	}
	if msg.Size > baseProtocolMaxMsgSize {
		return nil, fmt.Errorf("message too big")
	}
	if msg.Code == discMsg {
		// Disconnect before protocol handshake is valid according to the
		// spec and we send it ourself if the posthanshake checks fail.
		// We can't return the reason directly, though, because it is echoed
		// back otherwise. Wrap it in a string instead.
		var reason [1]DiscReason
		rlp.Decode(msg.Payload, &reason)
		return nil, reason[0]
	}
	if msg.Code != handshakeMsg {
		return nil, fmt.Errorf("expected handshake, got %x", msg.Code)
	}
	var hs protoHandshake
	if err := msg.Decode(&hs); err != nil {
		return nil, err
	}
	if (hs.ID == discover.NodeID{}) {
		return nil, DiscInvalidIdentity
	}
	return &hs, nil
}
Beispiel #2
0
func (p *Peer) handle(msg Msg) error {
	switch {
	case msg.Code == pingMsg:
		msg.Discard()
		go SendItems(p.rw, pongMsg)
	case msg.Code == discMsg:
		var reason [1]DiscReason
		// This is the last message. We don't need to discard or
		// check errors because, the connection will be closed after it.
		rlp.Decode(msg.Payload, &reason)
		return reason[0]
	case msg.Code < baseProtocolLength:
		// ignore other base protocol messages
		return msg.Discard()
	default:
		// it's a subprotocol message
		proto, err := p.getProto(msg.Code)
		if err != nil {
			return fmt.Errorf("msg code out of range: %v", msg.Code)
		}
		select {
		case proto.in <- msg:
			return nil
		case <-p.closed:
			return io.EOF
		}
	}
	return nil
}
Beispiel #3
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
}
Beispiel #4
0
func NewStateObjectFromBytes(address common.Address, data []byte, db common.Database) *StateObject {
	// TODO clean me up
	var extobject struct {
		Nonce    uint64
		Balance  *big.Int
		Root     common.Hash
		CodeHash []byte
	}
	err := rlp.Decode(bytes.NewReader(data), &extobject)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	object := &StateObject{address: address, db: db}
	object.nonce = extobject.Nonce
	object.balance = extobject.Balance
	object.codeHash = extobject.CodeHash
	object.trie = trie.NewSecure(extobject.Root[:], db)
	object.storage = make(map[string]common.Hash)
	object.gasPool = new(big.Int)
	object.code, _ = db.Get(extobject.CodeHash)

	return object
}
Beispiel #5
0
func (self *Object) Storage() (storage map[string]string) {
	storage = make(map[string]string)

	it := self.StateObject.Trie().Iterator()
	for it.Next() {
		var data []byte
		rlp.Decode(bytes.NewReader(it.Value), &data)
		storage[common.ToHex(self.Trie().GetKey(it.Key))] = common.ToHex(data)
	}

	return
}
// [deprecated by the header/block split, remove eventually]
// GetBlockByHashOld returns the old combined block corresponding to the hash
// or nil if not found. This method is only used by the upgrade mechanism to
// access the old combined block representation. It will be dropped after the
// network transitions to eth/63.
func GetBlockByHashOld(db ethdb.Database, hash common.Hash) *types.Block {
	data, _ := db.Get(append(blockHashPrefix, hash[:]...))
	if len(data) == 0 {
		return nil
	}
	var block types.StorageBlock
	if err := rlp.Decode(bytes.NewReader(data), &block); err != nil {
		glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err)
		return nil
	}
	return (*types.Block)(&block)
}
// GetTd retrieves a block's total difficulty corresponding to the hash, nil if
// none found.
func GetTd(db ethdb.Database, hash common.Hash) *big.Int {
	data, _ := db.Get(append(append(blockPrefix, hash.Bytes()...), tdSuffix...))
	if len(data) == 0 {
		return nil
	}
	td := new(big.Int)
	if err := rlp.Decode(bytes.NewReader(data), td); err != nil {
		glog.V(logger.Error).Infof("invalid block total difficulty RLP for hash %x: %v", hash, err)
		return nil
	}
	return td
}
// GetBody retrieves the block body (transactons, uncles) corresponding to the
// hash, nil if none found.
func GetBody(db ethdb.Database, hash common.Hash) *types.Body {
	data := GetBodyRLP(db, hash)
	if len(data) == 0 {
		return nil
	}
	body := new(types.Body)
	if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
		glog.V(logger.Error).Infof("invalid block body RLP for hash %x: %v", hash, err)
		return nil
	}
	return body
}
// GetHeader retrieves the block header corresponding to the hash, nil if none
// found.
func GetHeader(db ethdb.Database, hash common.Hash) *types.Header {
	data := GetHeaderRLP(db, hash)
	if len(data) == 0 {
		return nil
	}
	header := new(types.Header)
	if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
		glog.V(logger.Error).Infof("invalid block header RLP for hash %x: %v", hash, err)
		return nil
	}
	return header
}
func loadChain(fn string, t *testing.T) (types.Blocks, error) {
	fh, err := os.OpenFile(filepath.Join("..", "_data", fn), os.O_RDONLY, os.ModePerm)
	if err != nil {
		return nil, err
	}
	defer fh.Close()

	var chain types.Blocks
	if err := rlp.Decode(fh, &chain); err != nil {
		return nil, err
	}

	return chain, nil
}
Beispiel #11
0
func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) {
	// read the header
	headbuf := make([]byte, 32)
	if _, err := io.ReadFull(rw.conn, headbuf); err != nil {
		return msg, err
	}
	// verify header mac
	shouldMAC := updateMAC(rw.ingressMAC, rw.macCipher, headbuf[:16])
	if !hmac.Equal(shouldMAC, headbuf[16:]) {
		return msg, errors.New("bad header MAC")
	}
	rw.dec.XORKeyStream(headbuf[:16], headbuf[:16]) // first half is now decrypted
	fsize := readInt24(headbuf)
	// ignore protocol type for now

	// read the frame content
	var rsize = fsize // frame size rounded up to 16 byte boundary
	if padding := fsize % 16; padding > 0 {
		rsize += 16 - padding
	}
	framebuf := make([]byte, rsize)
	if _, err := io.ReadFull(rw.conn, framebuf); err != nil {
		return msg, err
	}

	// read and validate frame MAC. we can re-use headbuf for that.
	rw.ingressMAC.Write(framebuf)
	fmacseed := rw.ingressMAC.Sum(nil)
	if _, err := io.ReadFull(rw.conn, headbuf[:16]); err != nil {
		return msg, err
	}
	shouldMAC = updateMAC(rw.ingressMAC, rw.macCipher, fmacseed)
	if !hmac.Equal(shouldMAC, headbuf[:16]) {
		return msg, errors.New("bad frame MAC")
	}

	// decrypt frame content
	rw.dec.XORKeyStream(framebuf, framebuf)

	// decode message code
	content := bytes.NewReader(framebuf[:fsize])
	if err := rlp.Decode(content, &msg.Code); err != nil {
		return msg, err
	}
	msg.Size = uint32(content.Len())
	msg.Payload = content
	return msg, nil
}
Beispiel #12
0
// NewStateSync create a new state trie download scheduler.
func NewStateSync(root common.Hash, database ethdb.Database) *StateSync {
	var syncer *trie.TrieSync

	callback := func(leaf []byte, parent common.Hash) error {
		var obj struct {
			Nonce    uint64
			Balance  *big.Int
			Root     common.Hash
			CodeHash []byte
		}
		if err := rlp.Decode(bytes.NewReader(leaf), &obj); err != nil {
			return err
		}
		syncer.AddSubTrie(obj.Root, 64, parent, nil)
		syncer.AddRawEntry(common.BytesToHash(obj.CodeHash), 64, parent)

		return nil
	}
	syncer = trie.NewTrieSync(root, database, callback)
	return (*StateSync)(syncer)
}
Beispiel #13
0
func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) {
	// Due to increasing return params and need to determine if this is from transaction pool or
	// some chain, this probably needs to be refactored for more expressiveness
	data, _ := self.backend.ChainDb().Get(common.FromHex(hash))
	if len(data) != 0 {
		dtx := new(types.Transaction)
		if err := rlp.DecodeBytes(data, dtx); err != nil {
			glog.V(logger.Error).Infoln(err)
			return
		}
		tx = dtx
	} else { // check pending transactions
		tx = self.backend.TxPool().GetTransaction(common.HexToHash(hash))
	}

	// meta
	var txExtra struct {
		BlockHash  common.Hash
		BlockIndex uint64
		Index      uint64
	}

	v, dberr := self.backend.ChainDb().Get(append(common.FromHex(hash), 0x0001))
	// TODO check specifically for ErrNotFound
	if dberr != nil {
		return
	}
	r := bytes.NewReader(v)
	err := rlp.Decode(r, &txExtra)
	if err == nil {
		blhash = txExtra.BlockHash
		blnum = big.NewInt(int64(txExtra.BlockIndex))
		txi = txExtra.Index
	} else {
		glog.V(logger.Error).Infoln(err)
	}

	return
}
Beispiel #14
0
// step moves the iterator to the next entry of the state trie.
func (it *NodeIterator) step() error {
	// Abort if we reached the end of the iteration
	if it.state == nil {
		return nil
	}
	// Initialize the iterator if we've just started
	if it.stateIt == nil {
		it.stateIt = it.state.trie.NodeIterator()
	}
	// If we had data nodes previously, we surely have at least state nodes
	if it.dataIt != nil {
		if cont := it.dataIt.Next(); !cont {
			if it.dataIt.Error != nil {
				return it.dataIt.Error
			}
			it.dataIt = nil
		}
		return nil
	}
	// If we had source code previously, discard that
	if it.code != nil {
		it.code = nil
		return nil
	}
	// Step to the next state trie node, terminating if we're out of nodes
	if cont := it.stateIt.Next(); !cont {
		if it.stateIt.Error != nil {
			return it.stateIt.Error
		}
		it.state, it.stateIt = nil, nil
		return nil
	}
	// If the state trie node is an internal entry, leave as is
	if !it.stateIt.Leaf {
		return nil
	}
	// Otherwise we've reached an account node, initiate data iteration
	var account struct {
		Nonce    uint64
		Balance  *big.Int
		Root     common.Hash
		CodeHash []byte
	}
	if err := rlp.Decode(bytes.NewReader(it.stateIt.LeafBlob), &account); err != nil {
		return err
	}
	dataTrie, err := trie.New(account.Root, it.state.db)
	if err != nil {
		return err
	}
	it.dataIt = trie.NewNodeIterator(dataTrie)
	if !it.dataIt.Next() {
		it.dataIt = nil
	}
	if bytes.Compare(account.CodeHash, emptyCodeHash) != 0 {
		it.codeHash = common.BytesToHash(account.CodeHash)
		it.code, err = it.state.db.Get(account.CodeHash)
		if err != nil {
			return fmt.Errorf("code %x: %v", account.CodeHash, err)
		}
	}
	it.accountHash = it.stateIt.Parent
	return nil
}
func mustConvertBlock(testBlock btBlock) (*types.Block, error) {
	var b types.Block
	r := bytes.NewReader(mustConvertBytes(testBlock.Rlp))
	err := rlp.Decode(r, &b)
	return &b, err
}
func decodeTx(data []byte) (*Transaction, error) {
	var tx Transaction
	return &tx, rlp.Decode(bytes.NewReader(data), &tx)
}