Commit bdc1ab9a authored by mdj33's avatar mdj33 Committed by vipwzw

cross asset transfer

parent bb9f022e
...@@ -32,6 +32,7 @@ func ParcCmd() *cobra.Command { ...@@ -32,6 +32,7 @@ func ParcCmd() *cobra.Command {
CreateRawTransferCmd(), CreateRawTransferCmd(),
CreateRawWithdrawCmd(), CreateRawWithdrawCmd(),
CreateRawTransferToExecCmd(), CreateRawTransferToExecCmd(),
CreateRawCrossAssetTransferCmd(),
superNodeCmd(), superNodeCmd(),
nodeGroupCmd(), nodeGroupCmd(),
paraConfigCmd(), paraConfigCmd(),
...@@ -236,6 +237,75 @@ func createWithdraw(cmd *cobra.Command, args []string) { ...@@ -236,6 +237,75 @@ func createWithdraw(cmd *cobra.Command, args []string) {
commands.CreateAssetWithdraw(cmd, args, pt.ParaX) commands.CreateAssetWithdraw(cmd, args, pt.ParaX)
} }
// CreateRawCrossAssetTransferCmd create raw cross asset transfer tx
func CreateRawCrossAssetTransferCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cross_transfer",
Short: "Create a cross asset transfer transaction",
Run: createCrossAssetTransfer,
}
addCreateCrossAssetTransferFlags(cmd)
return cmd
}
func addCreateCrossAssetTransferFlags(cmd *cobra.Command) {
cmd.Flags().Uint32P("type", "d", 0, "transfer type: 0:to paraChain, 1:to mainChain")
cmd.MarkFlagRequired("type")
cmd.Flags().StringP("to", "t", "", "transfer to account")
cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("symbol", "s", "", "default for bty, parachain symbol like user.p.xx.bty")
}
func createCrossAssetTransfer(cmd *cobra.Command, args []string) {
ty, _ := cmd.Flags().GetUint32("type")
toAddr, _ := cmd.Flags().GetString("to")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
amount, _ := cmd.Flags().GetFloat64("amount")
if amount < 0 {
fmt.Fprintln(os.Stderr, "amount < 0")
return
}
amountInt64 := int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4
paraName, _ := cmd.Flags().GetString("paraName")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
execName := paraName + pt.ParaX
if ty > 0 && symbol == "" {
fmt.Fprintln(os.Stderr, "transfer to main chain, symbol should not be null")
return
}
var config pt.CrossAssetTransfer
config.Type = ty
config.AssetSymbol = symbol
config.ToAddr = toAddr
config.Note = note
config.Amount = amountInt64
params := &rpctypes.CreateTxIn{
Execer: execName,
ActionName: "CrossAssetTransfer",
Payload: types.MustPBToJSON(&config),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
func superNodeCmd() *cobra.Command { func superNodeCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "super_node", Use: "super_node",
...@@ -1015,7 +1085,7 @@ func paraAssetTransfer(cmd *cobra.Command, args []string) { ...@@ -1015,7 +1085,7 @@ func paraAssetTransfer(cmd *cobra.Command, args []string) {
} }
params.Payload = types.MustPBToJSON(&req) params.Payload = types.MustPBToJSON(&req)
var res pt.ParacrossAssetRsp var res pt.ParacrossAsset
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res) ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
ctx.Run() ctx.Run()
} }
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/client" "github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -101,7 +102,7 @@ func checkCommitInfo(cfg *types.Chain33Config, commit *pt.ParacrossCommitAction) ...@@ -101,7 +102,7 @@ func checkCommitInfo(cfg *types.Chain33Config, commit *pt.ParacrossCommitAction)
return types.ErrInvalidParam return types.ErrInvalidParam
} }
clog.Debug("paracross.Commit check input", "height", commit.Status.Height, "mainHeight", commit.Status.MainBlockHeight, clog.Debug("paracross.Commit check input", "height", commit.Status.Height, "mainHeight", commit.Status.MainBlockHeight,
"mainHash", hex.EncodeToString(commit.Status.MainBlockHash), "blockHash", hex.EncodeToString(commit.Status.BlockHash)) "mainHash", common.ToHex(commit.Status.MainBlockHash), "blockHash", common.ToHex(commit.Status.BlockHash))
if commit.Status.Height == 0 { if commit.Status.Height == 0 {
if len(commit.Status.Title) == 0 || len(commit.Status.BlockHash) == 0 { if len(commit.Status.Title) == 0 || len(commit.Status.BlockHash) == 0 {
...@@ -355,8 +356,8 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -355,8 +356,8 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
if titleStatus.Height+1 == commit.Status.Height && commit.Status.Height > 0 && !pt.IsParaForkHeight(cfg, commit.Status.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) { if titleStatus.Height+1 == commit.Status.Height && commit.Status.Height > 0 && !pt.IsParaForkHeight(cfg, commit.Status.MainBlockHeight, pt.ForkLoopCheckCommitTxDone) {
if !bytes.Equal(titleStatus.BlockHash, commit.Status.PreBlockHash) { if !bytes.Equal(titleStatus.BlockHash, commit.Status.PreBlockHash) {
clog.Error("paracross.Commit", "check PreBlockHash", hex.EncodeToString(titleStatus.BlockHash), clog.Error("paracross.Commit", "check PreBlockHash", common.ToHex(titleStatus.BlockHash),
"commit tx", hex.EncodeToString(commit.Status.PreBlockHash), "commitheit", commit.Status.Height, "commit tx", common.ToHex(commit.Status.PreBlockHash), "commitheit", commit.Status.Height,
"from", a.fromaddr) "from", a.fromaddr)
return nil, pt.ErrParaBlockHashNoMatch return nil, pt.ErrParaBlockHashNoMatch
} }
...@@ -388,8 +389,8 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -388,8 +389,8 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
//对于主链,校验的是主链高度对应的blockhash是否和commit的一致 //对于主链,校验的是主链高度对应的blockhash是否和commit的一致
//对于平行链, 校验的是commit信息的平行链height block对应的mainHash是否和本地相同高度对应的mainHash一致, 在主链hash一致的时候看平行链共识blockhash是否一致 //对于平行链, 校验的是commit信息的平行链height block对应的mainHash是否和本地相同高度对应的mainHash一致, 在主链hash一致的时候看平行链共识blockhash是否一致
if !bytes.Equal(dbMainHash, commit.Status.MainBlockHash) && commit.Status.Height > 0 { if !bytes.Equal(dbMainHash, commit.Status.MainBlockHash) && commit.Status.Height > 0 {
clog.Error("paracross.Commit blockHash not match", "isMain", !cfg.IsPara(), "db", hex.EncodeToString(dbMainHash), clog.Error("paracross.Commit blockHash not match", "isMain", !cfg.IsPara(), "db", common.ToHex(dbMainHash),
"commit", hex.EncodeToString(commit.Status.MainBlockHash), "commitHeight", commit.Status.Height, "commit", common.ToHex(commit.Status.MainBlockHash), "commitHeight", commit.Status.Height,
"commitMainHeight", commit.Status.MainBlockHeight, "from", a.fromaddr) "commitMainHeight", commit.Status.MainBlockHeight, "from", a.fromaddr)
return nil, types.ErrBlockHashNoMatch return nil, types.ErrBlockHashNoMatch
} }
...@@ -488,7 +489,7 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac ...@@ -488,7 +489,7 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
clog.Debug("paracross.Commit commit", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes)) clog.Debug("paracross.Commit commit", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes))
for i, v := range stat.Details.Addrs { for i, v := range stat.Details.Addrs {
clog.Debug("paracross.Commit commit detail", "addr", v, "hash", hex.EncodeToString(stat.Details.BlockHash[i])) clog.Debug("paracross.Commit commit detail", "addr", v, "hash", common.ToHex(stat.Details.BlockHash[i]))
} }
commitCount := len(stat.Details.Addrs) commitCount := len(stat.Details.Addrs)
...@@ -496,7 +497,7 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac ...@@ -496,7 +497,7 @@ func (a *action) commitTxDone(nodeStatus *pt.ParacrossNodeStatus, stat *pt.Parac
if !isCommitDone(nodes, most) { if !isCommitDone(nodes, most) {
return receipt, nil return receipt, nil
} }
clog.Debug("paracross.Commit commit ----pass", "most", most, "mostHash", hex.EncodeToString([]byte(mostHash))) clog.Debug("paracross.Commit commit ----pass", "most", most, "mostHash", common.ToHex([]byte(mostHash)))
stat.Status = pt.ParacrossStatusCommitDone stat.Status = pt.ParacrossStatusCommitDone
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat) saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
...@@ -532,20 +533,20 @@ func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt. ...@@ -532,20 +533,20 @@ func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt.
} }
saveTitle(a.db, calcTitleKey(titleStatus.Title), titleStatus) saveTitle(a.db, calcTitleKey(titleStatus.Title), titleStatus)
clog.Debug("paracross.Commit commit done", "height", nodeStatus.Height, "statusBlockHash", hex.EncodeToString(nodeStatus.BlockHash)) clog.Debug("paracross.Commit commit done", "height", nodeStatus.Height, "statusBlockHash", common.ToHex(nodeStatus.BlockHash))
//parallel chain not need to process cross commit tx here //parallel chain not need to process cross commit tx here
if cfg.IsPara() { if cfg.IsPara() {
//平行链自共识校验 //平行链自共识校验
selfBlockHash, err := getBlockHash(a.api, nodeStatus.Height) selfBlockHash, err := getBlockHash(a.api, nodeStatus.Height)
if err != nil { if err != nil {
clog.Error("paracross.CommitDone getBlockHash", "err", err, "commit tx height", nodeStatus.Height, "tx", hex.EncodeToString(a.txhash)) clog.Error("paracross.CommitDone getBlockHash", "err", err, "commit tx height", nodeStatus.Height, "tx", common.ToHex(a.txhash))
return nil, err return nil, err
} }
//说明本节点blockhash和共识hash不一致,需要停止本节点执行 //说明本节点blockhash和共识hash不一致,需要停止本节点执行
if !bytes.Equal(selfBlockHash.Hash, nodeStatus.BlockHash) { if !bytes.Equal(selfBlockHash.Hash, nodeStatus.BlockHash) {
clog.Error("paracross.CommitDone mosthash not match", "height", nodeStatus.Height, clog.Error("paracross.CommitDone mosthash not match", "height", nodeStatus.Height,
"blockHash", hex.EncodeToString(selfBlockHash.Hash), "mosthash", hex.EncodeToString(nodeStatus.BlockHash)) "blockHash", common.ToHex(selfBlockHash.Hash), "mosthash", common.ToHex(nodeStatus.BlockHash))
return nil, types.ErrConsensusHashErr return nil, types.ErrConsensusHashErr
} }
...@@ -554,7 +555,7 @@ func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt. ...@@ -554,7 +555,7 @@ func (a *action) commitTxDoneStep2(nodeStatus *pt.ParacrossNodeStatus, stat *pt.
//错误会导致和主链处理的共识结果不一致 //错误会导致和主链处理的共识结果不一致
if err != nil { if err != nil {
clog.Error("paracross mining reward err", "height", nodeStatus.Height, clog.Error("paracross mining reward err", "height", nodeStatus.Height,
"blockhash", hex.EncodeToString(nodeStatus.BlockHash), "err", err) "blockhash", common.ToHex(nodeStatus.BlockHash), "err", err)
return nil, err return nil, err
} }
receipt = mergeReceipt(receipt, rewardReceipt) receipt = mergeReceipt(receipt, rewardReceipt)
...@@ -666,7 +667,7 @@ func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus ...@@ -666,7 +667,7 @@ func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus
receipt := &types.Receipt{} receipt := &types.Receipt{}
clog.Debug("paracross.commitTxDoneByStat", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes)) clog.Debug("paracross.commitTxDoneByStat", "stat.title", stat.Title, "stat.height", stat.Height, "notes", len(nodes))
for i, v := range stat.Details.Addrs { for i, v := range stat.Details.Addrs {
clog.Debug("paracross.commitTxDoneByStat detail", "addr", v, "hash", hex.EncodeToString(stat.Details.BlockHash[i])) clog.Debug("paracross.commitTxDoneByStat detail", "addr", v, "hash", common.ToHex(stat.Details.BlockHash[i]))
} }
updateCommitAddrs(stat, nodes) updateCommitAddrs(stat, nodes)
...@@ -675,7 +676,7 @@ func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus ...@@ -675,7 +676,7 @@ func (a *action) commitTxDoneByStat(stat *pt.ParacrossHeightStatus, titleStatus
if !isCommitDone(nodes, most) { if !isCommitDone(nodes, most) {
return nil, nil return nil, nil
} }
clog.Debug("paracross.commitTxDoneByStat ----pass", "most", most, "mostHash", hex.EncodeToString([]byte(mostHash))) clog.Debug("paracross.commitTxDoneByStat ----pass", "most", most, "mostHash", common.ToHex([]byte(mostHash)))
stat.Status = pt.ParacrossStatusCommitDone stat.Status = pt.ParacrossStatusCommitDone
saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat) saveTitleHeight(a.db, calcTitleHeightKey(stat.Title, stat.Height), stat)
r := makeCommitStatReceipt(stat) r := makeCommitStatReceipt(stat)
...@@ -752,18 +753,21 @@ func execCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*t ...@@ -752,18 +753,21 @@ func execCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) (*t
var payload pt.ParacrossAction var payload pt.ParacrossAction
err := types.Decode(tx.Tx.Payload, &payload) err := types.Decode(tx.Tx.Payload, &payload)
if err != nil { if err != nil {
clog.Crit("paracross.Commit Decode Tx failed", "error", err, "txHash", hex.EncodeToString(crossTxHash)) clog.Crit("paracross.Commit Decode Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err return nil, err
} }
}
//主链共识后,执行主链资产withdraw, 在支持CrossAssetTransfer之前使用此action
if payload.Ty == pt.ParacrossActionAssetWithdraw { if payload.Ty == pt.ParacrossActionAssetWithdraw {
receiptWithdraw, err := a.assetWithdraw(payload.GetAssetWithdraw(), tx.Tx) receiptWithdraw, err := a.assetWithdraw(payload.GetAssetWithdraw(), tx.Tx)
if err != nil { if err != nil {
clog.Crit("paracross.Commit withdraw Tx failed", "error", err, "txHash", hex.EncodeToString(crossTxHash)) clog.Crit("paracross.Commit withdraw Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err) return nil, errors.Cause(err)
} }
clog.Debug("paracross.Commit WithdrawCoins", "txHash", hex.EncodeToString(crossTxHash)) clog.Debug("paracross.Commit WithdrawCoins", "txHash", common.ToHex(crossTxHash))
return receiptWithdraw, nil return receiptWithdraw, nil
} }
return nil, nil return nil, nil
...@@ -777,18 +781,73 @@ func rollbackCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte) ...@@ -777,18 +781,73 @@ func rollbackCrossTx(a *action, tx *types.TransactionDetail, crossTxHash []byte)
var payload pt.ParacrossAction var payload pt.ParacrossAction
err := types.Decode(tx.Tx.Payload, &payload) err := types.Decode(tx.Tx.Payload, &payload)
if err != nil { if err != nil {
clog.Crit("paracross.Commit.rollbackCrossTx Decode Tx failed", "error", err, "txHash", hex.EncodeToString(crossTxHash)) clog.Crit("paracross.Commit.rollbackCrossTx Decode Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err return nil, err
} }
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(a.tx.Execer))
if err != nil {
clog.Crit("paracross.Commit getCrossAction Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, err
}
if act == pt.ParacrossMainWithdraw || act == pt.ParacrossParaTransfer {
receipt, err := a.crossAssetTransfer(payload.GetCrossAssetTransfer(), act, tx.Tx)
if err != nil {
clog.Crit("paracross.Commit crossAssetTransfer Tx failed", "error", err, "act", act, "txHash", common.ToHex(crossTxHash))
return nil, err
}
clog.Debug("paracross.Commit crossAssetTransfer done", "act", act, "txHash", common.ToHex(crossTxHash))
return receipt, nil
}
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(a.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.ParacrossMainTransfer {
receipt, err := a.assetTransferRollback(payload.GetCrossAssetTransfer(), tx.Tx)
if err != nil {
clog.Crit("paracross.Commit crossAssetTransfer rbk failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
}
clog.Debug("paracross.Commit crossAssetTransfer rollbackCrossTx", "txHash", common.ToHex(crossTxHash), "mainHeight", a.height)
return receipt, nil
}
//主链共识后,平行链执行出错的平行链资产withdraw回滚
if act == pt.ParacrossParaWithdraw {
receipt, err := a.paraAssetWithdrawRollback(payload.GetCrossAssetTransfer(), tx.Tx)
if err != nil {
clog.Crit("paracross.Commit rbk paraAssetWithdraw Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err)
}
clog.Debug("paracross.Commit paraAssetWithdraw rollbackCrossTx", "txHash", common.ToHex(crossTxHash), "mainHeight", a.height)
return receipt, nil
}
}
//主链共识后,平行链执行出错的主链资产transfer回滚
if payload.Ty == pt.ParacrossActionAssetTransfer { if payload.Ty == pt.ParacrossActionAssetTransfer {
receipt, err := a.assetTransferRollback(payload.GetAssetTransfer(), tx.Tx) assettf := payload.GetAssetTransfer()
cross := &pt.CrossAssetTransfer{
AssetSymbol: assettf.Cointoken,
Amount: assettf.Amount,
Note: string(assettf.Note),
ToAddr: assettf.To,
}
receipt, err := a.assetTransferRollback(cross, tx.Tx)
if err != nil { if err != nil {
clog.Crit("paracross.Commit rbk Tx failed", "error", err, "txHash", hex.EncodeToString(crossTxHash)) clog.Crit("paracross.Commit rbk asset transfer Tx failed", "error", err, "txHash", common.ToHex(crossTxHash))
return nil, errors.Cause(err) return nil, errors.Cause(err)
} }
clog.Debug("paracross.Commit rollbackCrossTx", "txHash", hex.EncodeToString(crossTxHash), "mainHeight", a.height) clog.Debug("paracross.Commit assetTransfer rollbackCrossTx", "txHash", common.ToHex(crossTxHash), "mainHeight", a.height)
return receipt, nil return receipt, nil
} }
return nil, nil return nil, nil
...@@ -824,7 +883,7 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS ...@@ -824,7 +883,7 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
} }
paraCrossHashs := FilterParaCrossTxHashes(paraAllTxs) paraCrossHashs := FilterParaCrossTxHashes(paraAllTxs)
crossRst := util.CalcBitMapByBitMap(paraCrossHashs, baseHashs, rst) crossRst := util.CalcBitMapByBitMap(paraCrossHashs, baseHashs, rst)
clog.Debug("getCrossTxHashsByRst.crossRst", "height", status.Height, "txResult", hex.EncodeToString(crossRst), "len", len(paraCrossHashs)) clog.Debug("getCrossTxHashsByRst.crossRst", "height", status.Height, "txResult", common.ToHex(crossRst), "len", len(paraCrossHashs))
return paraCrossHashs, crossRst, nil return paraCrossHashs, crossRst, nil
...@@ -841,7 +900,7 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus ...@@ -841,7 +900,7 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
if len(status.CrossTxHashs) == 0 { if len(status.CrossTxHashs) == 0 {
clog.Error("getCrossTxHashs len=0", "paraHeight", status.Height, clog.Error("getCrossTxHashs len=0", "paraHeight", status.Height,
"mainHeight", status.MainBlockHeight, "mainHash", hex.EncodeToString(status.MainBlockHash)) "mainHeight", status.MainBlockHeight, "mainHash", common.ToHex(status.MainBlockHash))
return nil, nil, types.ErrCheckTxHash return nil, nil, types.ErrCheckTxHash
} }
...@@ -860,14 +919,14 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus ...@@ -860,14 +919,14 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
crossCheckHash := CalcTxHashsHash(paraCrossHashs) crossCheckHash := CalcTxHashsHash(paraCrossHashs)
if !bytes.Equal(status.CrossTxHashs[0], crossCheckHash) { if !bytes.Equal(status.CrossTxHashs[0], crossCheckHash) {
clog.Error("getCrossTxHashs para hash not equal", "paraHeight", status.Height, clog.Error("getCrossTxHashs para hash not equal", "paraHeight", status.Height,
"mainHeight", status.MainBlockHeight, "mainHash", hex.EncodeToString(status.MainBlockHash), "mainHeight", status.MainBlockHeight, "mainHash", common.ToHex(status.MainBlockHash),
"main.crossHash", hex.EncodeToString(crossCheckHash), "commit.crossHash", hex.EncodeToString(status.CrossTxHashs[0]), "main.crossHash", common.ToHex(crossCheckHash), "commit.crossHash", common.ToHex(status.CrossTxHashs[0]),
"main.baseHash", hex.EncodeToString(baseCheckTxHash), "commit.baseHash", hex.EncodeToString(status.TxHashs[0])) "main.baseHash", common.ToHex(baseCheckTxHash), "commit.baseHash", common.ToHex(status.TxHashs[0]))
for _, hash := range baseHashs { for _, hash := range baseHashs {
clog.Error("getCrossTxHashs base tx hash", "txhash", hex.EncodeToString(hash)) clog.Error("getCrossTxHashs base tx hash", "txhash", common.ToHex(hash))
} }
for _, hash := range paraCrossHashs { for _, hash := range paraCrossHashs {
clog.Error("getCrossTxHashs paracross tx hash", "txhash", hex.EncodeToString(hash)) clog.Error("getCrossTxHashs paracross tx hash", "txhash", common.ToHex(hash))
} }
return nil, nil, types.ErrCheckTxHash return nil, nil, types.ErrCheckTxHash
} }
...@@ -886,11 +945,11 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus ...@@ -886,11 +945,11 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
func crossTxProc(a *action, txHash []byte, fn func(*action, *types.TransactionDetail, []byte) (*types.Receipt, error)) (*types.Receipt, error) { func crossTxProc(a *action, txHash []byte, fn func(*action, *types.TransactionDetail, []byte) (*types.Receipt, error)) (*types.Receipt, error) {
tx, err := GetTx(a.api, txHash) tx, err := GetTx(a.api, txHash)
if err != nil { if err != nil {
clog.Crit("paracross.Commit Load Tx failed", "error", err, "txHash", hex.EncodeToString(txHash)) clog.Crit("paracross.Commit Load Tx failed", "error", err, "txHash", common.ToHex(txHash))
return nil, err return nil, err
} }
if tx == nil { if tx == nil {
clog.Error("paracross.Commit Load Tx nil", "error", err, "txHash", hex.EncodeToString(txHash)) clog.Error("paracross.Commit Load Tx nil", "error", err, "txHash", common.ToHex(txHash))
return nil, types.ErrHashNotExist return nil, types.ErrHashNotExist
} }
receiptCross, err := fn(a, tx, txHash) receiptCross, err := fn(a, tx, txHash)
...@@ -911,7 +970,7 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e ...@@ -911,7 +970,7 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
} }
for i := 0; i < len(crossTxHashs); i++ { for i := 0; i < len(crossTxHashs); i++ {
clog.Debug("paracross.Commit commitDone", "do cross number", i, "hash", hex.EncodeToString(crossTxHashs[i]), clog.Debug("paracross.Commit commitDone", "do cross number", i, "hash", common.ToHex(crossTxHashs[i]),
"res", util.BitMapBit(crossTxResult, uint32(i))) "res", util.BitMapBit(crossTxResult, uint32(i)))
if util.BitMapBit(crossTxResult, uint32(i)) { if util.BitMapBit(crossTxResult, uint32(i)) {
receiptCross, err := crossTxProc(a, crossTxHashs[i], execCrossTx) receiptCross, err := crossTxProc(a, crossTxHashs[i], execCrossTx)
...@@ -927,7 +986,7 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e ...@@ -927,7 +986,7 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
receipt.Logs = append(receipt.Logs, receiptCross.Logs...) receipt.Logs = append(receipt.Logs, receiptCross.Logs...)
} else { } else {
clog.Error("paracross.Commit commitDone", "do cross number", i, "hash", clog.Error("paracross.Commit commitDone", "do cross number", i, "hash",
hex.EncodeToString(crossTxHashs[i]), "para res", util.BitMapBit(crossTxResult, uint32(i))) common.ToHex(crossTxHashs[i]), "para res", util.BitMapBit(crossTxResult, uint32(i)))
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaAssetTransferRbk) { if cfg.IsDappFork(a.height, pt.ParaX, pt.ForkParaAssetTransferRbk) {
receiptCross, err := crossTxProc(a, crossTxHashs[i], rollbackCrossTx) receiptCross, err := crossTxProc(a, crossTxHashs[i], rollbackCrossTx)
...@@ -973,7 +1032,7 @@ func (a *action) AssetWithdraw(withdraw *types.AssetsWithdraw) (*types.Receipt, ...@@ -973,7 +1032,7 @@ func (a *action) AssetWithdraw(withdraw *types.AssetsWithdraw) (*types.Receipt,
return nil, nil return nil, nil
} }
clog.Debug("paracross.AssetWithdraw isPara", "execer", string(a.tx.Execer), clog.Debug("paracross.AssetWithdraw isPara", "execer", string(a.tx.Execer),
"txHash", hex.EncodeToString(a.tx.Hash()), "token name", withdraw.Cointoken) "txHash", common.ToHex(a.tx.Hash()), "token name", withdraw.Cointoken)
receipt, err := a.assetWithdraw(withdraw, a.tx) receipt, err := a.assetWithdraw(withdraw, a.tx)
if err != nil { if err != nil {
clog.Error("AssetWithdraw failed", "err", err) clog.Error("AssetWithdraw failed", "err", err)
...@@ -982,6 +1041,27 @@ func (a *action) AssetWithdraw(withdraw *types.AssetsWithdraw) (*types.Receipt, ...@@ -982,6 +1041,27 @@ func (a *action) AssetWithdraw(withdraw *types.AssetsWithdraw) (*types.Receipt,
return receipt, nil return receipt, nil
} }
func (a *action) CrossAssetTransfer(transfer *pt.CrossAssetTransfer) (*types.Receipt, error) {
clog.Debug("Paracross.CrossAssetTransfer", "exec", transfer.AssetExec, "symbol", transfer.AssetSymbol)
cfg := a.api.GetConfig()
isPara := cfg.IsPara()
act, err := getCrossAction(transfer, string(a.tx.Execer))
if act == pt.ParacrossNoneTransfer {
return nil, err
}
// 需要平行链先执行, 达成共识时,继续执行
if !isPara && (act == pt.ParacrossMainWithdraw || act == pt.ParacrossParaTransfer) {
return nil, nil
}
receipt, err := a.crossAssetTransfer(transfer, act, a.tx)
if err != nil {
clog.Error("CrossAssetTransfer failed", "err", err)
return nil, err
}
return receipt, nil
}
//当前miner tx不需要校验上一个区块的衔接性,因为tx就是本节点发出,高度,preHash等都在本区块里面的blockchain做了校验 //当前miner tx不需要校验上一个区块的衔接性,因为tx就是本节点发出,高度,preHash等都在本区块里面的blockchain做了校验
func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) { func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
...@@ -1057,7 +1137,7 @@ func (a *Paracross) CrossLimits(tx *types.Transaction, index int) bool { ...@@ -1057,7 +1137,7 @@ func (a *Paracross) CrossLimits(tx *types.Transaction, index int) bool {
txs, err := a.GetTxGroup(index) txs, err := a.GetTxGroup(index)
if err != nil { if err != nil {
clog.Error("crossLimits", "get tx group failed", err, "hash", hex.EncodeToString(tx.Hash())) clog.Error("crossLimits", "get tx group failed", err, "hash", common.ToHex(tx.Hash()))
return false return false
} }
......
...@@ -7,94 +7,300 @@ package executor ...@@ -7,94 +7,300 @@ package executor
import ( import (
"encoding/hex" "encoding/hex"
"strings"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/db" "github.com/33cn/chain33/common/db"
coins "github.com/33cn/chain33/system/dapp/coins/types"
"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"
token "github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
func (a *action) assetTransfer(transfer *types.AssetsTransfer) (*types.Receipt, error) { const SYMBOL_BTY = "bty"
//平行链向主链transfer,先在平行链处理,共识后再在主链铸造
//主链的token转移到user.p.bb.平行链,在平行链上表示为mavl-paracross-token.symbol:
//主链的平行链转移进来的token在主链表示为mavl-paracross-user.p.aa.token.symbol 转移到user.p.bb.平行链,在平行链bb上表示mavl-paracross-paracross.user.p.aa.token.symbol
//在用户看来,平行链的资产是user.p.test.ccny, 主链资产是coins.bty, 平行链往主链转还是主链往平行链转都是这个名字
//如果主链上user.p.test.coins.ccny往user.p.test.平行链转,就是withdraw流程,如果往另一个平行链user.p.xx.转,则是转移流程
//主链转移场景: type=0,tx.exec:user.p.test.
//1. 主链本币转移: exec:coins/token symbol:{coins/token}.bty/cny or bty/cny,
// 平行链资产: paracross-coins.bty
//2. 主链外币转移: exec:paracross, symbol: user.p.para.coins.ccny,
// 平行链资产: paracross-paracross.user.p.para.coins.ccny
//3. 平行链本币提回:  exec:coins, symbol: user.p.test.coins.ccny
// 平行链资产: paracross账户coins.ccny资产释放
//平行链转移场景:type=1,tx.exec:user.p.test.
//1. 平行链本币转移: exec:coins/token, symbol:user.p.test.{coins/token}.ccny
// 主链产生资产: paracross-user.p.test.{coins}.ccny
//2. 主链外币提取: exec:paracross, symbol: user.p.para.coins.ccny
// 主链恢复外币资产: user.p.test.paracross地址释放user.p.para.coins.ccny
//3. 主链本币提取: exec:coins/token, symbol: coins.bty
// 主链恢复本币资产: user.p.test.paracross地址释放coin.bty
func getCrossAction(transfer *pt.CrossAssetTransfer, txExecer string) (int64, error) {
paraTitle, ok := types.GetParaExecTitleName(txExecer)
if !ok {
return pt.ParacrossNoneTransfer, errors.Wrapf(types.ErrInvalidParam, "getCrossAction wrong execer:%s", txExecer)
}
//主链向平行链转移, 转移主链资产(包括主链本币和平行链转移进来的外币)或平行链资产withdraw
if transfer.Type == 0 {
// same prefix for paraChain and Symbol
if strings.Contains(transfer.AssetSymbol, paraTitle) {
return pt.ParacrossParaWithdraw, nil
}
// different paraChain symbol or mainChain symbol -> main asset transfer
return pt.ParacrossMainTransfer, nil
}
//从平行链向主链转移,平行链资产转移或者主链资产withdraw
//symbol和paraChain prefix一致,或者symbol没有"." -> para asset transfer
if strings.Contains(transfer.AssetSymbol, paraTitle) {
return pt.ParacrossParaTransfer, nil
}
// different paraChain symbol or mainChain symbol or null symbol -> main asset withdraw
return pt.ParacrossMainWithdraw, nil
}
//自动补充一些参数,比如paracross执行器或symbol
func formatTransfer(transfer *pt.CrossAssetTransfer, act int64) *pt.CrossAssetTransfer {
newTransfer := *transfer
if act == pt.ParacrossMainTransfer || act == pt.ParacrossMainWithdraw {
//转移平行链资产到另一个平行链
if strings.HasPrefix(transfer.AssetSymbol, types.ParaKeyX) {
newTransfer.AssetExec = pt.ParaX
return &newTransfer
}
//转移资产symbol为bty 或 token.bty场景
if len(transfer.AssetSymbol) > 0 {
if strings.Contains(transfer.AssetSymbol, ".") {
elements := strings.Split(transfer.AssetSymbol, ".")
newTransfer.AssetExec = elements[len(elements)-2]
newTransfer.AssetSymbol = elements[len(elements)-1]
return &newTransfer
}
newTransfer.AssetExec = token.TokenX
return &newTransfer
}
//assetSymbol 为null
newTransfer.AssetExec = coins.CoinsX
newTransfer.AssetSymbol = SYMBOL_BTY
return &newTransfer
}
//把user.p.{para}.ccny prefix去掉,保留ccny
if act == pt.ParacrossParaTransfer || act == pt.ParacrossParaWithdraw {
e := strings.Split(transfer.AssetSymbol, ".")
newTransfer.AssetSymbol = e[len(e)-1]
newTransfer.AssetExec = e[len(e)-2]
//user.p.xx.ccny,没有写coins 执行器场景
if len(e) == 4 {
newTransfer.AssetExec = coins.CoinsX
}
return &newTransfer
}
return transfer
}
func (a *action) crossAssetTransfer(transfer *pt.CrossAssetTransfer, act int64, actTx *types.Transaction) (*types.Receipt, error) {
newTransfer := formatTransfer(transfer, act)
clog.Info("paracross.crossAssetTransfer", "action", act, "newExec", newTransfer.AssetExec, "newSymbol", newTransfer.AssetSymbol,
"ori.symbol", transfer.AssetSymbol, "type", transfer.Type, "txHash", common.ToHex(a.tx.Hash()))
switch act {
case pt.ParacrossMainTransfer:
return a.mainAssetTransfer(newTransfer)
case pt.ParacrossMainWithdraw:
return a.mainAssetWithdraw(newTransfer, actTx)
case pt.ParacrossParaTransfer:
return a.paraAssetTransfer(newTransfer)
case pt.ParacrossParaWithdraw:
return a.paraAssetWithdraw(newTransfer, actTx)
default:
return nil, types.ErrNotSupport
}
}
func (a *action) mainAssetTransfer(transfer *pt.CrossAssetTransfer) (*types.Receipt, error) {
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
isPara := cfg.IsPara() isPara := cfg.IsPara()
//主链处理分支 //主链处理分支
if !isPara { if !isPara {
accDB, err := createAccount(cfg, a.db, transfer.Cointoken) return a.execTransfer(transfer)
if err != nil { }
return nil, errors.Wrap(err, "assetTransferToken call account.NewAccountDB failed") return a.execCreateAsset(transfer)
} }
execAddr := address.ExecAddress(pt.ParaX)
fromAcc := accDB.LoadExecAccount(a.fromaddr, execAddr) func (a *action) mainAssetWithdraw(withdraw *pt.CrossAssetTransfer, withdrawTx *types.Transaction) (*types.Receipt, error) {
if fromAcc.Balance < transfer.Amount { cfg := a.api.GetConfig()
return nil, errors.Wrap(types.ErrNoBalance, "assetTransfer") isPara := cfg.IsPara()
} //主链处理分支
toAddr := address.ExecAddress(string(a.tx.Execer)) if !isPara {
clog.Debug("paracross.AssetTransfer not isPara", "execer", string(a.tx.Execer), return a.execWithdraw(withdraw, withdrawTx)
"txHash", hex.EncodeToString(a.tx.Hash())) }
return accDB.ExecTransfer(a.fromaddr, toAddr, execAddr, transfer.Amount) return a.execDestroyAsset(withdraw)
}
func (a *action) paraAssetTransfer(transfer *pt.CrossAssetTransfer) (*types.Receipt, error) {
cfg := a.api.GetConfig()
isPara := cfg.IsPara()
//平行链链处理分支
if isPara {
return a.execTransfer(transfer)
}
return a.execCreateAsset(transfer)
}
//平行链从主链提回, 先在主链处理,然后在平行链处理, 如果平行链执行失败,共识后主链再回滚
func (a *action) paraAssetWithdraw(withdraw *pt.CrossAssetTransfer, withdrawTx *types.Transaction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
isPara := cfg.IsPara()
//平行链链处理分支
if isPara {
return a.execWithdraw(withdraw, withdrawTx)
}
return a.execDestroyAsset(withdraw)
}
func (a *action) execTransfer(transfer *pt.CrossAssetTransfer) (*types.Receipt, error) {
cfg := a.api.GetConfig()
accDB, err := a.createAccount(cfg, a.db, transfer.AssetExec, transfer.AssetSymbol)
if err != nil {
return nil, errors.Wrap(err, "execTransfer.createAccount failed")
} }
//平行链处理分支
//主链上存入toAddr为user.p.xx.paracross地址
execAddr := address.ExecAddress(pt.ParaX)
toAddr := address.ExecAddress(string(a.tx.Execer))
//在平行链上存入toAddr为paracross地址
if cfg.IsPara() {
execAddr = address.ExecAddress(string(a.tx.Execer))
toAddr = address.ExecAddress(pt.ParaX)
}
fromAcc := accDB.LoadExecAccount(a.fromaddr, execAddr)
if fromAcc.Balance < transfer.Amount {
return nil, errors.Wrapf(types.ErrNoBalance, "execTransfer,fromBalance=%d", fromAcc.Balance)
}
clog.Debug("paracross.execTransfer", "execer", string(a.tx.Execer), "assetexec", transfer.AssetExec, "symbol", transfer.AssetSymbol,
"txHash", hex.EncodeToString(a.tx.Hash()))
return accDB.ExecTransfer(a.fromaddr, toAddr, execAddr, transfer.Amount)
}
func (a *action) execWithdraw(withdraw *pt.CrossAssetTransfer, withdrawTx *types.Transaction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
accDB, err := a.createAccount(cfg, a.db, withdraw.AssetExec, withdraw.AssetSymbol)
if err != nil {
return nil, errors.Wrap(err, "execWithdraw.createAccount failed")
}
execAddr := address.ExecAddress(pt.ParaX)
fromAddr := address.ExecAddress(string(withdrawTx.Execer))
if cfg.IsPara() {
execAddr = address.ExecAddress(string(withdrawTx.Execer))
fromAddr = address.ExecAddress(pt.ParaX)
}
clog.Debug("Paracross.execWithdraw", "amount", withdraw.Amount, "from", fromAddr,
"assetExec", withdraw.AssetExec, "symbol", withdraw.AssetSymbol, "execAddr", execAddr, "txHash", hex.EncodeToString(a.tx.Hash()))
return accDB.ExecTransfer(fromAddr, withdraw.ToAddr, execAddr, withdraw.Amount)
}
func (a *action) execCreateAsset(transfer *pt.CrossAssetTransfer) (*types.Receipt, error) {
cfg := a.api.GetConfig()
paraTitle, err := getTitleFrom(a.tx.Execer) paraTitle, err := getTitleFrom(a.tx.Execer)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "assetTransferCoins call getTitleFrom failed") return nil, errors.Wrapf(err, "execCreateAsset call getTitleFrom failed,exec=%s", string(a.tx.Execer))
}
assetExec := transfer.AssetExec
assetSymbol := transfer.AssetSymbol
if assetSymbol == "" {
assetExec = coins.CoinsX
assetSymbol = SYMBOL_BTY
} else if assetExec == "" {
assetExec = token.TokenX
} }
var paraAcc *account.DB if !cfg.IsPara() {
if transfer.Cointoken == "" { assetExec = string(paraTitle) + assetExec
paraAcc, err = NewParaAccount(cfg, string(paraTitle), "coins", "bty", a.db)
} else {
paraAcc, err = NewParaAccount(cfg, string(paraTitle), "token", transfer.Cointoken, a.db)
} }
paraAcc, err := NewParaAccount(cfg, string(paraTitle), assetExec, assetSymbol, a.db)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "assetTransferCoins call NewParaAccount failed") return nil, errors.Wrapf(err, "execCreateAsset call NewParaAccount failed,exec=%s,symbol=%s", assetExec, assetSymbol)
} }
clog.Debug("paracross.AssetTransfer isPara", "execer", string(a.tx.Execer), clog.Debug("paracross.execCreateAsset", "execer", string(a.tx.Execer), "assetExec", assetExec, "symbol", assetSymbol,
"txHash", hex.EncodeToString(a.tx.Hash())) "txHash", hex.EncodeToString(a.tx.Hash()))
return assetDepositBalance(paraAcc, transfer.To, transfer.Amount) return assetDepositBalance(paraAcc, transfer.ToAddr, transfer.Amount)
} }
func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types.Transaction) (*types.Receipt, error) { func (a *action) execDestroyAsset(withdraw *pt.CrossAssetTransfer) (*types.Receipt, error) {
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
isPara := cfg.IsPara()
//主链处理分支
if !isPara {
accDB, err := createAccount(cfg, a.db, withdraw.Cointoken)
if err != nil {
return nil, errors.Wrap(err, "assetWithdrawCoins call account.NewAccountDB failed")
}
fromAddr := address.ExecAddress(string(withdrawTx.Execer))
execAddr := address.ExecAddress(pt.ParaX)
clog.Debug("Paracross.Exec", "AssettWithdraw", withdraw.Amount, "from", fromAddr,
"to", withdraw.To, "exec", execAddr, "withdrawTx execor", string(withdrawTx.Execer))
return accDB.ExecTransfer(fromAddr, withdraw.To, execAddr, withdraw.Amount)
}
//平行链处理分支
paraTitle, err := getTitleFrom(a.tx.Execer) paraTitle, err := getTitleFrom(a.tx.Execer)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "assetWithdrawCoins call getTitleFrom failed") return nil, errors.Wrap(err, "execDestroyAsset call getTitleFrom failed")
}
assetExec := withdraw.AssetExec
assetSymbol := withdraw.AssetSymbol
if assetSymbol == "" {
assetExec = coins.CoinsX
assetSymbol = SYMBOL_BTY
} else if assetExec == "" {
assetExec = token.TokenX
} }
var paraAcc *account.DB if !cfg.IsPara() {
if withdraw.Cointoken == "" { assetExec = string(paraTitle) + assetExec
paraAcc, err = NewParaAccount(cfg, string(paraTitle), "coins", "bty", a.db)
} else {
paraAcc, err = NewParaAccount(cfg, string(paraTitle), "token", withdraw.Cointoken, a.db)
} }
paraAcc, err := NewParaAccount(cfg, string(paraTitle), assetExec, assetSymbol, a.db)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "assetWithdrawCoins call NewParaAccount failed") return nil, errors.Wrapf(err, "execDestroyAsset call NewParaAccount failed,exec=%s,symbol=%s", assetExec, assetSymbol)
} }
clog.Debug("paracross.assetWithdrawCoins isPara", "execer", string(a.tx.Execer), clog.Debug("paracross.execDestroyAsset", "execer", string(a.tx.Execer), "assetExec", assetExec, "symbol", assetSymbol,
"txHash", hex.EncodeToString(a.tx.Hash()), "from", a.fromaddr, "amount", withdraw.Amount) "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)
} }
func (a *action) assetTransferRollback(transfer *types.AssetsTransfer, transferTx *types.Transaction) (*types.Receipt, error) { //旧的接口,只有主链向平行链转移
func (a *action) assetTransfer(transfer *types.AssetsTransfer) (*types.Receipt, error) {
tr := &pt.CrossAssetTransfer{
AssetSymbol: transfer.Cointoken,
Amount: transfer.Amount,
Note: string(transfer.Note),
ToAddr: transfer.To,
}
return a.mainAssetTransfer(tr)
}
func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types.Transaction) (*types.Receipt, error) {
tr := &pt.CrossAssetTransfer{
AssetExec: withdraw.ExecName,
AssetSymbol: withdraw.Cointoken,
Amount: withdraw.Amount,
Note: string(withdraw.Note),
ToAddr: withdraw.To,
}
//旧的只有主链向平行链转移和withdraw操作,如果cointoken非空,执行器就是token,不会是其他的
if withdraw.Cointoken != "" {
tr.AssetExec = token.TokenX
}
return a.mainAssetWithdraw(tr, withdrawTx)
}
func (a *action) assetTransferRollback(tr *pt.CrossAssetTransfer, transferTx *types.Transaction) (*types.Receipt, error) {
cfg := a.api.GetConfig() cfg := a.api.GetConfig()
isPara := cfg.IsPara() isPara := cfg.IsPara()
//主链处理分支 //主链处理分支
if !isPara { if !isPara {
accDB, err := createAccount(cfg, a.db, transfer.Cointoken) transfer := formatTransfer(tr, pt.ParacrossMainTransfer)
accDB, err := a.createAccount(cfg, a.db, transfer.AssetExec, transfer.AssetSymbol)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "assetTransferToken call account.NewAccountDB failed") return nil, errors.Wrap(err, "assetTransferRollback.createAccount failed")
} }
execAddr := address.ExecAddress(pt.ParaX) execAddr := address.ExecAddress(pt.ParaX)
fromAcc := address.ExecAddress(string(transferTx.Execer)) fromAcc := address.ExecAddress(string(transferTx.Execer))
...@@ -105,14 +311,37 @@ func (a *action) assetTransferRollback(transfer *types.AssetsTransfer, transferT ...@@ -105,14 +311,37 @@ func (a *action) assetTransferRollback(transfer *types.AssetsTransfer, transferT
return nil, nil return nil, nil
} }
func createAccount(cfg *types.Chain33Config, db db.KV, symbol string) (*account.DB, error) { //平行链从主链withdraw在平行链执行失败,主链恢复数据,主链执行
func (a *action) paraAssetWithdrawRollback(wtw *pt.CrossAssetTransfer, withdrawTx *types.Transaction) (*types.Receipt, error) {
cfg := a.api.GetConfig()
isPara := cfg.IsPara()
//主链处理分支
if !isPara {
withdraw := formatTransfer(wtw, pt.ParacrossParaWithdraw)
paraTitle, err := getTitleFrom(a.tx.Execer)
if err != nil {
return nil, errors.Wrap(err, "paraAssetWithdrawRollback call getTitleFrom failed")
}
var paraAcc *account.DB
paraAcc, err = NewParaAccount(cfg, string(paraTitle), string(paraTitle)+withdraw.AssetExec, withdraw.AssetSymbol, a.db)
if err != nil {
return nil, errors.Wrap(err, "paraAssetWithdrawRollback call NewParaAccount failed")
}
clog.Debug("paracross.paraAssetWithdrawRollback", "execer", string(a.tx.Execer), "txHash", hex.EncodeToString(a.tx.Hash()))
return assetDepositBalance(paraAcc, withdrawTx.From(), withdraw.Amount)
}
return nil, nil
}
func (a *action) createAccount(cfg *types.Chain33Config, db db.KV, exec, symbol string) (*account.DB, error) {
var accDB *account.DB var accDB *account.DB
var err error
if symbol == "" { if symbol == "" {
accDB = account.NewCoinsAccount(cfg) accDB = account.NewCoinsAccount(cfg)
accDB.SetDB(db) accDB.SetDB(db)
} else { return accDB, nil
accDB, err = account.NewAccountDB(cfg, "token", symbol, db) }
if exec == "" {
exec = token.TokenX
} }
return accDB, err return account.NewAccountDB(cfg, exec, symbol, db)
} }
...@@ -42,7 +42,6 @@ func (e *Paracross) Exec_AssetTransfer(payload *types.AssetsTransfer, tx *types. ...@@ -42,7 +42,6 @@ func (e *Paracross) Exec_AssetTransfer(payload *types.AssetsTransfer, tx *types.
//Exec_AssetWithdraw asset withdraw exec process //Exec_AssetWithdraw asset withdraw exec process
func (e *Paracross) Exec_AssetWithdraw(payload *types.AssetsWithdraw, tx *types.Transaction, index int) (*types.Receipt, error) { func (e *Paracross) Exec_AssetWithdraw(payload *types.AssetsWithdraw, tx *types.Transaction, index int) (*types.Receipt, error) {
clog.Debug("Paracross.Exec", "withdraw", "")
_, err := e.checkTxGroup(tx, index) _, err := e.checkTxGroup(tx, index)
if err != nil { if err != nil {
clog.Error("ParacrossActionAssetWithdraw", "get tx group failed", err, "hash", hex.EncodeToString(tx.Hash())) clog.Error("ParacrossActionAssetWithdraw", "get tx group failed", err, "hash", hex.EncodeToString(tx.Hash()))
...@@ -57,6 +56,22 @@ func (e *Paracross) Exec_AssetWithdraw(payload *types.AssetsWithdraw, tx *types. ...@@ -57,6 +56,22 @@ func (e *Paracross) Exec_AssetWithdraw(payload *types.AssetsWithdraw, tx *types.
return receipt, nil return receipt, nil
} }
//Exec_ParaAssetTransfer parallel chain asset transfer exec process
func (e *Paracross) Exec_CrossAssetTransfer(payload *pt.CrossAssetTransfer, tx *types.Transaction, index int) (*types.Receipt, error) {
_, err := e.checkTxGroup(tx, index)
if err != nil {
clog.Error("ParacrossActionCrossAssetTransfer", "get tx group failed", err, "hash", hex.EncodeToString(tx.Hash()))
return nil, err
}
a := newAction(e, tx)
receipt, err := a.CrossAssetTransfer(payload)
if err != nil {
clog.Error("Paracross CrossAssetTransfer failed", "error", err, "hash", hex.EncodeToString(tx.Hash()))
return nil, errors.Cause(err)
}
return receipt, nil
}
//Exec_Miner miner tx exec process //Exec_Miner miner tx exec process
func (e *Paracross) Exec_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, index int) (*types.Receipt, error) { func (e *Paracross) Exec_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, index int) (*types.Receipt, error) {
if index != 0 { if index != 0 {
......
...@@ -145,7 +145,7 @@ func (e *Paracross) ExecDelLocal_AssetTransfer(payload *types.AssetsTransfer, tx ...@@ -145,7 +145,7 @@ func (e *Paracross) ExecDelLocal_AssetTransfer(payload *types.AssetsTransfer, tx
// 主链转出记录, // 主链转出记录,
// 转入在 commit done 时记录, 因为没有日志里没有当时tx信息 // 转入在 commit done 时记录, 因为没有日志里没有当时tx信息
r, err := e.initLocalAssetTransfer(tx, true, true) r, err := e.initLocalAssetTransfer(tx, true, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -159,6 +159,18 @@ func (e *Paracross) ExecDelLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx ...@@ -159,6 +159,18 @@ func (e *Paracross) ExecDelLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx
return nil, nil return nil, nil
} }
//ExecDelLocal_AssetTransfer asset transfer del local db process
func (e *Paracross) ExecDelLocal_CrossAssetTransfer(payload *pt.CrossAssetTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
r, err := e.initLocalAssetTransfer(tx, true, nil)
if err != nil {
return nil, err
}
set.KV = append(set.KV, r)
return &set, nil
}
//ExecDelLocal_Miner miner tx del local db process //ExecDelLocal_Miner miner tx del local db process
func (e *Paracross) ExecDelLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (e *Paracross) ExecDelLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if index != 0 { if index != 0 {
......
...@@ -148,7 +148,11 @@ func (e *Paracross) ExecLocal_AssetTransfer(payload *types.AssetsTransfer, tx *t ...@@ -148,7 +148,11 @@ func (e *Paracross) ExecLocal_AssetTransfer(payload *types.AssetsTransfer, tx *t
// 主链转出记录, // 主链转出记录,
// 转入在 commit done 时记录, 因为没有日志里没有当时tx信息 // 转入在 commit done 时记录, 因为没有日志里没有当时tx信息
r, err := e.initLocalAssetTransfer(tx, true, false) asset, err := e.getAssetTransferInfo(tx, payload.Cointoken, false)
if err != nil {
return nil, err
}
r, err := e.initLocalAssetTransfer(tx, false, asset)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -162,6 +166,33 @@ func (e *Paracross) ExecLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx *t ...@@ -162,6 +166,33 @@ func (e *Paracross) ExecLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx *t
return nil, nil return nil, nil
} }
//ExecLocal_AssetTransfer asset transfer local proc
func (e *Paracross) ExecLocal_CrossAssetTransfer(payload *pt.CrossAssetTransfer, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
var set types.LocalDBSet
cfg := e.GetAPI().GetConfig()
act, err := getCrossAction(payload, string(tx.Execer))
if err != nil {
clog.Crit("local CrossAssetTransfer getCrossAction failed", "error", err)
return nil, err
}
// 主链转出和平行链提取记录,
// 主链提取和平行链转出在 commit done 时记录
if !cfg.IsPara() && (act == pt.ParacrossMainWithdraw || act == pt.ParacrossParaTransfer) {
return nil, nil
}
asset, err := e.getCrossAssetTransferInfo(payload, tx)
if err != nil {
return nil, err
}
r, err := e.initLocalAssetTransfer(tx, false, asset)
if err != nil {
return nil, err
}
set.KV = append(set.KV, r)
return &set, nil
}
func setMinerTxResult(cfg *types.Chain33Config, payload *pt.ParacrossMinerAction, txs []*types.Transaction, receipts []*types.ReceiptData) error { func setMinerTxResult(cfg *types.Chain33Config, payload *pt.ParacrossMinerAction, txs []*types.Transaction, receipts []*types.ReceiptData) error {
isCommitTx := make(map[string]bool) isCommitTx := make(map[string]bool)
var curTxHashs, paraTxHashs, crossTxHashs [][]byte var curTxHashs, paraTxHashs, crossTxHashs [][]byte
......
...@@ -8,12 +8,12 @@ import ( ...@@ -8,12 +8,12 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"github.com/33cn/chain33/common"
log "github.com/33cn/chain33/common/log/log15" log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp" drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types" pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
) )
var ( var (
...@@ -135,14 +135,46 @@ func (c *Paracross) udpateLocalParaTxs(paraTitle string, paraHeight int64, cross ...@@ -135,14 +135,46 @@ func (c *Paracross) udpateLocalParaTxs(paraTitle string, paraHeight int64, cross
hex.EncodeToString(crossTxHashs[i])) hex.EncodeToString(crossTxHashs[i]))
return nil, err return nil, err
} }
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
act, err := getCrossAction(payload.GetCrossAssetTransfer(), string(paraTx.Tx.Execer))
if err != nil {
clog.Crit("udpateLocalParaTxs getCrossAction failed", "error", err)
return nil, err
}
//主链共识后,平行链执行出错的主链资产transfer回滚
if act == pt.ParacrossMainTransfer || act == pt.ParacrossParaWithdraw {
kv, err := c.updateLocalAssetTransfer(paraTx.Tx, paraHeight, success, isDel)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kv)
}
//主链共识后,平行链执行出错的平行链资产withdraw回滚
if act == pt.ParacrossMainWithdraw || act == pt.ParacrossParaTransfer {
asset, err := c.getCrossAssetTransferInfo(payload.GetCrossAssetTransfer(), paraTx.Tx)
if err != nil {
return nil, err
}
kv, err := c.initLocalAssetTransferDone(paraTx.Tx, asset, paraHeight, success, isDel)
if err != nil {
return nil, err
}
set.KV = append(set.KV, kv)
}
}
if payload.Ty == pt.ParacrossActionAssetTransfer { if payload.Ty == pt.ParacrossActionAssetTransfer {
kv, err := c.updateLocalAssetTransfer(paraHeight, paraTx.Tx, success, isDel) kv, err := c.updateLocalAssetTransfer(paraTx.Tx, paraHeight, success, isDel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
set.KV = append(set.KV, kv) set.KV = append(set.KV, kv)
} else if payload.Ty == pt.ParacrossActionAssetWithdraw { } else if payload.Ty == pt.ParacrossActionAssetWithdraw {
kv, err := c.initLocalAssetWithdraw(paraHeight, paraTx.Tx, true, success, isDel) asset, err := c.getAssetTransferInfo(paraTx.Tx, payload.GetAssetWithdraw().Cointoken, true)
if err != nil {
return nil, err
}
kv, err := c.initLocalAssetTransferDone(paraTx.Tx, asset, paraHeight, success, isDel)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -153,105 +185,90 @@ func (c *Paracross) udpateLocalParaTxs(paraTitle string, paraHeight int64, cross ...@@ -153,105 +185,90 @@ func (c *Paracross) udpateLocalParaTxs(paraTitle string, paraHeight int64, cross
return &set, nil return &set, nil
} }
func (c *Paracross) initLocalAssetTransfer(tx *types.Transaction, success, isDel bool) (*types.KeyValue, error) { func (c *Paracross) getAssetTransferInfo(tx *types.Transaction, coinToken string, isWithdraw bool) (*pt.ParacrossAsset, error) {
clog.Debug("para execLocal", "tx hash", hex.EncodeToString(tx.Hash()), "action name", log.Lazy{Fn: tx.ActionName})
key := calcLocalAssetKey(tx.Hash())
if isDel {
c.GetLocalDB().Set(key, nil)
return &types.KeyValue{Key: key, Value: nil}, nil
}
var payload pt.ParacrossAction
err := types.Decode(tx.Payload, &payload)
if err != nil {
return nil, err
}
if payload.GetAssetTransfer() == nil {
return nil, errors.New("GetAssetTransfer is nil")
}
exec := "coins" exec := "coins"
symbol := types.BTY symbol := types.BTY
if payload.GetAssetTransfer().Cointoken != "" { if coinToken != "" {
exec = "token" exec = "token"
symbol = payload.GetAssetTransfer().Cointoken symbol = coinToken
} }
var asset pt.ParacrossAsset
amount, err := tx.Amount() amount, err := tx.Amount()
if err != nil { if err != nil {
return nil, err return nil, err
} }
asset = pt.ParacrossAsset{ asset := &pt.ParacrossAsset{
From: tx.From(), From: tx.From(),
To: tx.To, To: tx.To,
Amount: amount, Amount: amount,
IsWithdraw: false, IsWithdraw: isWithdraw,
TxHash: tx.Hash(), TxHash: common.ToHex(tx.Hash()),
Height: c.GetHeight(), Height: c.GetHeight(),
Exec: exec, Exec: exec,
Symbol: symbol, Symbol: symbol,
} }
return asset, nil
}
err = c.GetLocalDB().Set(key, types.Encode(&asset)) func (c *Paracross) getCrossAssetTransferInfo(payload *pt.CrossAssetTransfer, tx *types.Transaction) (*pt.ParacrossAsset, error) {
exec := payload.AssetExec
symbol := payload.AssetSymbol
if payload.AssetSymbol == "" {
symbol = types.BTY
exec = "coins"
}
amount, err := tx.Amount()
if err != nil { if err != nil {
clog.Error("para execLocal", "set", hex.EncodeToString(tx.Hash()), "failed", err) return nil, err
} }
return &types.KeyValue{Key: key, Value: types.Encode(&asset)}, nil
asset := &pt.ParacrossAsset{
From: tx.From(),
To: tx.To,
Amount: amount,
TxHash: common.ToHex(tx.Hash()),
Height: c.GetHeight(),
Exec: exec,
Symbol: symbol,
}
return asset, nil
} }
func (c *Paracross) initLocalAssetWithdraw(paraHeight int64, tx *types.Transaction, isWithdraw, success, isDel bool) (*types.KeyValue, error) { func (c *Paracross) initLocalAssetTransfer(tx *types.Transaction, isDel bool, asset *pt.ParacrossAsset) (*types.KeyValue, error) {
clog.Debug("para execLocal", "tx hash", hex.EncodeToString(tx.Hash()), "action name", log.Lazy{Fn: tx.ActionName})
key := calcLocalAssetKey(tx.Hash()) key := calcLocalAssetKey(tx.Hash())
if isDel { if isDel {
c.GetLocalDB().Set(key, nil) c.GetLocalDB().Set(key, nil)
return &types.KeyValue{Key: key, Value: nil}, nil return &types.KeyValue{Key: key, Value: nil}, nil
} }
var asset pt.ParacrossAsset err := c.GetLocalDB().Set(key, types.Encode(asset))
amount, err := tx.Amount()
if err != nil { if err != nil {
return nil, err clog.Error("para execLocal", "set", hex.EncodeToString(tx.Hash()), "failed", err)
}
asset.ParaHeight = paraHeight
var payload pt.ParacrossAction
err = types.Decode(tx.Payload, &payload)
if err != nil {
return nil, err
}
if payload.GetAssetWithdraw() == nil {
return nil, errors.New("GetAssetWithdraw is nil")
}
exec := "coins"
symbol := types.BTY
if payload.GetAssetWithdraw().Cointoken != "" {
exec = "token"
symbol = payload.GetAssetWithdraw().Cointoken
} }
return &types.KeyValue{Key: key, Value: types.Encode(asset)}, nil
}
asset = pt.ParacrossAsset{ func (c *Paracross) initLocalAssetTransferDone(tx *types.Transaction, asset *pt.ParacrossAsset, paraHeight int64, success, isDel bool) (*types.KeyValue, error) {
From: tx.From(), key := calcLocalAssetKey(tx.Hash())
To: tx.To, if isDel {
Amount: amount, c.GetLocalDB().Set(key, nil)
IsWithdraw: isWithdraw, return &types.KeyValue{Key: key, Value: nil}, nil
TxHash: tx.Hash(),
Height: c.GetHeight(),
Exec: exec,
Symbol: symbol,
} }
asset.ParaHeight = paraHeight
asset.CommitDoneHeight = c.GetHeight() asset.CommitDoneHeight = c.GetHeight()
asset.Success = success asset.Success = success
err = c.GetLocalDB().Set(key, types.Encode(&asset)) err := c.GetLocalDB().Set(key, types.Encode(asset))
if err != nil { if err != nil {
clog.Error("para execLocal", "set", "", "failed", err) clog.Error("para execLocal", "set", "", "failed", err)
} }
return &types.KeyValue{Key: key, Value: types.Encode(&asset)}, nil return &types.KeyValue{Key: key, Value: types.Encode(asset)}, nil
} }
func (c *Paracross) updateLocalAssetTransfer(paraHeight int64, tx *types.Transaction, success, isDel bool) (*types.KeyValue, error) { func (c *Paracross) updateLocalAssetTransfer(tx *types.Transaction, paraHeight int64, success, isDel bool) (*types.KeyValue, error) {
clog.Debug("para execLocal", "tx hash", hex.EncodeToString(tx.Hash())) clog.Debug("para execLocal", "tx hash", hex.EncodeToString(tx.Hash()))
key := calcLocalAssetKey(tx.Hash()) key := calcLocalAssetKey(tx.Hash())
...@@ -317,6 +334,11 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error { ...@@ -317,6 +334,11 @@ func (c *Paracross) allow(tx *types.Transaction, index int) error {
return nil return nil
} }
} }
if cfg.IsDappFork(c.GetHeight(), pt.ParaX, pt.ForkParaAssetTransferRbk) {
if payload.Ty == pt.ParacrossActionCrossAssetTransfer {
return nil
}
}
} }
return types.ErrNotAllow return types.ErrNotAllow
} }
......
...@@ -441,28 +441,7 @@ func (p *Paracross) paracrossGetAssetTxResult(hash []byte) (types.Message, error ...@@ -441,28 +441,7 @@ func (p *Paracross) paracrossGetAssetTxResult(hash []byte) (types.Message, error
return nil, err return nil, err
} }
rsp := &pt.ParacrossAssetRsp{ return &rst, nil
From: rst.From,
To: rst.To,
Amount: rst.Amount,
Exec: rst.Exec,
Symbol: rst.Symbol,
Height: rst.Height,
CommitDoneHeight: rst.CommitDoneHeight,
ParaHeight: rst.ParaHeight,
}
rsp.TxHash = common.ToHex(rst.TxHash)
rsp.IsWithdraw = "false"
if rst.IsWithdraw {
rsp.IsWithdraw = "true"
}
rsp.Success = "false"
if rst.Success {
rsp.Success = "true"
}
return rsp, nil
} }
//Query_GetSelfConsStages get self consensus stages configed //Query_GetSelfConsStages get self consensus stages configed
......
...@@ -268,6 +268,15 @@ message ParacrossMinerAction { ...@@ -268,6 +268,15 @@ message ParacrossMinerAction {
bool isSelfConsensus = 2; bool isSelfConsensus = 2;
} }
message CrossAssetTransfer {
uint32 type = 1;
string assetExec = 2;
string assetSymbol = 3;
int64 amount = 4;
string toAddr = 5;
string note = 6;
}
message ParacrossAction { message ParacrossAction {
oneof value { oneof value {
ParacrossCommitAction commit = 1; ParacrossCommitAction commit = 1;
...@@ -280,6 +289,7 @@ message ParacrossAction { ...@@ -280,6 +289,7 @@ message ParacrossAction {
ParaNodeAddrConfig nodeConfig = 9; ParaNodeAddrConfig nodeConfig = 9;
ParaNodeGroupConfig nodeGroupConfig = 10; ParaNodeGroupConfig nodeGroupConfig = 10;
ParaStageConfig selfStageConfig = 11; ParaStageConfig selfStageConfig = 11;
CrossAssetTransfer crossAssetTransfer = 12;
} }
int32 ty = 2; int32 ty = 2;
} }
...@@ -359,10 +369,12 @@ message ParacrossAsset { ...@@ -359,10 +369,12 @@ message ParacrossAsset {
string from = 1; string from = 1;
string to = 2; string to = 2;
bool isWithdraw = 3; bool isWithdraw = 3;
bytes txHash = 4; string txHash = 4;
int64 amount = 5; int64 amount = 5;
string exec = 6; string exec = 6;
string symbol = 7; string symbol = 7;
//跨链类型 0:to para, 1:to main
uint32 crossType = 8;
// 主链部分 // 主链部分
int64 height = 10; int64 height = 10;
// 平行链部分 // 平行链部分
...@@ -371,22 +383,6 @@ message ParacrossAsset { ...@@ -371,22 +383,6 @@ message ParacrossAsset {
bool success = 23; bool success = 23;
} }
message ParacrossAssetRsp {
// input
string from = 1;
string to = 2;
string isWithdraw = 3;
string txHash = 4;
int64 amount = 5;
string exec = 6;
string symbol = 7;
// 主链部分
int64 height = 10;
// 平行链部分
int64 commitDoneHeight = 21;
int64 paraHeight = 22;
string success = 23;
}
message ParaLocalDbBlock { message ParaLocalDbBlock {
int64 height = 1; int64 height = 1;
......
...@@ -46,6 +46,8 @@ const ( ...@@ -46,6 +46,8 @@ const (
TyLogParaSelfConsStageConfig = 665 TyLogParaSelfConsStageConfig = 665
TyLogParaStageVoteDone = 666 TyLogParaStageVoteDone = 666
TyLogParaStageGroupUpdate = 667 TyLogParaStageGroupUpdate = 667
//TyLogParaCrossAssetTransfer 统一的跨链资产转移
TyLogParaCrossAssetTransfer = 670
) )
type paracrossCommitTx struct { type paracrossCommitTx struct {
...@@ -73,9 +75,9 @@ const ( ...@@ -73,9 +75,9 @@ const (
) )
const ( const (
// ParacrossActionAssetTransfer paracross asset transfer key // ParacrossActionAssetTransfer mainchain paracross asset transfer key
ParacrossActionAssetTransfer = iota + paraCrossTransferActionTypeStart ParacrossActionAssetTransfer = iota + paraCrossTransferActionTypeStart
// ParacrossActionAssetWithdraw paracross asset withdraw key // ParacrossActionAssetWithdraw mainchain paracross asset withdraw key
ParacrossActionAssetWithdraw ParacrossActionAssetWithdraw
//ParacrossActionNodeConfig para super node config //ParacrossActionNodeConfig para super node config
ParacrossActionNodeConfig ParacrossActionNodeConfig
...@@ -83,6 +85,16 @@ const ( ...@@ -83,6 +85,16 @@ const (
ParacrossActionNodeGroupApply ParacrossActionNodeGroupApply
//ParacrossActionSelfConsensStageConfig apply for self consensus stage config //ParacrossActionSelfConsensStageConfig apply for self consensus stage config
ParacrossActionSelfStageConfig ParacrossActionSelfStageConfig
// ParacrossActionCrossAssetTransfer crossChain asset transfer key
ParacrossActionCrossAssetTransfer
)
const (
ParacrossNoneTransfer = iota
ParacrossMainTransfer
ParacrossMainWithdraw
ParacrossParaTransfer
ParacrossParaWithdraw
) )
// status // status
...@@ -342,6 +354,21 @@ func (p ParacrossType) CreateRawTransferTx(action string, param json.RawMessage) ...@@ -342,6 +354,21 @@ func (p ParacrossType) CreateRawTransferTx(action string, param json.RawMessage)
return tx, nil return tx, nil
} }
//CreateRawCrossAssetTransferTx create raw cross asset transfer tx
func CreateRawCrossAssetTransferTx(apply *CrossAssetTransfer) (*types.Transaction, error) {
action := &ParacrossAction{
Ty: ParacrossActionCrossAssetTransfer,
Value: &ParacrossAction_CrossAssetTransfer{apply},
}
tx := &types.Transaction{
Payload: types.Encode(action),
}
return tx, nil
}
//GetDappForkHeight get paracross dapp fork height //GetDappForkHeight get paracross dapp fork height
func GetDappForkHeight(cfg *types.Chain33Config, forkKey string) int64 { func GetDappForkHeight(cfg *types.Chain33Config, forkKey string) int64 {
var forkHeight int64 var forkHeight int64
......
...@@ -96,6 +96,7 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo { ...@@ -96,6 +96,7 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo {
TyLogParaAssetWithdraw: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetWithdraw"}, TyLogParaAssetWithdraw: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetWithdraw"},
TyLogParaAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetTransfer"}, TyLogParaAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetTransfer"},
TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"}, TyLogParaAssetDeposit: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaAssetDeposit"},
TyLogParaCrossAssetTransfer: {Ty: reflect.TypeOf(types.ReceiptAccountTransfer{}), Name: "LogParaCrossAssetTransfer"},
TyLogParacrossMiner: {Ty: reflect.TypeOf(ReceiptParacrossMiner{}), Name: "LogParacrossMiner"}, TyLogParacrossMiner: {Ty: reflect.TypeOf(ReceiptParacrossMiner{}), Name: "LogParacrossMiner"},
TyLogParaNodeConfig: {Ty: reflect.TypeOf(ReceiptParaNodeConfig{}), Name: "LogParaNodeConfig"}, TyLogParaNodeConfig: {Ty: reflect.TypeOf(ReceiptParaNodeConfig{}), Name: "LogParaNodeConfig"},
TyLogParaNodeStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeAddrStatUpdate{}), Name: "LogParaNodeAddrStatUpdate"}, TyLogParaNodeStatusUpdate: {Ty: reflect.TypeOf(ReceiptParaNodeAddrStatUpdate{}), Name: "LogParaNodeAddrStatUpdate"},
...@@ -112,16 +113,17 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo { ...@@ -112,16 +113,17 @@ func (p *ParacrossType) GetLogMap() map[int64]*types.LogInfo {
// GetTypeMap get action type // GetTypeMap get action type
func (p *ParacrossType) GetTypeMap() map[string]int32 { func (p *ParacrossType) GetTypeMap() map[string]int32 {
return map[string]int32{ return map[string]int32{
"Commit": ParacrossActionCommit, "Commit": ParacrossActionCommit,
"Miner": ParacrossActionMiner, "Miner": ParacrossActionMiner,
"AssetTransfer": ParacrossActionAssetTransfer, "AssetTransfer": ParacrossActionAssetTransfer,
"AssetWithdraw": ParacrossActionAssetWithdraw, "AssetWithdraw": ParacrossActionAssetWithdraw,
"Transfer": ParacrossActionTransfer, "Transfer": ParacrossActionTransfer,
"Withdraw": ParacrossActionWithdraw, "Withdraw": ParacrossActionWithdraw,
"TransferToExec": ParacrossActionTransferToExec, "TransferToExec": ParacrossActionTransferToExec,
"NodeConfig": ParacrossActionNodeConfig, "CrossAssetTransfer": ParacrossActionCrossAssetTransfer,
"NodeGroupConfig": ParacrossActionNodeGroupApply, "NodeConfig": ParacrossActionNodeConfig,
"SelfStageConfig": ParacrossActionSelfStageConfig, "NodeGroupConfig": ParacrossActionNodeGroupApply,
"SelfStageConfig": ParacrossActionSelfStageConfig,
} }
} }
...@@ -156,6 +158,14 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types. ...@@ -156,6 +158,14 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types.
action == "ParacrossTransferToExec" || action == "TransferToExec" { action == "ParacrossTransferToExec" || action == "TransferToExec" {
return p.CreateRawTransferTx(action, message) return p.CreateRawTransferTx(action, message)
} else if action == "CrossAssetTransfer" {
var param CrossAssetTransfer
err := types.JSONToPB(message, &param)
if err != nil {
glog.Error("CreateTx.CrossAssetTransfer", "Error", err)
return nil, types.ErrInvalidParam
}
return CreateRawCrossAssetTransferTx(&param)
} else if action == "NodeConfig" { } else if action == "NodeConfig" {
var param ParaNodeAddrConfig var param ParaNodeAddrConfig
err := types.JSONToPB(message, &param) err := types.JSONToPB(message, &param)
......
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