Commit 66d7594d authored by madengji's avatar madengji Committed by 33cn

correct collect addr error

parent 5ea68097
......@@ -93,7 +93,7 @@ type subConfig struct {
MultiDownServerRspTime uint32 `json:"multiDownServerRspTime,omitempty"`
RmCommitParamMainHeight int64 `json:"rmCommitParamMainHeight,omitempty"`
JumpDownloadClose bool `json:"jumpDownloadClose,omitempty"`
BlsSignOff bool `json:"blsSignOff,omitempty"`
BlsSign bool `json:"blsSign,omitempty"`
BlsLeaderSwitchInt int32 `json:"blsLeaderSwitchInt,omitempty"`
}
......
......@@ -24,8 +24,9 @@ const (
maxRcvTxCount = 100 //channel buffer, max 100 nodes, 1 height tx or 1 txgroup per node
leaderSyncInt = 15 //15s heartbeat sync interval
defLeaderSwitchInt = 100 //每隔100个共识高度切换一次leader,大约6小时(按50个空块间隔计算)
delaySubP2pTopic = 30 //30s to sub p2p topic
defaultParaBlsSignTopic = "PARA-BLS-SIGN-TOPIC"
paraBlsSignTopic = "PARA-BLS-SIGN-TOPIC"
)
//新增需要保证顺序
......@@ -82,7 +83,7 @@ func (b *blsClient) procLeaderSync() {
var feedDogTicker <-chan time.Time
var watchDogTicker <-chan time.Time
p2pTimer := time.After(time.Minute)
p2pTimer := time.After(delaySubP2pTopic * time.Second)
out:
for {
select {
......@@ -92,7 +93,7 @@ out:
if isLeader {
act := &pt.ParaP2PSubMsg{Ty: P2pSubLeaderSyncMsg}
act.Value = &pt.ParaP2PSubMsg_SyncMsg{SyncMsg: &pt.LeaderSyncInfo{ID: b.selfID, BaseIdx: base, Offset: off}}
err := b.paraClient.SendPubP2PMsg(defaultParaBlsSignTopic, types.Encode(act))
err := b.paraClient.SendPubP2PMsg(paraBlsSignTopic, types.Encode(act))
if err != nil {
plog.Error("para.procLeaderSync feed dog", "err", err)
}
......@@ -112,10 +113,10 @@ out:
atomic.StoreUint32(&b.feedDog, 0)
case <-p2pTimer:
err := b.paraClient.SendSubP2PTopic(defaultParaBlsSignTopic)
err := b.paraClient.SendSubP2PTopic(paraBlsSignTopic)
if err != nil {
plog.Error("procLeaderSync.SubP2PTopic", "err", err)
p2pTimer = time.After(time.Minute)
p2pTimer = time.After(delaySubP2pTopic * time.Second)
continue
}
feedDogTicker = time.NewTicker(leaderSyncInt * time.Second).C
......@@ -201,7 +202,7 @@ out:
if isLeader {
b.sendAggregateTx(nodes)
}
//聚合签名总共消耗大约1.5ms
//清空txsBuff,重新收集
b.commitsPool = make(map[int64]*pt.ParaBlsSignSumDetails)
b.mutex.Unlock()
......@@ -218,7 +219,7 @@ func (b *blsClient) sendAggregateTx(nodes []string) error {
if len(dones) <= 0 {
return nil
}
acts, err := b.AggregateCommit2Action(nodes, dones)
acts, err := aggregateCommit2Action(nodes, dones)
if err != nil {
plog.Error("sendAggregateTx AggregateCommit2Action", "err", err)
return err
......@@ -273,7 +274,7 @@ func (b *blsClient) checkCommitTx(txs []*types.Transaction) ([]*pt.ParacrossComm
if tx.From() != commit.Bls.Addrs[0] {
return nil, errors.Wrapf(types.ErrFromAddr, "from=%s,bls addr=%s", tx.From(), commit.Bls.Addrs[0])
}
//验证bls 签名
//验证bls 签名,大概40ms, 是secp 80倍
err = b.verifyBlsSign(tx.From(), commit)
if err != nil {
return nil, errors.Wrapf(pt.ErrBlsSignVerify, "from=%s", tx.From())
......@@ -284,6 +285,15 @@ func (b *blsClient) checkCommitTx(txs []*types.Transaction) ([]*pt.ParacrossComm
return commits, nil
}
func hasCommited(addrs []string, addr string) (bool, int) {
for i, a := range addrs {
if a == addr {
return true, i
}
}
return false, 0
}
//整合相同高度commits
func integrateCommits(pool map[int64]*pt.ParaBlsSignSumDetails, commits []*pt.ParacrossCommitAction) {
for _, cmt := range commits {
......@@ -291,14 +301,13 @@ func integrateCommits(pool map[int64]*pt.ParaBlsSignSumDetails, commits []*pt.Pa
pool[cmt.Status.Height] = &pt.ParaBlsSignSumDetails{Height: cmt.Status.Height}
}
a := pool[cmt.Status.Height]
for i, v := range a.Addrs {
//节点更新交易参数的场景
if v == cmt.Bls.Addrs[0] {
found, i := hasCommited(a.Addrs, cmt.Bls.Addrs[0])
if found {
a.Msgs[i] = types.Encode(cmt.Status)
a.Signs[i] = cmt.Bls.Sign
continue
}
}
a.Addrs = append(a.Addrs, cmt.Bls.Addrs[0])
a.Msgs = append(a.Msgs, types.Encode(cmt.Status))
a.Signs = append(a.Signs, cmt.Bls.Sign)
......@@ -322,26 +331,25 @@ func isMostCommitDone(peers int, txsBuff map[int64]*pt.ParaBlsSignSumDetails) bo
}
//找出共识并达到2/3的commits, 并去除与共识不同的commits,为后面聚合签名做准备
func filterDoneCommits(peers int, txs map[int64]*pt.ParaBlsSignSumDetails) []*pt.ParaBlsSignSumDetails {
func filterDoneCommits(peers int, pool map[int64]*pt.ParaBlsSignSumDetails) []*pt.ParaBlsSignSumDetails {
var seq []int64
for i, v := range txs {
for i, v := range pool {
most, hash := getMostCommit(v.Msgs)
if !isCommitDone(peers, most) {
plog.Debug("blssign.filterDoneCommits not commit done", "height", i)
delete(txs, i)
continue
}
seq = append(seq, i)
//只保留与most相同的commits做聚合签名使用
a := &pt.ParaBlsSignSumDetails{Msgs: [][]byte{[]byte(hash)}}
a := &pt.ParaBlsSignSumDetails{Height: i, Msgs: [][]byte{[]byte(hash)}}
for j, m := range v.Msgs {
if bytes.Equal([]byte(hash), m) {
a.Addrs = append(a.Addrs, v.Addrs[j])
a.Signs = append(a.Signs, v.Signs[j])
}
}
txs[i] = a
pool[i] = a
}
if len(seq) <= 0 {
......@@ -350,7 +358,6 @@ func filterDoneCommits(peers int, txs map[int64]*pt.ParaBlsSignSumDetails) []*pt
//从低到高找出连续的commits
sort.Slice(seq, func(i, j int) bool { return seq[i] < seq[j] })
plog.Debug("blssign.filterDoneCommits", "seq", seq)
var signs []*pt.ParaBlsSignSumDetails
//共识高度要连续,不连续则退出
lastSeq := seq[0] - 1
......@@ -358,7 +365,7 @@ func filterDoneCommits(peers int, txs map[int64]*pt.ParaBlsSignSumDetails) []*pt
if lastSeq+1 != h {
return signs
}
signs = append(signs, txs[h])
signs = append(signs, pool[h])
lastSeq = h
}
return signs
......@@ -366,7 +373,7 @@ func filterDoneCommits(peers int, txs map[int64]*pt.ParaBlsSignSumDetails) []*pt
}
//聚合多个签名为一个签名,并设置地址bitmap
func (b *blsClient) AggregateCommit2Action(nodes []string, commits []*pt.ParaBlsSignSumDetails) ([]*pt.ParacrossCommitAction, error) {
func aggregateCommit2Action(nodes []string, commits []*pt.ParaBlsSignSumDetails) ([]*pt.ParacrossCommitAction, error) {
var notify []*pt.ParacrossCommitAction
for _, v := range commits {
......@@ -375,13 +382,14 @@ func (b *blsClient) AggregateCommit2Action(nodes []string, commits []*pt.ParaBls
types.Decode(v.Msgs[0], s)
a.Status = s
sign, err := b.aggregateSigns(v.Signs)
sign, err := aggregateSigns(v.Signs)
if err != nil {
return nil, errors.Wrapf(err, "bls aggreate=%s", v.Addrs)
return nil, errors.Wrapf(err, "bls aggregate=%s", v.Addrs)
}
signData := sign.Serialize()
a.Bls.Sign = append(a.Bls.Sign, signData[:]...)
bits, remains := setAddrsBitMap(nodes, v.Addrs)
plog.Debug("AggregateCommit2Action", "nodes", nodes, "addr", v.Addrs, "bits", common.ToHex(bits), "height", v.Height)
if len(remains) > 0 {
plog.Info("bls.signDoneCommits", "remains", remains)
}
......@@ -391,7 +399,7 @@ func (b *blsClient) AggregateCommit2Action(nodes []string, commits []*pt.ParaBls
return notify, nil
}
func (b *blsClient) aggregateSigns(signs [][]byte) (*g2pubs.Signature, error) {
func aggregateSigns(signs [][]byte) (*g2pubs.Signature, error) {
var signatures []*g2pubs.Signature
for _, data := range signs {
var s [48]byte
......
......@@ -188,11 +188,11 @@ func (client *commitMsgClient) createCommitTx() {
return
}
//bls sign, send to p2p
if !client.paraClient.subCfg.BlsSignOff {
if client.paraClient.subCfg.BlsSign {
//send to p2p pubsub
plog.Info("para commitMs send to p2p", "hash", common.ToHex(tx.Hash()))
act := &pt.ParaP2PSubMsg{Ty: P2pSubCommitTx, Value: &pt.ParaP2PSubMsg_CommitTx{CommitTx: tx}}
client.paraClient.SendPubP2PMsg(defaultParaBlsSignTopic, types.Encode(act))
client.paraClient.SendPubP2PMsg(paraBlsSignTopic, types.Encode(act))
return
}
client.pushCommitTx(tx)
......@@ -314,15 +314,7 @@ func (client *commitMsgClient) reSendCommitTx(tx *types.Transaction) bool {
if client.checkTxCommitTimes < client.waitMainBlocks {
return false
}
client.checkTxCommitTimes = 0
//bls聚合签名场景,发送未成功上链,继续发送交易
if !client.paraClient.subCfg.BlsSignOff {
//resend tx
client.sendMsgCh <- tx
return false
}
//非聚合签名场景,发送未成功,触发重新构建交易发送
client.resetSendEnv()
return true
}
......@@ -429,7 +421,7 @@ func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*type
commits = append(commits, &pt.ParacrossCommitAction{Status: stat})
}
if !client.paraClient.subCfg.BlsSignOff {
if client.paraClient.subCfg.BlsSign {
err = client.paraClient.blsSignCli.blsSign(commits)
if err != nil {
plog.Error("paracommitmsg bls sign", "err", err)
......
......@@ -7,8 +7,6 @@ package para
import (
"testing"
"encoding/hex"
"github.com/33cn/chain33/queue"
_ "github.com/33cn/chain33/system"
drivers "github.com/33cn/chain33/system/consensus"
......@@ -73,10 +71,3 @@ func TestSetSelfConsEnable(t *testing.T) {
assert.Equal(t, ep1, para.commitMsgClient.selfConsEnableList)
}
func TestSetAddrsBitMap(t *testing.T) {
nodes := []string{"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4", "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR", "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k", "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"}
addrs := []string{"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}
val, remain := setAddrsBitMap(nodes, addrs)
t.Log("val", hex.EncodeToString(val), "remain", remain)
}
......@@ -7,6 +7,7 @@ package executor
import (
"bytes"
"encoding/hex"
"strings"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
......@@ -300,6 +301,9 @@ func (a *action) getNodesGroup(title string) (map[string]struct{}, []string, err
//相同的BlockHash,只保留一份数据
func updateCommitBlockHashs(stat *pt.ParacrossHeightStatus, commit *pt.ParacrossNodeStatus) {
if stat.BlockDetails == nil {
stat.BlockDetails = &pt.ParacrossStatusBlockDetails{}
}
for _, blockHash := range stat.BlockDetails.BlockHashs {
if bytes.Equal(blockHash, commit.BlockHash) {
return
......@@ -343,30 +347,21 @@ func paraCheckSelfConsOn(cfg *types.Chain33Config, db dbm.KV, commit *pt.Paracro
return true, nil, nil
}
func (a *action) preCheckCommitInfo(commit *pt.ParacrossNodeStatus, commitAddr string) error {
func (a *action) preCheckCommitInfo(commit *pt.ParacrossNodeStatus, commitAddrs []string) error {
cfg := a.api.GetConfig()
err := checkCommitInfo(cfg, commit)
if err != nil {
return err
}
nodesMap, _, err := a.getNodesGroup(commit.Title)
if err != nil {
return err
}
//允许a.fromAddr非nodegroup成员,将来也许可以代nodegroup提交共识交易
if !validNode(commitAddr, nodesMap) {
return errors.Wrapf(pt.ErrNodeNotForTheTitle, "not validNode:%s", commitAddr)
}
titleStatus, err := getTitle(a.db, calcTitleKey(commit.Title))
if err != nil {
return errors.Wrapf(err, "getTitle:%s", commitAddr)
return errors.Wrapf(err, "getTitle=%s", commit.Title)
}
if titleStatus.Height+1 == commit.Height && commit.Height > 0 && !pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
if !bytes.Equal(titleStatus.BlockHash, commit.PreBlockHash) {
clog.Error("paracross.Commit", "check PreBlockHash", common.ToHex(titleStatus.BlockHash),
"commit tx", common.ToHex(commit.PreBlockHash), "commitheit", commit.Height, "from", commitAddr)
"commit tx", common.ToHex(commit.PreBlockHash), "commitheit", commit.Height, "from", commitAddrs)
return pt.ErrParaBlockHashNoMatch
}
}
......@@ -379,7 +374,7 @@ func (a *action) preCheckCommitInfo(commit *pt.ParacrossNodeStatus, commitAddr s
if !cfg.IsPara() {
blockHash, err := getBlockHash(a.api, commit.MainBlockHeight)
if err != nil {
clog.Error("paracross.Commit getBlockHash", "err", err, "commit tx height", commit.MainBlockHeight, "from", commitAddr)
clog.Error("paracross.Commit getBlockHash", "err", err, "commit tx height", commit.MainBlockHeight, "from", commitAddrs)
return err
}
dbMainHash = blockHash.Hash
......@@ -387,7 +382,7 @@ func (a *action) preCheckCommitInfo(commit *pt.ParacrossNodeStatus, commitAddr s
} else {
block, err := getBlockInfo(a.api, commit.Height)
if err != nil {
clog.Error("paracross.Commit getBlockInfo", "err", err, "height", commit.Height, "from", commitAddr)
clog.Error("paracross.Commit getBlockInfo", "err", err, "height", commit.Height, "from", commitAddrs)
return err
}
dbMainHash = block.MainHash
......@@ -398,13 +393,80 @@ func (a *action) preCheckCommitInfo(commit *pt.ParacrossNodeStatus, commitAddr s
if !bytes.Equal(dbMainHash, commit.MainBlockHash) && commit.Height > 0 {
clog.Error("paracross.Commit blockHash not match", "isMain", !cfg.IsPara(), "db", common.ToHex(dbMainHash),
"commit", common.ToHex(commit.MainBlockHash), "commitHeight", commit.Height,
"commitMainHeight", commit.MainBlockHeight, "from", commitAddr)
"commitMainHeight", commit.MainBlockHeight, "from", commitAddrs)
return types.ErrBlockHashNoMatch
}
return nil
}
func getValidAddrs(nodes map[string]struct{}, addrs []string) []string {
var ret []string
for _, addr := range addrs {
if !validNode(addr, nodes) {
clog.Error("paracross.Commit getValidAddrs not valid", "addr", addr)
continue
}
ret = append(ret, addr)
}
return ret
}
//bls签名共识交易验证 大约耗时100ms
func (a *action) verifyBlsSign(commit *pt.ParacrossCommitAction) ([]string, error) {
_, nodesArry, err := a.getNodesGroup(commit.Status.Title)
if err != nil {
return nil, errors.Wrapf(err, "getNodegroup")
}
//1. 获取addr对应的bls 公钥
signAddrs := getAddrsByBitMap(nodesArry, commit.Bls.AddrsMap)
var pubs []string
for _, addr := range signAddrs {
pub, err := getAddrBlsPubKey(a.db, commit.Status.Title, addr)
if err != nil {
return nil, errors.Wrapf(err, "pubkey not exist to addr=%s", addr)
}
pubs = append(pubs, pub)
}
pubKeys := make([]*g2pubs.PublicKey, 0)
for _, p := range pubs {
k := [96]byte{}
val, err := common.FromHex(p)
if err != nil {
return nil, errors.Wrapf(err, "fromhex.p=%s", p)
}
copy(k[:], val)
key, err := g2pubs.DeserializePublicKey(k)
if err != nil {
return nil, errors.Wrapf(err, "DeserializePublicKey=%s", p)
}
pubKeys = append(pubKeys, key)
}
//2. 聚合公钥
aPub := g2pubs.AggregatePublicKeys(pubKeys)
//3. 获取聚合的签名
signkey := [48]byte{}
copy(signkey[:], commit.Bls.Sign)
sign, err := g2pubs.DeserializeSignature(signkey)
if err != nil {
return nil, errors.Wrapf(err, "DeserializeSignature,key=%s", common.ToHex(commit.Bls.Sign))
}
//4. 获取签名前原始msg
msg := types.Encode(commit.Status)
if !g2pubs.Verify(msg, aPub, sign) {
clog.Error("paracross.Commit bls sign verify", "title", commit.Status.Title, "height", commit.Status.Height,
"addrsMap", common.ToHex(commit.Bls.AddrsMap), "sign", common.ToHex(commit.Bls.Sign), "addr", signAddrs, "nodes", nodesArry)
clog.Error("paracross.commit bls sign verify", "data", common.ToHex(msg), "height", commit.Status.Height, "from", a.fromaddr)
return nil, pt.ErrBlsSignVerify
}
return signAddrs, nil
}
//共识commit msg 处理
func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
......@@ -412,58 +474,50 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
if cfg.IsPara() {
isSelfConsOn, receipt, err := paraCheckSelfConsOn(cfg, a.db, commit.Status)
if !isSelfConsOn {
return receipt, err
}
return receipt, errors.Wrap(err, "checkSelfConsOn")
}
if commit.Bls != nil {
return a.commitBls(commit)
}
return a.proCommitMsg(commit.Status, a.fromaddr)
}
//bls签名共识交易处理
func (a *action) commitBls(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
commitAddrs, err := a.verifyBlsSign(commit)
//获取commitAddrs, bls sign 包含多个账户的聚合签名
commitAddrs := []string{a.fromaddr}
if commit.Bls != nil {
addrs, err := a.verifyBlsSign(commit)
if err != nil {
clog.Error("paracross.Commit verifyBlsSign failed", "err", err)
return nil, err
return nil, errors.Wrap(err, "verifyBlsSign")
}
receipt := &types.Receipt{Ty: types.ExecOk}
for _, addr := range commitAddrs {
r, err := a.proCommitMsg(commit.Status, addr)
commitAddrs = addrs
}
nodesMap, _, err := a.getNodesGroup(commit.Status.Title)
if err != nil {
clog.Error("paracross.CommitBls proCommitMsg failed", "err", err)
return nil, err
return nil, errors.Wrap(err, "getNodesGroup")
}
receipt = mergeReceipt(receipt, r)
correctAddrs := getValidAddrs(nodesMap, commitAddrs)
if len(correctAddrs) <= 0 {
return nil, errors.Wrapf(err, "getValidAddrs nil commitAddrs=%s", strings.Join(commitAddrs, ","))
}
return receipt, nil
return a.proCommitMsg(commit.Status, nodesMap, correctAddrs)
}
func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, commitAddr string) (*types.Receipt, error) {
func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, nodes map[string]struct{}, commitAddrs []string) (*types.Receipt, error) {
cfg := a.api.GetConfig()
err := a.preCheckCommitInfo(commit, commitAddr)
if err != nil {
return nil, err
}
nodes, _, err := a.getNodesGroup(commit.Title)
err := a.preCheckCommitInfo(commit, commitAddrs)
if err != nil {
return nil, err
}
titleStatus, err := getTitle(a.db, calcTitleKey(commit.Title))
if err != nil {
return nil, errors.Wrapf(err, "getTitle:%s", a.fromaddr)
return nil, errors.Wrapf(err, "getTitle:%s", commit.Title)
}
// 在完成共识之后来的, 增加 record log, 只记录不修改已经达成的共识
if commit.Height <= titleStatus.Height {
clog.Debug("paracross.Commit record", "node", commitAddr, "titile", commit.Title, "height", commit.Height)
return makeRecordReceipt(commitAddr, commit), nil
clog.Debug("paracross.Commit record", "node", commitAddrs, "titile", commit.Title, "height", commit.Height)
return makeRecordReceipt(strings.Join(commitAddrs, ","), commit), nil
}
// 未共识处理, 接受当前高度以及后续高度
......@@ -474,47 +528,40 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, commitAddr string)
}
var receipt *types.Receipt
var copyStat *pt.ParacrossHeightStatus
if isNotFound(err) {
stat = &pt.ParacrossHeightStatus{
Status: pt.ParacrossStatusCommiting,
Title: commit.Title,
Height: commit.Height,
Details: &pt.ParacrossStatusDetails{
Addrs: []string{commitAddr},
BlockHash: [][]byte{commit.BlockHash},
},
Details: &pt.ParacrossStatusDetails{},
}
if pt.IsParaForkHeight(cfg, a.exec.GetMainHeight(), pt.ForkCommitTx) {
stat.MainHeight = commit.MainBlockHeight
stat.MainHash = commit.MainBlockHash
}
//用commit.MainBlockHeight 判断更准确,如果用a.exec.MainHeight也可以,但是可能收到MainHeight之前的高度共识tx,
// 后面loopCommitTxDone时候也是用当前共识高度大于分叉高度判断
if pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
stat.BlockDetails = &pt.ParacrossStatusBlockDetails{}
updateCommitBlockHashs(stat, commit)
} else {
copyStat = proto.Clone(stat).(*pt.ParacrossHeightStatus)
}
receipt = makeCommitReceipt(commitAddr, commit, nil, stat)
} else {
copyStat := proto.Clone(stat).(*pt.ParacrossHeightStatus)
for _, addr := range commitAddrs {
// 如有分叉, 同一个节点可能再次提交commit交易
found, index := hasCommited(stat.Details.Addrs, commitAddr)
found, index := hasCommited(stat.Details.Addrs, addr)
if found {
stat.Details.BlockHash[index] = commit.BlockHash
if pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
updateCommitBlockHashs(stat, commit)
}
} else {
stat.Details.Addrs = append(stat.Details.Addrs, commitAddr)
stat.Details.Addrs = append(stat.Details.Addrs, addr)
stat.Details.BlockHash = append(stat.Details.BlockHash, commit.BlockHash)
if pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
updateCommitBlockHashs(stat, commit)
}
}
receipt = makeCommitReceipt(commitAddr, commit, copyStat, stat)
//用commit.MainBlockHeight 判断更准确,如果用a.exec.MainHeight也可以,但是可能收到MainHeight之前的高度共识tx,
// 后面loopCommitTxDone时候也是用当前共识高度大于分叉高度判断
if pt.IsParaForkHeight(cfg, commit.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
updateCommitBlockHashs(stat, commit)
}
receipt = makeCommitReceipt(strings.Join(commitAddrs, ","), commit, copyStat, stat)
//平行链fork pt.ForkCommitTx=0,主链在ForkCommitTx后支持nodegroup,这里平行链dappFork一定为true
if cfg.IsDappFork(commit.MainBlockHeight, pt.ParaX, pt.ForkCommitTx) {
updateCommitAddrs(stat, nodes)
......@@ -546,60 +593,6 @@ func (a *action) proCommitMsg(commit *pt.ParacrossNodeStatus, commitAddr string)
return receipt, nil
}
func (a *action) verifyBlsSign(commit *pt.ParacrossCommitAction) ([]string, error) {
_, nodesArry, err := a.getNodesGroup(commit.Status.Title)
if err != nil {
return nil, errors.Wrapf(err, "getNodegroup")
}
//1. 获取addr对应的bls 公钥
signAddrs := getAddrsByBitMap(nodesArry, commit.Bls.AddrsMap)
var pubs []string
for _, addr := range signAddrs {
pub, err := getAddrBlsPubKey(a.db, commit.Status.Title, addr)
if err != nil {
return nil, errors.Wrapf(err, "pubkey not exist to addr=%s", addr)
}
pubs = append(pubs, pub)
}
pubKeys := make([]*g2pubs.PublicKey, 0)
for _, p := range pubs {
k := [96]byte{}
val, err := common.FromHex(p)
if err != nil {
return nil, errors.Wrapf(err, "fromhex.p=%s", p)
}
copy(k[:], val)
key, err := g2pubs.DeserializePublicKey(k)
if err != nil {
return nil, errors.Wrapf(err, "DeserializePublicKey=%s", p)
}
pubKeys = append(pubKeys, key)
}
//2. 聚合公钥
aPub := g2pubs.AggregatePublicKeys(pubKeys)
//3. 获取聚合的签名
signkey := [48]byte{}
copy(signkey[:], commit.Bls.Sign)
sign, err := g2pubs.DeserializeSignature(signkey)
if err != nil {
return nil, errors.Wrapf(err, "DeserializeSignature,key=%s", common.ToHex(commit.Bls.Sign))
}
//4. 获取签名前原始msg
msg := types.Encode(commit.Status)
if !g2pubs.Verify(msg, aPub, sign) {
clog.Error("paracross.Commit bls sign verify", "title", commit.Status.Title, "height", commit.Status.Height,
"addrsMap", common.ToHex(commit.Bls.AddrsMap), "sign", common.ToHex(commit.Bls.Sign), "addr", signAddrs, "nodes", nodesArry)
clog.Error("paracross.commit bls sign verify", "data", common.ToHex(msg), "height", commit.Status.Height)
return nil, pt.ErrBlsSignVerify
}
return signAddrs, nil
}
//分叉以前stat里面只记录了blockhash的信息,没有crossTxHash等信息,无法通过stat直接重构出mostCommitStatus
func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus, titleStatus *pt.ParacrossStatus,
nodes map[string]struct{}) (*types.Receipt, error) {
......@@ -610,12 +603,11 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
clog.Debug("paracross.Commit commit detail", "addr", v, "hash", common.ToHex(stat.Details.BlockHash[i]))
}
commitCount := len(stat.Details.Addrs)
most, mostHash := GetMostCommit(stat.Details.BlockHash)
if !isCommitDone(len(nodes), most) {
mostCount, mostHash := GetMostCommit(stat.Details.BlockHash)
if !isCommitDone(len(nodes), mostCount) {
return receipt, nil
}
clog.Debug("paracross.Commit commit ----pass", "most", most, "mostHash", common.ToHex([]byte(mostHash)))
clog.Debug("paracross.Commit commit ----pass", "most", mostCount, "mostHash", common.ToHex([]byte(mostHash)))
stat.Status = pt.ParacrossStatusCommitDone
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
......@@ -627,7 +619,7 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
}
//add commit done receipt
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, nodeStatus, int32(most), int32(commitCount), int32(len(nodes)))
receiptDone := makeDoneReceipt(cfg, a.exec.GetMainHeight(), a.height, nodeStatus, int32(mostCount), int32(len(stat.Details.Addrs)), int32(len(nodes)))
receipt = mergeReceipt(receipt, receiptDone)
r, err := a.commitTxDoneStep2(nodeStatus, stat, titleStatus)
......@@ -864,25 +856,25 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossNodeStatus, titleStatus
}
func execCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
if !bytes.HasSuffix(tx.Tx.Execer, []byte(pt.ParaX)) {
func execCrossTx(a *action, cross *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
if !bytes.HasSuffix(cross.Tx.Execer, []byte(pt.ParaX)) {
return nil, nil
}
var payload pt.ParacrossAction
err := types.Decode(tx.Tx.Payload, &payload)
err := types.Decode(cross.Tx.Payload, &payload)
if err != nil {
clog.Crit("paracross.Commit Decode Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err
}
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(tx.Tx.Execer))
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(cross.Tx.Execer))
if err != nil {
clog.Crit("paracross.Commit getCrossAction Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err
}
if act == pt.ParacrossMainAssetWithdraw || act == pt.ParacrossParaAssetTransfer {
receipt, err := a.crossAssetTransfer(payload.GetCrossAssetTransfer(), act, tx.Tx)
receipt, err := a.crossAssetTransfer(payload.GetCrossAssetTransfer(), act, cross.Tx)
if err != nil {
clog.Crit("paracross.Commit crossAssetTransfer Tx failed", "error", err, "act", act, "txHash", common.ToHex(crossTxHash))
return nil, err
......@@ -895,7 +887,7 @@ func execCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*t
//主链共识后,执行主链资产withdraw, 在支持CrossAssetTransfer之前使用此action
if payload.Ty == pt.ParacrossActionAssetWithdraw {
receiptWithdraw, err := a.assetWithdraw(payload.GetAssetWithdraw(), tx.Tx)
receiptWithdraw, err := a.assetWithdraw(payload.GetAssetWithdraw(), cross.Tx)
if err != nil {
clog.Crit("paracross.Commit withdraw Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
......@@ -908,26 +900,26 @@ func execCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*t
}
func rollbackCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
if !bytes.HasSuffix(tx.Tx.Execer, []byte(pt.ParaX)) {
func rollbackCrossTx(a *action, cross *types.TransactionDetail, crossTxHash []byte) (*types.Receipt, error) {
if !bytes.HasSuffix(cross.Tx.Execer, []byte(pt.ParaX)) {
return nil, nil
}
var payload pt.ParacrossAction
err := types.Decode(tx.Tx.Payload, &payload)
err := types.Decode(cross.Tx.Payload, &payload)
if err != nil {
clog.Crit("paracross.Commit.rollbackCrossTx Decode Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err
}
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(tx.Tx.Execer))
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(cross.Tx.Execer))
if err != nil {
clog.Crit("paracross.Commit.rollbackCrossTx getCrossAction failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err
}
//主链共识后,平行链执行出错的主链资产transfer回滚
if act == pt.ParacrossMainAssetTransfer {
receipt, err := a.assetTransferRollback(payload.GetCrossAssetTransfer(), tx.Tx)
receipt, err := a.assetTransferRollback(payload.GetCrossAssetTransfer(), cross.Tx)
if err != nil {
clog.Crit("paracross.Commit crossAssetTransfer rbk failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
......@@ -938,7 +930,7 @@ func rollbackCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte)
}
//主链共识后,平行链执行出错的平行链资产withdraw回滚
if act == pt.ParacrossParaAssetWithdraw {
receipt, err := a.paraAssetWithdrawRollback(payload.GetCrossAssetTransfer(), tx.Tx)
receipt, err := a.paraAssetWithdrawRollback(payload.GetCrossAssetTransfer(), cross.Tx)
if err != nil {
clog.Crit("paracross.Commit rbk paraAssetWithdraw Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
......@@ -951,15 +943,15 @@ func rollbackCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte)
//主链共识后,平行链执行出错的主链资产transfer回滚
if payload.Ty == pt.ParacrossActionAssetTransfer {
assettf := payload.GetAssetTransfer()
cross := &pt.CrossAssetTransfer{
AssetSymbol: assettf.Cointoken,
Amount: assettf.Amount,
Note: string(assettf.Note),
ToAddr: assettf.To,
cfg := payload.GetAssetTransfer()
transfer := &pt.CrossAssetTransfer{
AssetSymbol: cfg.Cointoken,
Amount: cfg.Amount,
Note: string(cfg.Note),
ToAddr: cfg.To,
}
receipt, err := a.assetTransferRollback(cross, tx.Tx)
receipt, err := a.assetTransferRollback(transfer, cross.Tx)
if err != nil {
clog.Crit("paracross.Commit rbk asset transfer Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
......
......@@ -9,7 +9,6 @@ import (
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
)
//Exec_Commit consensus commit tx exec process
......@@ -18,7 +17,7 @@ func (e *Paracross) Exec_Commit(payload *pt.ParacrossCommitAction, tx *types.Tra
receipt, err := a.Commit(payload)
if err != nil {
clog.Error("Paracross commit failed", "error", err, "hash", hex.EncodeToString(tx.Hash()))
return nil, errors.Cause(err)
return nil, err
}
return receipt, nil
}
......
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