// GetTransaction retrieves a specific transaction from the database, along with // its added positional metadata. func GetTransaction(db ethdb.Database, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { // Retrieve the transaction itself from the database data, _ := db.Get(hash.Bytes()) if len(data) == 0 { return nil, common.Hash{}, 0, 0 } var tx types.Transaction if err := rlp.DecodeBytes(data, &tx); err != nil { return nil, common.Hash{}, 0, 0 } // Retrieve the blockchain positional metadata data, _ = db.Get(append(hash.Bytes(), txMetaSuffix...)) if len(data) == 0 { return nil, common.Hash{}, 0, 0 } var meta struct { BlockHash common.Hash BlockIndex uint64 Index uint64 } if err := rlp.DecodeBytes(data, &meta); err != nil { return nil, common.Hash{}, 0, 0 } return &tx, meta.BlockHash, meta.BlockIndex, meta.Index }
// DecodeRLP is a specialized decoder for hashOrNumber to decode the contents // into either a block hash or a block number. func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { _, size, _ := s.Kind() origin, err := s.Raw() if err == nil { switch { case size == 32: err = rlp.DecodeBytes(origin, &hn.Hash) case size <= 8: err = rlp.DecodeBytes(origin, &hn.Number) default: err = fmt.Errorf("invalid input size %d for origin", size) } } return err }
func (self *XEth) PushTx(encodedTx string) (string, error) { tx := new(types.Transaction) err := rlp.DecodeBytes(common.FromHex(encodedTx), tx) if err != nil { glog.V(logger.Error).Infoln(err) return "", err } err = self.backend.TxPool().Add(tx) if err != nil { return "", err } if tx.To() == nil { from, err := tx.From() if err != nil { return "", err } addr := crypto.CreateAddress(from, tx.Nonce()) glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr) } else { glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To()) } return tx.Hash().Hex(), nil }
func decodePacket(buf []byte) (packet, NodeID, []byte, error) { if len(buf) < headSize+1 { return nil, NodeID{}, nil, errPacketTooSmall } hash, sig, sigdata := buf[:macSize], buf[macSize:headSize], buf[headSize:] shouldhash := crypto.Sha3(buf[macSize:]) if !bytes.Equal(hash, shouldhash) { return nil, NodeID{}, nil, errBadHash } fromID, err := recoverNodeID(crypto.Sha3(buf[headSize:]), sig) if err != nil { return nil, NodeID{}, hash, err } var req packet switch ptype := sigdata[0]; ptype { case pingPacket: req = new(ping) case pongPacket: req = new(pong) case findnodePacket: req = new(findnode) case neighborsPacket: req = new(neighbors) default: return nil, fromID, hash, fmt.Errorf("unknown type: %d", ptype) } err = rlp.DecodeBytes(sigdata[1:], req) return req, fromID, hash, err }
func NewTransactionFromBytes(data []byte) *Transaction { // TODO: remove this function if possible. callers would // much better off decoding into transaction directly. // it's not that hard. tx := new(Transaction) rlp.DecodeBytes(data, tx) return tx }
// NewValueFromBytes decodes RLP data. // The contained value will be nil if data contains invalid RLP. func NewValueFromBytes(data []byte) *Value { v := new(Value) if len(data) != 0 { if err := rlp.DecodeBytes(data, v); err != nil { v.Val = nil } } return v }
// getAddr gets the storage value at the given address from the trie func (c *StateObject) getAddr(ctx context.Context, addr common.Hash) (common.Hash, error) { var ret []byte val, err := c.trie.Get(ctx, addr[:]) if err != nil { return common.Hash{}, err } rlp.DecodeBytes(val, &ret) return common.BytesToHash(ret), nil }
func checkDecodeInterface(b []byte, isValid bool) error { err := rlp.DecodeBytes(b, new(interface{})) switch { case isValid && err != nil: return fmt.Errorf("decoding failed: %v", err) case !isValid && err == nil: return fmt.Errorf("decoding of invalid value succeeded") } return nil }
func getBlockReceipts(db common.Database, bhash common.Hash) (receipts types.Receipts, err error) { var rdata []byte rdata, err = db.Get(append(receiptsPre, bhash[:]...)) if err == nil { err = rlp.DecodeBytes(rdata, &receipts) } else { glog.V(logger.Detail).Infof("getBlockReceipts error %v\n", err) } return }
func GetTransaction(db ethdb.Database, txhash common.Hash) *types.Transaction { data, _ := db.Get(txhash[:]) if len(data) != 0 { var tx types.Transaction if err := rlp.DecodeBytes(data, &tx); err != nil { return nil } return &tx } return nil }
// GetReceipt returns a receipt by hash func GetReceipt(db ethdb.Database, txHash common.Hash) *types.Receipt { data, _ := db.Get(append(receiptsPrefix, txHash[:]...)) if len(data) == 0 { return nil } var receipt types.ReceiptForStorage err := rlp.DecodeBytes(data, &receipt) if err != nil { glog.V(logger.Core).Infoln("GetReceipt err:", err) } return (*types.Receipt)(&receipt) }
// GetBlockReceipts returns the receipts generated by the transactions // included in block's given hash. func GetBlockReceipts(db ethdb.Database, hash common.Hash) types.Receipts { data, _ := db.Get(append(blockReceiptsPre, hash[:]...)) if len(data) == 0 { return nil } var receipts types.Receipts err := rlp.DecodeBytes(data, &receipts) if err != nil { glog.V(logger.Core).Infoln("GetReceiptse err", err) } return receipts }
// node retrieves a node with a given id from the database. func (db *nodeDB) node(id NodeID) *Node { blob, err := db.lvl.Get(makeKey(id, nodeDBDiscoverRoot), nil) if err != nil { glog.V(logger.Detail).Infof("failed to retrieve node %v: %v", id, err) return nil } node := new(Node) if err := rlp.DecodeBytes(blob, node); err != nil { glog.V(logger.Warn).Infof("failed to decode node RLP: %v", err) return nil } node.sha = crypto.Sha3Hash(node.ID[:]) return node }
// GetBlockReceipts retrieves the receipts generated by the transactions included // in a block given by its hash. func GetBlockReceipts(db ethdb.Database, hash common.Hash) types.Receipts { data, _ := db.Get(append(blockReceiptsPrefix, hash[:]...)) if len(data) == 0 { return nil } storageReceipts := []*types.ReceiptForStorage{} if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { glog.V(logger.Error).Infof("invalid receipt array RLP for hash %x: %v", hash, err) return nil } receipts := make(types.Receipts, len(storageReceipts)) for i, receipt := range storageReceipts { receipts[i] = (*types.Receipt)(receipt) } return receipts }
// DecodeRLP decodes an Envelope from an RLP data stream. func (self *Envelope) DecodeRLP(s *rlp.Stream) error { raw, err := s.Raw() if err != nil { return err } // The decoding of Envelope uses the struct fields but also needs // to compute the hash of the whole RLP-encoded envelope. This // type has the same structure as Envelope but is not an // rlp.Decoder so we can reuse the Envelope struct definition. type rlpenv Envelope if err := rlp.DecodeBytes(raw, (*rlpenv)(self)); err != nil { return err } self.hash = crypto.Sha3Hash(raw) return nil }
// from bcValidBlockTest.json, "SimpleTx" func TestBlockEncoding(t *testing.T) { blockEnc := common.FromHex("f90260f901f9a083cafc574e1f51ba9dc0568fc617a08ea2429fb384059c972f13b19fa1c8dd55a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a05fe50b260da6308036625b850b5d6ced6d0a9f814c0688bc91ffb7b7a3a54b67a0bc37d79753ad738a6dac4921e57392f145d8887476de3f783dfa7edae9283e52b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4f861f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1c0") var block Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } check := func(f string, got, want interface{}) { if !reflect.DeepEqual(got, want) { t.Errorf("%s mismatch: got %v, want %v", f, got, want) } } check("Difficulty", block.Difficulty(), big.NewInt(131072)) check("GasLimit", block.GasLimit(), big.NewInt(3141592)) check("GasUsed", block.GasUsed(), big.NewInt(21000)) check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1")) check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498")) check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017")) check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e")) check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4)) check("Time", block.Time(), int64(1426516743)) check("Size", block.Size(), common.StorageSize(len(blockEnc))) to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") check("Transactions", block.Transactions(), Transactions{ { Payload: []byte{}, Amount: big.NewInt(10), Price: big.NewInt(10), GasLimit: big.NewInt(50000), AccountNonce: 0, V: 27, R: common.String2Big("0x9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f"), S: common.String2Big("0x8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1"), Recipient: &to, }, }) ourBlockEnc, err := rlp.EncodeToBytes(&block) if err != nil { t.Fatal("encode error: ", err) } if !bytes.Equal(ourBlockEnc, blockEnc) { t.Errorf("encoded block mismatch:\ngot: %x\nwant: %x", ourBlockEnc, blockEnc) } }
// 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 }
// Tests that the custom union field encoder and decoder works correctly. func TestGetBlockHeadersDataEncodeDecode(t *testing.T) { // Create a "random" hash for testing var hash common.Hash for i, _ := range hash { hash[i] = byte(i) } // Assemble some table driven tests tests := []struct { packet *getBlockHeadersData fail bool }{ // Providing the origin as either a hash or a number should both work {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Number: 314}}}, {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}}}, // Providing arbitrary query field should also work {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Number: 314}, Amount: 314, Skip: 1, Reverse: true}}, {fail: false, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: 314, Skip: 1, Reverse: true}}, // Providing both the origin hash and origin number must fail {fail: true, packet: &getBlockHeadersData{Origin: hashOrNumber{Hash: hash, Number: 314}}}, } // Iterate over each of the tests and try to encode and then decode for i, tt := range tests { bytes, err := rlp.EncodeToBytes(tt.packet) if err != nil && !tt.fail { t.Fatalf("test %d: failed to encode packet: %v", i, err) } else if err == nil && tt.fail { t.Fatalf("test %d: encode should have failed", i) } if !tt.fail { packet := new(getBlockHeadersData) if err := rlp.DecodeBytes(bytes, packet); err != nil { t.Fatalf("test %d: failed to decode packet: %v", i, err) } if packet.Origin.Hash != tt.packet.Origin.Hash || packet.Origin.Number != tt.packet.Origin.Number || packet.Amount != tt.packet.Amount || packet.Skip != tt.packet.Skip || packet.Reverse != tt.packet.Reverse { t.Fatalf("test %d: encode decode mismatch: have %+v, want %+v", i, packet, tt.packet) } } } }
// DecodeObject decodes an RLP-encoded state object. func DecodeObject(ctx context.Context, address common.Address, odr OdrBackend, data []byte) (*StateObject, error) { var ( obj = &StateObject{address: address, odr: odr, storage: make(Storage)} ext extStateObject err error ) if err = rlp.DecodeBytes(data, &ext); err != nil { return nil, err } obj.trie = NewLightTrie(ext.Root, odr, true) if !bytes.Equal(ext.CodeHash, emptyCodeHash) { if obj.code, err = retrieveNodeData(ctx, obj.odr, common.BytesToHash(ext.CodeHash)); err != nil { return nil, fmt.Errorf("can't find code for hash %x: %v", ext.CodeHash, err) } } obj.nonce = ext.Nonce obj.balance = ext.Balance obj.codeHash = ext.CodeHash return obj, nil }
func addMipmapBloomBins(db ethdb.Database) (err error) { const mipmapVersion uint = 2 // check if the version is set. We ignore data for now since there's // only one version so we can easily ignore it for now var data []byte data, _ = db.Get([]byte("setting-mipmap-version")) if len(data) > 0 { var version uint if err := rlp.DecodeBytes(data, &version); err == nil && version == mipmapVersion { return nil } } defer func() { if err == nil { var val []byte val, err = rlp.EncodeToBytes(mipmapVersion) if err == nil { err = db.Put([]byte("setting-mipmap-version"), val) } return } }() latestBlock := core.GetBlock(db, core.GetHeadBlockHash(db)) if latestBlock == nil { // clean database return } tstart := time.Now() glog.V(logger.Info).Infoln("upgrading db log bloom bins") for i := uint64(0); i <= latestBlock.NumberU64(); i++ { hash := core.GetCanonicalHash(db, i) if (hash == common.Hash{}) { return fmt.Errorf("chain db corrupted. Could not find block %d.", i) } core.WriteMipmapBloom(db, i, core.GetBlockReceipts(db, hash)) } glog.V(logger.Info).Infoln("upgrade completed in", time.Since(tstart)) return nil }
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 }
// DecodeObject decodes an RLP-encoded state object. func DecodeObject(address common.Address, db trie.Database, data []byte) (*StateObject, error) { var ( obj = &StateObject{address: address, db: db, storage: make(Storage)} ext extStateObject err error ) if err = rlp.DecodeBytes(data, &ext); err != nil { return nil, err } if obj.trie, err = trie.NewSecure(ext.Root, db); err != nil { return nil, err } if !bytes.Equal(ext.CodeHash, emptyCodeHash) { if obj.code, err = db.Get(ext.CodeHash); err != nil { return nil, fmt.Errorf("can't find code for hash %x: %v", ext.CodeHash, err) } } obj.nonce = ext.Nonce obj.balance = ext.Balance obj.codeHash = ext.CodeHash return obj, nil }
func runTransactionTest(txTest TransactionTest) (err error) { tx := new(types.Transaction) err = rlp.DecodeBytes(mustConvertBytes(txTest.Rlp), tx) if err != nil { if txTest.Sender == "" { // RLP decoding failed and this is expected (test OK) return nil } else { // RLP decoding failed but is expected to succeed (test FAIL) return fmt.Errorf("RLP decoding failed when expected to succeed: ", err) } } validationError := verifyTxFields(txTest, tx) if txTest.Sender == "" { if validationError != nil { // RLP decoding works but validation should fail (test OK) return nil } else { // RLP decoding works but validation should fail (test FAIL) // (this should not be possible but added here for completeness) return errors.New("Field validations succeeded but should fail") } } if txTest.Sender != "" { if validationError == nil { // RLP decoding works and validations pass (test OK) return nil } else { // RLP decoding works and validations pass (test FAIL) return fmt.Errorf("Field validations failed after RLP decoding: ", validationError) } } return errors.New("Should not happen: verify RLP decoding and field validation") }
// GetBlockChainVersion reads the version number from db. func GetBlockChainVersion(db ethdb.Database) int { var vsn uint enc, _ := db.Get([]byte("BlockchainVersion")) rlp.DecodeBytes(enc, &vsn) return int(vsn) }
func (c *StateObject) getAddr(addr common.Hash) common.Hash { var ret []byte rlp.DecodeBytes(c.trie.Get(addr[:]), &ret) return common.BytesToHash(ret) }