Commit 23b237bf authored by 张振华's avatar 张振华

Merge branch 'master' into guess

parents 13813d32 f4d8ec54
...@@ -60,7 +60,7 @@ type client struct { ...@@ -60,7 +60,7 @@ type client struct {
conn *grpc.ClientConn conn *grpc.ClientConn
grpcClient types.Chain33Client grpcClient types.Chain33Client
paraClient paracross.ParacrossClient paraClient paracross.ParacrossClient
isCatchingUp bool isCaughtUp bool
commitMsgClient *commitMsgClient commitMsgClient *commitMsgClient
authAccount string authAccount string
privateKey crypto.PrivKey privateKey crypto.PrivKey
...@@ -119,6 +119,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -119,6 +119,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
paraClient: paraCli, paraClient: paraCli,
authAccount: cfg.AuthAccount, authAccount: cfg.AuthAccount,
privateKey: priKey, privateKey: priKey,
isCaughtUp: false,
} }
if cfg.WaitBlocks4CommitMsg < 2 { if cfg.WaitBlocks4CommitMsg < 2 {
...@@ -444,9 +445,9 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type ...@@ -444,9 +445,9 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type
plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", seqTy) plog.Info("GetCurrentSeq", "Len of txs", len(txs), "seqTy", seqTy)
if lastSeq-currSeq > emptyBlockInterval { if lastSeq-currSeq > emptyBlockInterval {
client.isCatchingUp = true client.isCaughtUp = false
} else { } else {
client.isCatchingUp = false client.isCaughtUp = true
} }
if client.authAccount != "" { if client.authAccount != "" {
...@@ -654,7 +655,7 @@ func (client *client) CreateBlock() { ...@@ -654,7 +655,7 @@ func (client *client) CreateBlock() {
plog.Error("Incorrect sequence type") plog.Error("Incorrect sequence type")
incSeqFlag = false incSeqFlag = false
} }
if !client.isCatchingUp { if client.isCaughtUp {
time.Sleep(time.Second * time.Duration(blockSec)) time.Sleep(time.Second * time.Duration(blockSec))
} }
} }
...@@ -766,6 +767,14 @@ func (client *client) DelBlock(block *types.Block, seq int64) error { ...@@ -766,6 +767,14 @@ func (client *client) DelBlock(block *types.Block, seq int64) error {
return nil return nil
} }
//IsCaughtUp 是否追上最新高度,
func (client *client) Query_IsCaughtUp(req *types.ReqNil) (types.Message, error) {
if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
return &types.IsCaughtUp{Iscaughtup: client.isCaughtUp}, nil
}
func checkMinerTx(current *types.BlockDetail) error { func checkMinerTx(current *types.BlockDetail) error {
//检查第一个笔交易的execs, 以及执行状态 //检查第一个笔交易的execs, 以及执行状态
if len(current.Block.Txs) == 0 { if len(current.Block.Txs) == 0 {
......
...@@ -83,7 +83,7 @@ out: ...@@ -83,7 +83,7 @@ out:
} }
case block := <-client.mainBlockAdd: case block := <-client.mainBlockAdd:
if client.currentTx != nil && !client.paraClient.isCatchingUp { if client.currentTx != nil && client.paraClient.isCaughtUp {
exist := checkTxInMainBlock(client.currentTx, block) exist := checkTxInMainBlock(client.currentTx, block)
if exist { if exist {
finishHeight = sendingHeight finishHeight = sendingHeight
......
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"os" "os"
"strings" "strings"
"github.com/33cn/chain33/rpc/jsonclient"
"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"
"github.com/spf13/cobra" "github.com/spf13/cobra"
...@@ -29,6 +30,7 @@ func ParcCmd() *cobra.Command { ...@@ -29,6 +30,7 @@ func ParcCmd() *cobra.Command {
CreateRawTransferCmd(), CreateRawTransferCmd(),
CreateRawWithdrawCmd(), CreateRawWithdrawCmd(),
CreateRawTransferToExecCmd(), CreateRawTransferToExecCmd(),
IsSyncCmd(),
) )
return cmd return cmd
} }
...@@ -281,3 +283,20 @@ func createTransferTx(cmd *cobra.Command, isWithdraw bool) (string, error) { ...@@ -281,3 +283,20 @@ func createTransferTx(cmd *cobra.Command, isWithdraw bool) (string, error) {
txHex := types.Encode(tx) txHex := types.Encode(tx)
return hex.EncodeToString(txHex), nil return hex.EncodeToString(txHex), nil
} }
// IsSyncCmd query parachain is sync
func IsSyncCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "is_sync",
Short: "query parachain is sync",
Run: isSync,
}
return cmd
}
func isSync(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
var res bool
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.IsSync", nil, &res)
ctx.Run()
}
...@@ -2,6 +2,7 @@ syntax = "proto3"; ...@@ -2,6 +2,7 @@ syntax = "proto3";
import "transaction.proto"; import "transaction.proto";
import "common.proto"; import "common.proto";
import "blockchain.proto";
package types; package types;
...@@ -130,4 +131,5 @@ service paracross { ...@@ -130,4 +131,5 @@ service paracross {
rpc ListTitles(ReqNil) returns (RespParacrossTitles) {} rpc ListTitles(ReqNil) returns (RespParacrossTitles) {}
rpc GetTitleHeight(ReqParacrossTitleHeight) returns (ReceiptParacrossDone) {} rpc GetTitleHeight(ReqParacrossTitleHeight) returns (ReceiptParacrossDone) {}
rpc GetAssetTxResult(ReqHash) returns (ParacrossAsset) {} rpc GetAssetTxResult(ReqHash) returns (ParacrossAsset) {}
rpc IsSync(ReqNil) returns (IsCaughtUp) {}
} }
\ No newline at end of file
...@@ -91,3 +91,26 @@ func (c *Jrpc) GetAssetTxResult(req *types.ReqHash, result *interface{}) error { ...@@ -91,3 +91,26 @@ func (c *Jrpc) GetAssetTxResult(req *types.ReqHash, result *interface{}) error {
*result = data *result = data
return err return err
} }
// IsSync query is sync
func (c *channelClient) IsSync(ctx context.Context, in *types.ReqNil) (*types.IsCaughtUp, error) {
data, err := c.QueryConsensusFunc("para", "IsCaughtUp", &types.ReqNil{})
if err != nil {
return nil, err
}
return data.(*types.IsCaughtUp), nil
}
// IsSync query is sync
func (c *Jrpc) IsSync(in *types.ReqNil, result *interface{}) error {
//TODO consensus and paracross are not the same registered names ?
data, err := c.cli.QueryConsensusFunc("para", "IsCaughtUp", &types.ReqNil{})
*result = false
if err != nil {
return err
}
if reply, ok := data.(*types.IsCaughtUp); ok {
*result = reply.Iscaughtup
}
return nil
}
/*
* Copyright Fuzamei Corp. 2018 All Rights Reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/
package rpc
//only load all plugin and system
import (
"testing"
"github.com/33cn/chain33/client/mocks"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
func newGrpc(api *mocks.QueueProtocolAPI) *channelClient {
return &channelClient{
ChannelClient: rpctypes.ChannelClient{QueueProtocolAPI: api},
}
}
func newJrpc(api *mocks.QueueProtocolAPI) *Jrpc {
return &Jrpc{cli: newGrpc(api)}
}
func TestChannelClient_GetTitle(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newGrpc(api)
client.Init("paracross", nil, nil, nil)
req := &types.ReqString{Data: "xxxxxxxxxxx"}
api.On("Query", pt.GetExecName(), "GetTitle", req).Return(&pt.ParacrossStatus{}, nil)
_, err := client.GetTitle(context.Background(), req)
assert.Nil(t, err)
}
func TestJrpc_GetTitle(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
j := newJrpc(api)
req := &types.ReqString{Data: "xxxxxxxxxxx"}
var result interface{}
api.On("Query", pt.GetExecName(), "GetTitle", req).Return(&pt.ParacrossStatus{}, nil)
err := j.GetHeight(req, &result)
assert.Nil(t, err)
}
func TestChannelClient_ListTitles(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newGrpc(api)
client.Init("paracross", nil, nil, nil)
req := &types.ReqNil{}
api.On("Query", pt.GetExecName(), "ListTitles", req).Return(&pt.RespParacrossTitles{}, nil)
_, err := client.ListTitles(context.Background(), req)
assert.Nil(t, err)
}
func TestJrpc_ListTitles(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
j := newJrpc(api)
req := &types.ReqNil{}
var result interface{}
api.On("Query", pt.GetExecName(), "ListTitles", req).Return(&pt.RespParacrossTitles{}, nil)
err := j.ListTitles(req, &result)
assert.Nil(t, err)
}
func TestChannelClient_GetTitleHeight(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newGrpc(api)
client.Init("paracross", nil, nil, nil)
req := &pt.ReqParacrossTitleHeight{}
api.On("Query", pt.GetExecName(), "GetTitleHeight", req).Return(&pt.ReceiptParacrossDone{}, nil)
_, err := client.GetTitleHeight(context.Background(), req)
assert.Nil(t, err)
}
func TestJrpc_GetTitleHeight(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
j := newJrpc(api)
req := &pt.ReqParacrossTitleHeight{}
var result interface{}
api.On("Query", pt.GetExecName(), "GetTitleHeight", req).Return(&pt.ReceiptParacrossDone{}, nil)
err := j.GetTitleHeight(req, &result)
assert.Nil(t, err)
}
func TestChannelClient_GetAssetTxResult(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newGrpc(api)
client.Init("paracross", nil, nil, nil)
req := &types.ReqHash{}
api.On("Query", pt.GetExecName(), "GetAssetTxResult", req).Return(&pt.ParacrossAsset{}, nil)
_, err := client.GetAssetTxResult(context.Background(), req)
assert.Nil(t, err)
}
func TestJrpc_GetAssetTxResult(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
j := newJrpc(api)
req := &types.ReqHash{}
var result interface{}
api.On("Query", pt.GetExecName(), "GetAssetTxResult", req).Return(&pt.ParacrossAsset{}, nil)
err := j.GetAssetTxResult(req, &result)
assert.Nil(t, err)
}
func TestChannelClient_IsSync(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newGrpc(api)
client.Init("paracross", nil, nil, nil)
req := &types.ReqNil{}
api.On("QueryConsensusFunc", "para", "IsCaughtUp", req).Return(&types.IsCaughtUp{}, nil)
_, err := client.IsSync(context.Background(), req)
assert.Nil(t, err)
}
func TestJrpc_IsSync(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
J := newJrpc(api)
req := &types.ReqNil{}
var result interface{}
api.On("QueryConsensusFunc", "para", "IsCaughtUp", req).Return(&types.IsCaughtUp{}, nil)
err := J.IsSync(req, &result)
assert.Nil(t, err)
}
//TODO wait finish
//func TestRPC_CallTestNode(t *testing.T) {
// api := new(mocks.QueueProtocolAPI)
// cfg, sub := testnode.GetDefaultConfig()
// // para consensus
// cfg.Consensus.Name = "para"
// cfg.Title="user.p.test."
// cfg.BlockChain.IsParaChain=true
// cfg.Store.Name="mavl"
// mock33 := testnode.NewWithConfig(cfg, sub, api)
// defer func() {
// mock33.Close()
// mock.AssertExpectationsForObjects(t, api)
// }()
// g := newGrpc(api)
// g.Init(pt.GetExecName(), mock33.GetRPC(), newJrpc(api), g)
// time.Sleep(time.Millisecond)
// mock33.Listen()
// time.Sleep(time.Millisecond)
// api.On("Query", pt.GetExecName(), "GetTitle", &types.ReqString{}).Return(&pt.ParacrossStatus{Title:"test"}, nil)
// api.On("Query", pt.GetExecName(), "ListTitles", &types.ReqNil{}).Return(&pt.RespParacrossTitles{Titles:[]*pt.ReceiptParacrossDone{&pt.ReceiptParacrossDone{Title:"test1"},&pt.ReceiptParacrossDone{Title:"test2"}}}, nil)
// api.On("Query", pt.GetExecName(), "GetTitleHeight", &pt.ReqParacrossTitleHeight{}).Return(&pt.ReceiptParacrossDone{Height:10}, nil)
// api.On("Query", pt.GetExecName(), "GetAssetTxResult", &types.ReqHash{}).Return(&pt.ParacrossAsset{Symbol:"test"}, nil)
// api.On("QueryConsensusFunc", "para", "IsCaughtUp",&types.ReqNil{}).Return(&types.IsCaughtUp{Iscaughtup:true}, nil)
// //test jrpc
// rpcCfg := mock33.GetCfg().RPC
// jsonClient, err := jsonclient.NewJSONClient("http://" + rpcCfg.JrpcBindAddr + "/")
// assert.Nil(t, err)
// assert.NotNil(t, jsonClient)
// var result pt.ParacrossStatus
// err = jsonClient.Call("paracross.GetHeight", nil, &result)
// fmt.Println(err)
// assert.Nil(t, err)
// assert.Equal(t, "test", result.Title)
//
// var reply types.IsCaughtUp
// err = jsonClient.Call("paracross.IsSync", &types.ReqNil{}, &reply)
// assert.Nil(t, err)
// assert.Equal(t, true, reply.Iscaughtup)
//
// var res pt.RespParacrossTitles
// err = jsonClient.Call("paracross.ListTitles", &types.ReqNil{}, &res)
// assert.Nil(t, err)
// assert.Equal(t, 2, len(res.Titles))
//
// //test grpc
//
// ctx := context.Background()
// c, err := grpc.DialContext(ctx, rpcCfg.GrpcBindAddr, grpc.WithInsecure())
// assert.Nil(t, err)
// assert.NotNil(t, c)
//
// client := pt.NewParacrossClient(c)
// issync, err := client.IsSync(ctx, &types.ReqNil{})
// assert.Nil(t, err)
// assert.Equal(t, true, issync.Iscaughtup)
//}
...@@ -1241,69 +1241,71 @@ func init() { ...@@ -1241,69 +1241,71 @@ func init() {
func init() { proto.RegisterFile("paracross.proto", fileDescriptor_6a397e38c9ea6747) } func init() { proto.RegisterFile("paracross.proto", fileDescriptor_6a397e38c9ea6747) }
var fileDescriptor_6a397e38c9ea6747 = []byte{ var fileDescriptor_6a397e38c9ea6747 = []byte{
// 985 bytes of a gzipped FileDescriptorProto // 1020 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4b, 0x6f, 0x23, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x5f, 0x6f, 0x1b, 0x45,
0x10, 0xf6, 0x8c, 0xdf, 0xe5, 0xd8, 0x09, 0xbd, 0x89, 0x77, 0x34, 0x2c, 0xc8, 0x1a, 0x01, 0xb2, 0x10, 0xf7, 0x9d, 0xff, 0x66, 0x1c, 0x3b, 0xe9, 0x36, 0x71, 0x4f, 0x47, 0x41, 0xd6, 0x09, 0x90,
0x38, 0x44, 0xc8, 0x91, 0x82, 0x10, 0xe2, 0xb0, 0x2f, 0xc5, 0x5a, 0x96, 0x05, 0x75, 0x22, 0x71, 0x85, 0x50, 0x84, 0x1c, 0x29, 0x08, 0x21, 0x1e, 0xda, 0xb4, 0x8a, 0x5b, 0x4a, 0x41, 0x9b, 0x20,
0x42, 0x62, 0x32, 0xee, 0xdd, 0x8c, 0xf0, 0xb8, 0xbd, 0xd3, 0xed, 0xdd, 0xe4, 0xce, 0x91, 0x33, 0x9e, 0x90, 0xb8, 0x9c, 0xb7, 0xf1, 0x09, 0xdf, 0xad, 0x7b, 0xbb, 0x6e, 0xe3, 0x77, 0x3e, 0x03,
0x3f, 0x83, 0x0b, 0xff, 0x81, 0x03, 0xbf, 0x0a, 0x75, 0xf5, 0x63, 0x1e, 0xb6, 0xac, 0x08, 0xb8, 0x1f, 0x83, 0x17, 0xde, 0xf8, 0x00, 0x3c, 0xf0, 0xa9, 0xd0, 0xce, 0xed, 0xee, 0xfd, 0x89, 0x65,
0x75, 0x55, 0x7f, 0x55, 0xd5, 0x55, 0xf5, 0x75, 0x75, 0xc3, 0xe1, 0x3a, 0xce, 0xe3, 0x24, 0xe7, 0x55, 0xd0, 0xb7, 0x9d, 0xd9, 0x99, 0xdf, 0xec, 0xcc, 0xfc, 0x76, 0x76, 0xe1, 0x60, 0x15, 0x66,
0x42, 0x9c, 0xae, 0x73, 0x2e, 0x39, 0x69, 0xcb, 0xbb, 0x35, 0x13, 0xe1, 0x07, 0x32, 0x8f, 0x57, 0x61, 0x94, 0x71, 0x21, 0x4e, 0x56, 0x19, 0x97, 0x9c, 0xb4, 0xe5, 0x66, 0xc5, 0x84, 0x7f, 0x4f,
0x22, 0x4e, 0x64, 0xca, 0x57, 0x7a, 0x27, 0x3c, 0x48, 0x78, 0x96, 0x59, 0x29, 0x7a, 0x09, 0xe3, 0x66, 0x61, 0x2a, 0xc2, 0x48, 0xc6, 0x3c, 0xcd, 0x77, 0xfc, 0xfd, 0x88, 0x27, 0x89, 0x95, 0x0e,
0x1f, 0xac, 0xe9, 0xa5, 0x8c, 0xe5, 0x46, 0x3c, 0x63, 0x32, 0x4e, 0x97, 0x82, 0x1c, 0x43, 0x3b, 0xaf, 0x97, 0x3c, 0xfa, 0x35, 0x5a, 0x84, 0xb1, 0xd6, 0x04, 0x2f, 0x60, 0xf4, 0x83, 0x01, 0xbb,
0x5e, 0x2c, 0x72, 0x11, 0x78, 0x93, 0xe6, 0xb4, 0x4f, 0xb5, 0x40, 0x1e, 0x41, 0xff, 0x7a, 0xc9, 0x94, 0xa1, 0x5c, 0x8b, 0x27, 0x4c, 0x86, 0xf1, 0x52, 0x90, 0x23, 0x68, 0x87, 0xf3, 0x79, 0x26,
0x93, 0x5f, 0xe6, 0xb1, 0xb8, 0x09, 0xfc, 0x49, 0x73, 0x7a, 0x40, 0x0b, 0x45, 0xf4, 0xbb, 0x07, 0x3c, 0x67, 0xdc, 0x9c, 0xec, 0xd1, 0x5c, 0x20, 0x0f, 0x61, 0x0f, 0x31, 0x66, 0xa1, 0x58, 0x78,
0x27, 0xce, 0xdd, 0x9c, 0xa5, 0x6f, 0x6e, 0xa4, 0x76, 0x4a, 0xc6, 0xd0, 0x11, 0xb8, 0x0a, 0xbc, 0xee, 0xb8, 0x39, 0xd9, 0xa7, 0x85, 0x22, 0xf8, 0xdd, 0x81, 0x63, 0x0b, 0x37, 0x63, 0xf1, 0xcd,
0x89, 0x37, 0x6d, 0x53, 0x23, 0xa9, 0x28, 0x32, 0x95, 0x4b, 0x16, 0xf8, 0x13, 0x4f, 0x45, 0x41, 0x42, 0xe6, 0xa0, 0x64, 0x04, 0x1d, 0x81, 0x2b, 0xcf, 0x19, 0x3b, 0x93, 0x36, 0xd5, 0x92, 0x8a,
0x41, 0xa1, 0x6f, 0xd0, 0x3a, 0x68, 0x4e, 0xbc, 0x69, 0x93, 0x1a, 0x89, 0x7c, 0x09, 0xdd, 0x85, 0x22, 0x63, 0xb9, 0x64, 0x9e, 0x3b, 0x76, 0x54, 0x14, 0x14, 0x94, 0xf5, 0x02, 0xbd, 0xbd, 0xe6,
0x3e, 0x5e, 0xd0, 0x9a, 0x78, 0xd3, 0xc1, 0xec, 0xa3, 0x53, 0xcc, 0xf3, 0x74, 0x77, 0x0e, 0xd4, 0xd8, 0x99, 0x34, 0xa9, 0x96, 0xc8, 0x97, 0xd0, 0x9d, 0xe7, 0xc7, 0xf3, 0x5a, 0x63, 0x67, 0xd2,
0xa2, 0xa3, 0x9f, 0xe0, 0xb0, 0x06, 0x29, 0x22, 0x7b, 0xbb, 0x23, 0xfb, 0x95, 0xc8, 0x95, 0xbc, 0x9f, 0x7e, 0x78, 0x82, 0x99, 0x9f, 0x6c, 0xcf, 0x81, 0x1a, 0xeb, 0xe0, 0x67, 0x38, 0xa8, 0x99,
0xd5, 0xa1, 0x2a, 0x79, 0xff, 0xd9, 0x84, 0x07, 0xce, 0xff, 0x2b, 0xbe, 0x60, 0x26, 0xc6, 0x27, 0x14, 0x91, 0x9d, 0xed, 0x91, 0xdd, 0x4a, 0xe4, 0x4a, 0xde, 0xea, 0x50, 0x95, 0xbc, 0xff, 0x6c,
0x30, 0xcc, 0xe2, 0x74, 0xf5, 0xc4, 0x59, 0x7a, 0x68, 0x59, 0x55, 0x92, 0x29, 0x1c, 0x16, 0x8a, 0xc2, 0x7d, 0x8b, 0xff, 0x92, 0xcf, 0x99, 0x8e, 0xf1, 0x31, 0x0c, 0x92, 0x30, 0x4e, 0x1f, 0x5b,
0x72, 0xf0, 0xba, 0xba, 0x38, 0x73, 0x73, 0xf7, 0x99, 0x5b, 0x95, 0x33, 0x47, 0x70, 0xb0, 0xce, 0x4f, 0x07, 0x3d, 0xab, 0x4a, 0x32, 0x81, 0x83, 0x42, 0x51, 0x0e, 0x5e, 0x57, 0x17, 0x67, 0x6e,
0x59, 0x11, 0xbc, 0x8d, 0xc1, 0x2b, 0xba, 0x6a, 0x5e, 0x9d, 0x5a, 0x5e, 0xc6, 0x83, 0x4a, 0x86, 0x6e, 0x3f, 0x73, 0xab, 0x72, 0xe6, 0x00, 0xf6, 0x57, 0x19, 0x2b, 0x82, 0xb7, 0x31, 0x78, 0x45,
0x21, 0xa0, 0xeb, 0x3c, 0x38, 0x9d, 0xf2, 0x20, 0x1c, 0xa0, 0xa7, 0x3d, 0x38, 0x05, 0x09, 0xa1, 0x57, 0xcd, 0xab, 0x53, 0xcb, 0x4b, 0x23, 0xa8, 0x64, 0x18, 0x1a, 0x74, 0x2d, 0x82, 0xd5, 0x29,
0x27, 0x6f, 0x9f, 0xf2, 0xcd, 0x4a, 0x8a, 0xa0, 0x3f, 0xf1, 0xa6, 0x43, 0xea, 0x64, 0xbd, 0x47, 0x04, 0x61, 0x0d, 0x7a, 0x39, 0x82, 0x55, 0x10, 0x1f, 0x7a, 0xf2, 0xf6, 0x9c, 0xaf, 0x53, 0x29,
0x99, 0xd8, 0x2c, 0x65, 0x00, 0x68, 0xe8, 0x64, 0x12, 0x40, 0x57, 0xde, 0x2a, 0x0f, 0x22, 0x18, 0xbc, 0xbd, 0xb1, 0x33, 0x19, 0x50, 0x2b, 0xe7, 0x7b, 0x94, 0x89, 0xf5, 0x52, 0x7a, 0x80, 0x8e,
0x20, 0xcb, 0xac, 0xa8, 0x6a, 0x8a, 0x65, 0xbe, 0xb2, 0xa6, 0x07, 0xba, 0xa6, 0x15, 0xa5, 0x3a, 0x56, 0x26, 0x1e, 0x74, 0xe5, 0xad, 0x42, 0x10, 0x5e, 0x1f, 0x59, 0x66, 0x44, 0x55, 0x53, 0x2c,
0xb9, 0x51, 0x68, 0x27, 0x43, 0x74, 0x52, 0xd1, 0x45, 0xdf, 0x96, 0xc8, 0xfa, 0x94, 0x67, 0x59, 0xf3, 0x95, 0x71, 0xdd, 0xcf, 0x6b, 0x5a, 0x51, 0xaa, 0x93, 0x6b, 0x45, 0x0e, 0x32, 0x40, 0x90,
0x2a, 0x1f, 0xe3, 0x45, 0x21, 0xb3, 0x0a, 0x59, 0x07, 0xb3, 0xb0, 0xce, 0xb2, 0xa2, 0xc5, 0x96, 0x8a, 0x2e, 0xf8, 0xb6, 0x44, 0xd6, 0x73, 0x9e, 0x24, 0xb1, 0x7c, 0x84, 0x57, 0x87, 0x4c, 0x2b,
0xc8, 0xd1, 0x0b, 0x38, 0x76, 0xdb, 0xdf, 0xa5, 0x2b, 0x96, 0xff, 0x07, 0x5f, 0x7f, 0x35, 0x4b, 0x64, 0xed, 0x4f, 0xfd, 0x3a, 0xcb, 0x8a, 0x16, 0x1b, 0x22, 0x07, 0xcf, 0xe1, 0xc8, 0x6e, 0x7f,
0x74, 0x35, 0x7e, 0xce, 0xa1, 0x93, 0xe0, 0x19, 0x8d, 0x9f, 0x47, 0x75, 0x3f, 0xe5, 0x0c, 0xe6, 0x17, 0xa7, 0x2c, 0xfb, 0x1f, 0x58, 0x7f, 0x37, 0x4b, 0x74, 0xd5, 0x38, 0x67, 0xd0, 0x89, 0xf0,
0x0d, 0x6a, 0xd0, 0xe4, 0x0c, 0xda, 0x99, 0x3a, 0x0e, 0x52, 0x66, 0x30, 0xfb, 0xb0, 0x6e, 0x56, 0x8c, 0x1a, 0xe7, 0x61, 0x1d, 0xa7, 0x9c, 0xc1, 0xac, 0x41, 0xb5, 0x35, 0x39, 0x85, 0x76, 0xa2,
0x3a, 0xeb, 0xbc, 0x41, 0x35, 0x96, 0x7c, 0x03, 0xc3, 0x58, 0x08, 0x26, 0xaf, 0xd4, 0xf4, 0x78, 0x8e, 0x83, 0x94, 0xe9, 0x4f, 0x3f, 0xa8, 0xbb, 0x95, 0xce, 0x3a, 0x6b, 0xd0, 0xdc, 0x96, 0x7c,
0xcd, 0x72, 0x73, 0xdb, 0x4e, 0x8c, 0xf1, 0x63, 0xb5, 0x27, 0xec, 0xe6, 0xbc, 0x41, 0xab, 0x68, 0x03, 0x83, 0x50, 0x08, 0x26, 0xaf, 0xd4, 0x3c, 0x79, 0xc5, 0x32, 0x7d, 0xdb, 0x8e, 0xb5, 0xf3,
0x67, 0xfe, 0x63, 0x2a, 0x6f, 0x16, 0x79, 0xfc, 0x1e, 0x99, 0x57, 0x37, 0xb7, 0x9b, 0xce, 0xdc, 0x23, 0xb5, 0x27, 0xcc, 0xe6, 0xac, 0x41, 0xab, 0xd6, 0xd6, 0xfd, 0xa7, 0x58, 0x2e, 0xe6, 0x59,
0x2a, 0xc8, 0x19, 0xf4, 0xa4, 0x0d, 0xdc, 0xd9, 0x1f, 0xd8, 0x01, 0x95, 0xd1, 0x7b, 0x1b, 0xae, 0xf8, 0x16, 0x99, 0x57, 0x77, 0x37, 0x9b, 0xd6, 0xdd, 0x28, 0xc8, 0x29, 0xf4, 0xa4, 0x09, 0xdc,
0xbb, 0x3f, 0x9c, 0x03, 0x92, 0xe7, 0x30, 0xb2, 0x0e, 0xae, 0xf8, 0xf3, 0x5b, 0x96, 0x20, 0x81, 0xd9, 0x1d, 0xd8, 0x1a, 0x2a, 0xa7, 0xb7, 0x26, 0x5c, 0x77, 0x77, 0x38, 0x6b, 0x48, 0x9e, 0xc2,
0x8b, 0x2a, 0x55, 0xe3, 0x69, 0xc8, 0xbc, 0x41, 0x6b, 0x46, 0x64, 0x04, 0xbe, 0xbc, 0xc3, 0x3b, 0xd0, 0x00, 0x5c, 0xf1, 0xa7, 0xb7, 0x2c, 0x42, 0x02, 0x17, 0x55, 0xaa, 0xc6, 0xcb, 0x4d, 0x66,
0xdb, 0xa6, 0xbe, 0xbc, 0x7b, 0xd2, 0x85, 0xf6, 0xbb, 0x78, 0xb9, 0x61, 0xd1, 0xdf, 0x1e, 0x8c, 0x0d, 0x5a, 0x73, 0x22, 0x43, 0x70, 0xe5, 0x06, 0xef, 0x6c, 0x9b, 0xba, 0x72, 0xf3, 0xb8, 0x0b,
0x29, 0x4b, 0x58, 0xba, 0x96, 0xb5, 0x3e, 0x11, 0x02, 0x2d, 0x35, 0x51, 0xcd, 0xf4, 0xc1, 0x75, 0xed, 0x37, 0xe1, 0x72, 0xcd, 0x82, 0x7f, 0x1c, 0x18, 0x51, 0x16, 0xb1, 0x78, 0x25, 0x6b, 0x7d,
0x89, 0x2b, 0xfe, 0x7d, 0xb9, 0x42, 0xbe, 0x80, 0xd6, 0x3a, 0x67, 0xef, 0x4c, 0x7b, 0xb7, 0x58, 0x22, 0x04, 0x5a, 0x6a, 0xa2, 0xea, 0xe9, 0x83, 0xeb, 0x12, 0x57, 0xdc, 0x77, 0xe5, 0x0a, 0xf9,
0x51, 0x1e, 0xc2, 0x14, 0x91, 0xe4, 0x1c, 0xba, 0xc9, 0x26, 0xcf, 0xd9, 0x4a, 0x9a, 0xb6, 0xee, 0x02, 0x5a, 0xab, 0x8c, 0xbd, 0xd1, 0xed, 0xbd, 0xc3, 0x8a, 0xf2, 0x10, 0xa6, 0x68, 0x49, 0xce,
0x37, 0xb2, 0x60, 0x75, 0x5d, 0xea, 0xb9, 0x20, 0x79, 0xfe, 0x15, 0xc5, 0x7f, 0xf5, 0xe1, 0xb8, 0xa0, 0x1b, 0xad, 0xb3, 0x8c, 0xa5, 0x52, 0xb7, 0x75, 0xb7, 0x93, 0x31, 0x56, 0xd7, 0xa5, 0x9e,
0xee, 0xed, 0x19, 0x5f, 0x31, 0xf2, 0x31, 0x80, 0xe4, 0x32, 0x5e, 0x2a, 0x1b, 0xfb, 0x58, 0x94, 0x0b, 0x92, 0xe7, 0x3f, 0x51, 0xfc, 0x37, 0x17, 0x8e, 0xea, 0x68, 0x4f, 0x78, 0xca, 0xc8, 0x47,
0x34, 0x64, 0x02, 0x03, 0x94, 0x74, 0x19, 0x4d, 0xd1, 0xcb, 0x2a, 0xf2, 0x19, 0x8c, 0x32, 0x2e, 0x00, 0x92, 0xcb, 0x70, 0xa9, 0x7c, 0xcc, 0x63, 0x51, 0xd2, 0x90, 0x31, 0xf4, 0x51, 0xca, 0xcb,
0xe4, 0x65, 0x9c, 0x31, 0x03, 0x6a, 0x22, 0xa8, 0xa6, 0x2d, 0x86, 0x69, 0x6b, 0xf7, 0x30, 0x6d, 0xa8, 0x8b, 0x5e, 0x56, 0x91, 0x4f, 0x61, 0x98, 0x70, 0x21, 0x2f, 0xc3, 0x84, 0x69, 0xa3, 0x26,
0xd7, 0x1f, 0x80, 0x62, 0xcc, 0x75, 0xf6, 0x8d, 0xb9, 0xee, 0x9e, 0x31, 0xd7, 0xab, 0x8e, 0xb9, 0x1a, 0xd5, 0xb4, 0xc5, 0x30, 0x6d, 0x6d, 0x1f, 0xa6, 0xed, 0xfa, 0x03, 0x50, 0x8c, 0xb9, 0xce,
0xe8, 0xe7, 0x6d, 0x7e, 0x50, 0x96, 0xf0, 0x7c, 0xf1, 0x7f, 0xf1, 0x23, 0xfa, 0x14, 0x06, 0x6e, 0xae, 0x31, 0xd7, 0xdd, 0x31, 0xe6, 0x7a, 0xd5, 0x31, 0x17, 0xfc, 0x72, 0x97, 0x1f, 0x94, 0x45,
0xfb, 0xea, 0x56, 0xa5, 0xa7, 0x07, 0xa9, 0x71, 0x6c, 0xa4, 0xe8, 0x02, 0x1e, 0x52, 0xf6, 0xb6, 0x3c, 0x9b, 0xbf, 0x2f, 0x7e, 0x04, 0x9f, 0x40, 0xdf, 0x6e, 0x5f, 0xdd, 0xaa, 0xf4, 0xf2, 0x41,
0x40, 0xaa, 0x5a, 0xd4, 0x1f, 0x9d, 0xfb, 0x3c, 0x94, 0xd1, 0x0b, 0x78, 0x40, 0x99, 0x58, 0x57, 0xaa, 0x81, 0xb5, 0x14, 0x5c, 0xc0, 0x03, 0xca, 0x5e, 0x17, 0x96, 0xaa, 0x16, 0xf5, 0x47, 0xe7,
0x3d, 0x09, 0x72, 0x06, 0x1d, 0xb4, 0xd3, 0xdf, 0x89, 0xe2, 0x86, 0xed, 0xe2, 0x00, 0x35, 0xd0, 0x5d, 0x1e, 0xca, 0xe0, 0x39, 0xdc, 0xa7, 0x4c, 0xac, 0xaa, 0x48, 0x82, 0x9c, 0x42, 0x07, 0xfd,
0xe8, 0x0f, 0x1f, 0x46, 0xc5, 0x1c, 0x54, 0x77, 0x51, 0x95, 0xe5, 0x75, 0xce, 0x33, 0x5b, 0x16, 0xf2, 0xef, 0x44, 0x71, 0xc3, 0xb6, 0x71, 0x80, 0x6a, 0xd3, 0xe0, 0x0f, 0x17, 0x86, 0xc5, 0x1c,
0xb5, 0xc6, 0xeb, 0xc7, 0xcd, 0x07, 0xc2, 0x97, 0x5c, 0x51, 0x28, 0x75, 0xf7, 0x1d, 0x9b, 0xdf, 0x54, 0x77, 0x51, 0x95, 0xe5, 0x55, 0xc6, 0x13, 0x53, 0x16, 0xb5, 0xc6, 0xeb, 0xc7, 0xf5, 0x07,
0xa3, 0x25, 0x4d, 0xa9, 0x06, 0x2d, 0x6c, 0x87, 0x91, 0x94, 0x3e, 0xce, 0x54, 0xcf, 0x6c, 0xeb, 0xc2, 0x95, 0x5c, 0x51, 0x28, 0xb6, 0xf7, 0x1d, 0x9b, 0xdf, 0xa3, 0x25, 0x4d, 0xa9, 0x06, 0x2d,
0xb5, 0xa4, 0x62, 0x32, 0x35, 0x1b, 0x3a, 0x3a, 0xa6, 0x5a, 0xe3, 0x7f, 0xe6, 0x2e, 0xbb, 0xe6, 0x6c, 0x87, 0x96, 0x94, 0x3e, 0x4c, 0x54, 0xcf, 0x4c, 0xeb, 0x73, 0x49, 0xc5, 0x64, 0x6a, 0x36,
0x4b, 0x6c, 0x77, 0x9f, 0x1a, 0xa9, 0x54, 0x16, 0xa8, 0xd0, 0xe7, 0x73, 0x38, 0xd2, 0x03, 0x59, 0x74, 0xf2, 0x98, 0x6a, 0x8d, 0xff, 0x99, 0x4d, 0x72, 0xcd, 0x97, 0xd8, 0xee, 0x3d, 0xaa, 0xa5,
0x25, 0x68, 0x1e, 0xf9, 0x13, 0x44, 0x6c, 0xe9, 0xd5, 0xf9, 0xd5, 0x77, 0xce, 0xa0, 0xc6, 0x88, 0x52, 0x59, 0xa0, 0x42, 0x9f, 0xcf, 0xe0, 0x30, 0x1f, 0xc8, 0x2a, 0x41, 0xfd, 0xc8, 0x1f, 0xa3,
0x2a, 0x69, 0xd4, 0xdb, 0x28, 0x36, 0x49, 0xc2, 0x84, 0x08, 0x1e, 0x62, 0x72, 0x56, 0x9c, 0xfd, 0xc5, 0x1d, 0xbd, 0x3a, 0xbf, 0xfa, 0xe0, 0x69, 0xab, 0x11, 0x5a, 0x95, 0x34, 0xea, 0x6d, 0x14,
0xe6, 0x43, 0xdf, 0xfd, 0x04, 0xc9, 0x39, 0xf4, 0x2e, 0x98, 0xc4, 0x06, 0x90, 0x23, 0x57, 0xef, 0xeb, 0x28, 0x62, 0x42, 0x78, 0x0f, 0x30, 0x39, 0x23, 0x4e, 0xff, 0x72, 0x61, 0xcf, 0xfe, 0x0d,
0xb7, 0x97, 0x32, 0x4f, 0x57, 0x6f, 0xc2, 0xf1, 0xee, 0xaf, 0x53, 0xd4, 0x20, 0x5f, 0x01, 0xbc, 0xc9, 0x19, 0xf4, 0x2e, 0x98, 0xc4, 0x06, 0x90, 0x43, 0x5b, 0xef, 0xd7, 0x97, 0x32, 0x8b, 0xd3,
0x4c, 0x85, 0x34, 0x9d, 0x1b, 0x16, 0x96, 0xaf, 0xd2, 0x65, 0x18, 0x3a, 0x71, 0xab, 0xc9, 0x51, 0x1b, 0x7f, 0xb4, 0xfd, 0xeb, 0x14, 0x34, 0xc8, 0x57, 0x00, 0x2f, 0x62, 0x21, 0x75, 0xe7, 0x06,
0x83, 0x7c, 0x0f, 0x23, 0x1b, 0xd2, 0x26, 0x53, 0x98, 0xef, 0x62, 0x57, 0xb8, 0x8f, 0x08, 0x51, 0x85, 0xe7, 0xcb, 0x78, 0xe9, 0xfb, 0x56, 0xbc, 0xd3, 0xe4, 0xa0, 0x41, 0xbe, 0x87, 0xa1, 0x09,
0x83, 0x7c, 0x0d, 0x47, 0x17, 0x4c, 0x62, 0xef, 0xdd, 0xdb, 0x3e, 0x2a, 0x5c, 0xaa, 0xbe, 0x85, 0x69, 0x92, 0x29, 0xdc, 0xb7, 0xb1, 0xcb, 0xdf, 0x45, 0x84, 0xa0, 0x41, 0xbe, 0x86, 0xc3, 0x0b,
0x27, 0xf5, 0x4c, 0x10, 0x1e, 0x35, 0xae, 0x3b, 0xf8, 0xc7, 0x3d, 0xfb, 0x27, 0x00, 0x00, 0xff, 0x26, 0xb1, 0xf7, 0xf6, 0x6d, 0x1f, 0x16, 0x90, 0xaa, 0x6f, 0xfe, 0x71, 0x3d, 0x13, 0x34, 0x0f,
0xff, 0x6c, 0x00, 0x31, 0x06, 0x1e, 0x0b, 0x00, 0x00, 0x1a, 0xe4, 0x73, 0xe8, 0x3c, 0x13, 0x97, 0x9b, 0x34, 0xaa, 0x27, 0x71, 0x4f, 0x8b, 0xcf, 0xc4,
0x79, 0xb8, 0xbe, 0x59, 0xc8, 0x1f, 0x57, 0x41, 0xe3, 0xba, 0x83, 0x3f, 0xe2, 0xd3, 0x7f, 0x03,
0x00, 0x00, 0xff, 0xff, 0x8a, 0x1e, 0xc2, 0xb5, 0x5e, 0x0b, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
...@@ -1322,6 +1324,7 @@ type ParacrossClient interface { ...@@ -1322,6 +1324,7 @@ type ParacrossClient interface {
ListTitles(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*RespParacrossTitles, error) ListTitles(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*RespParacrossTitles, error)
GetTitleHeight(ctx context.Context, in *ReqParacrossTitleHeight, opts ...grpc.CallOption) (*ReceiptParacrossDone, error) GetTitleHeight(ctx context.Context, in *ReqParacrossTitleHeight, opts ...grpc.CallOption) (*ReceiptParacrossDone, error)
GetAssetTxResult(ctx context.Context, in *types.ReqHash, opts ...grpc.CallOption) (*ParacrossAsset, error) GetAssetTxResult(ctx context.Context, in *types.ReqHash, opts ...grpc.CallOption) (*ParacrossAsset, error)
IsSync(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.IsCaughtUp, error)
} }
type paracrossClient struct { type paracrossClient struct {
...@@ -1368,12 +1371,22 @@ func (c *paracrossClient) GetAssetTxResult(ctx context.Context, in *types.ReqHas ...@@ -1368,12 +1371,22 @@ func (c *paracrossClient) GetAssetTxResult(ctx context.Context, in *types.ReqHas
return out, nil return out, nil
} }
func (c *paracrossClient) IsSync(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.IsCaughtUp, error) {
out := new(types.IsCaughtUp)
err := c.cc.Invoke(ctx, "/types.paracross/IsSync", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ParacrossServer is the server API for Paracross service. // ParacrossServer is the server API for Paracross service.
type ParacrossServer interface { type ParacrossServer interface {
GetTitle(context.Context, *types.ReqString) (*ParacrossStatus, error) GetTitle(context.Context, *types.ReqString) (*ParacrossStatus, error)
ListTitles(context.Context, *types.ReqNil) (*RespParacrossTitles, error) ListTitles(context.Context, *types.ReqNil) (*RespParacrossTitles, error)
GetTitleHeight(context.Context, *ReqParacrossTitleHeight) (*ReceiptParacrossDone, error) GetTitleHeight(context.Context, *ReqParacrossTitleHeight) (*ReceiptParacrossDone, error)
GetAssetTxResult(context.Context, *types.ReqHash) (*ParacrossAsset, error) GetAssetTxResult(context.Context, *types.ReqHash) (*ParacrossAsset, error)
IsSync(context.Context, *types.ReqNil) (*types.IsCaughtUp, error)
} }
func RegisterParacrossServer(s *grpc.Server, srv ParacrossServer) { func RegisterParacrossServer(s *grpc.Server, srv ParacrossServer) {
...@@ -1452,6 +1465,24 @@ func _Paracross_GetAssetTxResult_Handler(srv interface{}, ctx context.Context, d ...@@ -1452,6 +1465,24 @@ func _Paracross_GetAssetTxResult_Handler(srv interface{}, ctx context.Context, d
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _Paracross_IsSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(types.ReqNil)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ParacrossServer).IsSync(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.paracross/IsSync",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ParacrossServer).IsSync(ctx, req.(*types.ReqNil))
}
return interceptor(ctx, in, info, handler)
}
var _Paracross_serviceDesc = grpc.ServiceDesc{ var _Paracross_serviceDesc = grpc.ServiceDesc{
ServiceName: "types.paracross", ServiceName: "types.paracross",
HandlerType: (*ParacrossServer)(nil), HandlerType: (*ParacrossServer)(nil),
...@@ -1472,6 +1503,10 @@ var _Paracross_serviceDesc = grpc.ServiceDesc{ ...@@ -1472,6 +1503,10 @@ var _Paracross_serviceDesc = grpc.ServiceDesc{
MethodName: "GetAssetTxResult", MethodName: "GetAssetTxResult",
Handler: _Paracross_GetAssetTxResult_Handler, Handler: _Paracross_GetAssetTxResult_Handler,
}, },
{
MethodName: "IsSync",
Handler: _Paracross_IsSync_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "paracross.proto", Metadata: "paracross.proto",
......
...@@ -91,7 +91,7 @@ func NewJoinTable(left *Table, right *Table, indexes []string) (*JoinTable, erro ...@@ -91,7 +91,7 @@ func NewJoinTable(left *Table, right *Table, indexes []string) (*JoinTable, erro
join.leftIndex = append(join.leftIndex, joinindex[0]) join.leftIndex = append(join.leftIndex, joinindex[0])
} }
if joinindex[1] == "" || !right.canGet(joinindex[1]) { if joinindex[1] == "" || !right.canGet(joinindex[1]) {
return nil, errors.New("jointable: left table can not get: " + joinindex[1]) return nil, errors.New("jointable: right table can not get: " + joinindex[1])
} }
if joinindex[1] != "" { if joinindex[1] != "" {
join.rightIndex = append(join.rightIndex, joinindex[1]) join.rightIndex = append(join.rightIndex, joinindex[1])
...@@ -160,6 +160,7 @@ func (join *JoinTable) GetData(primaryKey []byte) (*Row, error) { ...@@ -160,6 +160,7 @@ func (join *JoinTable) GetData(primaryKey []byte) (*Row, error) {
} }
rowjoin := join.meta.CreateRow() rowjoin := join.meta.CreateRow()
rowjoin.Ty = None rowjoin.Ty = None
rowjoin.Primary = leftrow.Primary
rowjoin.Data.(*JoinData).Left = leftrow.Data rowjoin.Data.(*JoinData).Left = leftrow.Data
rowjoin.Data.(*JoinData).Right = rightrow.Data rowjoin.Data.(*JoinData).Right = rightrow.Data
return rowjoin, nil return rowjoin, nil
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment