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
2ab24a2a
Unverified
Commit
2ab24a2a
authored
Jun 04, 2018
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: concurrent background transaction sender ecrecover
parent
400332b9
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
113 additions
and
0 deletions
+113
-0
blockchain.go
core/blockchain.go
+7
-0
tx_cacher.go
core/tx_cacher.go
+105
-0
tx_pool.go
core/tx_pool.go
+1
-0
No files found.
core/blockchain.go
View file @
2ab24a2a
...
...
@@ -1005,6 +1005,10 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
// only reason this method exists as a separate one is to make locking cleaner
// with deferred statements.
func
(
bc
*
BlockChain
)
insertChain
(
chain
types
.
Blocks
)
(
int
,
[]
interface
{},
[]
*
types
.
Log
,
error
)
{
// Sanity check that we have something meaningful to import
if
len
(
chain
)
==
0
{
return
0
,
nil
,
nil
,
nil
}
// Do a sanity check that the provided chain is actually ordered and linked
for
i
:=
1
;
i
<
len
(
chain
);
i
++
{
if
chain
[
i
]
.
NumberU64
()
!=
chain
[
i
-
1
]
.
NumberU64
()
+
1
||
chain
[
i
]
.
ParentHash
()
!=
chain
[
i
-
1
]
.
Hash
()
{
...
...
@@ -1043,6 +1047,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
abort
,
results
:=
bc
.
engine
.
VerifyHeaders
(
bc
,
headers
,
seals
)
defer
close
(
abort
)
// Start a parallel signature recovery (signer will fluke on fork transition, minimal perf loss)
senderCacher
.
recoverFromBlocks
(
types
.
MakeSigner
(
bc
.
chainConfig
,
chain
[
0
]
.
Number
()),
chain
)
// Iterate over the blocks and insert when the verifier permits
for
i
,
block
:=
range
chain
{
// If the chain is terminating, stop processing blocks
...
...
core/tx_cacher.go
0 → 100644
View file @
2ab24a2a
// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package
core
import
(
"runtime"
"github.com/ethereum/go-ethereum/core/types"
)
// senderCacher is a concurrent tranaction sender recoverer anc cacher.
var
senderCacher
=
newTxSenderCacher
(
runtime
.
NumCPU
())
// txSenderCacherRequest is a request for recovering transaction senders with a
// specific signature scheme and caching it into the transactions themselves.
//
// The inc field defines the number of transactions to skip after each recovery,
// which is used to feed the same underlying input array to different threads but
// ensure they process the early transactions fast.
type
txSenderCacherRequest
struct
{
signer
types
.
Signer
txs
[]
*
types
.
Transaction
inc
int
}
// txSenderCacher is a helper structure to concurrently ecrecover transaction
// senders from digital signatures on background threads.
type
txSenderCacher
struct
{
threads
int
tasks
chan
*
txSenderCacherRequest
}
// newTxSenderCacher creates a new transaction sender background cacher and starts
// as many procesing goroutines as allowed by the GOMAXPROCS on construction.
func
newTxSenderCacher
(
threads
int
)
*
txSenderCacher
{
cacher
:=
&
txSenderCacher
{
tasks
:
make
(
chan
*
txSenderCacherRequest
,
threads
),
threads
:
threads
,
}
for
i
:=
0
;
i
<
threads
;
i
++
{
go
cacher
.
cache
()
}
return
cacher
}
// cache is an infinite loop, caching transaction senders from various forms of
// data structures.
func
(
cacher
*
txSenderCacher
)
cache
()
{
for
task
:=
range
cacher
.
tasks
{
for
i
:=
0
;
i
<
len
(
task
.
txs
);
i
+=
task
.
inc
{
types
.
Sender
(
task
.
signer
,
task
.
txs
[
i
])
}
}
}
// recover recovers the senders from a batch of transactions and caches them
// back into the same data structures. There is no validation being done, nor
// any reaction to invalid signatures. That is up to calling code later.
func
(
cacher
*
txSenderCacher
)
recover
(
signer
types
.
Signer
,
txs
[]
*
types
.
Transaction
)
{
// If there's nothing to recover, abort
if
len
(
txs
)
==
0
{
return
}
// Ensure we have meaningful task sizes and schedule the recoveries
tasks
:=
cacher
.
threads
if
len
(
txs
)
<
tasks
*
4
{
tasks
=
(
len
(
txs
)
+
3
)
/
4
}
for
i
:=
0
;
i
<
tasks
;
i
++
{
cacher
.
tasks
<-
&
txSenderCacherRequest
{
signer
:
signer
,
txs
:
txs
[
i
:
],
inc
:
tasks
,
}
}
}
// recoverFromBlocks recovers the senders from a batch of blocks and caches them
// back into the same data structures. There is no validation being done, nor
// any reaction to invalid signatures. That is up to calling code later.
func
(
cacher
*
txSenderCacher
)
recoverFromBlocks
(
signer
types
.
Signer
,
blocks
[]
*
types
.
Block
)
{
count
:=
0
for
_
,
block
:=
range
blocks
{
count
+=
len
(
block
.
Transactions
())
}
txs
:=
make
([]
*
types
.
Transaction
,
0
,
count
)
for
_
,
block
:=
range
blocks
{
txs
=
append
(
txs
,
block
.
Transactions
()
...
)
}
cacher
.
recover
(
signer
,
txs
)
}
core/tx_pool.go
View file @
2ab24a2a
...
...
@@ -411,6 +411,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
// Inject any transactions discarded due to reorgs
log
.
Debug
(
"Reinjecting stale transactions"
,
"count"
,
len
(
reinject
))
senderCacher
.
recover
(
pool
.
signer
,
reinject
)
pool
.
addTxsLocked
(
reinject
,
false
)
// validate the pool of pending transactions, this will remove
...
...
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