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
6f69b4d6
Commit
6f69b4d6
authored
Jul 04, 2015
by
Jeffrey Wilcke
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1399 from obscuren/receipts-storing-fix
core, eth, miner, xeth: receipt storage fix
parents
efd7da0c
2feb23c1
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
75 additions
and
57 deletions
+75
-57
block_processor.go
core/block_processor.go
+15
-19
block_processor_test.go
core/block_processor_test.go
+4
-7
chain_manager.go
core/chain_manager.go
+1
-1
transaction_util.go
core/transaction_util.go
+42
-8
receipt.go
core/types/receipt.go
+6
-2
gasprice.go
eth/gasprice.go
+3
-6
worker.go
miner/worker.go
+1
-1
xeth.go
xeth/xeth.go
+3
-13
No files found.
core/block_processor.go
View file @
6f69b4d6
...
...
@@ -9,12 +9,12 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/rlp"
"gopkg.in/fatih/set.v0"
)
...
...
@@ -24,8 +24,6 @@ const (
BlockChainVersion
=
3
)
var
receiptsPre
=
[]
byte
(
"receipts-"
)
type
BlockProcessor
struct
{
db
common
.
Database
extraDb
common
.
Database
...
...
@@ -83,6 +81,12 @@ func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, stated
usedGas
.
Add
(
usedGas
,
gas
)
receipt
:=
types
.
NewReceipt
(
statedb
.
Root
()
.
Bytes
(),
usedGas
)
receipt
.
TxHash
=
tx
.
Hash
()
if
MessageCreatesContract
(
tx
)
{
from
,
_
:=
tx
.
From
()
receipt
.
ContractAddress
=
crypto
.
CreateAddress
(
from
,
tx
.
Nonce
())
}
logs
:=
statedb
.
GetLogs
(
tx
.
Hash
())
receipt
.
SetLogs
(
logs
)
receipt
.
Bloom
=
types
.
CreateBloom
(
types
.
Receipts
{
receipt
})
...
...
@@ -319,16 +323,20 @@ func (sm *BlockProcessor) VerifyUncles(statedb *state.StateDB, block, parent *ty
}
// GetBlockReceipts returns the receipts beloniging to the block hash
func
(
sm
*
BlockProcessor
)
GetBlockReceipts
(
bhash
common
.
Hash
)
(
receipts
types
.
Receipts
,
err
error
)
{
return
getBlockReceipts
(
sm
.
extraDb
,
bhash
)
func
(
sm
*
BlockProcessor
)
GetBlockReceipts
(
bhash
common
.
Hash
)
types
.
Receipts
{
if
block
:=
sm
.
ChainManager
()
.
GetBlock
(
bhash
);
block
!=
nil
{
return
GetReceiptsFromBlock
(
sm
.
extraDb
,
block
)
}
return
nil
}
// GetLogs returns the logs of the given block. This method is using a two step approach
// where it tries to get it from the (updated) method which gets them from the receipts or
// the depricated way by re-processing the block.
func
(
sm
*
BlockProcessor
)
GetLogs
(
block
*
types
.
Block
)
(
logs
state
.
Logs
,
err
error
)
{
receipts
,
err
:=
sm
.
GetBlockReceipts
(
block
.
Hash
()
)
if
err
==
nil
&&
len
(
receipts
)
>
0
{
receipts
:=
GetReceiptsFromBlock
(
sm
.
extraDb
,
block
)
if
len
(
receipts
)
>
0
{
// coalesce logs
for
_
,
receipt
:=
range
receipts
{
logs
=
append
(
logs
,
receipt
.
Logs
()
...
)
...
...
@@ -391,15 +399,3 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check
return
nil
}
func
getBlockReceipts
(
db
common
.
Database
,
bhash
common
.
Hash
)
(
receipts
types
.
Receipts
,
err
error
)
{
var
rdata
[]
byte
rdata
,
err
=
db
.
Get
(
append
(
receiptsPre
,
bhash
[
:
]
...
))
if
err
==
nil
{
err
=
rlp
.
DecodeBytes
(
rdata
,
&
receipts
)
}
else
{
glog
.
V
(
logger
.
Detail
)
.
Infof
(
"getBlockReceipts error %v
\n
"
,
err
)
}
return
}
core/block_processor_test.go
View file @
6f69b4d6
...
...
@@ -64,12 +64,9 @@ func TestPutReceipt(t *testing.T) {
Index
:
0
,
}})
PutReceipts
(
db
,
hash
,
types
.
Receipts
{
receipt
})
receipts
,
err
:=
getBlockReceipts
(
db
,
hash
)
if
err
!=
nil
{
t
.
Error
(
"got err:"
,
err
)
}
if
len
(
receipts
)
!=
1
{
t
.
Error
(
"expected to get 1 receipt, got"
,
len
(
receipts
))
PutReceipts
(
db
,
types
.
Receipts
{
receipt
})
receipt
=
GetReceipt
(
db
,
common
.
Hash
{})
if
receipt
==
nil
{
t
.
Error
(
"expected to get 1 receipt, got none."
)
}
}
core/chain_manager.go
View file @
6f69b4d6
...
...
@@ -632,7 +632,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) {
// This puts transactions in a extra db for rpc
PutTransactions
(
self
.
extraDb
,
block
,
block
.
Transactions
())
// store the receipts
PutReceipts
(
self
.
extraDb
,
block
.
Hash
(),
receipts
)
PutReceipts
(
self
.
extraDb
,
receipts
)
case
SideStatTy
:
if
glog
.
V
(
logger
.
Detail
)
{
glog
.
Infof
(
"inserted forked block #%d (TD=%v) (%d TXs %d UNCs) (%x...). Took %v
\n
"
,
block
.
Number
(),
block
.
Difficulty
(),
len
(
block
.
Transactions
()),
len
(
block
.
Uncles
()),
block
.
Hash
()
.
Bytes
()[
0
:
4
],
time
.
Since
(
bstart
))
...
...
core/transaction_util.go
View file @
6f69b4d6
...
...
@@ -8,6 +8,9 @@ import (
"github.com/ethereum/go-ethereum/rlp"
)
var
receiptsPre
=
[]
byte
(
"receipts-"
)
// PutTransactions stores the transactions in the given database
func
PutTransactions
(
db
common
.
Database
,
block
*
types
.
Block
,
txs
types
.
Transactions
)
{
for
i
,
tx
:=
range
block
.
Transactions
()
{
rlpEnc
,
err
:=
rlp
.
EncodeToBytes
(
tx
)
...
...
@@ -34,18 +37,49 @@ func PutTransactions(db common.Database, block *types.Block, txs types.Transacti
}
}
func
PutReceipts
(
db
common
.
Database
,
hash
common
.
Hash
,
receipts
types
.
Receipts
)
error
{
storageReceipts
:=
make
([]
*
types
.
ReceiptForStorage
,
len
(
receipts
))
for
i
,
receipt
:=
range
receipts
{
storageReceipts
[
i
]
=
(
*
types
.
ReceiptForStorage
)(
receipt
)
// PutReceipts stores the receipts in the current database
func
PutReceipts
(
db
common
.
Database
,
receipts
types
.
Receipts
)
error
{
for
_
,
receipt
:=
range
receipts
{
storageReceipt
:=
(
*
types
.
ReceiptForStorage
)(
receipt
)
bytes
,
err
:=
rlp
.
EncodeToBytes
(
storageReceipt
)
if
err
!=
nil
{
return
err
}
err
=
db
.
Put
(
append
(
receiptsPre
,
receipt
.
TxHash
[
:
]
...
),
bytes
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
// GetReceipt returns a receipt by hash
func
GetReceipt
(
db
common
.
Database
,
txHash
common
.
Hash
)
*
types
.
Receipt
{
data
,
_
:=
db
.
Get
(
append
(
receiptsPre
,
txHash
[
:
]
...
))
if
len
(
data
)
==
0
{
return
nil
}
bytes
,
err
:=
rlp
.
EncodeToBytes
(
storageReceipts
)
var
receipt
types
.
Receipt
err
:=
rlp
.
DecodeBytes
(
data
,
&
receipt
)
if
err
!=
nil
{
return
err
glog
.
V
(
logger
.
Error
)
.
Infoln
(
"GetReceipt err:"
,
err
)
}
return
&
receipt
}
db
.
Put
(
append
(
receiptsPre
,
hash
[
:
]
...
),
bytes
)
// GetReceiptFromBlock returns all receipts with the given block
func
GetReceiptsFromBlock
(
db
common
.
Database
,
block
*
types
.
Block
)
types
.
Receipts
{
// at some point we want:
//receipts := make(types.Receipts, len(block.Transactions()))
// but since we need to support legacy, we can't (yet)
var
receipts
types
.
Receipts
for
_
,
tx
:=
range
block
.
Transactions
()
{
if
receipt
:=
GetReceipt
(
db
,
tx
.
Hash
());
receipt
!=
nil
{
receipts
=
append
(
receipts
,
receipt
)
}
}
return
nil
return
receipts
}
core/types/receipt.go
View file @
6f69b4d6
...
...
@@ -15,6 +15,8 @@ type Receipt struct {
PostState
[]
byte
CumulativeGasUsed
*
big
.
Int
Bloom
Bloom
TxHash
common
.
Hash
ContractAddress
common
.
Address
logs
state
.
Logs
}
...
...
@@ -39,12 +41,14 @@ func (self *Receipt) DecodeRLP(s *rlp.Stream) error {
PostState
[]
byte
CumulativeGasUsed
*
big
.
Int
Bloom
Bloom
TxHash
common
.
Hash
ContractAddress
common
.
Address
Logs
state
.
Logs
}
if
err
:=
s
.
Decode
(
&
r
);
err
!=
nil
{
return
err
}
self
.
PostState
,
self
.
CumulativeGasUsed
,
self
.
Bloom
,
self
.
logs
=
r
.
PostState
,
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
Logs
self
.
PostState
,
self
.
CumulativeGasUsed
,
self
.
Bloom
,
self
.
TxHash
,
self
.
ContractAddress
,
self
.
logs
=
r
.
PostState
,
r
.
CumulativeGasUsed
,
r
.
Bloom
,
r
.
TxHash
,
r
.
ContractAddress
,
r
.
Logs
return
nil
}
...
...
@@ -56,7 +60,7 @@ func (self *ReceiptForStorage) EncodeRLP(w io.Writer) error {
for
i
,
log
:=
range
self
.
logs
{
storageLogs
[
i
]
=
(
*
state
.
LogForStorage
)(
log
)
}
return
rlp
.
Encode
(
w
,
[]
interface
{}{
self
.
PostState
,
self
.
CumulativeGasUsed
,
self
.
Bloom
,
storageLogs
})
return
rlp
.
Encode
(
w
,
[]
interface
{}{
self
.
PostState
,
self
.
CumulativeGasUsed
,
self
.
Bloom
,
s
elf
.
TxHash
,
self
.
ContractAddress
,
s
torageLogs
})
}
func
(
self
*
Receipt
)
RlpEncode
()
[]
byte
{
...
...
eth/gasprice.go
View file @
6f69b4d6
...
...
@@ -131,13 +131,10 @@ func (self *GasPriceOracle) processBlock(block *types.Block) {
// returns the lowers possible price with which a tx was or could have been included
func
(
self
*
GasPriceOracle
)
lowestPrice
(
block
*
types
.
Block
)
*
big
.
Int
{
gasUsed
:=
new
(
big
.
Int
)
recepits
,
err
:=
self
.
eth
.
BlockProcessor
()
.
GetBlockReceipts
(
block
.
Hash
())
if
err
!=
nil
{
return
self
.
eth
.
GpoMinGasPrice
}
if
len
(
recepits
)
>
0
{
gasUsed
=
recepits
[
len
(
recepits
)
-
1
]
.
CumulativeGasUsed
receipts
:=
self
.
eth
.
BlockProcessor
()
.
GetBlockReceipts
(
block
.
Hash
())
if
len
(
receipts
)
>
0
{
gasUsed
=
receipts
[
len
(
receipts
)
-
1
]
.
CumulativeGasUsed
}
if
new
(
big
.
Int
)
.
Mul
(
gasUsed
,
big
.
NewInt
(
100
))
.
Cmp
(
new
(
big
.
Int
)
.
Mul
(
block
.
GasLimit
(),
...
...
miner/worker.go
View file @
6f69b4d6
...
...
@@ -255,7 +255,7 @@ func (self *worker) wait() {
// This puts transactions in a extra db for rpc
core
.
PutTransactions
(
self
.
extraDb
,
block
,
block
.
Transactions
())
// store the receipts
core
.
PutReceipts
(
self
.
extraDb
,
block
.
Hash
(),
self
.
current
.
receipts
)
core
.
PutReceipts
(
self
.
extraDb
,
self
.
current
.
receipts
)
}
// check staleness and display confirmation
...
...
xeth/xeth.go
View file @
6f69b4d6
...
...
@@ -364,22 +364,12 @@ func (self *XEth) CurrentBlock() *types.Block {
return
self
.
backend
.
ChainManager
()
.
CurrentBlock
()
}
func
(
self
*
XEth
)
GetBlockReceipts
(
bhash
common
.
Hash
)
(
receipts
types
.
Receipts
,
err
error
)
{
func
(
self
*
XEth
)
GetBlockReceipts
(
bhash
common
.
Hash
)
types
.
Receipts
{
return
self
.
backend
.
BlockProcessor
()
.
GetBlockReceipts
(
bhash
)
}
func
(
self
*
XEth
)
GetTxReceipt
(
txhash
common
.
Hash
)
(
receipt
*
types
.
Receipt
,
err
error
)
{
_
,
bhash
,
_
,
txi
:=
self
.
EthTransactionByHash
(
common
.
ToHex
(
txhash
[
:
]))
var
receipts
types
.
Receipts
receipts
,
err
=
self
.
backend
.
BlockProcessor
()
.
GetBlockReceipts
(
bhash
)
if
err
==
nil
{
if
txi
<
uint64
(
len
(
receipts
))
{
receipt
=
receipts
[
txi
]
}
else
{
err
=
fmt
.
Errorf
(
"Invalid tx index"
)
}
}
return
func
(
self
*
XEth
)
GetTxReceipt
(
txhash
common
.
Hash
)
*
types
.
Receipt
{
return
core
.
GetReceipt
(
self
.
backend
.
ExtraDb
(),
txhash
)
}
func
(
self
*
XEth
)
GasLimit
()
*
big
.
Int
{
...
...
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