Commit 7f71d2a5 authored by 张振华's avatar 张振华

bug fix

parent 4f86f81b
......@@ -565,7 +565,7 @@ func (cs *ConsensusState) QueryCycleBoundaryInfo(cycle int64)(*dty.DposCBInfo, e
req := &dty.DposCBQuery{Cycle: cycle, Ty: dty.QueryCBInfoByCycle}
param, err := proto.Marshal(req)
if err != nil {
dposlog.Error("Marshal DposCBQuery failed", "err", err)
dposlog.Error("Marshal DposCBQuery failed", "cycle", cycle, "err", err)
return nil, err
}
msg := cs.client.GetQueueClient().NewMessage("execs", types.EventBlockChainQuery,
......@@ -578,17 +578,21 @@ func (cs *ConsensusState) QueryCycleBoundaryInfo(cycle int64)(*dty.DposCBInfo, e
err = cs.client.GetQueueClient().Send(msg, true)
if err != nil {
dposlog.Error("send DposCBQuery to dpos exec failed", "err", err)
dposlog.Error("send DposCBQuery to dpos exec failed", "cycle", cycle, "err", err)
return nil, err
}
msg, err = cs.client.GetQueueClient().Wait(msg)
if err != nil {
dposlog.Error("send DposCBQuery wait failed", "err", err)
dposlog.Error("send DposCBQuery wait failed", "cycle", cycle, "err", err)
return nil, err
}
return msg.GetData().(types.Message).(*dty.DposCBInfo), nil
res := msg.GetData().(types.Message).(*dty.DposCBReply)
info := res.CbInfo
dposlog.Info("DposCBQuery get reply", "cycle", cycle, "stopHeight", info.StopHeight, "stopHash", info.StopHash, "pubkey", info.Pubkey)
return info, nil
}
// Init method
......@@ -719,7 +723,7 @@ func (cs *ConsensusState) VerifyCBInfo(info *dty.DposCBInfo) bool {
// SendCBTx method
func (cs *ConsensusState) SendCBTx(info *dty.DposCBInfo) bool {
info.Pubkey = hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())
//info.Pubkey = strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes()))
canonical := dty.CanonicalOnceCBInfo{
Cycle: info.Cycle,
StopHeight: info.StopHeight,
......@@ -752,7 +756,7 @@ func (cs *ConsensusState) SendCBTx(info *dty.DposCBInfo) bool {
dposlog.Error("Send RecordCBTx to mempool failed.", "err", err)
return false
} else {
dposlog.Error("Send RecordCBTx to mempool ok.", "err", err)
dposlog.Info("Send RecordCBTx to mempool ok.")
}
}
}
......@@ -776,7 +780,7 @@ func (cs *ConsensusState) SendRegistVrfMTx(info *dty.DposVrfMRegist) bool {
dposlog.Error("Send RegistVrfMTx to mempool failed.", "err", err)
return false
} else {
dposlog.Error("Send RegistVrfMTx to mempool ok.", "err", err)
dposlog.Info("Send RegistVrfMTx to mempool ok.")
}
}
......@@ -815,6 +819,7 @@ func (cs *ConsensusState) QueryVrf(pubkey []byte, cycle int64) (info *dty.VrfInf
return nil, err
}
info = nil
if len(infos) > 0 {
info = infos[0]
}
......@@ -902,7 +907,6 @@ func (cs *ConsensusState) QueryVrfs(set *ttypes.ValidatorSet, cycle int64) (info
return nil, err
}
return infos, nil
}
......@@ -958,16 +962,16 @@ func (cs *ConsensusState) UpdateVrfInfos(cycle int64, infos []*dty.VrfInfo) {
}
// GetVrfInfosByCircle method
func (cs *ConsensusState) GetVrfInfosByCircle(cycle int64) (info []*dty.VrfInfo) {
func (cs *ConsensusState) GetVrfInfosByCircle(cycle int64) (infos []*dty.VrfInfo) {
if v, ok := cs.vrfInfosMap[cycle];ok {
info = v
return info
infos = v
return infos
}
infos, err := cs.QueryVrfs(cs.validatorMgr.Validators, cycle)
if err == nil && infos != nil {
if err == nil && len(infos) > 0 {
cs.UpdateVrfInfos(cycle, infos)
return info
return infos
}
return nil
......@@ -977,27 +981,33 @@ func (cs *ConsensusState) GetVrfInfosByCircle(cycle int64) (info []*dty.VrfInfo)
func (cs *ConsensusState) ShuffleValidators(cycle int64){
if cycle == cs.validatorMgr.ShuffleCycle {
//如果已经洗过牌,则直接返回,不重复洗牌
dposlog.Info("Shuffle for this cycle is done already.", "cycle", cycle)
return
}
infos := cs.GetVrfInfosByCircle(cycle - 1)
if infos == nil {
cbInfo := cs.GetCBInfoByCircle(cycle - 1)
if cbInfo == nil {
dposlog.Info("GetCBInfoByCircle for Shuffle failed, don't use vrf to shuffle.", "cycle", cycle)
cs.validatorMgr.VrfValidators = nil
cs.validatorMgr.NoVrfValidators = nil
cs.validatorMgr.ShuffleCycle = cycle
cs.validatorMgr.ShuffleType = ShuffleTypeNoVrf
return
}
cs.validatorMgr.LastCycleBoundaryInfo = cbInfo
dposlog.Info("GetCBInfoByCircle for Shuffle ok", "cycle", cycle, "stopHeight", cbInfo.StopHeight, "stopHash", cbInfo.StopHash)
infos := cs.GetVrfInfosByCircle(cycle - 1)
if infos == nil {
dposlog.Info("GetVrfInfosByCircle for Shuffle failed, don't use vrf to shuffle.", "cycle", cycle)
cbInfo := cs.GetCBInfoByCircle(cycle - 1)
if cbInfo == nil {
cs.validatorMgr.VrfValidators = nil
cs.validatorMgr.NoVrfValidators = nil
cs.validatorMgr.ShuffleCycle = cycle
cs.validatorMgr.ShuffleType = ShuffleTypeNoVrf
return
}
cs.validatorMgr.LastCycleBoundaryInfo = cbInfo
var vrfValidators []*ttypes.Validator
var noVrfValidators []*ttypes.Validator
......@@ -1019,10 +1029,14 @@ func (cs *ConsensusState) ShuffleValidators(cycle int64){
set := cs.validatorMgr.Validators.Validators
if len(vrfValidators) == 0 {
dposlog.Info("Vrf validators is zero, don't use vrf to shuffle.", "cycle", cycle)
cs.validatorMgr.ShuffleCycle = cycle
cs.validatorMgr.ShuffleType = ShuffleTypeNoVrf
return
} else if len(vrfValidators) == len(set) {
dposlog.Info("Vrf validators is full,use pure vrf to shuffle.", "cycle", cycle)
cs.validatorMgr.ShuffleCycle = cycle
cs.validatorMgr.ShuffleType = ShuffleTypeVrf
cs.validatorMgr.VrfValidators = ttypes.NewValidatorSet(vrfValidators)
......@@ -1046,10 +1060,11 @@ func (cs *ConsensusState) ShuffleValidators(cycle int64){
cs.validatorMgr.VrfValidators = ttypes.NewValidatorSet(vrfValidators)
cs.validatorMgr.NoVrfValidators = ttypes.NewValidatorSet(noVrfValidators)
dposlog.Info("Vrf validators is part,use part vrf to shuffle.", "cycle", cycle, "vrf validators size", cs.validatorMgr.VrfValidators.Size(), "non vrf validators size", cs.validatorMgr.NoVrfValidators.Size())
}
func isValidVrfInfo(info *dty.VrfInfo) bool {
if info != nil && len(info.M) > 0 || len(info.R) > 0 || len(info.P) > 0 {
if info != nil && len(info.M) > 0 && len(info.R) > 0 && len(info.P) > 0 {
return true
}
......
......@@ -8,7 +8,10 @@ import (
"bytes"
"encoding/hex"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/util"
"strings"
"time"
"fmt"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/log/log15"
......@@ -17,7 +20,6 @@ import (
drivers "github.com/33cn/chain33/system/consensus"
cty "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
ttypes "github.com/33cn/plugin/plugin/consensus/dpos/types"
dty "github.com/33cn/plugin/plugin/dapp/dposvote/types"
......@@ -260,11 +262,13 @@ OuterLoop:
}
hint.Stop()
//如果非候选节点,直接返回,接受同步区块数据,不做任何共识相关的事情。
if !isValidator {
dposlog.Info("This node is not a validator,does not join the consensus, just syncs blocks from validators")
client.InitBlock()
return
}
var valMgr ValidatorMgr
valMgrTmp, err := MakeGenesisValidatorMgr(client.genesisDoc)
if err != nil {
......@@ -278,7 +282,7 @@ OuterLoop:
panic(err)
}
if block != nil {
time.Sleep(time.Second * 5)
//time.Sleep(time.Second * 5)
cands, err := client.QueryCandidators()
if err != nil {
dposlog.Info("QueryCandidators failed", "err", err)
......@@ -325,12 +329,12 @@ OuterLoop:
// 对于受托节点,才需要初始化区块,启动共识相关程序等,后续支持投票要做成动态切换的。
if client.isDelegator {
client.InitBlock()
time.Sleep(time.Second * 2)
client.csState.Init()
node.Start()
}
go client.MonitorCandidators()
//go client.CreateBlock()
//go client.MonitorCandidators()
}
// GetGenesisBlockTime ...
......@@ -406,6 +410,7 @@ func (client *Client) CreateBlock() {
}
// CreateBlock a routine monitor whether some transactions available and tell client by available channel
/*
func (client *Client) CreateBlockWithPriorTxs(priorTxs []*types.Transaction) {
lastBlock := client.GetCurrentBlock()
txs := client.RequestTx(int(types.GetP(lastBlock.Height + 1).MaxTxNumber), nil)
......@@ -451,6 +456,7 @@ func (client *Client) CreateBlockWithPriorTxs(priorTxs []*types.Transaction) {
return
}
}
*/
// StopC stop client
func (client *Client) StopC() <-chan struct{} {
return client.stopC
......@@ -707,7 +713,7 @@ func (client *Client)QueryVrfInfos(pubkeys [][]byte, cycle int64)([]*dty.VrfInfo
}
for i := 0; i < len(pubkeys); i++ {
req.Pubkeys = append(req.Pubkeys, hex.EncodeToString(pubkeys[i]))
req.Pubkeys = append(req.Pubkeys, strings.ToUpper(hex.EncodeToString(pubkeys[i])))
}
param, err := proto.Marshal(req)
......@@ -736,6 +742,11 @@ func (client *Client)QueryVrfInfos(pubkeys [][]byte, cycle int64)([]*dty.VrfInfo
}
res := msg.GetData().(types.Message).(*dty.DposVrfReply)
if len(res.Vrf) > 0 {
dposlog.Info("DposVrfQuerys ok") //, "info", fmt.Sprintf("Cycle:%d,pubkey:%s,Height:%d,M:%s,R:%s,P:%s", res.Vrf[0].Cycle, res.Vrf[0].Pubkey, res.Vrf[0].Height, res.Vrf[0].M, res.Vrf[0].R, res.Vrf[0].P))
} else {
dposlog.Info("DposVrfQuerys ok,but no info")
}
var infos []*dty.VrfInfo
for _, val := range res.Vrf {
......@@ -770,10 +781,14 @@ func (client *Client)QueryVrfInfos(pubkeys [][]byte, cycle int64)([]*dty.VrfInfo
}
infos = append(infos, info)
dposlog.Info("VrfInfos", "info", fmt.Sprintf("Cycle:%d,pubkey:%s,Height:%d,M:%s,R:%s,P:%s", val.Cycle, val.Pubkey, val.Height, val.M, val.R, val.P))
}
return infos, nil
}
/*
func (client *Client)QueryVrfInfo(pubkeys []byte, cycle int64)(*dty.VrfInfo, error) {
req := &dty.DposVrfQuery{
Cycle: cycle,
......@@ -808,7 +823,11 @@ func (client *Client)QueryVrfInfo(pubkeys []byte, cycle int64)(*dty.VrfInfo, err
}
res := msg.GetData().(types.Message).(*dty.DposVrfReply)
if len(res.Vrf) > 0 {
dposlog.Info("DposVrfQuery ok", "info", fmt.Sprintf("Cycle:%d,pubkey:%s,Height:%d,M:%s,R:%s,P:%s", res.Vrf[0].Cycle, res.Vrf[0].Pubkey, res.Vrf[0].Height, res.Vrf[0].M, res.Vrf[0].R, res.Vrf[0].P))
} else {
dposlog.Info("DposVrfQuery ok,but no info")
}
vrf := res.Vrf[0]
bPubkey, err := hex.DecodeString(vrf.Pubkey)
if err != nil {
......@@ -842,3 +861,4 @@ func (client *Client)QueryVrfInfo(pubkeys []byte, cycle int64)(*dty.VrfInfo, err
return info, nil
}
*/
\ No newline at end of file
{"genesis_time":"0001-01-01T00:00:00Z","chain_id":"test-chain-Ep9EcD","validators":[{"pub_key":{"type":"ed25519","data":"220ACBE680DF2473A0CB48987A00FCC1812F106A7390BE6B8E2D31122C992A19"},"name":""}],"app_hash":""}
{"genesis_time":"2018-08-16T15:38:56.951569432+08:00","chain_id":"chain33-Z2cgFj","validators":[{"pub_key":{"type":"secp256k1","data":"03EF0E1D3112CF571743A3318125EDE2E52A4EB904BCBAA4B1F75020C2846A7EB4"},"name":""},{"pub_key":{"type":"secp256k1","data":"027848E7FA630B759DB406940B5506B666A344B1060794BBF314EB459D40881BB3"},"name":""},{"pub_key":{"type":"secp256k1","data":"03F4AB6659E61E8512C9A24AC385CC1AC4D52B87D10ADBDF060086EA82BE62CDDE"},"name":""}],"app_hash":null}
\ No newline at end of file
......@@ -513,7 +513,7 @@ FOR_LOOP:
dposlog.Error("peerConn recvRoutine Unmarshal data failed", "err", err)
continue
}
if pc.transferChannel != nil && (pkt.TypeID == ttypes.VoteID || pkt.TypeID == ttypes.VoteReplyID || pkt.TypeID == ttypes.NotifyID) {
if pc.transferChannel != nil && (pkt.TypeID == ttypes.VoteID || pkt.TypeID == ttypes.VoteReplyID || pkt.TypeID == ttypes.NotifyID || pkt.TypeID == ttypes.CBInfoID) {
pc.transferChannel <- MsgInfo{pkt.TypeID, realMsg.(proto.Message), pc.ID(), pc.ip.String()}
}
} else {
......
......@@ -9,6 +9,7 @@ import (
"encoding/hex"
"encoding/json"
"math"
"strings"
"time"
"github.com/33cn/chain33/common"
......@@ -48,6 +49,8 @@ var VotedStateObj = &VotedState{}
// WaitNotifyStateObj is the WaitNotifyState obj
var WaitNotifyStateObj = &WaitNofifyState{}
var LastCheckVrfMTime = int64(0)
var LastCheckVrfRPTime = int64(0)
// Task 为计算当前时间所属周期的数据结构
type Task struct {
NodeID int64
......@@ -137,30 +140,51 @@ func checkVrf(cs *ConsensusState) {
task := DecideTaskByTime(now)
middleTime := task.CycleStart + (task.CycleStop - task.CycleStart) / 2
if now < middleTime {
if now - LastCheckVrfMTime < dposBlockInterval * 2 {
return
}
info := cs.GetVrfInfoByCircle(task.Cycle, VrfQueryTypeM)
if info == nil {
if cs.currentVote.LastCBInfo != nil {
vrfM := &dty.DposVrfMRegist{
Pubkey: hex.EncodeToString(cs.privValidator.GetPubKey().Bytes()),
Pubkey: strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())),
Cycle: task.Cycle,
M: cs.currentVote.LastCBInfo.StopHash,
//M: cs.currentVote.LastCBInfo.StopHash,
}
vrfM.M = cs.currentVote.LastCBInfo.StopHash
dposlog.Info("SendRegistVrfMTx", "pubkey", vrfM.Pubkey, "cycle", vrfM.Cycle, "M", vrfM.M)
cs.SendRegistVrfMTx(vrfM)
} else {
dposlog.Info("No avaliable LastCBInfo, so don't SendRegistVrfMTx, just wait another cycle")
}
} else {
dposlog.Info("VrfM is already registed", "now", now, "middle", middleTime, "cycle", task.Cycle, "pubkey", strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())))
}
LastCheckVrfMTime = now
} else {
if now - LastCheckVrfRPTime < dposBlockInterval * 2 {
return
}
info := cs.GetVrfInfoByCircle(task.Cycle, VrfQueryTypeRP)
if info != nil && len(info.M) > 0 && (len(info.R) == 0 || len(info.P) == 0){
hash, proof := cs.VrfEvaluate(info.M)
vrfRP := &dty.DposVrfRPRegist{
Pubkey: hex.EncodeToString(cs.privValidator.GetPubKey().Bytes()),
Pubkey: strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())),
Cycle: task.Cycle,
R: hex.EncodeToString(hash[:]),
P: hex.EncodeToString(proof),
}
dposlog.Info("SendRegistVrfRPTx", "pubkey", vrfRP.Pubkey, "cycle", vrfRP.Cycle, "R", vrfRP.R, "P", vrfRP.P)
cs.SendRegistVrfRPTx(vrfRP)
} else if info != nil && len(info.M) > 0 && len(info.R) > 0 && len(info.P) > 0 {
dposlog.Info("VrfRP is already registed", "now", now, "middle", middleTime, "cycle", task.Cycle, "pubkey", strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())))
} else{
dposlog.Info("No available VrfM, so don't SendRegistVrfRPTx, just wait another cycle")
}
LastCheckVrfRPTime = now
}
}
......@@ -290,6 +314,7 @@ func (voting *VotingState) sendVote(cs *ConsensusState, vote *dpostype.DPosVote)
func (voting *VotingState) recvVote(cs *ConsensusState, vote *dpostype.DPosVote) {
dposlog.Info("VotingState get a vote", "VotedNodeIndex", vote.VoteItem.VotedNodeIndex,
"VotedNodeAddress", common.ToHex(vote.VoteItem.VotedNodeAddress),
"Cycle", vote.VoteItem.Cycle,
"CycleStart", vote.VoteItem.CycleStart,
"CycleStop", vote.VoteItem.CycleStop,
"PeriodStart", vote.VoteItem.PeriodStart,
......@@ -326,8 +351,6 @@ func (voting *VotingState) recvVote(cs *ConsensusState, vote *dpostype.DPosVote)
panic("This node's validators are not the same with final vote, please check")
}
}
//进行VRF相关处理
checkVrf(cs)
//1s后检查是否出块,是否需要重新投票
cs.scheduleDPosTimeout(time.Millisecond*500, VotedStateType)
} else if result == continueToVote {
......@@ -385,20 +408,19 @@ func (voted *VotedState) timeOut(cs *ConsensusState) {
//时间到了节点切换时刻
if now >= cs.currentVote.PeriodStop {
//当前时间超过了节点切换时间,需要进行重新投票
dposlog.Info("VotedState timeOut over periodStop.", "periodStop", cs.currentVote.PeriodStop)
dposlog.Info("VotedState timeOut over periodStop.", "periodStop", cs.currentVote.PeriodStop, "cycleStop", cs.currentVote.CycleStop)
//如果到了cycle结尾,需要构造一个交易,把最终的CycleBoundary信息发布出去
if now >= cs.currentVote.CycleStop {
if cs.currentVote.PeriodStop == cs.currentVote.CycleStop {
dposlog.Info("Create new tx for cycle change to record cycle boundary info.", "height", block.Height)
info := &dty.DposCBInfo{
Cycle: cs.currentVote.Cycle,
StopHeight: block.Height,
StopHash: hex.EncodeToString(block.Hash()),
Pubkey: hex.EncodeToString(cs.privValidator.GetPubKey().Bytes()),
Pubkey: strings.ToUpper(hex.EncodeToString(cs.privValidator.GetPubKey().Bytes())),
}
cs.SendCBTx(info)
info2 := &dpostype.DPosCBInfo{
Cycle: info.Cycle,
StopHeight: info.StopHeight,
......@@ -406,7 +428,11 @@ func (voted *VotedState) timeOut(cs *ConsensusState) {
Pubkey: info.Pubkey,
Signature: info.Signature,
}
cs.SendCBTx(info)
cs.UpdateCBInfo(info)
dposlog.Info("Send CBInfo in consensus network", "cycle", info2.Cycle, "stopHeight", info2.StopHeight, "stopHash", info2.StopHash, "pubkey", info2.Pubkey)
voted.sendCBInfo(cs, info2)
}
......@@ -450,6 +476,7 @@ func (voted *VotedState) timeOut(cs *ConsensusState) {
return
}
checkVrf(cs)
//当前时间未到节点切换时间,则继续进行出块判断
if block.BlockTime >= task.BlockStop {
//已出块,或者时间落后了。
......
......@@ -69,6 +69,7 @@ func TestDecideTaskByTime(t *testing.T) {
setParams(2, 3, 12)
/*
for i := 0; i < 120; i++ {
now = time.Now().Unix()
task = DecideTaskByTime(now)
......@@ -76,4 +77,5 @@ func TestDecideTaskByTime(t *testing.T) {
assertTask(&task, t)
time.Sleep(time.Second * 1)
}
*/
}
package dpos
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTicker(t *testing.T) {
ticker := NewTimeoutTicker()
ticker.Start()
ti := timeoutInfo{
Duration: time.Second * time.Duration(2),
State: InitStateType,
}
now := time.Now().Unix()
ticker.ScheduleTimeout(ti)
<- ticker.Chan()
end := time.Now().Unix()
ticker.Stop()
assert.True(t, end - now == 2)
}
\ No newline at end of file
package types
import (
"encoding/json"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"testing"
"time"
)
func init(){
//为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1))
if err != nil {
panic("init ConsensusCrypto failed.")
return
}
ConsensusCrypto = cr
}
func TestVote(t *testing.T) {
filename := "./tmp_priv_validator.json"
save(filename, priv_validator_file)
privValidator := LoadOrGenPrivValidatorFS(filename)
now := time.Now().Unix()
//task := dpos.DecideTaskByTime(now)
//生成vote, 对于vote进行签名
voteItem := &VoteItem{
VotedNodeAddress: privValidator.Address,
VotedNodeIndex: int32(0),
Cycle: 100,
CycleStart: 18888,
CycleStop: 28888,
PeriodStart: 20000,
PeriodStop: 21000,
Height: 100,
}
encode, err := json.Marshal(voteItem)
if err != nil {
panic("Marshal vote failed.")
}
voteItem.VoteID = crypto.Ripemd160(encode)
vote := &Vote{
DPosVote: &DPosVote{
VoteItem: voteItem,
VoteTimestamp: now,
VoterNodeAddress: privValidator.GetAddress(),
VoterNodeIndex: int32(0),
},
}
assert.True(t, 0 == len(vote.Signature))
chainID := "test-chain-Ep9EcD"
privValidator.SignVote(chainID, vote)
assert.True(t, 0 <= len(vote.Signature))
vote2 := vote.Copy()
err = vote2.Verify(chainID, privValidator.PubKey)
require.Nil(t, err)
assert.True(t, 0 < len(vote.Hash()))
remove(filename)
}
func TestNotify(t *testing.T) {
filename := "./tmp_priv_validator.json"
save(filename, priv_validator_file)
privValidator := LoadOrGenPrivValidatorFS(filename)
now := time.Now().Unix()
//task := dpos.DecideTaskByTime(now)
//生成vote, 对于vote进行签名
voteItem := &VoteItem{
VotedNodeAddress: privValidator.Address,
VotedNodeIndex: int32(0),
Cycle: 100,
CycleStart: 18888,
CycleStop: 28888,
PeriodStart: 20000,
PeriodStop: 21000,
Height: 100,
}
encode, err := json.Marshal(voteItem)
if err != nil {
panic("Marshal vote failed.")
}
voteItem.VoteID = crypto.Ripemd160(encode)
chainID := "test-chain-Ep9EcD"
notify := &Notify{
DPosNotify: &DPosNotify{
Vote: voteItem,
HeightStop: 200,
HashStop: []byte("abcdef121212"),
NotifyTimestamp: now,
NotifyNodeAddress: privValidator.GetAddress(),
NotifyNodeIndex: int32(0),
},
}
err = privValidator.SignNotify(chainID, notify)
require.Nil(t, err)
notify2 := notify.Copy()
err = notify2.Verify(chainID, privValidator.PubKey)
require.Nil(t, err)
assert.True(t, 0 < len(notify.Hash()))
remove(filename)
}
\ No newline at end of file
......@@ -10,7 +10,6 @@ import (
"math/rand"
"os"
"path/filepath"
"strconv"
"sync"
"syscall"
"time"
......@@ -116,23 +115,6 @@ func Parallel(tasks ...func()) {
wg.Wait()
}
// Percent represents a percentage in increments of 1/1000th of a percent.
type Percent uint32
// Float ...
func (p Percent) Float() float64 {
return float64(p) * 1e-3
}
func (p Percent) String() string {
var buf [12]byte
b := strconv.AppendUint(buf[:0], uint64(p)/1000, 10)
n := len(b)
b = strconv.AppendUint(b, 1000+uint64(p)%1000, 10)
b[n] = '.'
return string(append(b, '%'))
}
// MinInt ...
func MinInt(a, b int) int {
if a < b {
......
package types
import (
"bytes"
"fmt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"os"
"os/signal"
"strings"
"testing"
"time"
)
func init(){
Init()
}
func TestWriteFile(t *testing.T) {
filename := "./tmp_priv_validator.json"
err := WriteFile(filename, []byte(priv_validator_file), 0664)
require.Nil(t, err)
file, err := os.Stat(filename)
require.Nil(t, err)
//assert.True(t, file.Mode() == 077)
fmt.Println(file.Name())
fmt.Println(file.Mode())
assert.True(t, file.Name() == "tmp_priv_validator.json")
assert.True(t, file.Mode() == 0664)
remove(filename)
}
func TestWriteFileAtomic(t *testing.T) {
filename := "./tmp_priv_validator.json"
err := WriteFileAtomic(filename, []byte(priv_validator_file), 0664)
require.Nil(t, err)
file, err := os.Stat(filename)
require.Nil(t, err)
//assert.True(t, file.Mode() == 077)
fmt.Println(file.Name())
fmt.Println(file.Mode())
assert.True(t, file.Name() == "tmp_priv_validator.json")
assert.True(t, file.Mode() == 0664)
remove(filename)
}
func TestTempfile(t *testing.T) {
filename := "tmp_priv_validator.json"
file, name := Tempfile(filename)
fmt.Println(name)
require.NotNil(t, file)
_, err := file.Write([]byte(priv_validator_file))
if err == nil {
err = file.Sync()
}
require.Nil(t, err)
if closeErr := file.Close(); err == nil {
err = closeErr
}
require.Nil(t, err)
if permErr := os.Chmod(file.Name(), 0777); err == nil {
err = permErr
}
require.Nil(t, err)
remove(name)
}
func TestFingerprint(t *testing.T) {
arr := []byte("abdcdfasdf")
finger := Fingerprint(arr)
assert.True(t, bytes.Equal(finger, arr[0:6]))
}
func TestKill(t *testing.T) {
c := make(chan os.Signal)
signal.Notify(c)
go Kill()
s := <- c
assert.True(t, s.String() == "terminated")
}
var (
go_index = 0
go_sum = 0
)
func test() {
go_index++
time.Sleep(time.Second * time.Duration(go_index))
go_sum++
}
func TestParallel(t *testing.T) {
f1 := test
f1()
f2 := test
f2()
go_sum = 0
Parallel(f1, f2)
assert.True(t, go_sum == 2)
}
func TestRandInt63n(t *testing.T) {
a := RandInt63n(10)
assert.True(t, a < 10)
b := RandInt63n(9999999999999999)
assert.True(t, b < 9999999999999999)
}
func TestRandIntn(t *testing.T) {
a := RandIntn(10)
assert.True(t, a < 10)
b := RandIntn(9999999999999)
assert.True(t, b < 9999999999999)
}
func TestRandUint32(t *testing.T) {
a := RandUint32()
assert.True(t, a >= 0)
b := RandUint32()
assert.True(t, b >= 0)
}
func TestPanicSanity(t *testing.T) {
defer func(){
if r:= recover(); r != nil {
//fmt.Println(r)
assert.True(t, strings.HasPrefix(r.(string), "Panicked on a Sanity Check: "))
}
}()
PanicSanity("hello")
}
func TestPanicCrisis(t *testing.T) {
defer func(){
if r:= recover(); r != nil {
//fmt.Println(r)
assert.True(t, strings.HasPrefix(r.(string), "Panicked on a Crisis: "))
}
}()
PanicCrisis("hello")
}
func TestPanicQ(t *testing.T) {
defer func(){
if r:= recover(); r != nil {
//fmt.Println(r)
assert.True(t, strings.HasPrefix(r.(string), "Panicked questionably: "))
}
}()
PanicQ("hello")
}
\ No newline at end of file
package types
import (
"bytes"
"encoding/hex"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"strings"
"testing"
"fmt"
)
const (
pubkey1 = "027848E7FA630B759DB406940B5506B666A344B1060794BBF314EB459D40881BB3"
pubkey2 = "03F4AB6659E61E8512C9A24AC385CC1AC4D52B87D10ADBDF060086EA82BE62CDDE"
pubkey3 = "03EF0E1D3112CF571743A3318125EDE2E52A4EB904BCBAA4B1F75020C2846A7EB4"
pubkey11 = "03541AB9887951C038273648545072E5B6A46A639BFF535F3957E8150CBE2A70D7"
pubkey12 = "03F2A7AFFA090763C42B370C6F33CC3E9B6140228ABAF0591240F3B88E8792F890"
)
var (
val1 *Validator
val2 *Validator
val3 *Validator
val11 *Validator
val12 *Validator
)
func init(){
//为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1))
if err != nil {
panic("init ConsensusCrypto failed.")
return
}
ConsensusCrypto = cr
pkbytes , err := hex.DecodeString(pubkey1)
pk1, err := ConsensusCrypto.PubKeyFromBytes(pkbytes)
pkbytes , err = hex.DecodeString(pubkey2)
pk2, err := ConsensusCrypto.PubKeyFromBytes(pkbytes)
pkbytes , err = hex.DecodeString(pubkey3)
pk3, err := ConsensusCrypto.PubKeyFromBytes(pkbytes)
val1 = NewValidator(pk1)
val2 = NewValidator(pk2)
val3 = NewValidator(pk3)
pkbytes , err = hex.DecodeString(pubkey11)
pk11, err := ConsensusCrypto.PubKeyFromBytes(pkbytes)
val11 = NewValidator(pk11)
pkbytes , err = hex.DecodeString(pubkey12)
pk12, err := ConsensusCrypto.PubKeyFromBytes(pkbytes)
val12 = NewValidator(pk12)
}
func TestValidator(t *testing.T) {
cval1 := val1.Copy()
assert.True(t, bytes.Equal(val1.PubKey, cval1.PubKey))
assert.True(t, bytes.Equal(val1.Address, cval1.Address))
assert.True(t, strings.HasPrefix(val2.String(), "Validator{"))
assert.True(t, len(val3.Hash()) > 0)
}
func match(index int, val *Validator) bool {
if bytes.Equal(val.Address, val1.Address){
return true
}
return false
}
func TestValidatorSet(t *testing.T) {
var vals []*Validator
vals = append(vals, val1)
vals = append(vals, val2)
vals = append(vals, val3)
valset := NewValidatorSet(vals)
//03f4ab6659e61e8512c9a24ac385cc1ac4d52b87d10adbdf060086ea82be62cdde
//027848e7fa630b759db406940b5506b666a344b1060794bbf314eb459d40881bb3
//03ef0e1d3112cf571743a3318125ede2e52a4eb904bcbaa4b1f75020c2846a7eb4
for _, v := range valset.Validators {
fmt.Println(hex.EncodeToString(v.PubKey))
}
assert.True(t, bytes.Equal(valset.Validators[0].PubKey, val2.PubKey))
assert.True(t, bytes.Equal(valset.Validators[1].PubKey, val1.PubKey))
assert.True(t, bytes.Equal(valset.Validators[2].PubKey, val3.PubKey))
assert.True(t, valset.HasAddress(val1.Address))
assert.True(t, valset.HasAddress(val2.Address))
assert.True(t, valset.HasAddress(val3.Address))
inx, val := valset.GetByAddress(val1.Address)
assert.True(t, inx == 1 && bytes.Equal(val.PubKey, val1.PubKey))
inx, val = valset.GetByAddress(val2.Address)
assert.True(t, inx == 0 && bytes.Equal(val.PubKey, val2.PubKey))
inx, val = valset.GetByAddress(val3.Address)
assert.True(t, inx == 2 && bytes.Equal(val.PubKey, val3.PubKey))
addr, val := valset.GetByIndex(1)
assert.True(t, bytes.Equal(val.PubKey, val1.PubKey))
assert.True(t, bytes.Equal(addr, val1.Address))
assert.True(t, 3 == valset.Size())
assert.True(t, 0 < len(valset.Hash()))
assert.True(t, valset.Add(val1) == false)
assert.True(t, valset.Size() == 3)
assert.True(t, valset.Add(val11) == true)
assert.True(t, valset.Size() == 4)
assert.True(t, valset.Update(val11) == true)
assert.True(t, valset.Size() == 4)
assert.True(t, valset.Update(val12) == false)
assert.True(t, valset.Size() == 4)
val, flag := valset.Remove(val11.Address)
assert.True(t, bytes.Equal(val.PubKey, val11.PubKey))
assert.True(t, flag == true)
val, flag = valset.Remove(val12.Address)
assert.True(t, flag == false)
require.Nil(t, val)
assert.True(t, valset.HasAddress(val1.Address) == true)
//fmt.Println(valset.String())
//fmt.Println(valset.StringIndented(" "))
valset.Iterate(match)
}
func TestValidatorsByAddress(t *testing.T) {
var arr ValidatorsByAddress
arr = append(arr, val1)
arr = append(arr, val2)
arr = append(arr, val3)
assert.True(t, arr.Len() == 3)
assert.True(t, arr.Less(0, 1) == false)
assert.True(t, arr.Less(0, 2) == true)
arr.Swap(0,1)
assert.True(t, bytes.Equal(arr[0].PubKey, val2.PubKey))
}
func TestValidatorSetException(t *testing.T) {
var vals []*Validator
valset := NewValidatorSet(vals)
assert.True(t, len(valset.Validators) == 0)
}
\ No newline at end of file
......@@ -46,22 +46,42 @@ type ValidatorMgr struct {
// Copy makes a copy of the State for mutating.
func (s ValidatorMgr) Copy() ValidatorMgr {
return ValidatorMgr{
mgr := 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{
//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,
//},
}
if s.LastCycleBoundaryInfo != nil {
mgr.LastCycleBoundaryInfo = &dty.DposCBInfo{
Cycle: s.LastCycleBoundaryInfo.Cycle,
StopHeight: s.LastCycleBoundaryInfo.StopHeight,
StopHash: s.LastCycleBoundaryInfo.StopHash,
Pubkey: s.LastCycleBoundaryInfo.Pubkey,
Signature: s.LastCycleBoundaryInfo.Signature,
},
}
}
if s.VrfValidators != nil {
mgr.VrfValidators = s.VrfValidators.Copy()
}
if s.NoVrfValidators != nil {
mgr.NoVrfValidators = s.NoVrfValidators.Copy()
}
return mgr
}
// Equals returns true if the States are identical.
......@@ -183,14 +203,16 @@ func (s *ValidatorMgr) GetIndexByPubKey(pubkey []byte) (index int) {
}
func (s *ValidatorMgr) FillVoteItem(voteItem *ttypes.VoteItem) {
if s.LastCycleBoundaryInfo != nil {
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++ {
for i := 0; s.Validators != nil && i < s.Validators.Size(); i++ {
node := &ttypes.SuperNode{
PubKey: s.Validators.Validators[i].PubKey,
Address: s.Validators.Validators[i].Address,
......@@ -198,7 +220,7 @@ func (s *ValidatorMgr) FillVoteItem(voteItem *ttypes.VoteItem) {
voteItem.Validators = append(voteItem.Validators, node)
}
for i := 0; i < s.VrfValidators.Size(); i++ {
for i := 0; s.VrfValidators != nil && i < s.VrfValidators.Size(); i++ {
node := &ttypes.SuperNode{
PubKey: s.VrfValidators.Validators[i].PubKey,
Address: s.VrfValidators.Validators[i].Address,
......@@ -206,7 +228,7 @@ func (s *ValidatorMgr) FillVoteItem(voteItem *ttypes.VoteItem) {
voteItem.VrfValidators = append(voteItem.VrfValidators, node)
}
for i := 0; i < s.NoVrfValidators.Size(); i++ {
for i := 0; s.NoVrfValidators != nil && i < s.NoVrfValidators.Size(); i++ {
node := &ttypes.SuperNode{
PubKey: s.NoVrfValidators.Validators[i].PubKey,
Address: s.NoVrfValidators.Validators[i].Address,
......@@ -217,14 +239,24 @@ func (s *ValidatorMgr) FillVoteItem(voteItem *ttypes.VoteItem) {
func (s *ValidatorMgr) UpdateFromVoteItem(voteItem *ttypes.VoteItem) bool {
validators := voteItem.Validators
if len(s.Validators.Validators) != len(voteItem.Validators){
return false
}
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 ||
if voteItem.LastCBInfo != nil {
if s.LastCycleBoundaryInfo == nil {
s.LastCycleBoundaryInfo = &dty.DposCBInfo{
Cycle: voteItem.LastCBInfo.Cycle,
StopHeight: voteItem.LastCBInfo.StopHeight,
StopHash: voteItem.LastCBInfo.StopHash,
}
} else if voteItem.LastCBInfo.Cycle != s.LastCycleBoundaryInfo.Cycle ||
voteItem.LastCBInfo.StopHeight != s.LastCycleBoundaryInfo.StopHeight ||
voteItem.LastCBInfo.StopHash != s.LastCycleBoundaryInfo.StopHash {
s.LastCycleBoundaryInfo = &dty.DposCBInfo{
......@@ -233,6 +265,9 @@ func (s *ValidatorMgr) UpdateFromVoteItem(voteItem *ttypes.VoteItem) bool {
StopHash: voteItem.LastCBInfo.StopHash,
}
}
}
s.ShuffleType = voteItem.ShuffleType
var vrfVals []*ttypes.Validator
for i := 0; i < len(voteItem.VrfValidators); i++ {
......
package dpos
import (
"bytes"
"encoding/hex"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
ttypes "github.com/33cn/plugin/plugin/consensus/dpos/types"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/assert"
dty "github.com/33cn/plugin/plugin/dapp/dposvote/types"
"os"
"testing"
"fmt"
)
const (
genesis_content = `{"genesis_time":"2018-08-16T15:38:56.951569432+08:00","chain_id":"chain33-Z2cgFj","validators":[{"pub_key":{"type":"secp256k1","data":"03EF0E1D3112CF571743A3318125EDE2E52A4EB904BCBAA4B1F75020C2846A7EB4"},"name":""},{"pub_key":{"type":"secp256k1","data":"027848E7FA630B759DB406940B5506B666A344B1060794BBF314EB459D40881BB3"},"name":""},{"pub_key":{"type":"secp256k1","data":"03F4AB6659E61E8512C9A24AC385CC1AC4D52B87D10ADBDF060086EA82BE62CDDE"},"name":""}],"app_hash":null}`
pubkey11 = "03541AB9887951C038273648545072E5B6A46A639BFF535F3957E8150CBE2A70D7"
)
var (
genDoc *ttypes.GenesisDoc
)
func init(){
//为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1))
if err != nil {
panic("init ConsensusCrypto failed.")
return
}
ttypes.ConsensusCrypto = cr
remove("./genesis.json")
save("./genesis.json", genesis_content)
genDoc, _ = ttypes.GenesisDocFromFile("./genesis.json")
}
func save(filename , filecontent string) {
f, err := os.Create(filename)
if err != nil {
fmt.Println("err = ", err)
return
}
defer f.Close()
n, err := f.WriteString(filecontent)
if err != nil {
fmt.Println("err = ", err)
return
}
fmt.Println("n=", n, " contentlen=", len(filecontent))
}
func remove(filename string) {
os.Remove(filename)
}
func TestMakeGenesisValidatorMgr(t *testing.T) {
vMgr, err := MakeGenesisValidatorMgr(genDoc)
require.Nil(t, err)
assert.True(t, vMgr.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgr.AppHash) == 0)
assert.True(t, len(vMgr.Validators.Validators) == 3)
assert.True(t, vMgr.VrfValidators == nil)
assert.True(t, vMgr.NoVrfValidators == nil)
assert.True(t, vMgr.LastCycleBoundaryInfo == nil)
vMgrCopy := vMgr.Copy()
assert.True(t, vMgrCopy.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgrCopy.AppHash) == 0)
assert.True(t, len(vMgrCopy.Validators.Validators) == 3)
assert.True(t, vMgrCopy.VrfValidators == nil)
assert.True(t, vMgrCopy.NoVrfValidators == nil)
assert.True(t, vMgrCopy.LastCycleBoundaryInfo == nil)
assert.True(t, vMgrCopy.Equals(vMgr))
assert.True(t, vMgrCopy.IsEmpty() == false)
assert.True(t, len(vMgrCopy.GetValidators().Validators) == 3)
}
func TestGetValidatorByIndex(t *testing.T) {
vMgr, err := MakeGenesisValidatorMgr(genDoc)
require.Nil(t, err)
assert.True(t, vMgr.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgr.AppHash) == 0)
assert.True(t, len(vMgr.Validators.Validators) == 3)
assert.True(t, vMgr.VrfValidators == nil)
assert.True(t, vMgr.NoVrfValidators == nil)
assert.True(t, vMgr.LastCycleBoundaryInfo == nil)
vMgr.ShuffleType = ShuffleTypeNoVrf
addr, val := vMgr.GetValidatorByIndex(-1)
require.Nil(t, addr)
require.Nil(t, val)
addr, val = vMgr.GetValidatorByIndex(1)
assert.True(t, bytes.Equal(addr, vMgr.Validators.Validators[1].Address))
assert.True(t, bytes.Equal(val.PubKey, vMgr.Validators.Validators[1].PubKey))
vMgr.VrfValidators = ttypes.NewValidatorSet(vMgr.Validators.Validators)
vMgr.ShuffleType = ShuffleTypeVrf
addr, val = vMgr.GetValidatorByIndex(2)
assert.True(t, bytes.Equal(addr, vMgr.VrfValidators.Validators[2].Address))
assert.True(t, bytes.Equal(val.PubKey, vMgr.VrfValidators.Validators[2].PubKey))
vMgr.ShuffleType = ShuffleTypePartVrf
val, flag := vMgr.VrfValidators.Remove(addr)
assert.True(t, flag)
vMgr.NoVrfValidators = &ttypes.ValidatorSet{}
vMgr.NoVrfValidators.Validators = append(vMgr.NoVrfValidators.Validators, val)
addr, val = vMgr.GetValidatorByIndex(2)
assert.True(t, bytes.Equal(addr, vMgr.NoVrfValidators.Validators[0].Address))
assert.True(t, bytes.Equal(val.PubKey, vMgr.NoVrfValidators.Validators[0].PubKey))
}
func TestGetIndexByPubKey(t *testing.T){
vMgr, err := MakeGenesisValidatorMgr(genDoc)
require.Nil(t, err)
assert.True(t, vMgr.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgr.AppHash) == 0)
assert.True(t, len(vMgr.Validators.Validators) == 3)
assert.True(t, vMgr.VrfValidators == nil)
assert.True(t, vMgr.NoVrfValidators == nil)
assert.True(t, vMgr.LastCycleBoundaryInfo == nil)
vMgr.ShuffleType = ShuffleTypeNoVrf
index := vMgr.GetIndexByPubKey(nil)
assert.True(t, index == -1)
index = vMgr.GetIndexByPubKey(vMgr.Validators.Validators[1].PubKey)
assert.True(t, index == 1)
index = vMgr.GetIndexByPubKey(vMgr.Validators.Validators[0].PubKey)
assert.True(t, index == 0)
index = vMgr.GetIndexByPubKey(vMgr.Validators.Validators[2].PubKey)
assert.True(t, index == 2)
index = vMgr.GetIndexByPubKey([]byte("afdafafdfa"))
assert.True(t, index == -1)
vMgr.VrfValidators = ttypes.NewValidatorSet(vMgr.Validators.Validators)
vMgr.ShuffleType = ShuffleTypeVrf
index = vMgr.GetIndexByPubKey(vMgr.VrfValidators.Validators[1].PubKey)
assert.True(t, index == 1)
index = vMgr.GetIndexByPubKey(vMgr.VrfValidators.Validators[0].PubKey)
assert.True(t, index == 0)
index = vMgr.GetIndexByPubKey(vMgr.VrfValidators.Validators[2].PubKey)
assert.True(t, index == 2)
index = vMgr.GetIndexByPubKey([]byte("afdafafdfa"))
assert.True(t, index == -1)
vMgr.ShuffleType = ShuffleTypePartVrf
val, flag := vMgr.VrfValidators.Remove(vMgr.VrfValidators.Validators[2].Address)
assert.True(t, flag)
vMgr.NoVrfValidators = &ttypes.ValidatorSet{}
vMgr.NoVrfValidators.Validators = append(vMgr.NoVrfValidators.Validators, val)
index = vMgr.GetIndexByPubKey(vMgr.NoVrfValidators.Validators[0].PubKey)
assert.True(t, index == 2)
}
func TestFillVoteItem(t *testing.T) {
vMgr, err := MakeGenesisValidatorMgr(genDoc)
require.Nil(t, err)
assert.True(t, vMgr.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgr.AppHash) == 0)
assert.True(t, len(vMgr.Validators.Validators) == 3)
assert.True(t, vMgr.VrfValidators == nil)
assert.True(t, vMgr.NoVrfValidators == nil)
assert.True(t, vMgr.LastCycleBoundaryInfo == nil)
vMgr.ShuffleType = ShuffleTypeNoVrf
voteItem := &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
assert.True(t, voteItem.LastCBInfo == nil)
assert.True(t, voteItem.ShuffleType == ShuffleTypeNoVrf)
assert.True(t, len(voteItem.Validators) == 3)
assert.True(t, voteItem.VrfValidators == nil)
assert.True(t, voteItem.NoVrfValidators == nil)
vMgr.VrfValidators = ttypes.NewValidatorSet(vMgr.Validators.Validators)
vMgr.ShuffleType = ShuffleTypeVrf
vMgr.LastCycleBoundaryInfo = &dty.DposCBInfo{
Cycle: 110,
StopHeight:1111,
StopHash: "abcdefg",
Pubkey:"xxxxxxxx",
}
voteItem = &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
assert.True(t, voteItem.LastCBInfo != nil)
assert.True(t, voteItem.LastCBInfo.Cycle == 110)
assert.True(t, voteItem.LastCBInfo.StopHeight == 1111)
assert.True(t, voteItem.LastCBInfo.StopHash == "abcdefg")
assert.True(t, voteItem.ShuffleType == ShuffleTypeVrf)
assert.True(t, len(voteItem.Validators) == 3)
assert.True(t, len(voteItem.VrfValidators) == 3)
assert.True(t, voteItem.NoVrfValidators == nil)
vMgr.ShuffleType = ShuffleTypePartVrf
val, flag := vMgr.VrfValidators.Remove(vMgr.Validators.Validators[2].Address)
assert.True(t, flag == true)
vMgr.NoVrfValidators = &ttypes.ValidatorSet{}
vMgr.NoVrfValidators.Validators = append(vMgr.NoVrfValidators.Validators, val)
assert.True(t, len(vMgr.VrfValidators.Validators) == 2)
assert.True(t, len(vMgr.NoVrfValidators.Validators) == 1)
voteItem = &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
assert.True(t, voteItem.LastCBInfo != nil)
assert.True(t, voteItem.ShuffleType == ShuffleTypePartVrf)
fmt.Println(len(voteItem.Validators))
assert.True(t, len(voteItem.Validators) == 3)
assert.True(t, len(voteItem.VrfValidators) == 2)
assert.True(t, len(voteItem.NoVrfValidators) == 1)
}
func TestUpdateFromVoteItem(t *testing.T) {
vMgr, err := MakeGenesisValidatorMgr(genDoc)
require.Nil(t, err)
assert.True(t, vMgr.ChainID == "chain33-Z2cgFj")
assert.True(t, len(vMgr.AppHash) == 0)
assert.True(t, len(vMgr.Validators.Validators) == 3)
assert.True(t, vMgr.VrfValidators == nil)
assert.True(t, vMgr.NoVrfValidators == nil)
assert.True(t, vMgr.LastCycleBoundaryInfo == nil)
vMgr.ShuffleType = ShuffleTypeNoVrf
voteItem := &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
assert.True(t, voteItem.LastCBInfo == nil)
assert.True(t, voteItem.ShuffleType == ShuffleTypeNoVrf)
assert.True(t, len(voteItem.Validators) == 3)
assert.True(t, voteItem.VrfValidators == nil)
assert.True(t, voteItem.NoVrfValidators == nil)
/////
newMgr := vMgr.Copy()
newMgr.LastCycleBoundaryInfo = nil
val, flag := newMgr.Validators.Remove(newMgr.Validators.Validators[0].Address)
assert.True(t, flag)
flag = newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, flag == false)
/////
pkbytes , err := hex.DecodeString(pubkey11)
pk11, err := ttypes.ConsensusCrypto.PubKeyFromBytes(pkbytes)
val.PubKey = pk11.Bytes()
newMgr.Validators.Add(val)
flag = newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, flag == false)
/////
vMgr.LastCycleBoundaryInfo = &dty.DposCBInfo{
Cycle: 110,
StopHeight:1111,
StopHash: "abcdefg",
Pubkey:"xxxxxxxx",
}
voteItem = &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
newMgr = vMgr.Copy()
newMgr.LastCycleBoundaryInfo = nil
newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, newMgr.LastCycleBoundaryInfo != nil)
assert.True(t, newMgr.LastCycleBoundaryInfo.Cycle == voteItem.LastCBInfo.Cycle)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHeight == voteItem.LastCBInfo.StopHeight)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHash == voteItem.LastCBInfo.StopHash)
/////
newMgr = vMgr.Copy()
newMgr.LastCycleBoundaryInfo.Cycle = 111110
newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, newMgr.LastCycleBoundaryInfo != nil)
assert.True(t, newMgr.LastCycleBoundaryInfo.Cycle == voteItem.LastCBInfo.Cycle)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHeight == voteItem.LastCBInfo.StopHeight)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHash == voteItem.LastCBInfo.StopHash)
/////
vMgr.VrfValidators = ttypes.NewValidatorSet(vMgr.Validators.Validators)
vMgr.ShuffleType = ShuffleTypeVrf
voteItem = &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
assert.True(t, voteItem.LastCBInfo != nil)
assert.True(t, voteItem.LastCBInfo.Cycle == 110)
assert.True(t, voteItem.LastCBInfo.StopHeight == 1111)
assert.True(t, voteItem.LastCBInfo.StopHash == "abcdefg")
assert.True(t, voteItem.ShuffleType == ShuffleTypeVrf)
assert.True(t, len(voteItem.Validators) == 3)
assert.True(t, len(voteItem.VrfValidators) == 3)
assert.True(t, voteItem.NoVrfValidators == nil)
newMgr = vMgr.Copy()
newMgr.ShuffleType = ShuffleTypeNoVrf
newMgr.VrfValidators = nil
newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, newMgr.LastCycleBoundaryInfo != nil)
assert.True(t, newMgr.LastCycleBoundaryInfo.Cycle == voteItem.LastCBInfo.Cycle)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHeight == voteItem.LastCBInfo.StopHeight)
assert.True(t, newMgr.LastCycleBoundaryInfo.StopHash == voteItem.LastCBInfo.StopHash)
assert.True(t, newMgr.ShuffleType == ShuffleTypeVrf)
assert.True(t, len(newMgr.Validators.Validators) == 3)
assert.True(t, len(newMgr.VrfValidators.Validators) == 3)
///
vMgr.ShuffleType = ShuffleTypePartVrf
val, flag = vMgr.VrfValidators.Remove(vMgr.Validators.Validators[2].Address)
assert.True(t, flag == true)
vMgr.NoVrfValidators = &ttypes.ValidatorSet{}
vMgr.NoVrfValidators.Validators = append(vMgr.NoVrfValidators.Validators, val)
assert.True(t, len(vMgr.VrfValidators.Validators) == 2)
assert.True(t, len(vMgr.NoVrfValidators.Validators) == 1)
voteItem = &ttypes.VoteItem{}
vMgr.FillVoteItem(voteItem)
newMgr = vMgr.Copy()
newMgr.ShuffleType = ShuffleTypeNoVrf
newMgr.VrfValidators = nil
newMgr.NoVrfValidators = nil
newMgr.UpdateFromVoteItem(voteItem)
assert.True(t, newMgr.LastCycleBoundaryInfo != nil)
assert.True(t, newMgr.ShuffleType == ShuffleTypePartVrf)
assert.True(t, len(newMgr.Validators.Validators) == 3)
assert.True(t, len(newMgr.VrfValidators.Validators) == 2)
assert.True(t, len(newMgr.NoVrfValidators.Validators) == 1)
}
\ No newline at end of file
......@@ -53,6 +53,7 @@ func DPosCmd() *cobra.Command {
DPosCreateCmd(),
DPosVrfVerifyCmd(),
DPosVrfEvaluateCmd(),
DPosCBQueryCmd(),
)
return cmd
......@@ -882,8 +883,8 @@ func addCBQueryFlags(cmd *cobra.Command) {
cmd.MarkFlagRequired("type")
cmd.Flags().Int64P("cycle", "c", 0, "cycle")
cmd.Flags().Int64P("height", "h", 0, "height")
cmd.Flags().StringP("hash", "m", "", "block hash")
cmd.Flags().Int64P("height", "m", 0, "height")
cmd.Flags().StringP("hash", "s", "", "block hash")
}
func cbQuery(cmd *cobra.Command, args []string) {
......
......@@ -169,7 +169,7 @@ func queryVrfByCycleAndPubkeys(kvdb db.KVDB, pubkeys []string, cycle int64) [] *
var tempPubkeys [] string
var vrfs [] *dty.VrfInfo
for i := 0; i < len(pubkeys); i ++ {
rows, err := query.ListIndex("pubkey_cycle", []byte(fmt.Sprintf("%s:%018d", pubkeys[i], cycle)), nil, 1, 0)
rows, err := query.ListIndex("pubkey_cycle", []byte(fmt.Sprintf("%s:%018d", strings.ToUpper(pubkeys[i]), cycle)), nil, 1, 0)
if err != nil {
logger.Error("queryVrf RP failed", "pubkey", pubkeys[i], "cycle", cycle)
tempPubkeys = append(tempPubkeys, pubkeys[i])
......@@ -188,7 +188,7 @@ func queryVrfByCycleAndPubkeys(kvdb db.KVDB, pubkeys []string, cycle int64) [] *
vrfMTable := dty.NewDposVrfMTable(kvdb)
query = vrfMTable.GetQuery(kvdb)
for i := 0; i < len(tempPubkeys); i++ {
rows, err := query.ListIndex("pubkey_cycle", []byte(fmt.Sprintf("%s:%018d", tempPubkeys[i], cycle)), nil, 1, 0)
rows, err := query.ListIndex("pubkey_cycle", []byte(fmt.Sprintf("%s:%018d", strings.ToUpper(tempPubkeys[i]), cycle)), nil, 1, 0)
if err != nil {
logger.Error("queryVrf M failed", "pubkey", tempPubkeys[i], "cycle", cycle)
continue
......@@ -602,7 +602,11 @@ func queryCBInfoByHash(kvdb db.KVDB, req *dty.DposCBQuery) (types.Message, error
cbTable := dty.NewDposCBTable(kvdb)
query := cbTable.GetQuery(kvdb)
rows, err := query.ListIndex("hash", []byte(fmt.Sprintf("%X", req.StopHash)), nil, 1, 0)
hash, err := hex.DecodeString(req.StopHash)
if err != nil {
return nil, err
}
rows, err := query.ListIndex("hash", hash, nil, 1, 0)
if err != nil {
return nil, err
}
......@@ -1129,6 +1133,8 @@ func (action *Action) RecordCB(cbInfo *dty.DposCBInfo) (*types.Receipt, error) {
return nil, types.ErrInvalidParam
}
logger.Info("RecordCB", "addr", action.fromaddr, "execaddr", action.execaddr, "info", fmt.Sprintf("cycle:%d,stopHeight:%d,stopHash:%s,pubkey:%s", cbInfo.Cycle, cbInfo.StopHeight, cbInfo.StopHash, cbInfo.Pubkey))
cb := &dty.DposCycleBoundaryInfo{
Cycle: cbInfo.Cycle,
StopHeight: cbInfo.StopHeight,
......
......@@ -505,8 +505,8 @@ func (s *P2pserver) ServerStreamRead(stream pb.P2Pgservice_ServerStreamReadServe
if block := in.GetBlock(); block != nil {
innerpeer := s.getInBoundPeerInfo(peername)
if innerpeer != nil {
log.Error("ServerStreamRead CheckVersion", "version", innerpeer.p2pversion, "ip", remoteIP)
if !s.checkVersion(innerpeer.p2pversion) {
log.Error("ServerStreamRead CheckVersion", "version", innerpeer.p2pversion, "ip", remoteIP)
return pb.ErrVersion
}
} else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment