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

commit tx hash rmv

parent 69b28d4f
...@@ -25,6 +25,7 @@ import ( ...@@ -25,6 +25,7 @@ import (
drivers "github.com/33cn/chain33/system/consensus" drivers "github.com/33cn/chain33/system/consensus"
cty "github.com/33cn/chain33/system/dapp/coins/types" cty "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
paracross "github.com/33cn/plugin/plugin/dapp/paracross/types" paracross "github.com/33cn/plugin/plugin/dapp/paracross/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types" pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
) )
...@@ -33,8 +34,6 @@ const ( ...@@ -33,8 +34,6 @@ const (
addAct int64 = 1 //add para block action addAct int64 = 1 //add para block action
delAct int64 = 2 //reference blockstore.go, del para block action delAct int64 = 2 //reference blockstore.go, del para block action
paraCrossTxCount = 2 //current only support 2 txs for cross
minBlockNum = 6 //min block number startHeight before lastHeight in mainchain minBlockNum = 6 //min block number startHeight before lastHeight in mainchain
) )
...@@ -50,7 +49,8 @@ var ( ...@@ -50,7 +49,8 @@ var (
minerPrivateKey = "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" minerPrivateKey = "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
searchHashMatchDepth int32 = 100 searchHashMatchDepth int32 = 100
mainBlockHashForkHeight int64 = 209186 //calc block hash fork height in main chain mainBlockHashForkHeight int64 = 209186 //calc block hash fork height in main chain
mainParaSelfConsensusForkHeight int64 = types.MaxHeight //support paracross commit tx fork height in main chain: ForkParacrossCommitTx mainParaSelfConsensusForkHeight int64 = types.MaxHeight //para chain self consensus height switch, must >= ForkParacrossCommitTx of main
mainForkParacrossCommitTx int64 = types.MaxHeight //support paracross commit tx fork height in main chain: ForkParacrossCommitTx
) )
func init() { func init() {
...@@ -82,6 +82,7 @@ type subConfig struct { ...@@ -82,6 +82,7 @@ type subConfig struct {
GenesisAmount int64 `json:"genesisAmount,omitempty"` GenesisAmount int64 `json:"genesisAmount,omitempty"`
MainBlockHashForkHeight int64 `json:"mainBlockHashForkHeight,omitempty"` MainBlockHashForkHeight int64 `json:"mainBlockHashForkHeight,omitempty"`
MainParaSelfConsensusForkHeight int64 `json:"mainParaSelfConsensusForkHeight,omitempty"` MainParaSelfConsensusForkHeight int64 `json:"mainParaSelfConsensusForkHeight,omitempty"`
MainForkParacrossCommitTx int64 `json:"mainForkParacrossCommitTx,omitempty"`
} }
// New function to init paracross env // New function to init paracross env
...@@ -117,6 +118,10 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -117,6 +118,10 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
mainParaSelfConsensusForkHeight = subcfg.MainParaSelfConsensusForkHeight mainParaSelfConsensusForkHeight = subcfg.MainParaSelfConsensusForkHeight
} }
if subcfg.MainForkParacrossCommitTx > 0 {
mainForkParacrossCommitTx = subcfg.MainForkParacrossCommitTx
}
pk, err := hex.DecodeString(minerPrivateKey) pk, err := hex.DecodeString(minerPrivateKey)
if err != nil { if err != nil {
panic(err) panic(err)
...@@ -267,56 +272,6 @@ func (client *client) ProcEvent(msg *queue.Message) bool { ...@@ -267,56 +272,6 @@ func (client *client) ProcEvent(msg *queue.Message) bool {
return false return false
} }
//1. 如果涉及跨链合约,如果有超过两条平行链的交易被判定为失败,交易组会执行不成功,也不PACK。(这样的情况下,主链交易一定会执行不成功)
//2. 如果不涉及跨链合约,那么交易组没有任何规定,可以是20比,10条链。 如果主链交易有失败,平行链也不会执行
//3. 如果交易组有一个ExecOk,主链上的交易都是ok的,可以全部打包
//4. 如果全部是ExecPack,有两种情况,一是交易组所有交易都是平行链交易,另一是主链有交易失败而打包了的交易,需要检查LogErr,如果有错,全部不打包
func calcParaCrossTxGroup(tx *types.Transaction, main *types.BlockDetail, index int) ([]*types.Transaction, int) {
var headIdx int
for i := index; i >= 0; i-- {
if bytes.Equal(tx.Header, main.Block.Txs[i].Hash()) {
headIdx = i
break
}
}
endIdx := headIdx + int(tx.GroupCount)
for i := headIdx; i < endIdx; i++ {
if types.IsMyParaExecName(string(main.Block.Txs[i].Execer)) {
continue
}
if main.Receipts[i].Ty == types.ExecOk {
return main.Block.Txs[headIdx:endIdx], endIdx
}
for _, log := range main.Receipts[i].Logs {
if log.Ty == types.TyLogErr {
return nil, endIdx
}
}
}
//全部是平行链交易 或主链执行非失败的tx
return main.Block.Txs[headIdx:endIdx], endIdx
}
func (client *client) FilterTxsForPara(main *types.BlockDetail) []*types.Transaction {
var txs []*types.Transaction
for i := 0; i < len(main.Block.Txs); i++ {
tx := main.Block.Txs[i]
if types.IsMyParaExecName(string(tx.Execer)) {
if tx.GroupCount >= paraCrossTxCount {
mainTxs, endIdx := calcParaCrossTxGroup(tx, main, i)
txs = append(txs, mainTxs...)
i = endIdx - 1
continue
}
txs = append(txs, tx)
}
}
return txs
}
//get the last sequence in parachain //get the last sequence in parachain
func (client *client) GetLastSeq() (int64, error) { func (client *client) GetLastSeq() (int64, error) {
blockedSeq, err := client.GetAPI().GetLastBlockSequence() blockedSeq, err := client.GetAPI().GetLastBlockSequence()
...@@ -472,7 +427,7 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type ...@@ -472,7 +427,7 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type
(bytes.Equal(preMainBlockHash, blockSeq.Detail.Block.ParentHash) && blockSeq.Seq.Type == addAct) || (bytes.Equal(preMainBlockHash, blockSeq.Detail.Block.ParentHash) && blockSeq.Seq.Type == addAct) ||
(bytes.Equal(preMainBlockHash, blockSeq.Seq.Hash) && blockSeq.Seq.Type == delAct) { (bytes.Equal(preMainBlockHash, blockSeq.Seq.Hash) && blockSeq.Seq.Type == delAct) {
txs := client.FilterTxsForPara(blockSeq.Detail) txs := util.FilterTxsForPara(types.GetTitle(), blockSeq.Detail)
plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", blockSeq.Seq.Type) plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", blockSeq.Seq.Type)
client.mtx.Lock() client.mtx.Lock()
...@@ -694,7 +649,7 @@ func (client *client) CreateBlock() { ...@@ -694,7 +649,7 @@ func (client *client) CreateBlock() {
} }
// miner tx need all para node create, but not all node has auth account, here just not sign to keep align // miner tx need all para node create, but not all node has auth account, here just not sign to keep align
func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *types.BlockSeq) error { func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *types.BlockSeq, txs []*types.Transaction) error {
status := &pt.ParacrossNodeStatus{ status := &pt.ParacrossNodeStatus{
Title: types.GetTitle(), Title: types.GetTitle(),
Height: block.Height, Height: block.Height,
...@@ -703,6 +658,16 @@ func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main * ...@@ -703,6 +658,16 @@ func (client *client) addMinerTx(preStateHash []byte, block *types.Block, main *
MainBlockHash: main.Seq.Hash, MainBlockHash: main.Seq.Hash,
MainBlockHeight: main.Detail.Block.Height, MainBlockHeight: main.Detail.Block.Height,
} }
//获取当前区块的所有原始tx hash 和跨链hash作为bitmap base hashs,因为有可能在执行过程中有些tx 执行error被剔除掉
if main.Detail.Block.Height >= mainForkParacrossCommitTx {
for _, tx := range txs {
status.TxHashs = append(status.TxHashs, tx.Hash())
}
txHashs := util.FilterParaCrossTxHashes(types.GetTitle(), txs)
status.CrossTxHashs = append(status.CrossTxHashs, txHashs...)
}
tx, err := paracross.CreateRawMinerTx(&pt.ParacrossMinerAction{ tx, err := paracross.CreateRawMinerTx(&pt.ParacrossMinerAction{
Status: status, Status: status,
IsSelfConsensus: isParaSelfConsensusForked(status.MainBlockHeight), IsSelfConsensus: isParaSelfConsensusForked(status.MainBlockHeight),
...@@ -722,7 +687,7 @@ func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transacti ...@@ -722,7 +687,7 @@ func (client *client) createBlock(lastBlock *types.Block, txs []*types.Transacti
newblock.ParentHash = lastBlock.Hash() newblock.ParentHash = lastBlock.Hash()
newblock.Height = lastBlock.Height + 1 newblock.Height = lastBlock.Height + 1
newblock.Txs = txs newblock.Txs = txs
err := client.addMinerTx(lastBlock.StateHash, &newblock, mainBlock) err := client.addMinerTx(lastBlock.StateHash, &newblock, mainBlock, txs)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
typesmocks "github.com/33cn/chain33/types/mocks" typesmocks "github.com/33cn/chain33/types/mocks"
"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/stretchr/testify/mock" "github.com/stretchr/testify/mock"
) )
...@@ -28,6 +29,23 @@ var ( ...@@ -28,6 +29,23 @@ var (
func TestFilterTxsForPara(t *testing.T) { func TestFilterTxsForPara(t *testing.T) {
types.Init(Title, nil) types.Init(Title, nil)
//only main txs
tx0, _ := createMainTx("ticket", "to")
//only main txs group
tx1, _ := createMainTx("ticket", "to")
tx2, _ := createMainTx("token", "to")
tx12 := []*types.Transaction{tx1, tx2}
txGroup12, err := createTxsGroup(tx12)
assert.Nil(t, err)
//para cross tx group succ
tx3, _ := createCrossMainTx("toA")
tx4, err := createCrossParaTx("toB", 4)
assert.Nil(t, err)
tx34 := []*types.Transaction{tx3, tx4}
txGroup34, err := createTxsGroup(tx34)
assert.Nil(t, err)
//all para tx group //all para tx group
tx5, err := createCrossParaTx("toB", 5) tx5, err := createCrossParaTx("toB", 5)
assert.Nil(t, err) assert.Nil(t, err)
...@@ -38,13 +56,18 @@ func TestFilterTxsForPara(t *testing.T) { ...@@ -38,13 +56,18 @@ func TestFilterTxsForPara(t *testing.T) {
assert.Nil(t, err) assert.Nil(t, err)
//para cross tx group fail //para cross tx group fail
tx7, _ := createCrossParaTx("toA", 1) tx7, _ := createCrossMainTx("toA")
tx8, err := createCrossParaTx("toB", 8) tx8, err := createCrossParaTx("toB", 8)
assert.Nil(t, err) assert.Nil(t, err)
tx78 := []*types.Transaction{tx7, tx8} tx78 := []*types.Transaction{tx7, tx8}
txGroup78, err := createTxsGroup(tx78) txGroup78, err := createTxsGroup(tx78)
assert.Nil(t, err) assert.Nil(t, err)
tx9, _ := createMainTx("relay", "to")
//single para tx
txA, err := createCrossParaTx("toB", 10)
assert.Nil(t, err)
//all para tx group //all para tx group
txB, err := createCrossParaTx("toB", 11) txB, err := createCrossParaTx("toB", 11)
assert.Nil(t, err) assert.Nil(t, err)
...@@ -58,9 +81,12 @@ func TestFilterTxsForPara(t *testing.T) { ...@@ -58,9 +81,12 @@ func TestFilterTxsForPara(t *testing.T) {
txD, err := createCrossParaTempTx("toB", 10) txD, err := createCrossParaTempTx("toB", 10)
assert.Nil(t, err) assert.Nil(t, err)
txs := []*types.Transaction{} txs := []*types.Transaction{tx0}
txs = append(txs, txGroup12...)
txs = append(txs, txGroup34...)
txs = append(txs, txGroup56...) txs = append(txs, txGroup56...)
txs = append(txs, txGroup78...) txs = append(txs, txGroup78...)
txs = append(txs, tx9, txA)
txs = append(txs, txGroupBC...) txs = append(txs, txGroupBC...)
txs = append(txs, txD) txs = append(txs, txD)
...@@ -68,6 +94,11 @@ func TestFilterTxsForPara(t *testing.T) { ...@@ -68,6 +94,11 @@ func TestFilterTxsForPara(t *testing.T) {
// t.Log("tx exec name", "i", i, "name", string(tx.Execer)) // t.Log("tx exec name", "i", i, "name", string(tx.Execer))
//} //}
recpt0 := &types.ReceiptData{Ty: types.ExecOk}
recpt1 := &types.ReceiptData{Ty: types.ExecOk}
recpt2 := &types.ReceiptData{Ty: types.ExecOk}
recpt3 := &types.ReceiptData{Ty: types.ExecOk}
recpt4 := &types.ReceiptData{Ty: types.ExecOk}
recpt5 := &types.ReceiptData{Ty: types.ExecPack} recpt5 := &types.ReceiptData{Ty: types.ExecPack}
recpt6 := &types.ReceiptData{Ty: types.ExecPack} recpt6 := &types.ReceiptData{Ty: types.ExecPack}
...@@ -76,10 +107,13 @@ func TestFilterTxsForPara(t *testing.T) { ...@@ -76,10 +107,13 @@ func TestFilterTxsForPara(t *testing.T) {
recpt7 := &types.ReceiptData{Ty: types.ExecPack, Logs: logs} recpt7 := &types.ReceiptData{Ty: types.ExecPack, Logs: logs}
recpt8 := &types.ReceiptData{Ty: types.ExecPack} recpt8 := &types.ReceiptData{Ty: types.ExecPack}
recpt9 := &types.ReceiptData{Ty: types.ExecOk}
recptA := &types.ReceiptData{Ty: types.ExecPack}
recptB := &types.ReceiptData{Ty: types.ExecPack} recptB := &types.ReceiptData{Ty: types.ExecPack}
recptC := &types.ReceiptData{Ty: types.ExecPack} recptC := &types.ReceiptData{Ty: types.ExecPack}
recptD := &types.ReceiptData{Ty: types.ExecPack} recptD := &types.ReceiptData{Ty: types.ExecPack}
receipts := []*types.ReceiptData{recpt5, recpt6, recpt7, recpt8, recptB, recptC, recptD} receipts := []*types.ReceiptData{recpt0, recpt1, recpt2, recpt3, recpt4, recpt5,
recpt6, recpt7, recpt8, recpt9, recptA, recptB, recptC, recptD}
block := &types.Block{Txs: txs} block := &types.Block{Txs: txs}
detail := &types.BlockDetail{ detail := &types.BlockDetail{
...@@ -87,13 +121,38 @@ func TestFilterTxsForPara(t *testing.T) { ...@@ -87,13 +121,38 @@ func TestFilterTxsForPara(t *testing.T) {
Receipts: receipts, Receipts: receipts,
} }
para := &client{} rst := util.FilterTxsForPara(Title, detail)
rst := para.FilterTxsForPara(detail) filterTxs := []*types.Transaction{tx3, tx4, tx5, tx6, txA, txB, txC}
filterTxs := []*types.Transaction{tx5, tx6, tx7, tx8, txB, txC}
assert.Equal(t, filterTxs, rst) assert.Equal(t, filterTxs, rst)
} }
func createMainTx(exec string, to string) (*types.Transaction, error) {
param := types.CreateTx{
To: to,
Amount: Amount,
Fee: 0,
Note: []byte("test"),
TokenSymbol: "",
ExecName: exec,
}
transfer := &pt.ParacrossAction{}
v := &pt.ParacrossAction_AssetTransfer{AssetTransfer: &types.AssetsTransfer{
Amount: param.Amount, Note: param.GetNote(), To: param.GetTo()}}
transfer.Value = v
transfer.Ty = pt.ParacrossActionAssetTransfer
tx := &types.Transaction{
Execer: []byte(param.GetExecName()),
Payload: types.Encode(transfer),
To: address.ExecAddress(param.GetExecName()),
Fee: param.Fee,
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
}
return tx, nil
}
func createCrossMainTx(to string) (*types.Transaction, error) { func createCrossMainTx(to string) (*types.Transaction, error) {
param := types.CreateTx{ param := types.CreateTx{
To: string(to), To: string(to),
......
...@@ -106,6 +106,8 @@ waitBlocks4CommitMsg=2 ...@@ -106,6 +106,8 @@ waitBlocks4CommitMsg=2
searchHashMatchedBlockDepth=10000 searchHashMatchedBlockDepth=10000
#创世地址额度 #创世地址额度
genesisAmount=100000000 genesisAmount=100000000
#主链支持平行链共识tx分叉高度,需要和主链保持严格一致
MainForkParacrossCommitTx=-1
[store] [store]
name="mavl" name="mavl"
......
...@@ -215,7 +215,14 @@ func hasCommited(addrs []string, addr string) (bool, int) { ...@@ -215,7 +215,14 @@ func hasCommited(addrs []string, addr string) (bool, int) {
} }
func (a *action) getNodesGroup(title string) (map[string]struct{}, error) { func (a *action) getNodesGroup(title string) (map[string]struct{}, error) {
if !types.IsDappFork(a.exec.GetMainHeight(), pt.ParaX, pt.ForkCommitTx) { forkHeight := types.GetDappFork(pt.ParaX, pt.ForkCommitTx)
if types.IsPara() {
forkHeight = types.Conf("config.consensus.sub.para").GInt("MainForkParacrossCommitTx")
if forkHeight <= 0 {
forkHeight = types.MaxHeight
}
}
if a.exec.GetMainHeight() < forkHeight {
key := calcManageConfigNodesKey(title) key := calcManageConfigNodesKey(title)
nodes, _, err := getNodes(a.db, key) nodes, _, err := getNodes(a.db, key)
if err != nil { if err != nil {
...@@ -388,7 +395,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -388,7 +395,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus) saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus)
clog.Info("paracross.Commit commit done", "height", commit.Status.Height, clog.Info("paracross.Commit commit done", "height", commit.Status.Height,
"cross tx count", len(commit.Status.CrossTxHashs), "statusBlockHash", hex.EncodeToString(titleStatus.BlockHash)) "cross tx bitmap", hex.EncodeToString(commit.Status.CrossTxResult), "statusBlockHash", hex.EncodeToString(titleStatus.BlockHash))
//parallel chain not need to process cross commit tx here //parallel chain not need to process cross commit tx here
if types.IsPara() { if types.IsPara() {
...@@ -407,7 +414,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -407,7 +414,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
return receipt, nil return receipt, nil
} }
func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCommitAction, i int) (*types.Receipt, error) { func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCommitAction, crossTxHash []byte) (*types.Receipt, error) {
if !bytes.HasSuffix(tx.Tx.Execer, []byte(pt.ParaX)) { if !bytes.HasSuffix(tx.Tx.Execer, []byte(pt.ParaX)) {
return nil, nil return nil, nil
} }
...@@ -415,8 +422,7 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCo ...@@ -415,8 +422,7 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCo
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", "para title", commit.Status.Title, clog.Crit("paracross.Commit Decode Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "error", err, "txHash", hex.EncodeToString(crossTxHash))
hex.EncodeToString(commit.Status.CrossTxHashs[i]))
return nil, err return nil, err
} }
...@@ -424,41 +430,83 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCo ...@@ -424,41 +430,83 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, commit *pt.ParacrossCo
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 Decode Tx failed", "para title", commit.Status.Title, clog.Crit("paracross.Commit Decode Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "error", err, "txHash", hex.EncodeToString(crossTxHash))
hex.EncodeToString(commit.Status.CrossTxHashs[i]))
return nil, errors.Cause(err) return nil, errors.Cause(err)
} }
clog.Info("paracross.Commit WithdrawCoins", "para title", commit.Status.Title, clog.Info("paracross.Commit WithdrawCoins", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "error", err, "txHash", hex.EncodeToString(crossTxHash))
hex.EncodeToString(commit.Status.CrossTxHashs[i]))
return receiptWithdraw, nil return receiptWithdraw, nil
} //else if tx.ActionName == pt.ParacrossActionAssetTransferStr { } //else if tx.ActionName == pt.ParacrossActionAssetTransferStr {
return nil, nil return nil, nil
//} //}
} }
func getCrossTxHashs(api client.QueueProtocolAPI, commit *pt.ParacrossCommitAction) ([][]byte, []byte, error) {
crossTxHashs := commit.Status.CrossTxHashs
crossTxResult := commit.Status.CrossTxResult
if types.IsDappFork(commit.Status.MainBlockHeight, pt.ParaX, pt.ForkCommitTx) {
if len(commit.Status.CrossTxHashs) == 0 {
return nil, nil, types.ErrCheckTxHash
}
blockDetail, err := GetBlock(api, commit.Status.MainBlockHash)
if err != nil {
return nil, nil, err
}
//校验
paraBaseTxs := util.FilterTxsForPara(commit.Status.Title, blockDetail)
paraCrossHashs := util.FilterParaCrossTxHashes(commit.Status.Title, paraBaseTxs)
var baseHashs [][]byte
for _, tx := range paraBaseTxs {
baseHashs = append(baseHashs, tx.Hash())
}
baseCheckTxHash := util.CalcTxHashsHash(baseHashs)
crossCheckHash := util.CalcTxHashsHash(paraCrossHashs)
if !bytes.Equal(commit.Status.CrossTxHashs[0], crossCheckHash) {
clog.Error("getCrossTxHashs para hash not equal", "main.crossHash", hex.EncodeToString(crossCheckHash),
"commit.crossHash", hex.EncodeToString(commit.Status.CrossTxHashs[0]),
"main.baseHash", hex.EncodeToString(baseCheckTxHash), "commit.baseHash", hex.EncodeToString(commit.Status.TxHashs[0]))
return nil, nil, types.ErrCheckTxHash
}
//只获取跨链tx
crossTxHashs = paraCrossHashs
crossTxResult = commit.Status.CrossTxResult
}
return crossTxHashs, crossTxResult, nil
}
func (a *action) execCrossTxs(commit *pt.ParacrossCommitAction) (*types.Receipt, error) { func (a *action) execCrossTxs(commit *pt.ParacrossCommitAction) (*types.Receipt, error) {
var receipt types.Receipt var receipt types.Receipt
for i := 0; i < len(commit.Status.CrossTxHashs); i++ {
clog.Debug("paracross.Commit commitDone", "do cross number", i, "hash", crossTxHashs, crossTxResult, err := getCrossTxHashs(a.api, commit)
hex.EncodeToString(commit.Status.CrossTxHashs[i]), if err != nil {
"res", util.BitMapBit(commit.Status.CrossTxResult, uint32(i))) clog.Error("paracross.Commit getCrossTxHashs", "err", err.Error())
if util.BitMapBit(commit.Status.CrossTxResult, uint32(i)) { return nil, err
tx, err := GetTx(a.api, commit.Status.CrossTxHashs[i]) }
if len(crossTxHashs) == 0 {
return &receipt, nil
}
for i := 0; i < len(crossTxHashs); i++ {
clog.Info("paracross.Commit commitDone", "do cross number", i, "hash",
hex.EncodeToString(crossTxHashs[i]),
"res", util.BitMapBit(crossTxResult, uint32(i)))
if util.BitMapBit(crossTxResult, uint32(i)) {
tx, err := GetTx(a.api, crossTxHashs[i])
if err != nil { if err != nil {
clog.Crit("paracross.Commit Load Tx failed", "para title", commit.Status.Title, clog.Crit("paracross.Commit Load Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "para tx index", i, "error", err, "txHash",
hex.EncodeToString(commit.Status.CrossTxHashs[i])) hex.EncodeToString(crossTxHashs[i]))
return nil, err return nil, err
} }
if tx == nil { if tx == nil {
clog.Error("paracross.Commit Load Tx failed", "para title", commit.Status.Title, clog.Error("paracross.Commit Load Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "para tx index", i, "error", err, "txHash",
hex.EncodeToString(commit.Status.CrossTxHashs[i])) hex.EncodeToString(crossTxHashs[i]))
return nil, types.ErrHashNotExist return nil, types.ErrHashNotExist
} }
receiptCross, err := a.execCrossTx(tx, commit, i) receiptCross, err := a.execCrossTx(tx, commit, crossTxHashs[i])
if err != nil { if err != nil {
return nil, errors.Cause(err) return nil, errors.Cause(err)
} }
...@@ -469,8 +517,8 @@ func (a *action) execCrossTxs(commit *pt.ParacrossCommitAction) (*types.Receipt, ...@@ -469,8 +517,8 @@ func (a *action) execCrossTxs(commit *pt.ParacrossCommitAction) (*types.Receipt,
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(commit.Status.CrossTxHashs[i]), hex.EncodeToString(crossTxHashs[i]),
"para res", util.BitMapBit(commit.Status.CrossTxResult, uint32(i))) "para res", util.BitMapBit(crossTxResult, uint32(i)))
} }
} }
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
package executor package executor
import ( import (
"bytes"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
...@@ -102,6 +100,43 @@ func (e *Paracross) ExecLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx *t ...@@ -102,6 +100,43 @@ func (e *Paracross) ExecLocal_AssetWithdraw(payload *types.AssetsWithdraw, tx *t
return nil, nil return nil, nil
} }
func setMinerTxResult(payload *pt.ParacrossMinerAction, txs []*types.Transaction, receipts []*types.ReceiptData) {
var curTxHashs, paraTxHashs [][]byte
for _, tx := range txs {
hash := tx.Hash()
curTxHashs = append(curTxHashs, hash)
//跨链交易包含了主链交易,需要过滤出来
if types.IsMyParaExecName(string(tx.Execer)) {
paraTxHashs = append(paraTxHashs, hash)
}
}
crossTxHashs := util.FilterParaMainCrossTxHashes(types.GetTitle(), txs)
payload.Status.TxHashs = paraTxHashs
payload.Status.TxResult = util.CalcSubBitMap(curTxHashs, paraTxHashs, receipts)
payload.Status.CrossTxHashs = crossTxHashs
payload.Status.CrossTxResult = util.CalcSubBitMap(curTxHashs, crossTxHashs, receipts)
}
func setMinerTxResultFork(payload *pt.ParacrossMinerAction, txs []*types.Transaction, receipts []*types.ReceiptData) {
var curTxHashs [][]byte
for _, tx := range txs {
hash := tx.Hash()
curTxHashs = append(curTxHashs, hash)
}
baseTxHashs := payload.Status.TxHashs
baseCrossTxHashs := payload.Status.CrossTxHashs
//主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map
//全部平行链tx结果
payload.Status.TxResult = util.CalcBitMap(baseTxHashs, curTxHashs, receipts)
//跨链tx结果
payload.Status.CrossTxResult = util.CalcBitMap(baseCrossTxHashs, curTxHashs, receipts)
payload.Status.TxHashs = [][]byte{util.CalcTxHashsHash(baseTxHashs)}
payload.Status.CrossTxHashs = [][]byte{util.CalcTxHashsHash(baseCrossTxHashs)}
}
//ExecLocal_Miner miner tx local db process //ExecLocal_Miner miner tx local db process
func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
if index != 0 { if index != 0 {
...@@ -109,39 +144,19 @@ func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types. ...@@ -109,39 +144,19 @@ func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.
} }
var set types.LocalDBSet var set types.LocalDBSet
var mixTxHashs, paraTxHashs, crossTxHashs [][]byte
txs := e.GetTxs() txs := e.GetTxs()
//remove the 0 vote tx
for i := 1; i < len(txs); i++ { forkHeight := types.Conf("config.consensus.sub.para").GInt("MainForkParacrossCommitTx")
tx := txs[i] if forkHeight == -1 || forkHeight == 0 {
hash := tx.Hash() forkHeight = types.MaxHeight
mixTxHashs = append(mixTxHashs, hash)
//跨链交易包含了主链交易,需要过滤出来
if types.IsMyParaExecName(string(tx.Execer)) {
paraTxHashs = append(paraTxHashs, hash)
}
}
for i := 1; i < len(txs); i++ {
tx := txs[i]
if tx.GroupCount >= 2 {
crossTxs, end := crossTxGroupProc(txs, i)
for _, crossTx := range crossTxs {
crossTxHashs = append(crossTxHashs, crossTx.Hash())
}
i = int(end) - 1
continue
}
if types.IsMyParaExecName(string(tx.Execer)) &&
bytes.HasSuffix(tx.Execer, []byte(pt.ParaX)) {
crossTxHashs = append(crossTxHashs, tx.Hash())
}
} }
payload.Status.TxHashs = paraTxHashs //removed the 0 vote tx
payload.Status.TxResult = util.CalcBitMap(paraTxHashs, mixTxHashs, e.GetReceipt()[1:]) if payload.Status.MainBlockHeight >= forkHeight {
payload.Status.CrossTxHashs = crossTxHashs setMinerTxResultFork(payload, txs[1:], e.GetReceipt()[1:])
payload.Status.CrossTxResult = util.CalcBitMap(crossTxHashs, mixTxHashs, e.GetReceipt()[1:]) } else {
setMinerTxResult(payload, txs[1:], e.GetReceipt()[1:])
}
set.KV = append(set.KV, &types.KeyValue{ set.KV = append(set.KV, &types.KeyValue{
Key: pt.CalcMinerHeightKey(payload.Status.Title, payload.Status.Height), Key: pt.CalcMinerHeightKey(payload.Status.Title, payload.Status.Height),
......
...@@ -67,36 +67,6 @@ func (c *Paracross) checkTxGroup(tx *types.Transaction, index int) ([]*types.Tra ...@@ -67,36 +67,6 @@ func (c *Paracross) checkTxGroup(tx *types.Transaction, index int) ([]*types.Tra
return nil, nil return nil, nil
} }
//经para filter之后,交易组里面只会存在主链平行链跨链交易或全部平行链交易,全部平行链交易group里面有可能有资产转移交易
func crossTxGroupProc(txs []*types.Transaction, index int) ([]*types.Transaction, int32) {
var headIdx, endIdx int32
for i := index; i >= 0; i-- {
if bytes.Equal(txs[index].Header, txs[i].Hash()) {
headIdx = int32(i)
break
}
}
//cross mix tx, contain main and para tx, main prefix with pt.ParaX
endIdx = headIdx + txs[index].GroupCount
for i := headIdx; i < endIdx; i++ {
if bytes.HasPrefix(txs[i].Execer, []byte(pt.ParaX)) {
return txs[headIdx:endIdx], endIdx
}
}
//cross asset transfer in tx group
var transfers []*types.Transaction
for i := headIdx; i < endIdx; i++ {
if types.IsMyParaExecName(string(txs[i].Execer)) &&
bytes.HasSuffix(txs[i].Execer, []byte(pt.ParaX)) {
transfers = append(transfers, txs[i])
}
}
return transfers, endIdx
}
func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types.LocalDBSet, error) { func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types.LocalDBSet, error) {
var set types.LocalDBSet var set types.LocalDBSet
...@@ -110,14 +80,22 @@ func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types. ...@@ -110,14 +80,22 @@ func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types.
} }
commit := payload.GetCommit() commit := payload.GetCommit()
for i := 0; i < len(commit.Status.CrossTxHashs); i++ { crossTxHashs, crossTxResult, err := getCrossTxHashs(c.GetAPI(), commit)
success := util.BitMapBit(commit.Status.CrossTxResult, uint32(i)) if err != nil {
return nil, err
}
if len(crossTxHashs) == 0 {
return &set, nil
}
for i := 0; i < len(crossTxHashs); i++ {
success := util.BitMapBit(crossTxResult, uint32(i))
paraTx, err := GetTx(c.GetAPI(), commit.Status.CrossTxHashs[i]) paraTx, err := GetTx(c.GetAPI(), crossTxHashs[i])
if err != nil { if err != nil {
clog.Crit("paracross.Commit Load Tx failed", "para title", commit.Status.Title, clog.Crit("paracross.Commit Load Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "para tx index", i, "error", err, "txHash",
hex.EncodeToString(commit.Status.CrossTxHashs[i])) hex.EncodeToString(crossTxHashs[i]))
return nil, err return nil, err
} }
...@@ -126,7 +104,7 @@ func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types. ...@@ -126,7 +104,7 @@ func (c *Paracross) saveLocalParaTxs(tx *types.Transaction, isDel bool) (*types.
if err != nil { if err != nil {
clog.Crit("paracross.Commit Decode Tx failed", "para title", commit.Status.Title, clog.Crit("paracross.Commit Decode Tx failed", "para title", commit.Status.Title,
"para height", commit.Status.Height, "para tx index", i, "error", err, "txHash", "para height", commit.Status.Height, "para tx index", i, "error", err, "txHash",
hex.EncodeToString(commit.Status.CrossTxHashs[i])) hex.EncodeToString(crossTxHashs[i]))
return nil, err return nil, err
} }
if payload.Ty == pt.ParacrossActionAssetTransfer { if payload.Ty == pt.ParacrossActionAssetTransfer {
......
...@@ -8,9 +8,6 @@ import ( ...@@ -8,9 +8,6 @@ import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"math/big"
"strconv"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
"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"
...@@ -165,7 +162,7 @@ func listLocalTitles(db dbm.KVDB) (types.Message, error) { ...@@ -165,7 +162,7 @@ func listLocalTitles(db dbm.KVDB) (types.Message, error) {
Height: st.Height, Height: st.Height,
StateHash: hex.EncodeToString(st.StateHash), StateHash: hex.EncodeToString(st.StateHash),
TxCounts: st.TxCounts, TxCounts: st.TxCounts,
TxResult: strconv.FormatUint(big.NewInt(0).SetBytes(st.TxResult).Uint64(), 2), TxResult: hex.EncodeToString(st.TxResult),
} }
resp.Titles = append(resp.Titles, rst) resp.Titles = append(resp.Titles, rst)
...@@ -214,7 +211,7 @@ func loadLocalTitle(db dbm.KV, title string, height int64) (types.Message, error ...@@ -214,7 +211,7 @@ func loadLocalTitle(db dbm.KV, title string, height int64) (types.Message, error
Height: st.Height, Height: st.Height,
StateHash: hex.EncodeToString(st.StateHash), StateHash: hex.EncodeToString(st.StateHash),
TxCounts: st.TxCounts, TxCounts: st.TxCounts,
TxResult: strconv.FormatUint(big.NewInt(0).SetBytes(st.TxResult).Uint64(), 2), TxResult: hex.EncodeToString(st.TxResult),
}, nil }, nil
} }
......
...@@ -408,7 +408,14 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro ...@@ -408,7 +408,14 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
return nil, pt.ErrInvalidTitle return nil, pt.ErrInvalidTitle
} }
if !types.IsDappFork(a.exec.GetMainHeight(), pt.ParaX, pt.ForkCommitTx) { forkHeight := types.GetDappFork(pt.ParaX, pt.ForkCommitTx)
if types.IsPara() {
forkHeight = types.Conf("config.consensus.sub.para").GInt("MainForkParacrossCommitTx")
if forkHeight == -1 || forkHeight == 0 {
forkHeight = types.MaxHeight
}
}
if a.exec.GetMainHeight() < forkHeight {
return nil, types.ErrNotSupport return nil, types.ErrNotSupport
} }
......
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