Commit 3adcf733 authored by mdj33's avatar mdj33 Committed by vipwzw

add para chain consensus in local

parent bf6dc085
...@@ -174,6 +174,7 @@ func (client *client) SetQueueClient(c queue.Client) { ...@@ -174,6 +174,7 @@ func (client *client) SetQueueClient(c queue.Client) {
func (client *client) InitBlock() { func (client *client) InitBlock() {
var err error var err error
// get main chain calc block hash fork height
mainBlockHashForkHeight, err = client.GetBlockHashForkHeightOnMainChain() mainBlockHashForkHeight, err = client.GetBlockHashForkHeightOnMainChain()
if err != nil { if err != nil {
panic(err) panic(err)
...@@ -341,36 +342,31 @@ func (client *client) GetBlockByHeight(height int64) (*types.Block, error) { ...@@ -341,36 +342,31 @@ func (client *client) GetBlockByHeight(height int64) (*types.Block, error) {
return blockDetails.Items[0].Block, nil return blockDetails.Items[0].Block, nil
} }
func (client *client) getLastBlockInfo() (int64, *types.Block, []byte, int64, error) { func (client *client) getLastBlockInfo() (int64, *types.Block, error) {
lastBlock, err := client.RequestLastBlock() lastBlock, err := client.RequestLastBlock()
if err != nil { if err != nil {
plog.Error("Parachain RequestLastBlock fail", "err", err) plog.Error("Parachain RequestLastBlock fail", "err", err)
return -2, nil, nil, -2, err return -2, nil, err
} }
blockedSeq, err := client.GetBlockedSeq(lastBlock.Hash()) blockedSeq, err := client.GetBlockedSeq(lastBlock.Hash())
if err != nil { if err != nil {
plog.Error("Parachain GetBlockedSeq fail", "err", err) plog.Error("Parachain GetBlockedSeq fail", "err", err)
return -2, nil, nil, -2, err return -2, nil, err
}
if lastBlock.Height > 0 {
miner, err := getMinerTxInfo(lastBlock)
if err != nil {
return -2, nil, nil, -2, err
}
return blockedSeq, lastBlock, miner.MainBlockHash, miner.MainBlockHeight, nil
} }
//sequence in main chain start from 0 if lastBlock.Height > 0 || blockedSeq == -1 {
seq := blockedSeq return blockedSeq, lastBlock, nil
if seq == -1 {
seq = 0
} }
main, err := client.GetBlockOnMainBySeq(seq) // lastBlockHeight=0 创世区块本身没有记录主块hash,有两种场景:
// 1, startSeq=-1,也就是从主链0高度同步区块,主链seq从0开始,此时特殊处理,获取主链seq=0区块,后续对请求seq=0的区块做特殊处理
// 2, startSeq!=-1, 也就是从主链n高度同步区块,此时创世区块倒退一个seq,seq=n-1 可以获取到主链n-1的hash
main, err := client.GetBlockOnMainBySeq(blockedSeq)
if err != nil { if err != nil {
return -2, nil, nil, -2, err return -2, nil, err
} }
return blockedSeq, lastBlock, main.Seq.Hash, main.Detail.Block.Height, nil lastBlock.MainHash = main.Seq.Hash
lastBlock.MainHeight = main.Detail.Block.Height
return blockedSeq, lastBlock, nil
} }
...@@ -502,13 +498,13 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type ...@@ -502,13 +498,13 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type
// for genesis seq=-1 scenario, mainHash not care, as the 0 seq instead of -1 // for genesis seq=-1 scenario, mainHash not care, as the 0 seq instead of -1
// not seq=-1 scenario, mainHash needed // not seq=-1 scenario, mainHash needed
func (client *client) syncFromGenesisBlock() (int64, []byte, error) { func (client *client) syncFromGenesisBlock() (int64, []byte, error) {
lastSeq, _, lastSeqMainHash, _, err := client.getLastBlockInfo() lastSeq, lastBlock, err := client.getLastBlockInfo()
if err != nil { if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err) plog.Error("Parachain getLastBlockInfo fail", "err", err)
return -2, nil, err return -2, nil, err
} }
plog.Info("syncFromGenesisBlock sync from height 0") plog.Info("syncFromGenesisBlock sync from height 0")
return lastSeq + 1, lastSeqMainHash, nil return lastSeq + 1, lastBlock.MainHash, nil
} }
// search base on para block but not last MainBlockHash, last MainBlockHash can not back tracing // search base on para block but not last MainBlockHash, last MainBlockHash can not back tracing
...@@ -530,24 +526,20 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro ...@@ -530,24 +526,20 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro
return -2, nil, err return -2, nil, err
} }
//当前block结构已经有mainHash和MainHeight但是从blockchain获取的block还没有写入,以后如果获取到,可以替换从minerTx获取 //当前block结构已经有mainHash和MainHeight但是从blockchain获取的block还没有写入,以后如果获取到,可以替换从minerTx获取
miner, err := getMinerTxInfo(block) plog.Info("switchHashMatchedBlock", "lastParaBlockHeight", height, "mainHeight",
if err != nil { block.MainHeight, "mainHash", hex.EncodeToString(block.MainHash))
return -2, nil, err mainSeq, err := client.GetSeqByHashOnMainChain(block.MainHash)
}
plog.Info("switchHashMatchedBlock", "lastParaBlock height", miner.Height, "mainHeight",
miner.MainBlockHeight, "mainHash", hex.EncodeToString(miner.MainBlockHash))
mainSeq, err := client.GetSeqByHashOnMainChain(miner.MainBlockHash)
if err != nil { if err != nil {
depth-- depth--
if depth == 0 { if depth == 0 {
plog.Error("switchHashMatchedBlock depth overflow", "last info:mainHeight", miner.MainBlockHeight, plog.Error("switchHashMatchedBlock depth overflow", "last info:mainHeight", block.MainHeight,
"mainHash", hex.EncodeToString(miner.MainBlockHash), "search startHeight", lastBlock.Height, "curHeight", miner.Height, "mainHash", hex.EncodeToString(block.MainHash), "search startHeight", lastBlock.Height, "curHeight", height,
"search depth", searchHashMatchDepth) "search depth", searchHashMatchDepth)
panic("search HashMatchedBlock overflow, re-setting search depth and restart to try") panic("search HashMatchedBlock overflow, re-setting search depth and restart to try")
} }
if height == 1 { if height == 1 {
plog.Error("switchHashMatchedBlock search to height=1 not found", "lastBlockHeight", lastBlock.Height, plog.Error("switchHashMatchedBlock search to height=1 not found", "lastBlockHeight", lastBlock.Height,
"height1 mainHash", hex.EncodeToString(miner.MainBlockHash)) "height1 mainHash", hex.EncodeToString(block.MainHash))
err = client.removeBlocks(0) err = client.removeBlocks(0)
if err != nil { if err != nil {
return currSeq, nil, nil return currSeq, nil, nil
...@@ -565,8 +557,8 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro ...@@ -565,8 +557,8 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro
} }
plog.Info("switchHashMatchedBlock succ", "currHeight", height, "initHeight", lastBlock.Height, plog.Info("switchHashMatchedBlock succ", "currHeight", height, "initHeight", lastBlock.Height,
"new currSeq", mainSeq+1, "new preMainBlockHash", hex.EncodeToString(miner.MainBlockHash)) "new currSeq", mainSeq+1, "new preMainBlockHash", hex.EncodeToString(block.MainHash))
return mainSeq + 1, miner.MainBlockHash, nil return mainSeq + 1, block.MainHash, nil
} }
return -2, nil, paracross.ErrParaCurHashNotMatch return -2, nil, paracross.ErrParaCurHashNotMatch
} }
...@@ -601,11 +593,12 @@ func (client *client) removeBlocks(endHeight int64) error { ...@@ -601,11 +593,12 @@ func (client *client) removeBlocks(endHeight int64) error {
func (client *client) CreateBlock() { func (client *client) CreateBlock() {
incSeqFlag := true incSeqFlag := true
//system startup, take the last added block's seq is ok //system startup, take the last added block's seq is ok
currSeq, _, lastSeqMainHash, _, err := client.getLastBlockInfo() currSeq, lastBlock, err := client.getLastBlockInfo()
if err != nil { if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err.Error()) plog.Error("Parachain getLastBlockInfo fail", "err", err.Error())
return return
} }
lastSeqMainHash := lastBlock.MainHash
for { for {
//should be lastSeq but not LastBlockSeq as del block case the seq is not equal //should be lastSeq but not LastBlockSeq as del block case the seq is not equal
lastSeq, err := client.GetLastSeq() lastSeq, err := client.GetLastSeq()
...@@ -640,7 +633,7 @@ func (client *client) CreateBlock() { ...@@ -640,7 +633,7 @@ func (client *client) CreateBlock() {
lastSeqMainHash = blockOnMain.Detail.Block.ParentHash lastSeqMainHash = blockOnMain.Detail.Block.ParentHash
} }
_, lastBlock, lastBlockMainHash, lastBlockMainHeight, err := client.getLastBlockInfo() _, lastBlock, err := client.getLastBlockInfo()
if err != nil { if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err) plog.Error("Parachain getLastBlockInfo fail", "err", err)
time.Sleep(time.Second) time.Sleep(time.Second)
...@@ -649,11 +642,11 @@ func (client *client) CreateBlock() { ...@@ -649,11 +642,11 @@ func (client *client) CreateBlock() {
plog.Info("Parachain process block", "lastBlockSeq", lastSeq, "curSeq", currSeq, plog.Info("Parachain process block", "lastBlockSeq", lastSeq, "curSeq", currSeq,
"currSeqMainHeight", lastSeqMainHeight, "currSeqMainHash", common.ToHex(lastSeqMainHash), "currSeqMainHeight", lastSeqMainHeight, "currSeqMainHash", common.ToHex(lastSeqMainHash),
"lastBlockMainHeight", lastBlockMainHeight, "lastBlockMainHash", common.ToHex(lastBlockMainHash), "seqTy", blockOnMain.Seq.Type) "lastBlockMainHeight", lastBlock.MainHeight, "lastBlockMainHash", common.ToHex(lastBlock.MainHash), "seqTy", blockOnMain.Seq.Type)
if blockOnMain.Seq.Type == delAct { if blockOnMain.Seq.Type == delAct {
if len(txs) == 0 { if len(txs) == 0 {
if lastSeqMainHeight > lastBlockMainHeight { if lastSeqMainHeight > lastBlock.MainHeight {
incSeqFlag = true incSeqFlag = true
continue continue
} }
...@@ -666,7 +659,7 @@ func (client *client) CreateBlock() { ...@@ -666,7 +659,7 @@ func (client *client) CreateBlock() {
} }
} else if blockOnMain.Seq.Type == addAct { } else if blockOnMain.Seq.Type == addAct {
if len(txs) == 0 { if len(txs) == 0 {
if lastSeqMainHeight-lastBlockMainHeight < emptyBlockInterval { if lastSeqMainHeight-lastBlock.MainHeight < emptyBlockInterval {
incSeqFlag = true incSeqFlag = true
continue continue
} }
...@@ -826,18 +819,3 @@ func checkMinerTx(current *types.BlockDetail) error { ...@@ -826,18 +819,3 @@ func checkMinerTx(current *types.BlockDetail) error {
} }
return nil return nil
} }
func getMinerTxInfo(block *types.Block) (*paracross.ParacrossNodeStatus, error) {
baseTx := block.Txs[0]
//判断交易类型和执行情况
var action paracross.ParacrossAction
err := types.Decode(baseTx.GetPayload(), &action)
if err != nil {
return nil, err
}
if action.GetTy() != paracross.ParacrossActionMiner {
return nil, paracross.ErrParaMinerTxType
}
return action.GetMiner().Status, nil
}
...@@ -227,7 +227,7 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T ...@@ -227,7 +227,7 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T
func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int, error) { func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int, error) {
var rawTxs types.Transactions var rawTxs types.Transactions
for _, status := range notifications { for _, status := range notifications {
tx, err := paracross.CreateRawCommitTx4MainChain(status, pt.ParaX, 0) tx, err := paracross.CreateRawCommitTx4MainChain(status, paracross.GetExecName(), 0)
if err != nil { if err != nil {
plog.Error("para get commit tx", "block height", status.Height) plog.Error("para get commit tx", "block height", status.Height)
return nil, 0, err return nil, 0, err
...@@ -243,7 +243,7 @@ func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNod ...@@ -243,7 +243,7 @@ func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNod
} }
func (client *commitMsgClient) singleCalcTx(status *pt.ParacrossNodeStatus) (*types.Transaction, error) { func (client *commitMsgClient) singleCalcTx(status *pt.ParacrossNodeStatus) (*types.Transaction, error) {
tx, err := paracross.CreateRawCommitTx4MainChain(status, pt.ParaX, 0) tx, err := paracross.CreateRawCommitTx4MainChain(status, paracross.GetExecName(), 0)
if err != nil { if err != nil {
plog.Error("para get commit tx", "block height", status.Height) plog.Error("para get commit tx", "block height", status.Height)
return nil, err return nil, err
...@@ -480,19 +480,15 @@ out: ...@@ -480,19 +480,15 @@ out:
req.FuncName = "GetTitle" req.FuncName = "GetTitle"
req.Param = types.Encode(&types.ReqString{Data: types.GetTitle()}) req.Param = types.Encode(&types.ReqString{Data: types.GetTitle()})
ret, err := client.paraClient.grpcClient.QueryChain(context.Background(), &req) //从本地查询共识高度
ret, err := client.paraClient.GetAPI().QueryChain(&req)
if err != nil { if err != nil {
plog.Error("getConsensusHeight ", "err", err.Error()) plog.Error("getConsensusHeight ", "err", err.Error())
continue continue
} }
if !ret.GetIsOk() { if resp, ok := ret.(*pt.ParacrossStatus); ok {
plog.Info("getConsensusHeight", "error", ret.GetMsg()) consensusRst <- resp
continue
} }
var result pt.ParacrossStatus
types.Decode(ret.Msg, &result)
consensusRst <- &result
} }
} }
......
...@@ -144,7 +144,6 @@ func (s *suiteParaCommitMsg) createBlock() { ...@@ -144,7 +144,6 @@ func (s *suiteParaCommitMsg) createBlock() {
func (s *suiteParaCommitMsg) TestRun_1() { func (s *suiteParaCommitMsg) TestRun_1() {
s.createBlock() s.createBlock()
s.testRunGetMinerTxInfo()
s.testRunRmvBlock() s.testRunRmvBlock()
lastBlock, _ := s.para.RequestLastBlock() lastBlock, _ := s.para.RequestLastBlock()
...@@ -155,17 +154,6 @@ func (s *suiteParaCommitMsg) TestRun_1() { ...@@ -155,17 +154,6 @@ func (s *suiteParaCommitMsg) TestRun_1() {
} }
func (s *suiteParaCommitMsg) testRunGetMinerTxInfo() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
plog.Info("para test testRunGetMinerTxInfo--------------", "last height", lastBlock.Height)
s.True(lastBlock.Height > 1)
status, err := getMinerTxInfo(lastBlock)
s.Nil(err)
s.Equal(int64(3), status.MainBlockHeight)
}
func (s *suiteParaCommitMsg) testRunRmvBlock() { func (s *suiteParaCommitMsg) testRunRmvBlock() {
lastBlock, err := s.para.RequestLastBlock() lastBlock, err := s.para.RequestLastBlock()
s.Nil(err) s.Nil(err)
......
...@@ -92,6 +92,12 @@ function para_transfer() { ...@@ -92,6 +92,12 @@ function para_transfer() {
para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR" para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k" para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" para_configkey "${CLI}" "paracross-nodes-user.p.${PARANAME}." "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
para_configkey "${PARA_CLI}" "paracross-nodes-user.p.${PARANAME}." "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
para_configkey "${PARA_CLI}" "paracross-nodes-user.p.${PARANAME}." "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
para_configkey "${PARA_CLI}" "paracross-nodes-user.p.${PARANAME}." "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
para_configkey "${PARA_CLI}" "paracross-nodes-user.p.${PARANAME}." "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
block_wait "${CLI}" 1 block_wait "${CLI}" 1
txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY") txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY")
......
...@@ -32,6 +32,8 @@ func ParcCmd() *cobra.Command { ...@@ -32,6 +32,8 @@ func ParcCmd() *cobra.Command {
CreateRawWithdrawCmd(), CreateRawWithdrawCmd(),
CreateRawTransferToExecCmd(), CreateRawTransferToExecCmd(),
IsSyncCmd(), IsSyncCmd(),
GetHeightCmd(),
GetBlockInfoCmd(),
) )
return cmd return cmd
} }
...@@ -243,3 +245,61 @@ func isSync(cmd *cobra.Command, args []string) { ...@@ -243,3 +245,61 @@ func isSync(cmd *cobra.Command, args []string) {
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.IsSync", nil, &res) ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.IsSync", nil, &res)
ctx.Run() ctx.Run()
} }
// GetHeightCmd get para chain's chain height and consensus height
func GetHeightCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "height",
Short: "query consensus height",
Run: consusHeight,
}
addTitleFlags(cmd)
return cmd
}
func addTitleFlags(cmd *cobra.Command) {
cmd.Flags().StringP("title", "t", "", "parallel chain's title, default null in para chain")
}
func consusHeight(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
title, _ := cmd.Flags().GetString("title")
var res pt.ParacrossConsensusStatus
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetHeight", &types.ReqString{Data: title}, &res)
ctx.Run()
}
// GetBlockInfoCmd get blocks hash with main chain hash map
func GetBlockInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "blocks",
Short: "Get blocks with main chain hash map between [start, end], the same in main",
Run: blockInfo,
}
addBlockBodyCmdFlags(cmd)
return cmd
}
func addBlockBodyCmdFlags(cmd *cobra.Command) {
cmd.Flags().Int64P("start", "s", 0, "block start height")
cmd.MarkFlagRequired("start")
cmd.Flags().Int64P("end", "e", 0, "block end height")
cmd.MarkFlagRequired("end")
}
func blockInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
startH, _ := cmd.Flags().GetInt64("start")
endH, _ := cmd.Flags().GetInt64("end")
params := types.ReqBlocks{
Start: startH,
End: endH,
}
var res pt.ParaBlock2MainInfo
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetBlock2MainInfo", params, &res)
ctx.Run()
}
...@@ -69,6 +69,9 @@ func getNodes(db dbm.KV, title string) (map[string]struct{}, error) { ...@@ -69,6 +69,9 @@ func getNodes(db dbm.KV, title string) (map[string]struct{}, error) {
} }
func validTitle(title string) bool { func validTitle(title string) bool {
if types.IsPara() {
return types.GetTitle() == title
}
return len(title) > 0 return len(title) > 0
} }
...@@ -241,19 +244,20 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -241,19 +244,20 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
// 主链 (1)Bn1 (3) rollback-Bn1 (4) commit-done in Bn2 // 主链 (1)Bn1 (3) rollback-Bn1 (4) commit-done in Bn2
// 平行链 (2)commit (5) 将得到一个错误的块 // 平行链 (2)commit (5) 将得到一个错误的块
// 所以有必要做这个检测 // 所以有必要做这个检测
blockHash, err := getBlockHash(a.api, commit.Status.MainBlockHeight) if !types.IsPara() {
if err != nil { blockHash, err := getBlockHash(a.api, commit.Status.MainBlockHeight)
clog.Error("paracross.Commit getBlockHash", "err", err, if err != nil {
"commit tx Main.height", commit.Status.MainBlockHeight, "from", a.fromaddr) clog.Error("paracross.Commit getBlockHash", "err", err,
return nil, err "commit tx Main.height", commit.Status.MainBlockHeight, "from", a.fromaddr)
} return nil, err
if !bytes.Equal(blockHash.Hash, commit.Status.MainBlockHash) && commit.Status.Height > 0 { }
clog.Error("paracross.Commit blockHash not match", "db", hex.EncodeToString(blockHash.Hash), if !bytes.Equal(blockHash.Hash, commit.Status.MainBlockHash) && commit.Status.Height > 0 {
"commit tx", hex.EncodeToString(commit.Status.MainBlockHash), "commitHeight", commit.Status.Height, clog.Error("paracross.Commit blockHash not match", "db", hex.EncodeToString(blockHash.Hash),
"from", a.fromaddr) "commit tx", hex.EncodeToString(commit.Status.MainBlockHash), "commitHeight", commit.Status.Height,
return nil, types.ErrBlockHashNoMatch "from", a.fromaddr)
return nil, types.ErrBlockHashNoMatch
}
} }
clog.Debug("paracross.Commit check input done") clog.Debug("paracross.Commit check input done")
// 在完成共识之后来的, 增加 record log, 只记录不修改已经达成的共识 // 在完成共识之后来的, 增加 record log, 只记录不修改已经达成的共识
if commit.Status.Height <= titleStatus.Height { if commit.Status.Height <= titleStatus.Height {
...@@ -293,19 +297,41 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -293,19 +297,41 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
} }
receipt = makeCommitReceipt(a.fromaddr, commit, &copyStat, stat) receipt = makeCommitReceipt(a.fromaddr, commit, &copyStat, stat)
} }
clog.Info("paracross.Commit commit", "stat", stat) clog.Info("paracross.Commit commit", "stat", stat, "notes", len(nodes))
if commit.Status.Height > titleStatus.Height+1 { if commit.Status.Height > titleStatus.Height+1 {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat) saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
return receipt, nil return receipt, nil
} }
for i, v := range stat.Details.Addrs {
clog.Debug("paracross.Commit stat detail", "addr", v, "hash", hex.EncodeToString(stat.Details.BlockHash[i]))
}
commitCount := len(stat.Details.Addrs) commitCount := len(stat.Details.Addrs)
most, _ := getMostCommit(stat) most, mostHash := getMostCommit(stat)
if !isCommitDone(stat, nodes, most) { if !isCommitDone(stat, nodes, most) {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat) saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
return receipt, nil return receipt, nil
} }
clog.Info("paracross.Commit commit ----pass", "most", most, "mostHash", hex.EncodeToString([]byte(mostHash)))
// parallel chain get self blockhash and compare with commit done result, if not match, just log and return
if types.IsPara() {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
blockHash, err := getBlockHash(a.api, stat.Height)
if err != nil {
clog.Error("paracross.Commit getBlockHash local", "err", err.Error(), "commitheight", commit.Status.Height,
"commitHash", hex.EncodeToString(commit.Status.BlockHash), "mainHash", hex.EncodeToString(commit.Status.MainBlockHash),
"mainHeight", commit.Status.MainBlockHeight)
return receipt, nil
}
if !bytes.Equal(blockHash.Hash, []byte(mostHash)) {
clog.Error("paracross.Commit blockHash not match", "selfBlockHash", hex.EncodeToString(blockHash.Hash),
"mostHash", hex.EncodeToString([]byte(mostHash)), "commitHeight", commit.Status.Height,
"commitMainHash", hex.EncodeToString(commit.Status.MainBlockHash), "commitMainHeight", commit.Status.MainBlockHeight)
return receipt, nil
}
}
stat.Status = pt.ParacrossStatusCommitDone stat.Status = pt.ParacrossStatusCommitDone
receiptDone := makeDoneReceipt(a.fromaddr, commit, stat, int32(most), int32(commitCount), int32(len(nodes))) receiptDone := makeDoneReceipt(a.fromaddr, commit, stat, int32(most), int32(commitCount), int32(len(nodes)))
...@@ -317,10 +343,15 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -317,10 +343,15 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
titleStatus.Height = commit.Status.Height titleStatus.Height = commit.Status.Height
titleStatus.BlockHash = commit.Status.BlockHash titleStatus.BlockHash = commit.Status.BlockHash
saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus) saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus)
clog.Info("paracross.Commit commit", "commitDone", titleStatus)
clog.Info("paracross.Commit commit", "commitDone", titleStatus, "height", commit.Status.Height, clog.Info("paracross.Commit commit done", "height", commit.Status.Height,
"cross tx count", len(commit.Status.CrossTxHashs)) "cross tx count", len(commit.Status.CrossTxHashs), "status", titleStatus)
//parallel chain not need to process cross commit tx here
if types.IsPara() {
return receipt, nil
}
if enableParacrossTransfer && commit.Status.Height > 0 && len(commit.Status.CrossTxHashs) > 0 { if enableParacrossTransfer && commit.Status.Height > 0 && len(commit.Status.CrossTxHashs) > 0 {
clog.Debug("paracross.Commit commitDone", "do cross", "") clog.Debug("paracross.Commit commitDone", "do cross", "")
crossTxReceipt, err := a.execCrossTxs(commit) crossTxReceipt, err := a.execCrossTxs(commit)
......
...@@ -81,7 +81,7 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types ...@@ -81,7 +81,7 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types
return nil, errors.Wrap(err, "assetWithdrawCoins call NewParaAccount failed") return nil, errors.Wrap(err, "assetWithdrawCoins call NewParaAccount failed")
} }
clog.Debug("paracross.assetWithdrawCoins isPara", "execer", string(a.tx.Execer), clog.Debug("paracross.assetWithdrawCoins isPara", "execer", string(a.tx.Execer),
"txHash", hex.EncodeToString(a.tx.Hash())) "txHash", hex.EncodeToString(a.tx.Hash()), "from", a.fromaddr, "amount", withdraw.Amount)
return assetWithdrawBalance(paraAcc, a.fromaddr, withdraw.Amount) return assetWithdrawBalance(paraAcc, a.fromaddr, withdraw.Amount)
} }
......
...@@ -312,13 +312,14 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error { ...@@ -312,13 +312,14 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error {
// 增加新的规则: 在主链执行器带着title的 asset-transfer/asset-withdraw 交易允许执行 // 增加新的规则: 在主链执行器带着title的 asset-transfer/asset-withdraw 交易允许执行
// 1. user.p.${tilte}.${paraX} // 1. user.p.${tilte}.${paraX}
// 1. payload 的 actionType = t/w // 1. payload 的 actionType = t/w
if !types.IsPara() && c.allowIsParaAssetTx(tx.Execer) { if !types.IsPara() && c.allowIsParaTx(tx.Execer) {
var payload pt.ParacrossAction var payload pt.ParacrossAction
err := types.Decode(tx.Payload, &payload) err := types.Decode(tx.Payload, &payload)
if err != nil { if err != nil {
return err return err
} }
if payload.Ty == pt.ParacrossActionAssetTransfer || payload.Ty == pt.ParacrossActionAssetWithdraw { if payload.Ty == pt.ParacrossActionAssetTransfer || payload.Ty == pt.ParacrossActionAssetWithdraw ||
payload.Ty == pt.ParacrossActionCommit {
return nil return nil
} }
} }
...@@ -336,7 +337,7 @@ func (c *Paracross) Allow(tx *types.Transaction, index int) error { ...@@ -336,7 +337,7 @@ func (c *Paracross) Allow(tx *types.Transaction, index int) error {
return c.allow(tx, index) return c.allow(tx, index)
} }
func (c *Paracross) allowIsParaAssetTx(execer []byte) bool { func (c *Paracross) allowIsParaTx(execer []byte) bool {
if !bytes.HasPrefix(execer, types.ParaKey) { if !bytes.HasPrefix(execer, types.ParaKey) {
return false return false
} }
......
...@@ -167,7 +167,7 @@ func fillRawCommitTx(suite suite.Suite) (*types.Transaction, error) { ...@@ -167,7 +167,7 @@ func fillRawCommitTx(suite suite.Suite) (*types.Transaction, error) {
CrossTxResult: []byte("abc"), CrossTxResult: []byte("abc"),
CrossTxHashs: [][]byte{}, CrossTxHashs: [][]byte{},
} }
tx, err := pt.CreateRawCommitTx4MainChain(&st1, pt.ParaX, 0) tx, err := pt.CreateRawCommitTx4MainChain(&st1, pt.GetExecName(), 0)
if err != nil { if err != nil {
suite.T().Error("TestExec", "create tx failed", err) suite.T().Error("TestExec", "create tx failed", err)
} }
......
...@@ -26,6 +26,24 @@ message ParacrossStatus { ...@@ -26,6 +26,24 @@ message ParacrossStatus {
bytes blockHash = 3; bytes blockHash = 3;
} }
message ParacrossConsensusStatus {
string title = 1;
int64 chainHeight = 2;
int64 consensHeight = 3;
string consensBlockHash = 4;
}
message ParaBlock2MainMap{
int64 height = 1;
string blockHash = 2;
int64 mainHeight = 3;
string mainHash = 4;
}
message ParaBlock2MainInfo{
repeated ParaBlock2MainMap items = 1;
}
// action // action
message ParacrossNodeStatus { message ParacrossNodeStatus {
bytes mainBlockHash = 1; bytes mainBlockHash = 1;
...@@ -127,7 +145,7 @@ message ParacrossAsset { ...@@ -127,7 +145,7 @@ message ParacrossAsset {
} }
service paracross { service paracross {
rpc GetTitle(ReqString) returns (ParacrossStatus) {} rpc GetTitle(ReqString) returns (ParacrossConsensusStatus) {}
rpc ListTitles(ReqNil) returns (RespParacrossTitles) {} rpc ListTitles(ReqNil) returns (RespParacrossTitles) {}
rpc GetTitleHeight(ReqParacrossTitleHeight) returns (ReceiptParacrossDone) {} rpc GetTitleHeight(ReqParacrossTitleHeight) returns (ReceiptParacrossDone) {}
rpc GetAssetTxResult(ReqHash) returns (ParacrossAsset) {} rpc GetAssetTxResult(ReqHash) returns (ParacrossAsset) {}
......
...@@ -7,28 +7,50 @@ package rpc ...@@ -7,28 +7,50 @@ package rpc
import ( import (
"context" "context"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types" pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
) )
func (c *channelClient) GetTitle(ctx context.Context, req *types.ReqString) (*pt.ParacrossStatus, error) { func (c *channelClient) GetTitle(ctx context.Context, req *types.ReqString) (*pt.ParacrossConsensusStatus, error) {
data, err := c.Query(pt.GetExecName(), "GetTitle", req) data, err := c.Query(pt.GetExecName(), "GetTitle", req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
header, err := c.GetLastHeader()
if err != nil {
return nil, err
}
chainHeight := header.Height
if resp, ok := data.(*pt.ParacrossStatus); ok { if resp, ok := data.(*pt.ParacrossStatus); ok {
return resp, nil // 如果主链上查询平行链的高度,chain height应该是平行链的高度而不是主链高度, 平行链的真实高度需要在平行链侧查询
if !types.IsPara() {
chainHeight = resp.Height
}
return &pt.ParacrossConsensusStatus{
Title: resp.Title,
ChainHeight: chainHeight,
ConsensHeight: resp.Height,
ConsensBlockHash: common.ToHex(resp.BlockHash),
}, nil
} }
return nil, types.ErrDecode return nil, types.ErrDecode
} }
// GetHeight jrpc get consensus height // GetHeight jrpc get consensus height
func (c *Jrpc) GetHeight(req *types.ReqString, result *interface{}) error { func (c *Jrpc) GetHeight(req *types.ReqString, result *interface{}) error {
if req == nil { if req == nil || req.Data == "" {
return types.ErrInvalidParam if types.IsPara() {
req = &types.ReqString{Data: types.GetTitle()}
} else {
return types.ErrInvalidParam
}
} }
data, err := c.cli.GetTitle(context.Background(), req) data, err := c.cli.GetTitle(context.Background(), req)
*result = data *result = *data
return err return err
} }
...@@ -114,3 +136,34 @@ func (c *Jrpc) IsSync(in *types.ReqNil, result *interface{}) error { ...@@ -114,3 +136,34 @@ func (c *Jrpc) IsSync(in *types.ReqNil, result *interface{}) error {
} }
return nil return nil
} }
func (c *channelClient) GetBlock2MainInfo(ctx context.Context, req *types.ReqBlocks) (*pt.ParaBlock2MainInfo, error) {
ret := &pt.ParaBlock2MainInfo{}
details, err := c.GetBlocks(req)
if err != nil {
return nil, err
}
for _, item := range details.Items {
data := &pt.ParaBlock2MainMap{
Height: item.Block.Height,
BlockHash: common.ToHex(item.Block.Hash()),
MainHeight: item.Block.MainHeight,
MainHash: common.ToHex(item.Block.MainHash),
}
ret.Items = append(ret.Items, data)
}
return ret, nil
}
// GetBlock2MainInfo jrpc get para block info with main chain map
func (c *Jrpc) GetBlock2MainInfo(req *types.ReqBlocks, result *interface{}) error {
if req == nil {
return types.ErrInvalidParam
}
ret, err := c.cli.GetBlock2MainInfo(context.Background(), req)
*result = *ret
return err
}
...@@ -13,8 +13,10 @@ import ( ...@@ -13,8 +13,10 @@ import (
"github.com/33cn/chain33/client/mocks" "github.com/33cn/chain33/client/mocks"
rpctypes "github.com/33cn/chain33/rpc/types" rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/common"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types" pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
...@@ -43,7 +45,9 @@ func TestJrpc_GetTitle(t *testing.T) { ...@@ -43,7 +45,9 @@ func TestJrpc_GetTitle(t *testing.T) {
j := newJrpc(api) j := newJrpc(api)
req := &types.ReqString{Data: "xxxxxxxxxxx"} req := &types.ReqString{Data: "xxxxxxxxxxx"}
var result interface{} var result interface{}
api.On("Query", pt.GetExecName(), "GetTitle", req).Return(&pt.ParacrossStatus{}, nil) api.On("Query", pt.GetExecName(), "GetTitle", req).Return(&pt.ParacrossStatus{
Title: "user.p.para", Height: int64(64), BlockHash: []byte{177, 17, 9, 106, 247, 117, 90, 242, 221, 160, 157, 31, 33, 51, 10, 99, 77, 47, 245, 223, 59, 64, 121, 121, 215, 167, 152, 17, 223, 218, 173, 83}}, nil)
api.On("GetLastHeader", mock.Anything).Return(&types.Header{}, nil)
err := j.GetHeight(req, &result) err := j.GetHeight(req, &result)
assert.Nil(t, err) assert.Nil(t, err)
} }
......
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