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
e4f570fc
Unverified
Commit
e4f570fc
authored
Oct 13, 2021
by
Ian Norden
Committed by
GitHub
Oct 13, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core/types: add MarshalBinary, UnmarshalBinary for Receipt (#22806)
parent
f9d683b0
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
223 additions
and
19 deletions
+223
-19
receipt.go
core/types/receipt.go
+71
-19
receipt_test.go
core/types/receipt_test.go
+152
-0
No files found.
core/types/receipt.go
View file @
e4f570fc
...
...
@@ -144,13 +144,29 @@ func (r *Receipt) EncodeRLP(w io.Writer) error {
buf
:=
encodeBufferPool
.
Get
()
.
(
*
bytes
.
Buffer
)
defer
encodeBufferPool
.
Put
(
buf
)
buf
.
Reset
()
buf
.
WriteByte
(
r
.
Type
)
if
err
:=
rlp
.
Encode
(
buf
,
data
);
err
!=
nil
{
if
err
:=
r
.
encodeTyped
(
data
,
buf
);
err
!=
nil
{
return
err
}
return
rlp
.
Encode
(
w
,
buf
.
Bytes
())
}
// encodeTyped writes the canonical encoding of a typed receipt to w.
func
(
r
*
Receipt
)
encodeTyped
(
data
*
receiptRLP
,
w
*
bytes
.
Buffer
)
error
{
w
.
WriteByte
(
r
.
Type
)
return
rlp
.
Encode
(
w
,
data
)
}
// MarshalBinary returns the consensus encoding of the receipt.
func
(
r
*
Receipt
)
MarshalBinary
()
([]
byte
,
error
)
{
if
r
.
Type
==
LegacyTxType
{
return
rlp
.
EncodeToBytes
(
r
)
}
data
:=
&
receiptRLP
{
r
.
statusEncoding
(),
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
}
var
buf
bytes
.
Buffer
err
:=
r
.
encodeTyped
(
data
,
&
buf
)
return
buf
.
Bytes
(),
err
}
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
// from an RLP stream.
func
(
r
*
Receipt
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
...
...
@@ -189,6 +205,42 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
}
}
// UnmarshalBinary decodes the consensus encoding of receipts.
// It supports legacy RLP receipts and EIP-2718 typed receipts.
func
(
r
*
Receipt
)
UnmarshalBinary
(
b
[]
byte
)
error
{
if
len
(
b
)
>
0
&&
b
[
0
]
>
0x7f
{
// It's a legacy receipt decode the RLP
var
data
receiptRLP
err
:=
rlp
.
DecodeBytes
(
b
,
&
data
)
if
err
!=
nil
{
return
err
}
r
.
Type
=
LegacyTxType
return
r
.
setFromRLP
(
data
)
}
// It's an EIP2718 typed transaction envelope.
return
r
.
decodeTyped
(
b
)
}
// decodeTyped decodes a typed receipt from the canonical format.
func
(
r
*
Receipt
)
decodeTyped
(
b
[]
byte
)
error
{
if
len
(
b
)
==
0
{
return
errEmptyTypedReceipt
}
switch
b
[
0
]
{
case
DynamicFeeTxType
,
AccessListTxType
:
var
data
receiptRLP
err
:=
rlp
.
DecodeBytes
(
b
[
1
:
],
&
data
)
if
err
!=
nil
{
return
err
}
r
.
Type
=
b
[
0
]
return
r
.
setFromRLP
(
data
)
default
:
return
ErrTxTypeNotSupported
}
}
func
(
r
*
Receipt
)
setFromRLP
(
data
receiptRLP
)
error
{
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
=
data
.
CumulativeGasUsed
,
data
.
Bloom
,
data
.
Logs
return
r
.
setStatus
(
data
.
PostStateOrStatus
)
...
...
@@ -354,42 +406,42 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) {
// DeriveFields fills the receipts with their computed fields based on consensus
// data and contextual infos like containing block and transactions.
func
(
r
Receipts
)
DeriveFields
(
config
*
params
.
ChainConfig
,
hash
common
.
Hash
,
number
uint64
,
txs
Transactions
)
error
{
func
(
r
s
Receipts
)
DeriveFields
(
config
*
params
.
ChainConfig
,
hash
common
.
Hash
,
number
uint64
,
txs
Transactions
)
error
{
signer
:=
MakeSigner
(
config
,
new
(
big
.
Int
)
.
SetUint64
(
number
))
logIndex
:=
uint
(
0
)
if
len
(
txs
)
!=
len
(
r
)
{
if
len
(
txs
)
!=
len
(
r
s
)
{
return
errors
.
New
(
"transaction and receipt count mismatch"
)
}
for
i
:=
0
;
i
<
len
(
r
);
i
++
{
for
i
:=
0
;
i
<
len
(
r
s
);
i
++
{
// The transaction type and hash can be retrieved from the transaction itself
r
[
i
]
.
Type
=
txs
[
i
]
.
Type
()
r
[
i
]
.
TxHash
=
txs
[
i
]
.
Hash
()
r
s
[
i
]
.
Type
=
txs
[
i
]
.
Type
()
r
s
[
i
]
.
TxHash
=
txs
[
i
]
.
Hash
()
// block location fields
r
[
i
]
.
BlockHash
=
hash
r
[
i
]
.
BlockNumber
=
new
(
big
.
Int
)
.
SetUint64
(
number
)
r
[
i
]
.
TransactionIndex
=
uint
(
i
)
r
s
[
i
]
.
BlockHash
=
hash
r
s
[
i
]
.
BlockNumber
=
new
(
big
.
Int
)
.
SetUint64
(
number
)
r
s
[
i
]
.
TransactionIndex
=
uint
(
i
)
// The contract address can be derived from the transaction itself
if
txs
[
i
]
.
To
()
==
nil
{
// Deriving the signer is expensive, only do if it's actually needed
from
,
_
:=
Sender
(
signer
,
txs
[
i
])
r
[
i
]
.
ContractAddress
=
crypto
.
CreateAddress
(
from
,
txs
[
i
]
.
Nonce
())
r
s
[
i
]
.
ContractAddress
=
crypto
.
CreateAddress
(
from
,
txs
[
i
]
.
Nonce
())
}
// The used gas can be calculated based on previous r
if
i
==
0
{
r
[
i
]
.
GasUsed
=
r
[
i
]
.
CumulativeGasUsed
r
s
[
i
]
.
GasUsed
=
rs
[
i
]
.
CumulativeGasUsed
}
else
{
r
[
i
]
.
GasUsed
=
r
[
i
]
.
CumulativeGasUsed
-
r
[
i
-
1
]
.
CumulativeGasUsed
r
s
[
i
]
.
GasUsed
=
rs
[
i
]
.
CumulativeGasUsed
-
rs
[
i
-
1
]
.
CumulativeGasUsed
}
// The derived log fields can simply be set from the block and transaction
for
j
:=
0
;
j
<
len
(
r
[
i
]
.
Logs
);
j
++
{
r
[
i
]
.
Logs
[
j
]
.
BlockNumber
=
number
r
[
i
]
.
Logs
[
j
]
.
BlockHash
=
hash
r
[
i
]
.
Logs
[
j
]
.
TxHash
=
r
[
i
]
.
TxHash
r
[
i
]
.
Logs
[
j
]
.
TxIndex
=
uint
(
i
)
r
[
i
]
.
Logs
[
j
]
.
Index
=
logIndex
for
j
:=
0
;
j
<
len
(
r
s
[
i
]
.
Logs
);
j
++
{
r
s
[
i
]
.
Logs
[
j
]
.
BlockNumber
=
number
r
s
[
i
]
.
Logs
[
j
]
.
BlockHash
=
hash
r
s
[
i
]
.
Logs
[
j
]
.
TxHash
=
rs
[
i
]
.
TxHash
r
s
[
i
]
.
Logs
[
j
]
.
TxIndex
=
uint
(
i
)
r
s
[
i
]
.
Logs
[
j
]
.
Index
=
logIndex
logIndex
++
}
}
...
...
core/types/receipt_test.go
View file @
e4f570fc
...
...
@@ -29,6 +29,59 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
var
(
legacyReceipt
=
&
Receipt
{
Status
:
ReceiptStatusFailed
,
CumulativeGasUsed
:
1
,
Logs
:
[]
*
Log
{
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x01
,
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
},
}
accessListReceipt
=
&
Receipt
{
Status
:
ReceiptStatusFailed
,
CumulativeGasUsed
:
1
,
Logs
:
[]
*
Log
{
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x01
,
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
},
Type
:
AccessListTxType
,
}
eip1559Receipt
=
&
Receipt
{
Status
:
ReceiptStatusFailed
,
CumulativeGasUsed
:
1
,
Logs
:
[]
*
Log
{
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x01
,
0x11
}),
Topics
:
[]
common
.
Hash
{
common
.
HexToHash
(
"dead"
),
common
.
HexToHash
(
"beef"
)},
Data
:
[]
byte
{
0x01
,
0x00
,
0xff
},
},
},
Type
:
DynamicFeeTxType
,
}
)
func
TestDecodeEmptyTypedReceipt
(
t
*
testing
.
T
)
{
input
:=
[]
byte
{
0x80
}
var
r
Receipt
...
...
@@ -312,6 +365,105 @@ func TestTypedReceiptEncodingDecoding(t *testing.T) {
}
}
func
TestReceiptMarshalBinary
(
t
*
testing
.
T
)
{
// Legacy Receipt
legacyReceipt
.
Bloom
=
CreateBloom
(
Receipts
{
legacyReceipt
})
have
,
err
:=
legacyReceipt
.
MarshalBinary
()
if
err
!=
nil
{
t
.
Fatalf
(
"marshal binary error: %v"
,
err
)
}
legacyReceipts
:=
Receipts
{
legacyReceipt
}
buf
:=
new
(
bytes
.
Buffer
)
legacyReceipts
.
EncodeIndex
(
0
,
buf
)
haveEncodeIndex
:=
buf
.
Bytes
()
if
!
bytes
.
Equal
(
have
,
haveEncodeIndex
)
{
t
.
Errorf
(
"BinaryMarshal and EncodeIndex mismatch, got %x want %x"
,
have
,
haveEncodeIndex
)
}
buf
.
Reset
()
if
err
:=
legacyReceipt
.
EncodeRLP
(
buf
);
err
!=
nil
{
t
.
Fatalf
(
"encode rlp error: %v"
,
err
)
}
haveRLPEncode
:=
buf
.
Bytes
()
if
!
bytes
.
Equal
(
have
,
haveRLPEncode
)
{
t
.
Errorf
(
"BinaryMarshal and EncodeRLP mismatch for legacy tx, got %x want %x"
,
have
,
haveRLPEncode
)
}
legacyWant
:=
common
.
FromHex
(
"f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
if
!
bytes
.
Equal
(
have
,
legacyWant
)
{
t
.
Errorf
(
"encoded RLP mismatch, got %x want %x"
,
have
,
legacyWant
)
}
// 2930 Receipt
buf
.
Reset
()
accessListReceipt
.
Bloom
=
CreateBloom
(
Receipts
{
accessListReceipt
})
have
,
err
=
accessListReceipt
.
MarshalBinary
()
if
err
!=
nil
{
t
.
Fatalf
(
"marshal binary error: %v"
,
err
)
}
accessListReceipts
:=
Receipts
{
accessListReceipt
}
accessListReceipts
.
EncodeIndex
(
0
,
buf
)
haveEncodeIndex
=
buf
.
Bytes
()
if
!
bytes
.
Equal
(
have
,
haveEncodeIndex
)
{
t
.
Errorf
(
"BinaryMarshal and EncodeIndex mismatch, got %x want %x"
,
have
,
haveEncodeIndex
)
}
accessListWant
:=
common
.
FromHex
(
"01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
if
!
bytes
.
Equal
(
have
,
accessListWant
)
{
t
.
Errorf
(
"encoded RLP mismatch, got %x want %x"
,
have
,
accessListWant
)
}
// 1559 Receipt
buf
.
Reset
()
eip1559Receipt
.
Bloom
=
CreateBloom
(
Receipts
{
eip1559Receipt
})
have
,
err
=
eip1559Receipt
.
MarshalBinary
()
if
err
!=
nil
{
t
.
Fatalf
(
"marshal binary error: %v"
,
err
)
}
eip1559Receipts
:=
Receipts
{
eip1559Receipt
}
eip1559Receipts
.
EncodeIndex
(
0
,
buf
)
haveEncodeIndex
=
buf
.
Bytes
()
if
!
bytes
.
Equal
(
have
,
haveEncodeIndex
)
{
t
.
Errorf
(
"BinaryMarshal and EncodeIndex mismatch, got %x want %x"
,
have
,
haveEncodeIndex
)
}
eip1559Want
:=
common
.
FromHex
(
"02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
if
!
bytes
.
Equal
(
have
,
eip1559Want
)
{
t
.
Errorf
(
"encoded RLP mismatch, got %x want %x"
,
have
,
eip1559Want
)
}
}
func
TestReceiptUnmarshalBinary
(
t
*
testing
.
T
)
{
// Legacy Receipt
legacyBinary
:=
common
.
FromHex
(
"f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
gotLegacyReceipt
:=
new
(
Receipt
)
if
err
:=
gotLegacyReceipt
.
UnmarshalBinary
(
legacyBinary
);
err
!=
nil
{
t
.
Fatalf
(
"unmarshal binary error: %v"
,
err
)
}
legacyReceipt
.
Bloom
=
CreateBloom
(
Receipts
{
legacyReceipt
})
if
!
reflect
.
DeepEqual
(
gotLegacyReceipt
,
legacyReceipt
)
{
t
.
Errorf
(
"receipt unmarshalled from binary mismatch, got %v want %v"
,
gotLegacyReceipt
,
legacyReceipt
)
}
// 2930 Receipt
accessListBinary
:=
common
.
FromHex
(
"01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
gotAccessListReceipt
:=
new
(
Receipt
)
if
err
:=
gotAccessListReceipt
.
UnmarshalBinary
(
accessListBinary
);
err
!=
nil
{
t
.
Fatalf
(
"unmarshal binary error: %v"
,
err
)
}
accessListReceipt
.
Bloom
=
CreateBloom
(
Receipts
{
accessListReceipt
})
if
!
reflect
.
DeepEqual
(
gotAccessListReceipt
,
accessListReceipt
)
{
t
.
Errorf
(
"receipt unmarshalled from binary mismatch, got %v want %v"
,
gotAccessListReceipt
,
accessListReceipt
)
}
// 1559 Receipt
eip1559RctBinary
:=
common
.
FromHex
(
"02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"
)
got1559Receipt
:=
new
(
Receipt
)
if
err
:=
got1559Receipt
.
UnmarshalBinary
(
eip1559RctBinary
);
err
!=
nil
{
t
.
Fatalf
(
"unmarshal binary error: %v"
,
err
)
}
eip1559Receipt
.
Bloom
=
CreateBloom
(
Receipts
{
eip1559Receipt
})
if
!
reflect
.
DeepEqual
(
got1559Receipt
,
eip1559Receipt
)
{
t
.
Errorf
(
"receipt unmarshalled from binary mismatch, got %v want %v"
,
got1559Receipt
,
eip1559Receipt
)
}
}
func
clearComputedFieldsOnReceipts
(
t
*
testing
.
T
,
receipts
Receipts
)
{
t
.
Helper
()
...
...
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