Merge pull request #220 from meshplus/refactor/executor-ibtp

refactor(*): optimize interchain tx execution
This commit is contained in:
Alexader 2020-10-23 19:22:18 +08:00 committed by GitHub
commit c2862576c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 49 deletions

View File

@ -257,22 +257,15 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
im := &InterchainManager{mockStub}
fakeIBTP := []byte{1}
res := im.HandleIBTP(fakeIBTP)
assert.False(t, res.Ok)
ibtp := &pb.IBTP{
From: from,
}
ibtpd, err := ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res := im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "this appchain does not exist", string(res.Result))
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "empty destination chain id", string(res.Result))
@ -287,74 +280,50 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
Version: "",
Extra: nil,
}
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
mockStub.EXPECT().Caller().Return(ibtp.To)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "ibtp from != caller", string(res.Result))
mockStub.EXPECT().Caller().Return(ibtp.From).MaxTimes(6)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "wrong index, required 2, but 0", string(res.Result))
ibtp.Index = 2
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_ASSET_EXCHANGE_INIT
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_ASSET_EXCHANGE_REFUND
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_ASSET_EXCHANGE_REDEEM
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_RECEIPT_SUCCESS
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.False(t, res.Ok)
assert.Equal(t, "ibtp to != caller", string(res.Result))
mockStub.EXPECT().Caller().Return(ibtp.To).AnyTimes()
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_RECEIPT_FAILURE
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
ibtp.Type = pb.IBTP_ASSET_EXCHANGE_RECEIPT
ibtpd, err = ibtp.Marshal()
assert.Nil(t, err)
res = im.HandleIBTP(ibtpd)
res = im.HandleIBTP(ibtp)
assert.True(t, res.Ok)
}

View File

@ -102,12 +102,7 @@ func (x *InterchainManager) GetInterchain(id string) *boltvm.Response {
return boltvm.Success(data)
}
func (x *InterchainManager) HandleIBTP(data []byte) *boltvm.Response {
ibtp := &pb.IBTP{}
if err := ibtp.Unmarshal(data); err != nil {
return boltvm.Error(err.Error())
}
func (x *InterchainManager) HandleIBTP(ibtp *pb.IBTP) *boltvm.Response {
if len(strings.Split(ibtp.From, "-")) == 2 {
return x.handleUnionIBTP(ibtp)
}

View File

@ -254,6 +254,12 @@ func (exec *BlockExecutor) postBlockEvent(block *pb.Block, interchainMeta *pb.In
}
func (exec *BlockExecutor) applyTransaction(i int, tx *pb.Transaction, opt *agency.TxOpt) ([]byte, error) {
if tx.IsIBTP() {
ctx := vm.NewContext(tx, uint64(i), nil, exec.ledger, exec.logger)
instance := boltvm.New(ctx, exec.validationEngine, exec.getContracts(opt))
return instance.HandleIBTP(tx.IBTP)
}
if tx.Payload == nil {
return nil, fmt.Errorf("empty transaction data")
}

View File

@ -9,6 +9,7 @@ import (
"github.com/meshplus/bitxhub-core/boltvm"
"github.com/meshplus/bitxhub-core/validator"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/executor/contracts"
"github.com/meshplus/bitxhub/pkg/vm"
)
@ -79,6 +80,28 @@ func (bvm *BoltVM) Run(input []byte) (ret []byte, err error) {
return res.Result, err
}
func (bvm *BoltVM) HandleIBTP(ibtp *pb.IBTP) (ret []byte, err error) {
defer func() {
if e := recover(); e != nil {
err = fmt.Errorf("%v", e)
}
}()
con := &contracts.InterchainManager{}
con.Stub = &BoltStubImpl{
bvm: bvm,
ctx: bvm.ctx,
ve: bvm.ve,
}
res := con.HandleIBTP(ibtp)
if !res.Ok {
return nil, fmt.Errorf("call error: %s", res.Result)
}
return res.Result, err
}
func parseArgs(in []*pb.Arg) ([]reflect.Value, error) {
args := make([]reflect.Value, len(in))
for i := 0; i < len(in); i++ {