Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
f1801a9f
Unverified
Commit
f1801a9f
authored
Aug 15, 2023
by
Delweng
Committed by
GitHub
Aug 15, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
internal/ethapi: implement eth_getBlockReceipts (#27702)
parent
509cd428
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
163 additions
and
19 deletions
+163
-19
ethclient.go
ethclient/ethclient.go
+10
-0
api.go
internal/ethapi/api.go
+36
-3
api_test.go
internal/ethapi/api_test.go
+112
-16
web3ext.go
internal/web3ext/web3ext.go
+5
-0
No files found.
ethclient/ethclient.go
View file @
f1801a9f
...
...
@@ -108,6 +108,16 @@ func (ec *Client) PeerCount(ctx context.Context) (uint64, error) {
return
uint64
(
result
),
err
}
// BlockReceipts returns the receipts of a given block number or hash
func
(
ec
*
Client
)
BlockReceipts
(
ctx
context
.
Context
,
blockNrOrHash
rpc
.
BlockNumberOrHash
)
([]
*
types
.
Receipt
,
error
)
{
var
r
[]
*
types
.
Receipt
err
:=
ec
.
c
.
CallContext
(
ctx
,
&
r
,
"eth_getBlockReceipts"
,
blockNrOrHash
)
if
err
==
nil
&&
r
==
nil
{
return
nil
,
ethereum
.
NotFound
}
return
r
,
err
}
type
rpcBlock
struct
{
Hash
common
.
Hash
`json:"hash"`
Transactions
[]
rpcTransaction
`json:"transactions"`
...
...
internal/ethapi/api.go
View file @
f1801a9f
...
...
@@ -897,6 +897,34 @@ func (s *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Address
return
res
[
:
],
state
.
Error
()
}
// GetBlockReceipts returns the block receipts for the given block hash or number or tag.
func
(
s
*
BlockChainAPI
)
GetBlockReceipts
(
ctx
context
.
Context
,
blockNrOrHash
rpc
.
BlockNumberOrHash
)
([]
map
[
string
]
interface
{},
error
)
{
block
,
err
:=
s
.
b
.
BlockByNumberOrHash
(
ctx
,
blockNrOrHash
)
if
block
==
nil
||
err
!=
nil
{
// When the block doesn't exist, the RPC method should return JSON null
// as per specification.
return
nil
,
nil
}
receipts
,
err
:=
s
.
b
.
GetReceipts
(
ctx
,
block
.
Hash
())
if
err
!=
nil
{
return
nil
,
err
}
txs
:=
block
.
Transactions
()
if
len
(
txs
)
!=
len
(
receipts
)
{
return
nil
,
fmt
.
Errorf
(
"receipts length mismatch: %d vs %d"
,
len
(
txs
),
len
(
receipts
))
}
// Derive the sender.
signer
:=
types
.
MakeSigner
(
s
.
b
.
ChainConfig
(),
block
.
Number
(),
block
.
Time
())
result
:=
make
([]
map
[
string
]
interface
{},
len
(
receipts
))
for
i
,
receipt
:=
range
receipts
{
result
[
i
]
=
marshalReceipt
(
receipt
,
block
.
Hash
(),
block
.
NumberU64
(),
signer
,
txs
[
i
],
i
)
}
return
result
,
nil
}
// OverrideAccount indicates the overriding fields of account during the execution
// of a message call.
// Note, state and stateDiff can't be specified at the same time. If state is
...
...
@@ -1717,13 +1745,18 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
// Derive the sender.
signer
:=
types
.
MakeSigner
(
s
.
b
.
ChainConfig
(),
header
.
Number
,
header
.
Time
)
return
marshalReceipt
(
receipt
,
blockHash
,
blockNumber
,
signer
,
tx
,
int
(
index
)),
nil
}
// marshalReceipt marshals a transaction receipt into a JSON object.
func
marshalReceipt
(
receipt
*
types
.
Receipt
,
blockHash
common
.
Hash
,
blockNumber
uint64
,
signer
types
.
Signer
,
tx
*
types
.
Transaction
,
txIndex
int
)
map
[
string
]
interface
{}
{
from
,
_
:=
types
.
Sender
(
signer
,
tx
)
fields
:=
map
[
string
]
interface
{}{
"blockHash"
:
blockHash
,
"blockNumber"
:
hexutil
.
Uint64
(
blockNumber
),
"transactionHash"
:
hash
,
"transactionIndex"
:
hexutil
.
Uint64
(
i
ndex
),
"transactionHash"
:
tx
.
Hash
()
,
"transactionIndex"
:
hexutil
.
Uint64
(
txI
ndex
),
"from"
:
from
,
"to"
:
tx
.
To
(),
"gasUsed"
:
hexutil
.
Uint64
(
receipt
.
GasUsed
),
...
...
@@ -1749,7 +1782,7 @@ func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.
if
receipt
.
ContractAddress
!=
(
common
.
Address
{})
{
fields
[
"contractAddress"
]
=
receipt
.
ContractAddress
}
return
fields
,
nil
return
fields
}
// sign is a helper function that signs a transaction with the private key of the given address.
...
...
internal/ethapi/api_test.go
View file @
f1801a9f
...
...
@@ -1766,9 +1766,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) {
}
}
func
TestRPCGetTransactionReceipt
(
t
*
testing
.
T
)
{
t
.
Parallel
()
func
setupReceiptBackend
(
t
*
testing
.
T
,
genBlocks
int
)
(
*
testBackend
,
[]
common
.
Hash
)
{
// Initialize test accounts
var
(
acc1Key
,
_
=
crypto
.
HexToECDSA
(
"8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a"
)
...
...
@@ -1794,9 +1792,8 @@ func TestRPCGetTransactionReceipt(t *testing.T) {
contract
:
{
Balance
:
big
.
NewInt
(
params
.
Ether
),
Code
:
common
.
FromHex
(
"0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a9059cbb14610030575b600080fd5b61004a6004803603810190610045919061016a565b610060565b60405161005791906101c5565b60405180910390f35b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516100bf91906101ef565b60405180910390a36001905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610101826100d6565b9050919050565b610111816100f6565b811461011c57600080fd5b50565b60008135905061012e81610108565b92915050565b6000819050919050565b61014781610134565b811461015257600080fd5b50565b6000813590506101648161013e565b92915050565b60008060408385031215610181576101806100d1565b5b600061018f8582860161011f565b92505060206101a085828601610155565b9150509250929050565b60008115159050919050565b6101bf816101aa565b82525050565b60006020820190506101da60008301846101b6565b92915050565b6101e981610134565b82525050565b600060208201905061020460008301846101e0565b9291505056fea2646970667358221220b469033f4b77b9565ee84e0a2f04d496b18160d26034d54f9487e57788fd36d564736f6c63430008120033"
)},
},
}
genBlocks
=
5
signer
=
types
.
LatestSignerForChainID
(
params
.
TestChainConfig
.
ChainID
)
txHashes
=
make
([]
common
.
Hash
,
genBlocks
)
signer
=
types
.
LatestSignerForChainID
(
params
.
TestChainConfig
.
ChainID
)
txHashes
=
make
([]
common
.
Hash
,
genBlocks
)
)
backend
:=
newTestBackend
(
t
,
genBlocks
,
genesis
,
func
(
i
int
,
b
*
core
.
BlockGen
)
{
var
(
...
...
@@ -1838,16 +1835,16 @@ func TestRPCGetTransactionReceipt(t *testing.T) {
txHashes
[
i
]
=
tx
.
Hash
()
}
})
api
:=
NewTransactionAPI
(
backend
,
new
(
AddrLocker
))
blockHashes
:=
make
([]
common
.
Hash
,
genBlocks
+
1
)
ctx
:=
context
.
Background
()
for
i
:=
0
;
i
<=
genBlocks
;
i
++
{
header
,
err
:=
backend
.
HeaderByNumber
(
ctx
,
rpc
.
BlockNumber
(
i
)
)
if
err
!=
nil
{
t
.
Errorf
(
"failed to get block: %d err: %v"
,
i
,
err
)
}
blockHashes
[
i
]
=
header
.
Hash
(
)
}
return
backend
,
txHashes
}
func
TestRPCGetTransactionReceipt
(
t
*
testing
.
T
)
{
t
.
Parallel
(
)
var
(
backend
,
txHashes
=
setupReceiptBackend
(
t
,
5
)
api
=
NewTransactionAPI
(
backend
,
new
(
AddrLocker
)
)
)
var
testSuite
=
[]
struct
{
txHash
common
.
Hash
...
...
@@ -2000,3 +1997,102 @@ func TestRPCGetTransactionReceipt(t *testing.T) {
require
.
JSONEqf
(
t
,
want
,
have
,
"test %d: json not match, want: %s, have: %s"
,
i
,
want
,
have
)
}
}
func
TestRPCGetBlockReceipts
(
t
*
testing
.
T
)
{
t
.
Parallel
()
var
(
genBlocks
=
5
backend
,
_
=
setupReceiptBackend
(
t
,
genBlocks
)
api
=
NewBlockChainAPI
(
backend
)
)
blockHashes
:=
make
([]
common
.
Hash
,
genBlocks
+
1
)
ctx
:=
context
.
Background
()
for
i
:=
0
;
i
<=
genBlocks
;
i
++
{
header
,
err
:=
backend
.
HeaderByNumber
(
ctx
,
rpc
.
BlockNumber
(
i
))
if
err
!=
nil
{
t
.
Errorf
(
"failed to get block: %d err: %v"
,
i
,
err
)
}
blockHashes
[
i
]
=
header
.
Hash
()
}
var
testSuite
=
[]
struct
{
test
rpc
.
BlockNumberOrHash
want
string
}{
// 0. block without any txs(hash)
{
test
:
rpc
.
BlockNumberOrHashWithHash
(
blockHashes
[
0
],
false
),
want
:
`[]`
,
},
// 1. block without any txs(number)
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
0
),
want
:
`[]`
,
},
// 2. earliest tag
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
rpc
.
EarliestBlockNumber
),
want
:
`[]`
,
},
// 3. latest tag
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
rpc
.
LatestBlockNumber
),
want
:
`[{"blockHash":"0x08e23d8e3711a21fbb8becd7de22fda8fb0a49fba14e1be763d00f99063627e1","blockNumber":"0x5","contractAddress":"0xfdaa97661a584d977b4d3abb5370766ff5b86a18","cumulativeGasUsed":"0xe01a","effectiveGasPrice":"0x1ecb3f75","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0xe01a","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0x8f3c4e2663af0312d508ebd8587f0c88dccbbc8a9bcc322421ff4bc28c456a92","transactionIndex":"0x0","type":"0x1"}]`
,
},
// 4. block with legacy transfer tx(hash)
{
test
:
rpc
.
BlockNumberOrHashWithHash
(
blockHashes
[
1
],
false
),
want
:
`[{"blockHash":"0x1356e49a24d4504e450b303aa770f4ae13c29b9ffacaea1d7dd4043396229dd9","blockNumber":"0x1","contractAddress":null,"cumulativeGasUsed":"0x5208","effectiveGasPrice":"0x342770c0","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x5208","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":"0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e","transactionHash":"0x644a31c354391520d00e95b9affbbb010fc79ac268144ab8e28207f4cf51097e","transactionIndex":"0x0","type":"0x0"}]`
,
},
// 5. block with contract create tx(number)
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
rpc
.
BlockNumber
(
2
)),
want
:
`[{"blockHash":"0x4fc27a4efa7fb8faa04b12b53ec8c8424ab4c21aab1323846365f000e8b4a594","blockNumber":"0x2","contractAddress":"0xae9bea628c4ce503dcfd7e305cab4e29e7476592","cumulativeGasUsed":"0xcf4e","effectiveGasPrice":"0x2db16291","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0xcf4e","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x1","to":null,"transactionHash":"0x340e58cda5086495010b571fe25067fecc9954dc4ee3cedece00691fa3f5904a","transactionIndex":"0x0","type":"0x0"}]`
,
},
// 6. block with legacy contract call tx(hash)
{
test
:
rpc
.
BlockNumberOrHashWithHash
(
blockHashes
[
3
],
false
),
want
:
`[{"blockHash":"0x73385c190219326907524b0020ef453ebc450eaa971ebce16f79e2d23e7e8d4d","blockNumber":"0x3","contractAddress":null,"cumulativeGasUsed":"0x5e28","effectiveGasPrice":"0x281c2534","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x5e28","logs":[{"address":"0x0000000000000000000000000000000000031ec7","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x000000000000000000000000703c4b2bd70c169f5717101caee543299fc946c7","0x0000000000000000000000000000000000000000000000000000000000000003"],"data":"0x000000000000000000000000000000000000000000000000000000000000000d","blockNumber":"0x3","transactionHash":"0x9dbf43ec9afc8d711932618616471088f66ba4f25fd5c672d97473d02dae967f","transactionIndex":"0x0","blockHash":"0x73385c190219326907524b0020ef453ebc450eaa971ebce16f79e2d23e7e8d4d","logIndex":"0x0","removed":false}],"logsBloom":"0x00000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000800000000000000008000000000000000000000000000000000020000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000400000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000","status":"0x1","to":"0x0000000000000000000000000000000000031ec7","transactionHash":"0x9dbf43ec9afc8d711932618616471088f66ba4f25fd5c672d97473d02dae967f","transactionIndex":"0x0","type":"0x0"}]`
,
},
// 7. block with dynamic fee tx(number)
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
rpc
.
BlockNumber
(
4
)),
want
:
`[{"blockHash":"0x77c3f8919590e0e68db4ce74a3da3140ac3e96dd3d078a48db1da4c08b07503d","blockNumber":"0x4","contractAddress":null,"cumulativeGasUsed":"0x538d","effectiveGasPrice":"0x2325c3e8","from":"0x703c4b2bd70c169f5717101caee543299fc946c7","gasUsed":"0x538d","logs":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","status":"0x0","to":"0x0000000000000000000000000000000000031ec7","transactionHash":"0x672e3e39adf23b5656989b7a36e54d54004b1866f53871113bc52e137edb9faf","transactionIndex":"0x0","type":"0x2"}]`
,
},
// 8. block is empty
{
test
:
rpc
.
BlockNumberOrHashWithHash
(
common
.
Hash
{},
false
),
want
:
`null`
,
},
// 9. block is not found
{
test
:
rpc
.
BlockNumberOrHashWithHash
(
common
.
HexToHash
(
"deadbeef"
),
false
),
want
:
`null`
,
},
// 10. block is not found
{
test
:
rpc
.
BlockNumberOrHashWithNumber
(
rpc
.
BlockNumber
(
genBlocks
+
1
)),
want
:
`null`
,
},
}
for
i
,
tt
:=
range
testSuite
{
var
(
result
interface
{}
err
error
)
result
,
err
=
api
.
GetBlockReceipts
(
context
.
Background
(),
tt
.
test
)
if
err
!=
nil
{
t
.
Errorf
(
"test %d: want no error, have %v"
,
i
,
err
)
continue
}
data
,
err
:=
json
.
Marshal
(
result
)
if
err
!=
nil
{
t
.
Errorf
(
"test %d: json marshal error"
,
i
)
continue
}
want
,
have
:=
tt
.
want
,
string
(
data
)
require
.
JSONEqf
(
t
,
want
,
have
,
"test %d: json not match, want: %s, have: %s"
,
i
,
want
,
have
)
}
}
internal/web3ext/web3ext.go
View file @
f1801a9f
...
...
@@ -617,6 +617,11 @@ web3._extend({
params: 4,
inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null],
}),
new web3._extend.Method({
name: 'getBlockReceipts',
call: 'eth_getBlockReceipts',
params: 1,
}),
],
properties: [
new web3._extend.Property({
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment