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) {
func (client *client) InitBlock() {
var err error
// get main chain calc block hash fork height
mainBlockHashForkHeight, err = client.GetBlockHashForkHeightOnMainChain()
if err != nil {
panic(err)
......@@ -341,36 +342,31 @@ func (client *client) GetBlockByHeight(height int64) (*types.Block, error) {
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()
if err != nil {
plog.Error("Parachain RequestLastBlock fail", "err", err)
return -2, nil, nil, -2, err
return -2, nil, err
}
blockedSeq, err := client.GetBlockedSeq(lastBlock.Hash())
if err != nil {
plog.Error("Parachain GetBlockedSeq fail", "err", err)
return -2, nil, nil, -2, 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
return -2, nil, err
}
//sequence in main chain start from 0
seq := blockedSeq
if seq == -1 {
seq = 0
if lastBlock.Height > 0 || blockedSeq == -1 {
return blockedSeq, lastBlock, nil
}
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 {
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
// for genesis seq=-1 scenario, mainHash not care, as the 0 seq instead of -1
// not seq=-1 scenario, mainHash needed
func (client *client) syncFromGenesisBlock() (int64, []byte, error) {
lastSeq, _, lastSeqMainHash, _, err := client.getLastBlockInfo()
lastSeq, lastBlock, err := client.getLastBlockInfo()
if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err)
return -2, nil, err
}
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
......@@ -530,24 +526,20 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro
return -2, nil, err
}
//当前block结构已经有mainHash和MainHeight但是从blockchain获取的block还没有写入,以后如果获取到,可以替换从minerTx获取
miner, err := getMinerTxInfo(block)
if err != nil {
return -2, nil, err
}
plog.Info("switchHashMatchedBlock", "lastParaBlock height", miner.Height, "mainHeight",
miner.MainBlockHeight, "mainHash", hex.EncodeToString(miner.MainBlockHash))
mainSeq, err := client.GetSeqByHashOnMainChain(miner.MainBlockHash)
plog.Info("switchHashMatchedBlock", "lastParaBlockHeight", height, "mainHeight",
block.MainHeight, "mainHash", hex.EncodeToString(block.MainHash))
mainSeq, err := client.GetSeqByHashOnMainChain(block.MainHash)
if err != nil {
depth--
if depth == 0 {
plog.Error("switchHashMatchedBlock depth overflow", "last info:mainHeight", miner.MainBlockHeight,
"mainHash", hex.EncodeToString(miner.MainBlockHash), "search startHeight", lastBlock.Height, "curHeight", miner.Height,
plog.Error("switchHashMatchedBlock depth overflow", "last info:mainHeight", block.MainHeight,
"mainHash", hex.EncodeToString(block.MainHash), "search startHeight", lastBlock.Height, "curHeight", height,
"search depth", searchHashMatchDepth)
panic("search HashMatchedBlock overflow, re-setting search depth and restart to try")
}
if height == 1 {
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)
if err != nil {
return currSeq, nil, nil
......@@ -565,8 +557,8 @@ func (client *client) switchHashMatchedBlock(currSeq int64) (int64, []byte, erro
}
plog.Info("switchHashMatchedBlock succ", "currHeight", height, "initHeight", lastBlock.Height,
"new currSeq", mainSeq+1, "new preMainBlockHash", hex.EncodeToString(miner.MainBlockHash))
return mainSeq + 1, miner.MainBlockHash, nil
"new currSeq", mainSeq+1, "new preMainBlockHash", hex.EncodeToString(block.MainHash))
return mainSeq + 1, block.MainHash, nil
}
return -2, nil, paracross.ErrParaCurHashNotMatch
}
......@@ -601,11 +593,12 @@ func (client *client) removeBlocks(endHeight int64) error {
func (client *client) CreateBlock() {
incSeqFlag := true
//system startup, take the last added block's seq is ok
currSeq, _, lastSeqMainHash, _, err := client.getLastBlockInfo()
currSeq, lastBlock, err := client.getLastBlockInfo()
if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err.Error())
return
}
lastSeqMainHash := lastBlock.MainHash
for {
//should be lastSeq but not LastBlockSeq as del block case the seq is not equal
lastSeq, err := client.GetLastSeq()
......@@ -640,7 +633,7 @@ func (client *client) CreateBlock() {
lastSeqMainHash = blockOnMain.Detail.Block.ParentHash
}
_, lastBlock, lastBlockMainHash, lastBlockMainHeight, err := client.getLastBlockInfo()
_, lastBlock, err := client.getLastBlockInfo()
if err != nil {
plog.Error("Parachain getLastBlockInfo fail", "err", err)
time.Sleep(time.Second)
......@@ -649,11 +642,11 @@ func (client *client) CreateBlock() {
plog.Info("Parachain process block", "lastBlockSeq", lastSeq, "curSeq", currSeq,
"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 len(txs) == 0 {
if lastSeqMainHeight > lastBlockMainHeight {
if lastSeqMainHeight > lastBlock.MainHeight {
incSeqFlag = true
continue
}
......@@ -666,7 +659,7 @@ func (client *client) CreateBlock() {
}
} else if blockOnMain.Seq.Type == addAct {
if len(txs) == 0 {
if lastSeqMainHeight-lastBlockMainHeight < emptyBlockInterval {
if lastSeqMainHeight-lastBlock.MainHeight < emptyBlockInterval {
incSeqFlag = true
continue
}
......@@ -826,18 +819,3 @@ func checkMinerTx(current *types.BlockDetail) error {
}
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
func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNodeStatus) (*types.Transaction, int, error) {
var rawTxs types.Transactions
for _, status := range notifications {
tx, err := paracross.CreateRawCommitTx4MainChain(status, pt.ParaX, 0)
tx, err := paracross.CreateRawCommitTx4MainChain(status, paracross.GetExecName(), 0)
if err != nil {
plog.Error("para get commit tx", "block height", status.Height)
return nil, 0, err
......@@ -243,7 +243,7 @@ func (client *commitMsgClient) batchCalcTxGroup(notifications []*pt.ParacrossNod
}
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 {
plog.Error("para get commit tx", "block height", status.Height)
return nil, err
......@@ -480,19 +480,15 @@ out:
req.FuncName = "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 {
plog.Error("getConsensusHeight ", "err", err.Error())
continue
}
if !ret.GetIsOk() {
plog.Info("getConsensusHeight", "error", ret.GetMsg())
continue
if resp, ok := ret.(*pt.ParacrossStatus); ok {
consensusRst <- resp
}
var result pt.ParacrossStatus
types.Decode(ret.Msg, &result)
consensusRst <- &result
}
}
......
......@@ -144,7 +144,6 @@ func (s *suiteParaCommitMsg) createBlock() {
func (s *suiteParaCommitMsg) TestRun_1() {
s.createBlock()
s.testRunGetMinerTxInfo()
s.testRunRmvBlock()
lastBlock, _ := s.para.RequestLastBlock()
......@@ -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() {
lastBlock, err := s.para.RequestLastBlock()
s.Nil(err)
......
......@@ -92,6 +92,12 @@ function para_transfer() {
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}." "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
txhash=$(para_configkey "${PARA_CLI}" "token-blacklist" "BTY")
......
......@@ -32,6 +32,8 @@ func ParcCmd() *cobra.Command {
CreateRawWithdrawCmd(),
CreateRawTransferToExecCmd(),
IsSyncCmd(),
GetHeightCmd(),
GetBlockInfoCmd(),
)
return cmd
}
......@@ -243,3 +245,61 @@ func isSync(cmd *cobra.Command, args []string) {
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.IsSync", nil, &res)
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) {
}
func validTitle(title string) bool {
if types.IsPara() {
return types.GetTitle() == title
}
return len(title) > 0
}
......@@ -241,6 +244,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
// 主链 (1)Bn1 (3) rollback-Bn1 (4) commit-done in Bn2
// 平行链 (2)commit (5) 将得到一个错误的块
// 所以有必要做这个检测
if !types.IsPara() {
blockHash, err := getBlockHash(a.api, commit.Status.MainBlockHeight)
if err != nil {
clog.Error("paracross.Commit getBlockHash", "err", err,
......@@ -253,7 +257,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
"from", a.fromaddr)
return nil, types.ErrBlockHashNoMatch
}
}
clog.Debug("paracross.Commit check input done")
// 在完成共识之后来的, 增加 record log, 只记录不修改已经达成的共识
if commit.Status.Height <= titleStatus.Height {
......@@ -293,19 +297,41 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
}
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 {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
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)
most, _ := getMostCommit(stat)
most, mostHash := getMostCommit(stat)
if !isCommitDone(stat, nodes, most) {
saveTitleHeight(a.db, calcTitleHeightKey(commit.Status.Title, commit.Status.Height), stat)
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
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
titleStatus.Height = commit.Status.Height
titleStatus.BlockHash = commit.Status.BlockHash
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,
"cross tx count", len(commit.Status.CrossTxHashs))
clog.Info("paracross.Commit commit done", "height", commit.Status.Height,
"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 {
clog.Debug("paracross.Commit commitDone", "do cross", "")
crossTxReceipt, err := a.execCrossTxs(commit)
......
......@@ -81,7 +81,7 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types
return nil, errors.Wrap(err, "assetWithdrawCoins call NewParaAccount failed")
}
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)
}
......
......@@ -312,13 +312,14 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error {
// 增加新的规则: 在主链执行器带着title的 asset-transfer/asset-withdraw 交易允许执行
// 1. user.p.${tilte}.${paraX}
// 1. payload 的 actionType = t/w
if !types.IsPara() && c.allowIsParaAssetTx(tx.Execer) {
if !types.IsPara() && c.allowIsParaTx(tx.Execer) {
var payload pt.ParacrossAction
err := types.Decode(tx.Payload, &payload)
if err != nil {
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
}
}
......@@ -336,7 +337,7 @@ func (c *Paracross) Allow(tx *types.Transaction, index int) error {
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) {
return false
}
......
......@@ -167,7 +167,7 @@ func fillRawCommitTx(suite suite.Suite) (*types.Transaction, error) {
CrossTxResult: []byte("abc"),
CrossTxHashs: [][]byte{},
}
tx, err := pt.CreateRawCommitTx4MainChain(&st1, pt.ParaX, 0)
tx, err := pt.CreateRawCommitTx4MainChain(&st1, pt.GetExecName(), 0)
if err != nil {
suite.T().Error("TestExec", "create tx failed", err)
}
......
......@@ -26,6 +26,24 @@ message ParacrossStatus {
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
message ParacrossNodeStatus {
bytes mainBlockHash = 1;
......@@ -127,7 +145,7 @@ message ParacrossAsset {
}
service paracross {
rpc GetTitle(ReqString) returns (ParacrossStatus) {}
rpc GetTitle(ReqString) returns (ParacrossConsensusStatus) {}
rpc ListTitles(ReqNil) returns (RespParacrossTitles) {}
rpc GetTitleHeight(ReqParacrossTitleHeight) returns (ReceiptParacrossDone) {}
rpc GetAssetTxResult(ReqHash) returns (ParacrossAsset) {}
......
......@@ -7,28 +7,50 @@ package rpc
import (
"context"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/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)
if err != nil {
return nil, err
}
header, err := c.GetLastHeader()
if err != nil {
return nil, err
}
chainHeight := header.Height
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
}
// GetHeight jrpc get consensus height
func (c *Jrpc) GetHeight(req *types.ReqString, result *interface{}) error {
if req == nil {
if req == nil || req.Data == "" {
if types.IsPara() {
req = &types.ReqString{Data: types.GetTitle()}
} else {
return types.ErrInvalidParam
}
}
data, err := c.cli.GetTitle(context.Background(), req)
*result = data
*result = *data
return err
}
......@@ -114,3 +136,34 @@ func (c *Jrpc) IsSync(in *types.ReqNil, result *interface{}) error {
}
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 (
"github.com/33cn/chain33/client/mocks"
rpctypes "github.com/33cn/chain33/rpc/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"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"golang.org/x/net/context"
)
......@@ -43,7 +45,9 @@ func TestJrpc_GetTitle(t *testing.T) {
j := newJrpc(api)
req := &types.ReqString{Data: "xxxxxxxxxxx"}
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)
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