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
b0f30b0b
Commit
b0f30b0b
authored
May 30, 2017
by
Péter Szilágyi
Committed by
GitHub
May 30, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14545 from karalabe/clique-cache-signatures
consensus/clique: cache block signatures for fast checks
parents
e96f2981
309da541
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
34 additions
and
23 deletions
+34
-23
clique.go
consensus/clique/clique.go
+12
-6
snapshot.go
consensus/clique/snapshot.go
+22
-17
No files found.
consensus/clique/clique.go
View file @
b0f30b0b
...
@@ -44,7 +44,7 @@ import (
...
@@ -44,7 +44,7 @@ import (
const
(
const
(
checkpointInterval
=
1024
// Number of blocks after which to save the vote snapshot to the database
checkpointInterval
=
1024
// Number of blocks after which to save the vote snapshot to the database
inmemorySnapshots
=
128
// Number of recent vote snapshots to keep in memory
inmemorySnapshots
=
128
// Number of recent vote snapshots to keep in memory
inmemorySignatures
=
1024
// Number of recent block
s to keep in memory
inmemorySignatures
=
4096
// Number of recent block signature
s to keep in memory
wiggleTime
=
500
*
time
.
Millisecond
// Random delay (per signer) to allow concurrent signers
wiggleTime
=
500
*
time
.
Millisecond
// Random delay (per signer) to allow concurrent signers
)
)
...
@@ -162,7 +162,12 @@ func sigHash(header *types.Header) (hash common.Hash) {
...
@@ -162,7 +162,12 @@ func sigHash(header *types.Header) (hash common.Hash) {
}
}
// ecrecover extracts the Ethereum account address from a signed header.
// ecrecover extracts the Ethereum account address from a signed header.
func
ecrecover
(
header
*
types
.
Header
)
(
common
.
Address
,
error
)
{
func
ecrecover
(
header
*
types
.
Header
,
sigcache
*
lru
.
ARCCache
)
(
common
.
Address
,
error
)
{
// If the signature's already cached, return that
hash
:=
header
.
Hash
()
if
address
,
known
:=
sigcache
.
Get
(
hash
);
known
{
return
address
.
(
common
.
Address
),
nil
}
// Retrieve the signature from the header extra-data
// Retrieve the signature from the header extra-data
if
len
(
header
.
Extra
)
<
extraSeal
{
if
len
(
header
.
Extra
)
<
extraSeal
{
return
common
.
Address
{},
errMissingSignature
return
common
.
Address
{},
errMissingSignature
...
@@ -177,6 +182,7 @@ func ecrecover(header *types.Header) (common.Address, error) {
...
@@ -177,6 +182,7 @@ func ecrecover(header *types.Header) (common.Address, error) {
var
signer
common
.
Address
var
signer
common
.
Address
copy
(
signer
[
:
],
crypto
.
Keccak256
(
pubkey
[
1
:
])[
12
:
])
copy
(
signer
[
:
],
crypto
.
Keccak256
(
pubkey
[
1
:
])[
12
:
])
sigcache
.
Add
(
hash
,
signer
)
return
signer
,
nil
return
signer
,
nil
}
}
...
@@ -223,7 +229,7 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
...
@@ -223,7 +229,7 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
// Author implements consensus.Engine, returning the Ethereum address recovered
// Author implements consensus.Engine, returning the Ethereum address recovered
// from the signature in the header's extra-data section.
// from the signature in the header's extra-data section.
func
(
c
*
Clique
)
Author
(
header
*
types
.
Header
)
(
common
.
Address
,
error
)
{
func
(
c
*
Clique
)
Author
(
header
*
types
.
Header
)
(
common
.
Address
,
error
)
{
return
ecrecover
(
header
)
return
ecrecover
(
header
,
c
.
signatures
)
}
}
// VerifyHeader checks whether a header conforms to the consensus rules.
// VerifyHeader checks whether a header conforms to the consensus rules.
...
@@ -369,7 +375,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo
...
@@ -369,7 +375,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo
}
}
// If an on-disk checkpoint snapshot can be found, use that
// If an on-disk checkpoint snapshot can be found, use that
if
number
%
checkpointInterval
==
0
{
if
number
%
checkpointInterval
==
0
{
if
s
,
err
:=
loadSnapshot
(
c
.
config
,
c
.
db
,
hash
);
err
==
nil
{
if
s
,
err
:=
loadSnapshot
(
c
.
config
,
c
.
signatures
,
c
.
db
,
hash
);
err
==
nil
{
log
.
Trace
(
"Loaded voting snapshot form disk"
,
"number"
,
number
,
"hash"
,
hash
)
log
.
Trace
(
"Loaded voting snapshot form disk"
,
"number"
,
number
,
"hash"
,
hash
)
snap
=
s
snap
=
s
break
break
...
@@ -385,7 +391,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo
...
@@ -385,7 +391,7 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo
for
i
:=
0
;
i
<
len
(
signers
);
i
++
{
for
i
:=
0
;
i
<
len
(
signers
);
i
++
{
copy
(
signers
[
i
][
:
],
genesis
.
Extra
[
extraVanity
+
i
*
common
.
AddressLength
:
])
copy
(
signers
[
i
][
:
],
genesis
.
Extra
[
extraVanity
+
i
*
common
.
AddressLength
:
])
}
}
snap
=
newSnapshot
(
c
.
config
,
0
,
genesis
.
Hash
(),
signers
)
snap
=
newSnapshot
(
c
.
config
,
c
.
signatures
,
0
,
genesis
.
Hash
(),
signers
)
if
err
:=
snap
.
store
(
c
.
db
);
err
!=
nil
{
if
err
:=
snap
.
store
(
c
.
db
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -464,7 +470,7 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p
...
@@ -464,7 +470,7 @@ func (c *Clique) verifySeal(chain consensus.ChainReader, header *types.Header, p
c
.
recents
.
Add
(
snap
.
Hash
,
snap
)
c
.
recents
.
Add
(
snap
.
Hash
,
snap
)
// Resolve the authorization key and check against signers
// Resolve the authorization key and check against signers
signer
,
err
:=
ecrecover
(
header
)
signer
,
err
:=
ecrecover
(
header
,
c
.
signatures
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
consensus/clique/snapshot.go
View file @
b0f30b0b
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/params"
lru
"github.com/hashicorp/golang-lru"
)
)
// Vote represents a single vote that an authorized signer made to modify the
// Vote represents a single vote that an authorized signer made to modify the
...
@@ -44,7 +45,8 @@ type Tally struct {
...
@@ -44,7 +45,8 @@ type Tally struct {
// Snapshot is the state of the authorization voting at a given point in time.
// Snapshot is the state of the authorization voting at a given point in time.
type
Snapshot
struct
{
type
Snapshot
struct
{
config
*
params
.
CliqueConfig
// Consensus engine parameters to fine tune behavior
config
*
params
.
CliqueConfig
// Consensus engine parameters to fine tune behavior
sigcache
*
lru
.
ARCCache
// Cache of recent block signatures to speed up ecrecover
Number
uint64
`json:"number"`
// Block number where the snapshot was created
Number
uint64
`json:"number"`
// Block number where the snapshot was created
Hash
common
.
Hash
`json:"hash"`
// Block hash where the snapshot was created
Hash
common
.
Hash
`json:"hash"`
// Block hash where the snapshot was created
...
@@ -57,14 +59,15 @@ type Snapshot struct {
...
@@ -57,14 +59,15 @@ type Snapshot struct {
// newSnapshot create a new snapshot with the specified startup parameters. This
// newSnapshot create a new snapshot with the specified startup parameters. This
// method does not initialize the set of recent signers, so only ever use if for
// method does not initialize the set of recent signers, so only ever use if for
// the genesis block.
// the genesis block.
func
newSnapshot
(
config
*
params
.
CliqueConfig
,
number
uint64
,
hash
common
.
Hash
,
signers
[]
common
.
Address
)
*
Snapshot
{
func
newSnapshot
(
config
*
params
.
CliqueConfig
,
sigcache
*
lru
.
ARCCache
,
number
uint64
,
hash
common
.
Hash
,
signers
[]
common
.
Address
)
*
Snapshot
{
snap
:=
&
Snapshot
{
snap
:=
&
Snapshot
{
config
:
config
,
config
:
config
,
Number
:
number
,
sigcache
:
sigcache
,
Hash
:
hash
,
Number
:
number
,
Signers
:
make
(
map
[
common
.
Address
]
struct
{}),
Hash
:
hash
,
Recents
:
make
(
map
[
uint64
]
common
.
Address
),
Signers
:
make
(
map
[
common
.
Address
]
struct
{}),
Tally
:
make
(
map
[
common
.
Address
]
Tally
),
Recents
:
make
(
map
[
uint64
]
common
.
Address
),
Tally
:
make
(
map
[
common
.
Address
]
Tally
),
}
}
for
_
,
signer
:=
range
signers
{
for
_
,
signer
:=
range
signers
{
snap
.
Signers
[
signer
]
=
struct
{}{}
snap
.
Signers
[
signer
]
=
struct
{}{}
...
@@ -73,7 +76,7 @@ func newSnapshot(config *params.CliqueConfig, number uint64, hash common.Hash, s
...
@@ -73,7 +76,7 @@ func newSnapshot(config *params.CliqueConfig, number uint64, hash common.Hash, s
}
}
// loadSnapshot loads an existing snapshot from the database.
// loadSnapshot loads an existing snapshot from the database.
func
loadSnapshot
(
config
*
params
.
CliqueConfig
,
db
ethdb
.
Database
,
hash
common
.
Hash
)
(
*
Snapshot
,
error
)
{
func
loadSnapshot
(
config
*
params
.
CliqueConfig
,
sigcache
*
lru
.
ARCCache
,
db
ethdb
.
Database
,
hash
common
.
Hash
)
(
*
Snapshot
,
error
)
{
blob
,
err
:=
db
.
Get
(
append
([]
byte
(
"clique-"
),
hash
[
:
]
...
))
blob
,
err
:=
db
.
Get
(
append
([]
byte
(
"clique-"
),
hash
[
:
]
...
))
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -83,6 +86,7 @@ func loadSnapshot(config *params.CliqueConfig, db ethdb.Database, hash common.Ha
...
@@ -83,6 +86,7 @@ func loadSnapshot(config *params.CliqueConfig, db ethdb.Database, hash common.Ha
return
nil
,
err
return
nil
,
err
}
}
snap
.
config
=
config
snap
.
config
=
config
snap
.
sigcache
=
sigcache
return
snap
,
nil
return
snap
,
nil
}
}
...
@@ -99,13 +103,14 @@ func (s *Snapshot) store(db ethdb.Database) error {
...
@@ -99,13 +103,14 @@ func (s *Snapshot) store(db ethdb.Database) error {
// copy creates a deep copy of the snapshot, though not the individual votes.
// copy creates a deep copy of the snapshot, though not the individual votes.
func
(
s
*
Snapshot
)
copy
()
*
Snapshot
{
func
(
s
*
Snapshot
)
copy
()
*
Snapshot
{
cpy
:=
&
Snapshot
{
cpy
:=
&
Snapshot
{
config
:
s
.
config
,
config
:
s
.
config
,
Number
:
s
.
Number
,
sigcache
:
s
.
sigcache
,
Hash
:
s
.
Hash
,
Number
:
s
.
Number
,
Signers
:
make
(
map
[
common
.
Address
]
struct
{}),
Hash
:
s
.
Hash
,
Recents
:
make
(
map
[
uint64
]
common
.
Address
),
Signers
:
make
(
map
[
common
.
Address
]
struct
{}),
Votes
:
make
([]
*
Vote
,
len
(
s
.
Votes
)),
Recents
:
make
(
map
[
uint64
]
common
.
Address
),
Tally
:
make
(
map
[
common
.
Address
]
Tally
),
Votes
:
make
([]
*
Vote
,
len
(
s
.
Votes
)),
Tally
:
make
(
map
[
common
.
Address
]
Tally
),
}
}
for
signer
:=
range
s
.
Signers
{
for
signer
:=
range
s
.
Signers
{
cpy
.
Signers
[
signer
]
=
struct
{}{}
cpy
.
Signers
[
signer
]
=
struct
{}{}
...
@@ -190,7 +195,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
...
@@ -190,7 +195,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
delete
(
snap
.
Recents
,
number
-
limit
)
delete
(
snap
.
Recents
,
number
-
limit
)
}
}
// Resolve the authorization key and check against signers
// Resolve the authorization key and check against signers
signer
,
err
:=
ecrecover
(
header
)
signer
,
err
:=
ecrecover
(
header
,
s
.
sigcache
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
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