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 }
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 }
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 }
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 }
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 }
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 }
// 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) }
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 }
// 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) }