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
8596fc59
Commit
8596fc59
authored
Aug 25, 2017
by
Péter Szilágyi
Committed by
GitHub
Aug 25, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15033 from fjl/core-receipt-status-bytes
core/types: encode receipt status in PostState field
parents
68955ed2
ad16aeb0
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
62 additions
and
83 deletions
+62
-83
database_util_test.go
core/database_util_test.go
+2
-2
receipt.go
core/types/receipt.go
+60
-81
No files found.
core/database_util_test.go
View file @
8596fc59
...
...
@@ -340,7 +340,7 @@ func TestBlockReceiptStorage(t *testing.T) {
db
,
_
:=
ethdb
.
NewMemDatabase
()
receipt1
:=
&
types
.
Receipt
{
PostState
:
[]
byte
{
0x01
}
,
Failed
:
true
,
CumulativeGasUsed
:
big
.
NewInt
(
1
),
Logs
:
[]
*
types
.
Log
{
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x11
})},
...
...
@@ -351,7 +351,7 @@ func TestBlockReceiptStorage(t *testing.T) {
GasUsed
:
big
.
NewInt
(
111111
),
}
receipt2
:=
&
types
.
Receipt
{
PostState
:
[]
byte
{
0x02
}
,
PostState
:
common
.
Hash
{
2
}
.
Bytes
()
,
CumulativeGasUsed
:
big
.
NewInt
(
2
),
Logs
:
[]
*
types
.
Log
{
{
Address
:
common
.
BytesToAddress
([]
byte
{
0x22
})},
...
...
core/types/receipt.go
View file @
8596fc59
...
...
@@ -17,6 +17,7 @@
package
types
import
(
"bytes"
"fmt"
"io"
"math/big"
...
...
@@ -28,9 +29,9 @@ import (
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
const
(
receiptStatus
Successful
=
byte
(
0x01
)
receiptStatus
Failed
=
byte
(
0x00
)
var
(
receiptStatus
Failed
=
[]
byte
{}
receiptStatus
Successful
=
[]
byte
{
0x01
}
)
// Receipt represents the results of a transaction.
...
...
@@ -54,22 +55,22 @@ type receiptMarshaling struct {
GasUsed
*
hexutil
.
Big
}
// homesteadReceiptRLP contains the receipt's Homestead consensus fields, used
// during RLP serialization.
type
homesteadReceiptRLP
struct
{
PostState
[]
byte
// receiptRLP is the consensus encoding of a receipt.
type
receiptRLP
struct
{
PostStateOrStatus
[]
byte
CumulativeGasUsed
*
big
.
Int
Bloom
Bloom
Logs
[]
*
Log
}
// metropolisReceiptRLP contains the receipt's Metropolis consensus fields, used
// during RLP serialization.
type
metropolisReceiptRLP
struct
{
Status
byte
type
receiptStorageRLP
struct
{
PostStateOrStatus
[]
byte
CumulativeGasUsed
*
big
.
Int
Bloom
Bloom
Logs
[]
*
Log
TxHash
common
.
Hash
ContractAddress
common
.
Address
Logs
[]
*
LogForStorage
GasUsed
*
big
.
Int
}
// NewReceipt creates a barebone transaction receipt, copying the init fields.
...
...
@@ -80,69 +81,46 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt {
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
// into an RLP stream. If no post state is present, metropolis fork is assumed.
func
(
r
*
Receipt
)
EncodeRLP
(
w
io
.
Writer
)
error
{
if
r
.
PostState
==
nil
{
status
:=
receiptStatusSuccessful
if
r
.
Failed
{
status
=
receiptStatusFailed
}
return
rlp
.
Encode
(
w
,
&
metropolisReceiptRLP
{
status
,
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
})
}
return
rlp
.
Encode
(
w
,
&
homesteadReceiptRLP
{
r
.
PostState
,
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
})
return
rlp
.
Encode
(
w
,
&
receiptRLP
{
r
.
statusEncoding
(),
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
})
}
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt
// from an RLP stream.
func
(
r
*
Receipt
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
// Load the raw bytes since we have multiple possible formats
raw
,
err
:=
s
.
Raw
()
if
err
!=
nil
{
return
err
}
content
,
_
,
err
:=
rlp
.
SplitList
(
raw
)
if
err
!=
nil
{
var
dec
receiptRLP
if
err
:=
s
.
Decode
(
&
dec
);
err
!=
nil
{
return
err
}
kind
,
cnt
,
_
,
err
:=
rlp
.
Split
(
content
)
if
err
!=
nil
{
if
err
:=
r
.
setStatus
(
dec
.
PostStateOrStatus
);
err
!=
nil
{
return
err
}
// Deserialize based on the first component type.
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
=
dec
.
CumulativeGasUsed
,
dec
.
Bloom
,
dec
.
Logs
return
nil
}
func
(
r
*
Receipt
)
setStatus
(
postStateOrStatus
[]
byte
)
error
{
switch
{
case
kind
==
rlp
.
Byte
||
(
kind
==
rlp
.
String
&&
len
(
cnt
)
==
0
)
:
// The first component of metropolis receipts is Byte (0x01), or the empty
// string (0x80, decoded as a byte with 0x00 value).
var
metro
metropolisReceiptRLP
if
err
:=
rlp
.
DecodeBytes
(
raw
,
&
metro
);
err
!=
nil
{
return
err
}
switch
metro
.
Status
{
case
receiptStatusSuccessful
:
case
bytes
.
Equal
(
postStateOrStatus
,
receiptStatusSuccessful
)
:
r
.
Failed
=
false
case
receiptStatusFailed
:
case
bytes
.
Equal
(
postStateOrStatus
,
receiptStatusFailed
)
:
r
.
Failed
=
true
case
len
(
postStateOrStatus
)
==
len
(
common
.
Hash
{})
:
r
.
PostState
=
postStateOrStatus
default
:
return
fmt
.
Errorf
(
"invalid status byte: 0x%x"
,
metro
.
Status
)
return
fmt
.
Errorf
(
"invalid receipt status %x"
,
postStateOr
Status
)
}
r
.
CumulativeGasUsed
=
metro
.
CumulativeGasUsed
r
.
Bloom
=
metro
.
Bloom
r
.
Logs
=
metro
.
Logs
return
nil
}
case
kind
==
rlp
.
String
:
// The first component of homestead receipts is non-empty String.
var
home
homesteadReceiptRLP
if
err
:=
rlp
.
DecodeBytes
(
raw
,
&
home
);
err
!=
nil
{
return
err
func
(
r
*
Receipt
)
statusEncoding
()
[]
byte
{
if
len
(
r
.
PostState
)
==
0
{
if
r
.
Failed
{
return
receiptStatusFailed
}
else
{
return
receiptStatusSuccessful
}
r
.
PostState
=
home
.
PostState
[
:
]
r
.
CumulativeGasUsed
=
home
.
CumulativeGasUsed
r
.
Bloom
=
home
.
Bloom
r
.
Logs
=
home
.
Logs
return
nil
default
:
return
fmt
.
Errorf
(
"invalid first receipt component: %v"
,
kind
)
}
return
r
.
PostState
}
// String implements the Stringer interface.
...
...
@@ -160,38 +138,39 @@ type ReceiptForStorage Receipt
// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt
// into an RLP stream.
func
(
r
*
ReceiptForStorage
)
EncodeRLP
(
w
io
.
Writer
)
error
{
logs
:=
make
([]
*
LogForStorage
,
len
(
r
.
Logs
))
enc
:=
&
receiptStorageRLP
{
PostStateOrStatus
:
(
*
Receipt
)(
r
)
.
statusEncoding
(),
CumulativeGasUsed
:
r
.
CumulativeGasUsed
,
Bloom
:
r
.
Bloom
,
TxHash
:
r
.
TxHash
,
ContractAddress
:
r
.
ContractAddress
,
Logs
:
make
([]
*
LogForStorage
,
len
(
r
.
Logs
)),
GasUsed
:
r
.
GasUsed
,
}
for
i
,
log
:=
range
r
.
Logs
{
l
ogs
[
i
]
=
(
*
LogForStorage
)(
log
)
enc
.
L
ogs
[
i
]
=
(
*
LogForStorage
)(
log
)
}
return
rlp
.
Encode
(
w
,
[]
interface
{}{
r
.
PostState
,
r
.
Failed
,
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
TxHash
,
r
.
ContractAddress
,
logs
,
r
.
GasUsed
}
)
return
rlp
.
Encode
(
w
,
enc
)
}
// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation
// fields of a receipt from an RLP stream.
func
(
r
*
ReceiptForStorage
)
DecodeRLP
(
s
*
rlp
.
Stream
)
error
{
var
receipt
struct
{
PostState
[]
byte
Failed
bool
CumulativeGasUsed
*
big
.
Int
Bloom
Bloom
TxHash
common
.
Hash
ContractAddress
common
.
Address
Logs
[]
*
LogForStorage
GasUsed
*
big
.
Int
var
dec
receiptStorageRLP
if
err
:=
s
.
Decode
(
&
dec
);
err
!=
nil
{
return
err
}
if
err
:=
s
.
Decode
(
&
receipt
);
err
!=
nil
{
if
err
:=
(
*
Receipt
)(
r
)
.
setStatus
(
dec
.
PostStateOrStatus
);
err
!=
nil
{
return
err
}
// Assign the consensus fields
r
.
PostState
,
r
.
Failed
,
r
.
CumulativeGasUsed
,
r
.
Bloom
=
receipt
.
PostState
,
receipt
.
Failed
,
receipt
.
CumulativeGasUsed
,
receipt
.
Bloom
r
.
Logs
=
make
([]
*
Log
,
len
(
receipt
.
Logs
))
for
i
,
log
:=
range
receipt
.
Logs
{
r
.
CumulativeGasUsed
,
r
.
Bloom
=
dec
.
CumulativeGasUsed
,
dec
.
Bloom
r
.
Logs
=
make
([]
*
Log
,
len
(
dec
.
Logs
))
for
i
,
log
:=
range
dec
.
Logs
{
r
.
Logs
[
i
]
=
(
*
Log
)(
log
)
}
// Assign the implementation fields
r
.
TxHash
,
r
.
ContractAddress
,
r
.
GasUsed
=
receipt
.
TxHash
,
receipt
.
ContractAddress
,
receipt
.
GasUsed
r
.
TxHash
,
r
.
ContractAddress
,
r
.
GasUsed
=
dec
.
TxHash
,
dec
.
ContractAddress
,
dec
.
GasUsed
return
nil
}
...
...
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