Commit 1c6d4f4b authored by 张振华's avatar 张振华

update

parent 1d227a8a
......@@ -6,6 +6,7 @@ package dpos
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/33cn/chain33/common/address"
"os"
......@@ -455,7 +456,25 @@ func (client *Client)QueryCandidators()([]*dty.Candidator, error) {
return nil, err
}
res = *result.(*dty.CandidatorReply)
return res.GetCandidators(), nil
var cands []*dty.Candidator
for _, val := range res.GetCandidators() {
bPubkey, err := hex.DecodeString(val.Pubkey)
if err != nil {
return nil, err
}
cand := &dty.Candidator{
Pubkey: bPubkey,
Address: val.Address,
Ip: val.Ip,
Votes: val.Votes,
Status: val.Status,
}
cands = append(cands, cand)
}
return cands, nil
}
func (client *Client)MonitorCandidators() {
......
......@@ -171,16 +171,16 @@ func addCancelVoteFlags(cmd *cobra.Command) {
cmd.Flags().StringP("pubkey", "k", "", "pubkey of a candidator")
cmd.MarkFlagRequired("pubkey")
cmd.Flags().Int64P("votes", "v", 0, "votes")
cmd.MarkFlagRequired("votes")
cmd.Flags().Int64P("index", "i", 0, "index")
cmd.MarkFlagRequired("index")
}
func cancelVote(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
pubkey, _ := cmd.Flags().GetString("pubkey")
votes, _ := cmd.Flags().GetInt64("votes")
index, _ := cmd.Flags().GetInt64("index")
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"votes\":\"%d\"}", pubkey, votes)
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"index\":\"%d\"}", pubkey, index)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(dty.DPosX),
ActionName: dty.CreateCancelVoteTx,
......@@ -358,7 +358,7 @@ func vrfM(cmd *cobra.Command, args []string) {
cycle, _ := cmd.Flags().GetInt64("cycle")
m, _ := cmd.Flags().GetString("m")
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"cycle\":\"%d\", \"m\":\"%X\"}", pubkey, cycle, m)
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"cycle\":\"%d\", \"m\":\"%s\"}", pubkey, cycle, m)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(dty.DPosX),
ActionName: dty.CreateRegistVrfMTx,
......@@ -399,10 +399,10 @@ func vrfRP(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
pubkey, _ := cmd.Flags().GetString("pubkey")
cycle, _ := cmd.Flags().GetInt64("cycle")
r, _ := cmd.Flags().GetString("r")
p, _ := cmd.Flags().GetString("p")
hash, _ := cmd.Flags().GetString("hash")
proof, _ := cmd.Flags().GetString("proof")
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"cycle\":\"%d\", \"r\":\"%s\", \"p\":\"%s\"}", pubkey, cycle, r, p)
payload := fmt.Sprintf("{\"pubkey\":\"%s\", \"cycle\":\"%d\", \"r\":\"%s\", \"p\":\"%s\"}", pubkey, cycle, hash, proof)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(dty.DPosX),
ActionName: dty.CreateRegistVrfRPTx,
......@@ -433,6 +433,7 @@ func addVrfQueryFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("timestamp", "s", 0, "time stamp from 1970-1-1")
cmd.Flags().Int64P("cycle", "c", 0, "cycle,one time point belongs to a cycle")
cmd.Flags().StringP("pubkeys", "k", "", "pubkeys")
}
func vrfQuery(cmd *cobra.Command, args []string) {
......@@ -441,6 +442,7 @@ func vrfQuery(cmd *cobra.Command, args []string) {
dtime, _ := cmd.Flags().GetString("time")
timestamp, _ := cmd.Flags().GetInt64("timestamp")
cycle, _ := cmd.Flags().GetInt64("cycle")
pubkeys, _ := cmd.Flags().GetString("pubkeys")
var params rpctypes.Query4Jrpc
params.Execer = dty.DPosX
......@@ -497,5 +499,45 @@ func vrfQuery(cmd *cobra.Command, args []string) {
var res dty.DposVrfReply
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "topN":
if cycle <= 0 {
fmt.Println("err cycle:", cycle)
return
}
req := &dty.DposVrfQuery{
Ty: dty.QueryVrfByCycleForTopN,
Cycle: cycle,
}
params.FuncName = dty.FuncNameQueryVrfByCycleForTopN
params.Payload = types.MustPBToJSON(req)
var res dty.DposVrfReply
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
case "pubkeys":
if cycle <= 0 {
fmt.Println("err cycle:", cycle)
return
}
req := &dty.DposVrfQuery{
Ty: dty.QueryVrfByCycleForPubkeys,
Cycle: cycle,
}
keys := strings.Split(pubkeys, ";")
for _, key := range keys {
req.Pubkeys = append(req.Pubkeys, key)
}
params.FuncName = dty.FuncNameQueryVrfByCycleForPubkeys
params.Payload = types.MustPBToJSON(req)
var res dty.DposVrfReply
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run()
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ package executor
/*
该合约主要是配合Dpos共识,完成(1)候选节点的注册、去注册、投票及查询管理。(2)Dpos共识运行过程中,得票数TopN(N为约定的受托节点数量)受托节点的VRF相关信息的分阶段发布管理。
主要过程:
(1)系统初始运行时,会有默认的几个受托节点进行共识运行。
(2)系统运行后,可以重新选举受托节点,各个候选节点需要抵押10000个币(暂未实现),注册成为候选节点。
(3)候选节点可以在社区宣传,让大家为自己投票。
......
This diff is collapsed.
......@@ -5,6 +5,7 @@
package executor
import (
"bytes"
"fmt"
"github.com/33cn/chain33/types"
......@@ -23,22 +24,15 @@ func (d *DPos) rollbackCand(cand *dty.CandidatorInfo, log *dty.ReceiptCandicator
}
//如果投票了,则需要把投票回滚
if log.Voted {
cand.Votes -= log.Votes
if log.Votes > 0 {
//如果是投票,则回滚时将投票删除。
cand.Voters = cand.Voters[:len(cand.Voters)-1]
} else {
//如果是撤销投票,则回滚时,将删除的投票还回来
voter := &dty.DposVoter{
FromAddr: log.FromAddr,
Pubkey: log.Pubkey,
Votes: -log.Votes,
Index: log.Index,
Time: log.Time - dty.VoteFrozenTime,
if log.VoteType == dty.VoteTypeVote {
for i := 0; i < len(cand.Voters); i++{
if cand.Voters[i].Index == log.Vote.Index && cand.Voters[i].FromAddr == log.Vote.FromAddr && bytes.Equal(cand.Voters[i].Pubkey, log.Vote.Pubkey){
cand.Voters = append(cand.Voters[0:i], cand.Voters[i+1:]...)
break
}
cand.Voters = append(cand.Voters, voter)
}
} else if log.VoteType == dty.VoteTypeCancelVote {
cand.Voters = append(cand.Voters, log.Vote)
}
}
......@@ -74,10 +68,16 @@ func (d *DPos) rollbackCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyVal
return nil, err
}
//删除投票信息
err = voterTable.Del([]byte(fmt.Sprintf("%018d", log.Index)))
if err != nil {
return nil, err
if log.VoteType == dty.VoteTypeVote {
err = voterTable.Del([]byte(fmt.Sprintf("%018d", log.Index)))
if err != nil {
return nil, err
}
} else if log.VoteType == dty.VoteTypeCancelVote {
err = voterTable.Add(log.Vote)
if err != nil {
return nil, err
}
}
kvs2, err := voterTable.Save()
......@@ -86,7 +86,7 @@ func (d *DPos) rollbackCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyVal
}
kvs = append(kvs1, kvs2...)
} else if log.Status == dty.CandidatorStatusCancelVoted {
} else if log.Status == dty.CandidatorStatusCancelRegist {
//撤销投票回滚,需要将撤销的投票还回来
candInfo := log.CandInfo
log.CandInfo = nil
......@@ -103,10 +103,13 @@ func (d *DPos) rollbackCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyVal
return nil, err
}
//删除投票信息
err = voterTable.Del([]byte(fmt.Sprintf("%018d", log.Index)))
if err != nil {
return nil, err
if log.VoteType == dty.VoteTypeCancelAllVote {
for i := 0; i < len(candInfo.Voters); i++ {
err = voterTable.Add(candInfo.Voters[i])
if err != nil {
return nil, err
}
}
}
kvs2, err := voterTable.Save()
......@@ -115,6 +118,14 @@ func (d *DPos) rollbackCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyVal
}
kvs = append(kvs1, kvs2...)
} else if log.Status == dty.CandidatorStatusReRegist {
//注册回滚,cand表删除记录
err = candTable.Del(log.Pubkey)
if err != nil {
return nil, err
}
kvs, err = candTable.Save()
return kvs, err
}
return kvs, nil
......@@ -153,7 +164,7 @@ func (d *DPos) execDelLocal(receipt *types.ReceiptData) (*types.LocalDBSet, erro
for _, log := range receipt.Logs {
switch log.GetTy() {
case dty.CandidatorStatusRegist, dty.CandidatorStatusVoted, dty.CandidatorStatusCancelVoted, dty.CandidatorStatusCancelRegist:
case dty.TyLogCandicatorRegist, dty.TyLogCandicatorVoted, dty.TyLogCandicatorCancelVoted, dty.TyLogCandicatorCancelRegist, dty.TyLogCandicatorReRegist:
receiptLog := &dty.ReceiptCandicator{}
if err := types.Decode(log.Log, receiptLog); err != nil {
return nil, err
......
......@@ -7,16 +7,17 @@ package executor
import (
"github.com/33cn/chain33/types"
dty "github.com/33cn/plugin/plugin/dapp/dposvote/types"
"fmt"
)
func (d *DPos) updateCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyValue, err error) {
voteTable := dty.NewDposVoteTable(d.GetLocalDB())
canTable := dty.NewDposCandidatorTable(d.GetLocalDB())
if log.Status == dty.CandidatorStatusRegist {
candInfo := log.CandInfo
log.CandInfo = nil
candInfo := log.CandInfo
log.CandInfo = nil
if log.Status == dty.CandidatorStatusRegist {
err = canTable.Add(candInfo)
if err != nil {
return nil, err
......@@ -27,9 +28,7 @@ func (d *DPos) updateCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyValue
return nil, err
}
} else if log.Status == dty.CandidatorStatusVoted {
candInfo := log.CandInfo
log.CandInfo = nil
voter := candInfo.Voters[len(candInfo.Voters)-1]
voter := log.Vote
err = canTable.Replace(candInfo)
if err != nil {
......@@ -41,9 +40,16 @@ func (d *DPos) updateCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyValue
return nil, err
}
err = voteTable.Add(voter)
if err != nil {
return nil, err
if log.VoteType == dty.VoteTypeVote {
err = voteTable.Add(voter)
if err != nil {
return nil, err
}
} else if log.VoteType == dty.VoteTypeCancelVote {
err = voteTable.Del([]byte(fmt.Sprintf("%018d", voter.Index)))
if err != nil {
return nil, err
}
}
kvs2, err := voteTable.Save()
......@@ -52,51 +58,40 @@ func (d *DPos) updateCandVote(log *dty.ReceiptCandicator) (kvs []*types.KeyValue
}
kvs = append(kvs1, kvs2...)
} else if log.Status == dty.CandidatorStatusCancelVoted {
candInfo := log.CandInfo
log.CandInfo = nil
voter := &dty.DposVoter{
FromAddr: log.FromAddr,
Pubkey: log.Pubkey,
Votes: log.Votes,
Index: log.Index,
Time: log.Time,
}
} else if log.Status == dty.CandidatorStatusReRegist {
err = canTable.Replace(candInfo)
if err != nil {
return nil, err
}
kvs1, err := canTable.Save()
kvs, err = canTable.Save()
if err != nil {
return nil, err
}
err = voteTable.Add(voter)
} else if log.Status == dty.CandidatorStatusCancelRegist {
err = canTable.Replace(candInfo)
if err != nil {
return nil, err
}
kvs2, err := voteTable.Save()
kvs1, err := canTable.Save()
if err != nil {
return nil, err
}
kvs = append(kvs1, kvs2...)
} else if log.Status == dty.CandidatorStatusReRegist || log.Status == dty.CandidatorStatusCancelRegist{
candInfo := log.CandInfo
log.CandInfo = nil
err = canTable.Replace(candInfo)
if err != nil {
return nil, err
for i := 0; i < len(candInfo.Voters); i++ {
err = voteTable.Del([]byte(fmt.Sprintf("%018d", candInfo.Voters[i].Index)))
if err != nil {
return nil, err
}
}
kvs, err = canTable.Save()
kvs2, err := voteTable.Save()
if err != nil {
return nil, err
}
kvs = append(kvs1, kvs2...)
}
return kvs, nil
......@@ -112,6 +107,9 @@ func (d *DPos) updateVrf(log *dty.ReceiptVrf) (kvs []*types.KeyValue, err error)
Height: log.Height,
M: log.M,
Time: log.Time,
CycleStart: log.CycleStart,
CycleMiddle: log.CycleMiddle,
CycleStop: log.CycleStop,
}
err = vrfMTable.Add(vrfM)
......@@ -134,6 +132,9 @@ func (d *DPos) updateVrf(log *dty.ReceiptVrf) (kvs []*types.KeyValue, err error)
P: log.P,
M: log.M,
Time: log.Time,
CycleStart: log.CycleStart,
CycleMiddle: log.CycleMiddle,
CycleStop: log.CycleStop,
}
err = VrfRPTable.Add(vrfRP)
......@@ -211,11 +212,11 @@ func (d *DPos) ExecLocal_CancelVote(payload *dty.DposCancelVote, tx *types.Trans
}
//ExecLocal_VrfMRegist method
func (d *DPos) ExecLocal_VrfMRegist(payload *dty.DposVrfMRegist, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
func (d *DPos) ExecLocal_RegistVrfM(payload *dty.DposVrfMRegist, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return d.execLocal(receiptData)
}
//ExecLocal_VrfRPRegist method
func (d *DPos) ExecLocal_VrfRPRegist(payload *dty.DposVrfRPRegist, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
func (d *DPos) ExecLocal_RegistVrfRP(payload *dty.DposVrfRPRegist, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return d.execLocal(receiptData)
}
\ No newline at end of file
......@@ -33,3 +33,13 @@ func (d *DPos) Query_QueryVrfByTime(in *dty.DposVrfQuery) (types.Message, error)
func (d *DPos) Query_QueryVrfByCycle(in *dty.DposVrfQuery) (types.Message, error) {
return queryVrfByCycle(d.GetLocalDB(), in)
}
//Query_QueryVrfByCycleForTopN method
func (d *DPos) Query_QueryVrfByCycleForTopN(in *dty.DposVrfQuery) (types.Message, error) {
return queryVrfByCycleForTopN(d.GetLocalDB(), in)
}
//Query_QueryVrfByCycleForPubkeys method
func (d *DPos) Query_QueryVrfByCycleForPubkeys(in *dty.DposVrfQuery) (types.Message, error) {
return queryVrfByCycleForPubkeys(d.GetLocalDB(), in)
}
\ No newline at end of file
......@@ -39,27 +39,27 @@ message Candidator {
//DposCandidatorRegist 注册Dpos候选节点,必须抵押一定数量的币,比如:10000个币
message DposCandidatorRegist{
string pubkey = 1; //候选节点的公钥
string address = 2; //候选节点的地址
string ip = 3; //候选节点的共识IP地址
string address = 2; //候选节点的地址
string ip = 3; //候选节点的共识IP地址
}
//DposCandidatorCancelRegist 注销Dpos候选节点,解冻抵押的币
message DposCandidatorCancelRegist{
string pubkey = 1; //候选节点的公钥
string address = 2; //候选节点的地址
string address = 2; //候选节点的地址
}
//DposVote 为Dpos候选节点投票
message DposVote{
string fromAddr = 1;
string pubkey = 2; //候选节点的公钥
int64 votes = 3; //投给候选节点的票数,不能超过锁在合约中的未使用票数
string fromAddr = 1;
string pubkey = 2; //候选节点的公钥
int64 votes = 3; //投给候选节点的票数,不能超过锁在合约中的未使用票数
}
//DposCancelVote 撤销为Dpos候选节点投票
message DposCancelVote{
string pubkey = 1; //候选节点的公钥
int64 votes = 2; //撤销投给候选节点的票数,不超过之前投给该候选节点的总票数,投票3天之后才可以撤销投票
string pubkey = 1; //候选节点的公钥
int64 index = 3;
}
//DposVoteAction DposVote动作
......@@ -85,8 +85,18 @@ message CandidatorQuery{
int32 ty = 3; //1:按公钥集合查询,2:按topN票数查询
}
//Candidator 候选节点信息
message JsonCandidator {
string pubkey = 1; //候选节点的公钥
string address = 2; //后续节点的地址
string ip = 3; //候选节点的运行IP
int64 votes = 4; //候选节点的投票数
int64 status = 5; //候选节点的状态,0:注册,1:当选,2:取消注册
}
message CandidatorReply{
repeated Candidator candidators = 1; //候选节点
repeated JsonCandidator candidators = 1; //候选节点
}
message DposVoteQuery{
......@@ -94,8 +104,16 @@ message DposVoteQuery{
string addr = 2; //要查询的地址
}
message JsonDposVoter{
string fromAddr = 1;
string pubkey = 2; //候选节点的公钥
int64 votes = 3; //投给候选节点的票数,不能超过锁在合约中的未使用票数
int64 index = 4;
int64 time = 5;
}
message DposVoteReply{
repeated DposVoter votes = 1; //某地址对具体候选节点的投票情况
repeated JsonDposVoter votes = 1; //某地址对具体候选节点的投票情况
}
//ReceiptCandicator 候选者收据信息
......@@ -106,8 +124,8 @@ message ReceiptCandicator {
int64 status = 4;
int64 preStatus = 5;
bool statusChange = 6;
bool voted = 7;
int64 votes = 8;
int32 voteType = 7;
DposVoter vote = 8;
string fromAddr = 9;
CandidatorInfo candInfo = 10;
int64 time = 11;
......@@ -120,6 +138,9 @@ message DposVrfM{
int64 height = 4;
bytes m = 5; //vrf的输入
int64 time = 6;
int64 cycleStart = 7;
int64 cycleMiddle = 8;
int64 cycleStop = 9;
}
message DposVrfRP{
......@@ -131,6 +152,9 @@ message DposVrfRP{
bytes r = 6; //vrf的hash
bytes p = 7; //vrf的hash的proof
int64 time = 8;
int64 cycleStart = 9;
int64 cycleMiddle = 10;
int64 cycleStop = 11;
}
message DposVrfMRegist{
......@@ -158,6 +182,9 @@ message ReceiptVrf {
bytes r = 7;
bytes p = 8;
int64 time = 9;
int64 cycleStart = 10;
int64 cycleMiddle = 11;
int64 cycleStop = 12;
}
......@@ -173,11 +200,23 @@ message VrfInfo {
}
message DposVrfQuery{
int64 ty = 1;
int64 timestamp = 2;
int64 cycle = 3;
repeated string pubkeys = 1;
int64 ty = 2;
int64 timestamp = 3;
int64 cycle = 4;
}
message JsonVrfInfo {
int64 Index = 1;
string pubkey = 2;
int64 cycle = 4;
int64 height = 5;
string m = 6;
string r = 7;
string p = 8;
int64 time = 9;
}
message DposVrfReply{
repeated VrfInfo vrf = 1;
repeated JsonVrfInfo vrf = 1;
}
\ No newline at end of file
......@@ -38,6 +38,11 @@ const (
const (
VoteFrozenTime = 3 * 24 * 3600
RegistFrozenCoins = 1000000000000
VoteTypeNone int32 = 1
VoteTypeVote int32 = 2
VoteTypeCancelVote int32 = 3
VoteTypeCancelAllVote int32 = 4
)
//包的名字可以通过配置文件来配置
//建议用github的组织名称,或者用户名字开头, 再加上自己的插件的名字
......@@ -60,6 +65,12 @@ const (
//FuncNameQueryVrfByCycle func name
FuncNameQueryVrfByCycle = "QueryVrfByCycle"
//FuncNameQueryVrfByCycleForTopN func name
FuncNameQueryVrfByCycleForTopN = "QueryVrfByCycleForTopN"
//FuncNameQueryVrfByCycleForPubkeys func name
FuncNameQueryVrfByCycleForPubkeys = "QueryVrfByCycleForPubkeys"
//FuncNameQueryVote func name
FuncNameQueryVote = "QueryVote"
......@@ -84,9 +95,15 @@ const (
//CreateRegistVrfRPTx 创建注册Vrf的R/P信息的交易
CreateRegistVrfRPTx = "RegistVrfRP"
//QueryVrfByTime 创建根据time查询Vrf信息查询
//QueryVrfByTime 创建根据time查询Vrf信息
QueryVrfByTime = 1
//QueryVrfByCycle 创建根据cycle查询Vrf信息查询
//QueryVrfByCycle 创建根据cycle查询Vrf信息
QueryVrfByCycle = 2
//QueryVrfByCycleForTopN 创建根据cycle查询当前topN的候选节点的Vrf信息
QueryVrfByCycleForTopN = 3
//QueryVrfByCycleForPubkeys 创建根据cycle查询指定pubkey的多个候选节点的Vrf信息
QueryVrfByCycleForPubkeys = 4
)
This diff is collapsed.
......@@ -8,6 +8,7 @@ import "errors"
// Errors for Dpos
var (
ErrNoSuchVote = errors.New("ErrNoSuchVote")
ErrNotEnoughVotes = errors.New("ErrNotEnoughVotes")
ErrCandidatorExist = errors.New("ErrCandidatorExist")
ErrCandidatorInvalidStatus = errors.New("ErrCandidatorInvalidStatus")
......
......@@ -126,7 +126,7 @@ var opt_dpos_vrfm = &table.Option{
Prefix: "LODB-dpos",
Name: "vrfm",
Primary: "index",
Index: []string{"pubkey_cycle"},
Index: []string{"pubkey_cycle","cycle"},
}
//NewDposVrfMTable 新建表
......@@ -169,6 +169,8 @@ func (tx *DposVrfMRow) Get(key string) ([]byte, error) {
return []byte(fmt.Sprintf("%018d", tx.Index)), nil
} else if key == "pubkey_cycle" {
return []byte(fmt.Sprintf("%X:%018d", tx.Pubkey, tx.Cycle)), nil
} else if key == "cycle" {
return []byte(fmt.Sprintf("%018d", tx.Cycle)), nil
}
return nil, types.ErrNotFound
......@@ -179,7 +181,7 @@ var opt_dpos_vrfrp = &table.Option{
Prefix: "LODB-dpos",
Name: "vrfrp",
Primary: "index",
Index: []string{"pubkey_cycle"},
Index: []string{"pubkey_cycle", "cycle"},
}
//NewDposVrfRPTable 新建表
......@@ -222,6 +224,8 @@ func (tx *DposVrfRPRow) Get(key string) ([]byte, error) {
return []byte(fmt.Sprintf("%018d", tx.Index)), nil
} else if key == "pubkey_cycle" {
return []byte(fmt.Sprintf("%X:%018d", tx.Pubkey, tx.Cycle)), nil
} else if key == "cycle" {
return []byte(fmt.Sprintf("%018d", tx.Cycle)), nil
}
return nil, types.ErrNotFound
......
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