aboutsummaryrefslogtreecommitdiffstats
path: root/light
diff options
context:
space:
mode:
Diffstat (limited to 'light')
-rw-r--r--light/odr.go17
-rw-r--r--light/odr_util.go21
2 files changed, 38 insertions, 0 deletions
diff --git a/light/odr.go b/light/odr.go
index 95f1948e7..d1185e4e0 100644
--- a/light/odr.go
+++ b/light/odr.go
@@ -175,3 +175,20 @@ func (req *BloomRequest) StoreResult(db ethdb.Database) {
rawdb.WriteBloomBits(db, req.BitIdx, sectionIdx, sectionHead, req.BloomBits[i])
}
}
+
+// TxStatus describes the status of a transaction
+type TxStatus struct {
+ Status core.TxStatus
+ Lookup *rawdb.LegacyTxLookupEntry `rlp:"nil"`
+ Error string
+}
+
+// TxStatusRequest is the ODR request type for retrieving transaction status
+type TxStatusRequest struct {
+ OdrRequest
+ Hashes []common.Hash
+ Status []TxStatus
+}
+
+// StoreResult stores the retrieved data in local database
+func (req *TxStatusRequest) StoreResult(db ethdb.Database) {}
diff --git a/light/odr_util.go b/light/odr_util.go
index cce532f8e..100bd5842 100644
--- a/light/odr_util.go
+++ b/light/odr_util.go
@@ -21,6 +21,7 @@ import (
"context"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
@@ -227,3 +228,23 @@ func GetBloomBits(ctx context.Context, odr OdrBackend, bitIdx uint, sectionIdxLi
return result, nil
}
}
+
+// GetTransaction retrieves a canonical transaction by hash and also returns its position in the chain
+func GetTransaction(ctx context.Context, odr OdrBackend, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
+ r := &TxStatusRequest{Hashes: []common.Hash{txHash}}
+ if err := odr.Retrieve(ctx, r); err != nil || r.Status[0].Status != core.TxStatusIncluded {
+ return nil, common.Hash{}, 0, 0, err
+ } else {
+ pos := r.Status[0].Lookup
+ // first ensure that we have the header, otherwise block body retrieval will fail
+ // also verify if this is a canonical block by getting the header by number and checking its hash
+ if header, err := GetHeaderByNumber(ctx, odr, pos.BlockIndex); err != nil || header.Hash() != pos.BlockHash {
+ return nil, common.Hash{}, 0, 0, err
+ }
+ if body, err := GetBody(ctx, odr, pos.BlockHash, pos.BlockIndex); err != nil || uint64(len(body.Transactions)) <= pos.Index || body.Transactions[pos.Index].Hash() != txHash {
+ return nil, common.Hash{}, 0, 0, err
+ } else {
+ return body.Transactions[pos.Index], pos.BlockHash, pos.BlockIndex, pos.Index, nil
+ }
+ }
+}