Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
whqwjb
go-ethereum
提交
f1b00cff
G
go-ethereum
项目概览
whqwjb
/
go-ethereum
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
go-ethereum
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
f1b00cff
编写于
12月 17, 2018
作者:
R
rjl493456442
提交者:
Péter Szilágyi
4月 08, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core: re-omit new log event when logs rebirth
上级
442320a8
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
224 addition
and
9 deletion
+224
-9
core/blockchain.go
core/blockchain.go
+19
-8
core/blockchain_test.go
core/blockchain_test.go
+205
-1
未找到文件。
core/blockchain.go
浏览文件 @
f1b00cff
...
...
@@ -1401,11 +1401,11 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
commonBlock
*
types
.
Block
deletedTxs
types
.
Transactions
deletedLogs
[]
*
types
.
Log
rebirthLogs
[]
*
types
.
Log
// collectLogs collects the logs that were generated during the
// processing of the block that corresponds with the given hash.
// These logs are later announced as deleted.
collectLogs
=
func
(
hash
common
.
Hash
)
{
// Coalesce logs and set 'Removed'.
// These logs are later announced as deleted or reborn
collectLogs
=
func
(
hash
common
.
Hash
,
removed
bool
)
{
number
:=
bc
.
hc
.
GetBlockNumber
(
hash
)
if
number
==
nil
{
return
...
...
@@ -1413,9 +1413,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
receipts
:=
rawdb
.
ReadReceipts
(
bc
.
db
,
hash
,
*
number
)
for
_
,
receipt
:=
range
receipts
{
for
_
,
log
:=
range
receipt
.
Logs
{
del
:=
*
log
del
.
Removed
=
true
deletedLogs
=
append
(
deletedLogs
,
&
del
)
l
:=
*
log
if
removed
{
l
.
Removed
=
true
deletedLogs
=
append
(
deletedLogs
,
&
l
)
}
else
{
rebirthLogs
=
append
(
rebirthLogs
,
&
l
)
}
}
}
}
...
...
@@ -1428,7 +1432,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
oldChain
=
append
(
oldChain
,
oldBlock
)
deletedTxs
=
append
(
deletedTxs
,
oldBlock
.
Transactions
()
...
)
collectLogs
(
oldBlock
.
Hash
())
collectLogs
(
oldBlock
.
Hash
()
,
true
)
}
}
else
{
// reduce new chain and append new chain blocks for inserting later on
...
...
@@ -1452,7 +1456,7 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
oldChain
=
append
(
oldChain
,
oldBlock
)
newChain
=
append
(
newChain
,
newBlock
)
deletedTxs
=
append
(
deletedTxs
,
oldBlock
.
Transactions
()
...
)
collectLogs
(
oldBlock
.
Hash
())
collectLogs
(
oldBlock
.
Hash
()
,
true
)
oldBlock
,
newBlock
=
bc
.
GetBlock
(
oldBlock
.
ParentHash
(),
oldBlock
.
NumberU64
()
-
1
),
bc
.
GetBlock
(
newBlock
.
ParentHash
(),
newBlock
.
NumberU64
()
-
1
)
if
oldBlock
==
nil
{
...
...
@@ -1478,6 +1482,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
for
i
:=
len
(
newChain
)
-
1
;
i
>=
0
;
i
--
{
// insert the block in the canonical way, re-writing history
bc
.
insert
(
newChain
[
i
])
// collect reborn logs due to chain reorg(except head block)
if
i
!=
0
{
collectLogs
(
newChain
[
i
]
.
Hash
(),
false
)
}
// write lookup entries for hash based transaction/receipt searches
rawdb
.
WriteTxLookupEntries
(
bc
.
db
,
newChain
[
i
])
addedTxs
=
append
(
addedTxs
,
newChain
[
i
]
.
Transactions
()
...
)
...
...
@@ -1495,6 +1503,9 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
if
len
(
deletedLogs
)
>
0
{
go
bc
.
rmLogsFeed
.
Send
(
RemovedLogsEvent
{
deletedLogs
})
}
if
len
(
rebirthLogs
)
>
0
{
go
bc
.
logsFeed
.
Send
(
rebirthLogs
)
}
if
len
(
oldChain
)
>
0
{
go
func
()
{
for
_
,
block
:=
range
oldChain
{
...
...
core/blockchain_test.go
浏览文件 @
f1b00cff
...
...
@@ -884,7 +884,6 @@ func TestChainTxReorgs(t *testing.T) {
}
func
TestLogReorgs
(
t
*
testing
.
T
)
{
var
(
key1
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
addr1
=
crypto
.
PubkeyToAddress
(
key1
.
PublicKey
)
...
...
@@ -930,6 +929,211 @@ func TestLogReorgs(t *testing.T) {
}
}
func
TestLogRebirth
(
t
*
testing
.
T
)
{
var
(
key1
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
addr1
=
crypto
.
PubkeyToAddress
(
key1
.
PublicKey
)
db
=
ethdb
.
NewMemDatabase
()
// this code generates a log
code
=
common
.
Hex2Bytes
(
"60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00"
)
gspec
=
&
Genesis
{
Config
:
params
.
TestChainConfig
,
Alloc
:
GenesisAlloc
{
addr1
:
{
Balance
:
big
.
NewInt
(
10000000000000
)}}}
genesis
=
gspec
.
MustCommit
(
db
)
signer
=
types
.
NewEIP155Signer
(
gspec
.
Config
.
ChainID
)
newLogCh
=
make
(
chan
bool
)
)
// listenNewLog checks whether the received logs number is equal with expected.
listenNewLog
:=
func
(
sink
chan
[]
*
types
.
Log
,
expect
int
)
{
cnt
:=
0
for
{
select
{
case
logs
:=
<-
sink
:
cnt
+=
len
(
logs
)
case
<-
time
.
NewTimer
(
5
*
time
.
Second
)
.
C
:
// new logs timeout
newLogCh
<-
false
return
}
if
cnt
==
expect
{
break
}
else
if
cnt
>
expect
{
// redundant logs received
newLogCh
<-
false
return
}
}
select
{
case
<-
sink
:
// redundant logs received
newLogCh
<-
false
case
<-
time
.
NewTimer
(
100
*
time
.
Millisecond
)
.
C
:
newLogCh
<-
true
}
}
blockchain
,
_
:=
NewBlockChain
(
db
,
nil
,
gspec
.
Config
,
ethash
.
NewFaker
(),
vm
.
Config
{},
nil
)
defer
blockchain
.
Stop
()
logsCh
:=
make
(
chan
[]
*
types
.
Log
)
blockchain
.
SubscribeLogsEvent
(
logsCh
)
rmLogsCh
:=
make
(
chan
RemovedLogsEvent
)
blockchain
.
SubscribeRemovedLogsEvent
(
rmLogsCh
)
chain
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
genesis
,
ethash
.
NewFaker
(),
db
,
2
,
func
(
i
int
,
gen
*
BlockGen
)
{
if
i
==
1
{
tx
,
err
:=
types
.
SignTx
(
types
.
NewContractCreation
(
gen
.
TxNonce
(
addr1
),
new
(
big
.
Int
),
1000000
,
new
(
big
.
Int
),
code
),
signer
,
key1
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create tx: %v"
,
err
)
}
gen
.
AddTx
(
tx
)
}
})
// Spawn a goroutine to receive log events
go
listenNewLog
(
logsCh
,
1
)
if
_
,
err
:=
blockchain
.
InsertChain
(
chain
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert chain: %v"
,
err
)
}
if
!<-
newLogCh
{
t
.
Fatalf
(
"failed to receive new log event"
)
}
// Generate long reorg chain
forkChain
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
genesis
,
ethash
.
NewFaker
(),
db
,
2
,
func
(
i
int
,
gen
*
BlockGen
)
{
if
i
==
1
{
tx
,
err
:=
types
.
SignTx
(
types
.
NewContractCreation
(
gen
.
TxNonce
(
addr1
),
new
(
big
.
Int
),
1000000
,
new
(
big
.
Int
),
code
),
signer
,
key1
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create tx: %v"
,
err
)
}
gen
.
AddTx
(
tx
)
// Higher block difficulty
gen
.
OffsetTime
(
-
9
)
}
})
// Spawn a goroutine to receive log events
go
listenNewLog
(
logsCh
,
1
)
if
_
,
err
:=
blockchain
.
InsertChain
(
forkChain
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert forked chain: %v"
,
err
)
}
if
!<-
newLogCh
{
t
.
Fatalf
(
"failed to receive new log event"
)
}
// Ensure removedLog events received
select
{
case
ev
:=
<-
rmLogsCh
:
if
len
(
ev
.
Logs
)
==
0
{
t
.
Error
(
"expected logs"
)
}
case
<-
time
.
NewTimer
(
1
*
time
.
Second
)
.
C
:
t
.
Fatal
(
"Timeout. There is no RemovedLogsEvent has been sent."
)
}
newBlocks
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
chain
[
len
(
chain
)
-
1
],
ethash
.
NewFaker
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{})
go
listenNewLog
(
logsCh
,
1
)
if
_
,
err
:=
blockchain
.
InsertChain
(
newBlocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert forked chain: %v"
,
err
)
}
// Rebirth logs should omit a newLogEvent
if
!<-
newLogCh
{
t
.
Fatalf
(
"failed to receive new log event"
)
}
// Ensure removedLog events received
select
{
case
ev
:=
<-
rmLogsCh
:
if
len
(
ev
.
Logs
)
==
0
{
t
.
Error
(
"expected logs"
)
}
case
<-
time
.
NewTimer
(
1
*
time
.
Second
)
.
C
:
t
.
Fatal
(
"Timeout. There is no RemovedLogsEvent has been sent."
)
}
}
func
TestSideLogRebirth
(
t
*
testing
.
T
)
{
var
(
key1
,
_
=
crypto
.
HexToECDSA
(
"b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291"
)
addr1
=
crypto
.
PubkeyToAddress
(
key1
.
PublicKey
)
db
=
ethdb
.
NewMemDatabase
()
// this code generates a log
code
=
common
.
Hex2Bytes
(
"60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00"
)
gspec
=
&
Genesis
{
Config
:
params
.
TestChainConfig
,
Alloc
:
GenesisAlloc
{
addr1
:
{
Balance
:
big
.
NewInt
(
10000000000000
)}}}
genesis
=
gspec
.
MustCommit
(
db
)
signer
=
types
.
NewEIP155Signer
(
gspec
.
Config
.
ChainID
)
newLogCh
=
make
(
chan
bool
)
)
// listenNewLog checks whether the received logs number is equal with expected.
listenNewLog
:=
func
(
sink
chan
[]
*
types
.
Log
,
expect
int
)
{
cnt
:=
0
for
{
select
{
case
logs
:=
<-
sink
:
cnt
+=
len
(
logs
)
case
<-
time
.
NewTimer
(
5
*
time
.
Second
)
.
C
:
// new logs timeout
newLogCh
<-
false
return
}
if
cnt
==
expect
{
break
}
else
if
cnt
>
expect
{
// redundant logs received
newLogCh
<-
false
return
}
}
select
{
case
<-
sink
:
// redundant logs received
newLogCh
<-
false
case
<-
time
.
NewTimer
(
100
*
time
.
Millisecond
)
.
C
:
newLogCh
<-
true
}
}
blockchain
,
_
:=
NewBlockChain
(
db
,
nil
,
gspec
.
Config
,
ethash
.
NewFaker
(),
vm
.
Config
{},
nil
)
defer
blockchain
.
Stop
()
logsCh
:=
make
(
chan
[]
*
types
.
Log
)
blockchain
.
SubscribeLogsEvent
(
logsCh
)
chain
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
genesis
,
ethash
.
NewFaker
(),
db
,
2
,
func
(
i
int
,
gen
*
BlockGen
)
{
if
i
==
1
{
// Higher block difficulty
gen
.
OffsetTime
(
-
9
)
}
})
if
_
,
err
:=
blockchain
.
InsertChain
(
chain
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert forked chain: %v"
,
err
)
}
// Generate side chain with lower difficulty
sideChain
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
genesis
,
ethash
.
NewFaker
(),
db
,
2
,
func
(
i
int
,
gen
*
BlockGen
)
{
if
i
==
1
{
tx
,
err
:=
types
.
SignTx
(
types
.
NewContractCreation
(
gen
.
TxNonce
(
addr1
),
new
(
big
.
Int
),
1000000
,
new
(
big
.
Int
),
code
),
signer
,
key1
)
if
err
!=
nil
{
t
.
Fatalf
(
"failed to create tx: %v"
,
err
)
}
gen
.
AddTx
(
tx
)
}
})
if
_
,
err
:=
blockchain
.
InsertChain
(
sideChain
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert forked chain: %v"
,
err
)
}
// Generate a new block based on side chain
newBlocks
,
_
:=
GenerateChain
(
params
.
TestChainConfig
,
sideChain
[
len
(
sideChain
)
-
1
],
ethash
.
NewFaker
(),
db
,
1
,
func
(
i
int
,
gen
*
BlockGen
)
{})
go
listenNewLog
(
logsCh
,
1
)
if
_
,
err
:=
blockchain
.
InsertChain
(
newBlocks
);
err
!=
nil
{
t
.
Fatalf
(
"failed to insert forked chain: %v"
,
err
)
}
// Rebirth logs should omit a newLogEvent
if
!<-
newLogCh
{
t
.
Fatalf
(
"failed to receive new log event"
)
}
}
func
TestReorgSideEvent
(
t
*
testing
.
T
)
{
var
(
db
=
ethdb
.
NewMemDatabase
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录