mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 19:00:46 +00:00
Merge 33e1d84d16 into dddbaa4bf3
This commit is contained in:
commit
bc5f9d85d8
15 changed files with 213 additions and 11 deletions
|
|
@ -1220,13 +1220,14 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64, config *param
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
|
// newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
|
||||||
func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes {
|
func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) *hexutil.Bytes {
|
||||||
txs := b.Transactions()
|
txs := b.Transactions()
|
||||||
if index >= uint64(len(txs)) {
|
if index >= uint64(len(txs)) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
blob, _ := txs[index].MarshalBinary()
|
blob, _ := txs[index].MarshalBinary()
|
||||||
return blob
|
b2 := hexutil.Bytes(blob)
|
||||||
|
return &b2
|
||||||
}
|
}
|
||||||
|
|
||||||
// accessListResult returns an optional accesslist
|
// accessListResult returns an optional accesslist
|
||||||
|
|
@ -1485,7 +1486,7 @@ func (api *TransactionAPI) GetTransactionByBlockHashAndIndex(ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
|
// GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
|
||||||
func (api *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes {
|
func (api *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *hexutil.Bytes {
|
||||||
if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil {
|
if block, _ := api.b.BlockByNumber(ctx, blockNr); block != nil {
|
||||||
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
||||||
}
|
}
|
||||||
|
|
@ -1493,7 +1494,7 @@ func (api *TransactionAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Co
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
|
// GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
|
||||||
func (api *TransactionAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes {
|
func (api *TransactionAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *hexutil.Bytes {
|
||||||
if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil {
|
if block, _ := api.b.BlockByHash(ctx, blockHash); block != nil {
|
||||||
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
return newRPCRawTransactionFromBlockIndex(block, uint64(index))
|
||||||
}
|
}
|
||||||
|
|
@ -1545,12 +1546,17 @@ func (api *TransactionAPI) GetTransactionByHash(ctx context.Context, hash common
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
// GetRawTransactionByHash returns the bytes of the transaction for the given hash.
|
||||||
func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (*hexutil.Bytes, error) {
|
||||||
// Retrieve a finalized transaction, or a pooled otherwise
|
// Retrieve a finalized transaction, or a pooled otherwise
|
||||||
found, tx, _, _, _ := api.b.GetCanonicalTransaction(hash)
|
found, tx, _, _, _ := api.b.GetCanonicalTransaction(hash)
|
||||||
if !found {
|
if !found {
|
||||||
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||||
return tx.MarshalBinary()
|
blob, err := tx.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b := hexutil.Bytes(blob)
|
||||||
|
return &b, nil
|
||||||
}
|
}
|
||||||
// If also not in the pool there is a chance the tx indexer is still in progress.
|
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||||
if !api.b.TxIndexDone() {
|
if !api.b.TxIndexDone() {
|
||||||
|
|
@ -1559,7 +1565,12 @@ func (api *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash com
|
||||||
// If the transaction is not found in the pool and the indexer is done, return nil
|
// If the transaction is not found in the pool and the indexer is done, return nil
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return tx.MarshalBinary()
|
blob, err := tx.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b := hexutil.Bytes(blob)
|
||||||
|
return &b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
||||||
|
|
@ -2089,12 +2100,17 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRawTransaction returns the bytes of the transaction for the given hash.
|
// GetRawTransaction returns the bytes of the transaction for the given hash.
|
||||||
func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) {
|
func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (*hexutil.Bytes, error) {
|
||||||
// Retrieve a finalized transaction, or a pooled otherwise
|
// Retrieve a finalized transaction, or a pooled otherwise
|
||||||
found, tx, _, _, _ := api.b.GetCanonicalTransaction(hash)
|
found, tx, _, _, _ := api.b.GetCanonicalTransaction(hash)
|
||||||
if !found {
|
if !found {
|
||||||
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
if tx = api.b.GetPoolTransaction(hash); tx != nil {
|
||||||
return tx.MarshalBinary()
|
blob, err := tx.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b := hexutil.Bytes(blob)
|
||||||
|
return &b, nil
|
||||||
}
|
}
|
||||||
// If also not in the pool there is a chance the tx indexer is still in progress.
|
// If also not in the pool there is a chance the tx indexer is still in progress.
|
||||||
if !api.b.TxIndexDone() {
|
if !api.b.TxIndexDone() {
|
||||||
|
|
@ -2103,7 +2119,12 @@ func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (h
|
||||||
// Transaction is not found in the pool and the indexer is done.
|
// Transaction is not found in the pool and the indexer is done.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return tx.MarshalBinary()
|
blob, err := tx.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b := hexutil.Bytes(blob)
|
||||||
|
return &b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintBlock retrieves a block and returns its pretty printed form.
|
// PrintBlock retrieves a block and returns its pretty printed form.
|
||||||
|
|
|
||||||
|
|
@ -672,7 +672,7 @@ func (b testBackend) TxIndexDone() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") }
|
func (b testBackend) GetPoolTransactions() (types.Transactions, error) { panic("implement me") }
|
||||||
func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { panic("implement me") }
|
func (b testBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction { return nil }
|
||||||
func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
func (b testBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
@ -4339,3 +4339,171 @@ func TestStateMethodsDefaultToLatest(t *testing.T) {
|
||||||
[]any{map[common.Address][]common.Hash{acc: {slot}}, "latest"},
|
[]any{map[common.Address][]common.Hash{acc: {slot}}, "latest"},
|
||||||
[]any{map[common.Address][]common.Hash{acc: {slot}}})
|
[]any{map[common.Address][]common.Hash{acc: {slot}}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRPCGetRawTransactionByHash(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
backend, txHashes = setupReceiptBackend(t, 2)
|
||||||
|
api = NewTransactionAPI(backend, new(AddrLocker))
|
||||||
|
)
|
||||||
|
|
||||||
|
var testSuite = []struct {
|
||||||
|
txHash common.Hash
|
||||||
|
file string
|
||||||
|
}{
|
||||||
|
// 0. legacy transfer tx (block 0 default case)
|
||||||
|
{
|
||||||
|
txHash: txHashes[0],
|
||||||
|
file: "found-legacy",
|
||||||
|
},
|
||||||
|
// 1. create contract tx (block 1)
|
||||||
|
{
|
||||||
|
txHash: txHashes[1],
|
||||||
|
file: "found-create",
|
||||||
|
},
|
||||||
|
// 2. zero hash, not in chain
|
||||||
|
{
|
||||||
|
txHash: common.Hash{},
|
||||||
|
file: "txhash-empty",
|
||||||
|
},
|
||||||
|
// 3. unknown hash, not in chain
|
||||||
|
{
|
||||||
|
txHash: common.HexToHash("deadbeef"),
|
||||||
|
file: "txhash-notfound",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range testSuite {
|
||||||
|
result, err := api.GetRawTransactionByHash(context.Background(), tt.txHash)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("test %d: want no error, have %v", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
testRPCResponseWithFile(t, i, result, "eth_getRawTransactionByHash", tt.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRPCGetRawTransactionByBlockHashAndIndex(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
backend, _ = setupReceiptBackend(t, 2)
|
||||||
|
api = NewTransactionAPI(backend, new(AddrLocker))
|
||||||
|
)
|
||||||
|
|
||||||
|
block1 := backend.chain.GetBlockByNumber(1)
|
||||||
|
if block1 == nil {
|
||||||
|
t.Fatal("block 1 not found")
|
||||||
|
}
|
||||||
|
block1Hash := block1.Hash()
|
||||||
|
unknownHash := common.HexToHash("deadbeef")
|
||||||
|
|
||||||
|
var testSuite = []struct {
|
||||||
|
blockHash common.Hash
|
||||||
|
index hexutil.Uint
|
||||||
|
file string
|
||||||
|
}{
|
||||||
|
// 0. block 1, index 0 → found (legacy tx)
|
||||||
|
{
|
||||||
|
blockHash: block1Hash,
|
||||||
|
index: 0,
|
||||||
|
file: "found-legacy",
|
||||||
|
},
|
||||||
|
// 1. block 1, index 1 → out of range → null
|
||||||
|
{
|
||||||
|
blockHash: block1Hash,
|
||||||
|
index: 1,
|
||||||
|
file: "index-outofrange",
|
||||||
|
},
|
||||||
|
// 2. unknown block hash, index 0 → null
|
||||||
|
{
|
||||||
|
blockHash: unknownHash,
|
||||||
|
index: 0,
|
||||||
|
file: "blockhash-notfound",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range testSuite {
|
||||||
|
result := api.GetRawTransactionByBlockHashAndIndex(context.Background(), tt.blockHash, tt.index)
|
||||||
|
testRPCResponseWithFile(t, i, result, "eth_getRawTransactionByBlockHashAndIndex", tt.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRPCGetRawTransactionByBlockNumberAndIndex(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
backend, _ = setupReceiptBackend(t, 2)
|
||||||
|
api = NewTransactionAPI(backend, new(AddrLocker))
|
||||||
|
)
|
||||||
|
|
||||||
|
var testSuite = []struct {
|
||||||
|
blockNumber rpc.BlockNumber
|
||||||
|
index hexutil.Uint
|
||||||
|
file string
|
||||||
|
}{
|
||||||
|
// 0. block 1, index 0 → found (legacy tx)
|
||||||
|
{
|
||||||
|
blockNumber: 1,
|
||||||
|
index: 0,
|
||||||
|
file: "found-legacy",
|
||||||
|
},
|
||||||
|
// 1. block 1, index 1 → out of range → null
|
||||||
|
{
|
||||||
|
blockNumber: 1,
|
||||||
|
index: 1,
|
||||||
|
file: "index-outofrange",
|
||||||
|
},
|
||||||
|
// 2. block 999, doesn't exist → null
|
||||||
|
{
|
||||||
|
blockNumber: 999,
|
||||||
|
index: 0,
|
||||||
|
file: "blocknumber-notfound",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range testSuite {
|
||||||
|
result := api.GetRawTransactionByBlockNumberAndIndex(context.Background(), tt.blockNumber, tt.index)
|
||||||
|
testRPCResponseWithFile(t, i, result, "eth_getRawTransactionByBlockNumberAndIndex", tt.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRPCDebugGetRawTransaction(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var (
|
||||||
|
backend, txHashes = setupReceiptBackend(t, 2)
|
||||||
|
api = NewDebugAPI(backend)
|
||||||
|
)
|
||||||
|
|
||||||
|
var testSuite = []struct {
|
||||||
|
txHash common.Hash
|
||||||
|
file string
|
||||||
|
}{
|
||||||
|
// 0. legacy transfer tx (block 0 default case)
|
||||||
|
{
|
||||||
|
txHash: txHashes[0],
|
||||||
|
file: "found-legacy",
|
||||||
|
},
|
||||||
|
// 1. zero hash, not in chain
|
||||||
|
{
|
||||||
|
txHash: common.Hash{},
|
||||||
|
file: "txhash-empty",
|
||||||
|
},
|
||||||
|
// 2. unknown hash, not in chain
|
||||||
|
{
|
||||||
|
txHash: common.HexToHash("deadbeef"),
|
||||||
|
file: "txhash-notfound",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tt := range testSuite {
|
||||||
|
result, err := api.GetRawTransaction(context.Background(), tt.txHash)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("test %d: want no error, have %v", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
testRPCResponseWithFile(t, i, result, "debug_getRawTransaction", tt.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
1
internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json
vendored
Normal file
1
internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf8658084342770c0825208940d3ab14bbad3d99f4203bd7a11acb94882050e7e8203e8801ba0cd190747077598c3b9c5f21ea06f8487d6ab1e23358fbe0e0e0c4e64651b68f3a0467ebcb2186b332969991e2e25244959dcdb3feb7652ff6b81ce96e646d86abd"
|
||||||
1
internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json
vendored
Normal file
1
internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json
vendored
Normal file
1
internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-blockhash-notfound.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-blockhash-notfound.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-found-legacy.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-found-legacy.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf8658084342770c0825208940d3ab14bbad3d99f4203bd7a11acb94882050e7e8203e8801ba0cd190747077598c3b9c5f21ea06f8487d6ab1e23358fbe0e0e0c4e64651b68f3a0467ebcb2186b332969991e2e25244959dcdb3feb7652ff6b81ce96e646d86abd"
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-index-outofrange.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByBlockHashAndIndex-index-outofrange.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByBlockNumberAndIndex-found-legacy.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByBlockNumberAndIndex-found-legacy.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf8658084342770c0825208940d3ab14bbad3d99f4203bd7a11acb94882050e7e8203e8801ba0cd190747077598c3b9c5f21ea06f8487d6ab1e23358fbe0e0e0c4e64651b68f3a0467ebcb2186b332969991e2e25244959dcdb3feb7652ff6b81ce96e646d86abd"
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByBlockNumberAndIndex-index-outofrange.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByBlockNumberAndIndex-index-outofrange.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByHash-found-create.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByHash-found-create.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf85301842db1629182cf6c8080846080604026a0fa210b09f8a13ea096b3a005a5feb0270121ab259555898bf03826e993ec14f4a007173d180059852006668647a793207d488723b89acdd6c484273f16beb9aaa3"
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByHash-found-legacy.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByHash-found-legacy.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
"0xf8658084342770c0825208940d3ab14bbad3d99f4203bd7a11acb94882050e7e8203e8801ba0cd190747077598c3b9c5f21ea06f8487d6ab1e23358fbe0e0e0c4e64651b68f3a0467ebcb2186b332969991e2e25244959dcdb3feb7652ff6b81ce96e646d86abd"
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByHash-txhash-empty.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByHash-txhash-empty.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
1
internal/ethapi/testdata/eth_getRawTransactionByHash-txhash-notfound.json
vendored
Normal file
1
internal/ethapi/testdata/eth_getRawTransactionByHash-txhash-notfound.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
null
|
||||||
Loading…
Reference in a new issue