Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
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
link33
plugin
Commits
2cb03695
Commit
2cb03695
authored
Aug 08, 2019
by
张振华
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
0ef31ffb
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
327 additions
and
96 deletions
+327
-96
consensus_state.go
plugin/consensus/dpos/consensus_state.go
+0
-0
dpos.go
plugin/consensus/dpos/dpos.go
+1
-1
dpos_msg.proto
plugin/consensus/dpos/proto/dpos_msg.proto
+15
-0
state_machine.go
plugin/consensus/dpos/state_machine.go
+102
-72
dpos_msg.pb.go
plugin/consensus/dpos/types/dpos_msg.pb.go
+0
-0
priv_validator.go
plugin/consensus/dpos/types/priv_validator.go
+42
-20
validator_manager.go
plugin/consensus/dpos/validator_manager.go
+167
-3
No files found.
plugin/consensus/dpos/consensus_state.go
View file @
2cb03695
This diff is collapsed.
Click to expand it.
plugin/consensus/dpos/dpos.go
View file @
2cb03695
...
...
@@ -325,7 +325,7 @@ OuterLoop:
// 对于受托节点,才需要初始化区块,启动共识相关程序等,后续支持投票要做成动态切换的。
if
client
.
isDelegator
{
client
.
InitBlock
()
client
.
csState
.
Init
CycleBoundaryInfo
()
client
.
csState
.
Init
()
node
.
Start
()
}
...
...
plugin/consensus/dpos/proto/dpos_msg.proto
View file @
2cb03695
...
...
@@ -3,6 +3,16 @@ syntax = "proto3";
package
types
;
message
CycleBoundaryInfo
{
int64
cycle
=
1
;
int64
stopHeight
=
2
;
string
stopHash
=
3
;
}
message
SuperNode
{
bytes
address
=
1
;
bytes
pubKey
=
2
;
}
message
VoteItem
{
int32
votedNodeIndex
=
1
;
//被投票的节点索引
bytes
votedNodeAddress
=
2
;
//被投票的节点地址
...
...
@@ -13,6 +23,11 @@ message VoteItem {
int64
periodStop
=
7
;
//新节点负责出块的终止时间
int64
height
=
8
;
//新节点负责出块的起始高度
bytes
voteID
=
9
;
//选票ID
CycleBoundaryInfo
lastCBInfo
=
10
;
int64
shuffleType
=
11
;
repeated
SuperNode
validators
=
12
;
repeated
SuperNode
vrfValidators
=
13
;
repeated
SuperNode
noVrfValidators
=
14
;
}
//DPosVote Dpos共识的节点投票,为达成共识用。
...
...
plugin/consensus/dpos/state_machine.go
View file @
2cb03695
This diff is collapsed.
Click to expand it.
plugin/consensus/dpos/types/dpos_msg.pb.go
View file @
2cb03695
This diff is collapsed.
Click to expand it.
plugin/consensus/dpos/types/priv_validator.go
View file @
2cb03695
...
...
@@ -6,6 +6,7 @@ package types
import
(
"bytes"
"crypto/ecdsa"
"encoding/hex"
"encoding/json"
"errors"
...
...
@@ -14,8 +15,9 @@ import (
"sync"
"github.com/33cn/chain33/common/crypto"
dty
"github.com/33cn/plugin/plugin/dapp/dposvote/types
"
vrf
"github.com/33cn/chain33/common/vrf/secp256k1
"
"github.com/33cn/chain33/types"
secp256k1
"github.com/btcsuite/btcd/btcec"
)
// KeyText ...
...
...
@@ -32,8 +34,10 @@ type PrivValidator interface {
SignVote
(
chainID
string
,
vote
*
Vote
)
error
SignNotify
(
chainID
string
,
notify
*
Notify
)
error
Sign
CBInfo
(
info
*
dty
.
DposCBInfo
)
error
Sign
Msg
(
msg
[]
byte
)
(
sig
string
,
err
error
)
SignTx
(
tx
*
types
.
Transaction
)
VrfEvaluate
(
input
[]
byte
)
(
hash
[
32
]
byte
,
proof
[]
byte
)
VrfProof
(
pubkey
[]
byte
,
input
[]
byte
,
hash
[
32
]
byte
,
proof
[]
byte
)
bool
}
// PrivValidatorFS implements PrivValidator using data persisted to disk
...
...
@@ -319,40 +323,58 @@ func (pv *PrivValidatorImp) SignNotify(chainID string, notify *Notify) error {
}
// SignCBInfo signs a canonical representation of the DposCBInfo, Implements PrivValidator.
func
(
pv
*
PrivValidatorImp
)
Sign
CBInfo
(
info
*
dty
.
DposCBInfo
)
error
{
func
(
pv
*
PrivValidatorImp
)
Sign
Msg
(
msg
[]
byte
)
(
sig
string
,
err
error
)
{
pv
.
mtx
.
Lock
()
defer
pv
.
mtx
.
Unlock
()
buf
:=
new
(
bytes
.
Buffer
)
info
.
Pubkey
=
hex
.
EncodeToString
(
pv
.
PubKey
.
Bytes
())
canonical
:=
dty
.
CanonicalOnceCBInfo
{
Cycle
:
info
.
Cycle
,
StopHeight
:
info
.
StopHeight
,
StopHash
:
info
.
StopHash
,
Pubkey
:
info
.
Pubkey
,
}
byteCB
,
err
:=
json
.
Marshal
(
&
canonical
)
if
err
!=
nil
{
return
errors
.
New
(
Fmt
(
"Error marshal CanonicalOnceCBInfo: %v"
,
err
))
}
_
,
err
=
buf
.
Write
(
byteCB
)
_
,
err
=
buf
.
Write
(
msg
)
if
err
!=
nil
{
return
errors
.
New
(
Fmt
(
"Error write buffer: %v"
,
err
))
return
""
,
errors
.
New
(
Fmt
(
"Error write buffer: %v"
,
err
))
}
signature
:=
pv
.
PrivKey
.
Sign
(
buf
.
Bytes
())
info
.
Signature
=
hex
.
EncodeToString
(
signature
.
Bytes
())
return
nil
sig
=
hex
.
EncodeToString
(
signature
.
Bytes
())
return
sig
,
nil
}
// SignTx signs a tx, Implements PrivValidator.
func
(
pv
*
PrivValidatorImp
)
SignTx
(
tx
*
types
.
Transaction
){
tx
.
Sign
(
types
.
SECP256K1
,
pv
.
PrivKey
)
}
// VrfEvaluate use input to generate hash & proof.
func
(
pv
*
PrivValidatorImp
)
VrfEvaluate
(
input
[]
byte
)
(
hash
[
32
]
byte
,
proof
[]
byte
)
{
pv
.
mtx
.
Lock
()
defer
pv
.
mtx
.
Unlock
()
privKey
,
_
:=
secp256k1
.
PrivKeyFromBytes
(
secp256k1
.
S256
(),
pv
.
PrivKey
.
Bytes
())
vrfPriv
:=
&
vrf
.
PrivateKey
{
PrivateKey
:
(
*
ecdsa
.
PrivateKey
)(
privKey
)}
hash
,
proof
=
vrfPriv
.
Evaluate
(
input
)
return
hash
,
proof
}
func
(
pv
*
PrivValidatorImp
)
VrfProof
(
pubkey
[]
byte
,
input
[]
byte
,
hash
[
32
]
byte
,
proof
[]
byte
)
bool
{
pv
.
mtx
.
Lock
()
defer
pv
.
mtx
.
Unlock
()
pubKey
,
err
:=
secp256k1
.
ParsePubKey
(
pubkey
,
secp256k1
.
S256
())
if
err
!=
nil
{
return
false
}
vrfPub
:=
&
vrf
.
PublicKey
{
PublicKey
:
(
*
ecdsa
.
PublicKey
)(
pubKey
)}
vrfHash
,
err
:=
vrfPub
.
ProofToHash
(
input
,
proof
)
if
err
!=
nil
{
return
false
}
if
bytes
.
Equal
(
hash
[
:
],
vrfHash
[
:
]){
return
true
}
return
false
}
// Persist height/round/step and signature
func
(
pv
*
PrivValidatorImp
)
saveSigned
(
signBytes
[]
byte
,
sig
crypto
.
Signature
)
{
...
...
plugin/consensus/dpos/validator_manager.go
View file @
2cb03695
...
...
@@ -12,12 +12,19 @@ import (
"math/rand"
ttypes
"github.com/33cn/plugin/plugin/consensus/dpos/types"
dty
"github.com/33cn/plugin/plugin/dapp/dposvote/types"
)
var
(
r
*
rand
.
Rand
)
const
(
ShuffleTypeNoVrf
=
iota
ShuffleTypeVrf
ShuffleTypePartVrf
)
// ValidatorMgr ...
type
ValidatorMgr
struct
{
// Immutable
...
...
@@ -28,7 +35,11 @@ type ValidatorMgr struct {
// Note that if s.LastBlockHeight causes a valset change,
// we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1
Validators
*
ttypes
.
ValidatorSet
VrfValidators
*
ttypes
.
ValidatorSet
NoVrfValidators
*
ttypes
.
ValidatorSet
LastCycleBoundaryInfo
*
dty
.
DposCBInfo
ShuffleCycle
int64
ShuffleType
int64
//0-no vrf 1-vrf 2-part vrf
// The latest AppHash we've received from calling abci.Commit()
AppHash
[]
byte
}
...
...
@@ -37,10 +48,19 @@ type ValidatorMgr struct {
func
(
s
ValidatorMgr
)
Copy
()
ValidatorMgr
{
return
ValidatorMgr
{
ChainID
:
s
.
ChainID
,
Validators
:
s
.
Validators
.
Copy
(),
AppHash
:
s
.
AppHash
,
ShuffleCycle
:
s
.
ShuffleCycle
,
ShuffleType
:
s
.
ShuffleType
,
VrfValidators
:
s
.
VrfValidators
.
Copy
(),
NoVrfValidators
:
s
.
NoVrfValidators
.
Copy
(),
LastCycleBoundaryInfo
:
&
dty
.
DposCBInfo
{
Cycle
:
s
.
LastCycleBoundaryInfo
.
Cycle
,
StopHeight
:
s
.
LastCycleBoundaryInfo
.
StopHeight
,
StopHash
:
s
.
LastCycleBoundaryInfo
.
StopHash
,
Pubkey
:
s
.
LastCycleBoundaryInfo
.
Pubkey
,
Signature
:
s
.
LastCycleBoundaryInfo
.
Signature
,
},
}
}
...
...
@@ -97,3 +117,146 @@ func MakeGenesisValidatorMgr(genDoc *ttypes.GenesisDoc) (ValidatorMgr, error) {
AppHash
:
genDoc
.
AppHash
,
},
nil
}
func
(
s
*
ValidatorMgr
)
GetValidatorByIndex
(
index
int
)
(
addres
[]
byte
,
val
*
ttypes
.
Validator
)
{
if
index
<
0
||
index
>=
len
(
s
.
Validators
.
Validators
)
{
return
nil
,
nil
}
if
s
.
ShuffleType
==
ShuffleTypeNoVrf
{
val
=
s
.
Validators
.
Validators
[
index
]
return
val
.
Address
,
val
.
Copy
()
}
else
if
s
.
ShuffleType
==
ShuffleTypeVrf
{
val
=
s
.
VrfValidators
.
Validators
[
index
]
return
address
.
PubKeyToAddress
(
val
.
PubKey
)
.
Hash160
[
:
],
val
.
Copy
()
}
else
if
s
.
ShuffleType
==
ShuffleTypePartVrf
{
if
index
<
len
(
s
.
VrfValidators
.
Validators
)
{
val
=
s
.
VrfValidators
.
Validators
[
index
]
return
address
.
PubKeyToAddress
(
val
.
PubKey
)
.
Hash160
[
:
],
val
.
Copy
()
}
else
{
val
=
s
.
NoVrfValidators
.
Validators
[
index
-
len
(
s
.
VrfValidators
.
Validators
)]
return
address
.
PubKeyToAddress
(
val
.
PubKey
)
.
Hash160
[
:
],
val
.
Copy
()
}
}
return
nil
,
nil
}
func
(
s
*
ValidatorMgr
)
GetIndexByPubKey
(
pubkey
[]
byte
)
(
index
int
)
{
if
nil
==
pubkey
{
return
-
1
}
index
=
-
1
if
s
.
ShuffleType
==
ShuffleTypeNoVrf
{
for
i
:=
0
;
i
<
s
.
Validators
.
Size
();
i
++
{
if
bytes
.
Equal
(
s
.
Validators
.
Validators
[
i
]
.
PubKey
,
pubkey
)
{
index
=
i
return
index
}
}
}
else
if
s
.
ShuffleType
==
ShuffleTypeVrf
{
for
i
:=
0
;
i
<
s
.
VrfValidators
.
Size
();
i
++
{
if
bytes
.
Equal
(
s
.
VrfValidators
.
Validators
[
i
]
.
PubKey
,
pubkey
)
{
index
=
i
return
index
}
}
}
else
if
s
.
ShuffleType
==
ShuffleTypePartVrf
{
for
i
:=
0
;
i
<
s
.
VrfValidators
.
Size
();
i
++
{
if
bytes
.
Equal
(
s
.
VrfValidators
.
Validators
[
i
]
.
PubKey
,
pubkey
)
{
index
=
i
return
index
}
}
for
j
:=
0
;
j
<
s
.
NoVrfValidators
.
Size
();
j
++
{
if
bytes
.
Equal
(
s
.
NoVrfValidators
.
Validators
[
j
]
.
PubKey
,
pubkey
)
{
index
=
j
+
s
.
VrfValidators
.
Size
()
return
index
}
}
}
return
index
}
func
(
s
*
ValidatorMgr
)
FillVoteItem
(
voteItem
*
ttypes
.
VoteItem
)
{
voteItem
.
LastCBInfo
=
&
ttypes
.
CycleBoundaryInfo
{
Cycle
:
s
.
LastCycleBoundaryInfo
.
Cycle
,
StopHeight
:
s
.
LastCycleBoundaryInfo
.
StopHeight
,
StopHash
:
s
.
LastCycleBoundaryInfo
.
StopHash
,
}
voteItem
.
ShuffleType
=
s
.
ShuffleType
for
i
:=
0
;
i
<
s
.
Validators
.
Size
();
i
++
{
node
:=
&
ttypes
.
SuperNode
{
PubKey
:
s
.
Validators
.
Validators
[
i
]
.
PubKey
,
Address
:
s
.
Validators
.
Validators
[
i
]
.
Address
,
}
voteItem
.
Validators
=
append
(
voteItem
.
Validators
,
node
)
}
for
i
:=
0
;
i
<
s
.
VrfValidators
.
Size
();
i
++
{
node
:=
&
ttypes
.
SuperNode
{
PubKey
:
s
.
VrfValidators
.
Validators
[
i
]
.
PubKey
,
Address
:
s
.
VrfValidators
.
Validators
[
i
]
.
Address
,
}
voteItem
.
VrfValidators
=
append
(
voteItem
.
VrfValidators
,
node
)
}
for
i
:=
0
;
i
<
s
.
NoVrfValidators
.
Size
();
i
++
{
node
:=
&
ttypes
.
SuperNode
{
PubKey
:
s
.
NoVrfValidators
.
Validators
[
i
]
.
PubKey
,
Address
:
s
.
NoVrfValidators
.
Validators
[
i
]
.
Address
,
}
voteItem
.
NoVrfValidators
=
append
(
voteItem
.
NoVrfValidators
,
node
)
}
}
func
(
s
*
ValidatorMgr
)
UpdateFromVoteItem
(
voteItem
*
ttypes
.
VoteItem
)
bool
{
validators
:=
voteItem
.
Validators
for
i
:=
0
;
i
<
s
.
Validators
.
Size
();
i
++
{
if
!
bytes
.
Equal
(
validators
[
i
]
.
PubKey
,
s
.
Validators
.
Validators
[
i
]
.
PubKey
)
{
return
false
}
}
if
s
.
LastCycleBoundaryInfo
==
nil
||
voteItem
.
LastCBInfo
.
Cycle
!=
s
.
LastCycleBoundaryInfo
.
Cycle
||
voteItem
.
LastCBInfo
.
StopHeight
!=
s
.
LastCycleBoundaryInfo
.
StopHeight
||
voteItem
.
LastCBInfo
.
StopHash
!=
s
.
LastCycleBoundaryInfo
.
StopHash
{
s
.
LastCycleBoundaryInfo
=
&
dty
.
DposCBInfo
{
Cycle
:
voteItem
.
LastCBInfo
.
Cycle
,
StopHeight
:
voteItem
.
LastCBInfo
.
StopHeight
,
StopHash
:
voteItem
.
LastCBInfo
.
StopHash
,
}
}
var
vrfVals
[]
*
ttypes
.
Validator
for
i
:=
0
;
i
<
len
(
voteItem
.
VrfValidators
);
i
++
{
val
:=
&
ttypes
.
Validator
{
Address
:
voteItem
.
VrfValidators
[
i
]
.
Address
,
PubKey
:
voteItem
.
VrfValidators
[
i
]
.
PubKey
,
}
vrfVals
=
append
(
vrfVals
,
val
)
}
s
.
VrfValidators
=
ttypes
.
NewValidatorSet
(
vrfVals
)
var
noVrfVals
[]
*
ttypes
.
Validator
for
i
:=
0
;
i
<
len
(
voteItem
.
NoVrfValidators
);
i
++
{
val
:=
&
ttypes
.
Validator
{
Address
:
voteItem
.
NoVrfValidators
[
i
]
.
Address
,
PubKey
:
voteItem
.
NoVrfValidators
[
i
]
.
PubKey
,
}
noVrfVals
=
append
(
noVrfVals
,
val
)
}
s
.
NoVrfValidators
=
ttypes
.
NewValidatorSet
(
noVrfVals
)
return
true
}
\ No newline at end of file
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