feat: adjust validation and wasm module
move wasm lib to validation module wasm instance now need imports to create
This commit is contained in:
parent
3e602dcd07
commit
d1af9adfef
|
@ -233,8 +233,11 @@ func (exec *BlockExecutor) applyTransaction(i int, tx *pb.Transaction) ([]byte,
|
|||
instance = boltvm.New(ctx, exec.validationEngine)
|
||||
case pb.TransactionData_XVM:
|
||||
ctx := vm.NewContext(tx, uint64(i), tx.Data, exec.ledger, exec.logger)
|
||||
var err error
|
||||
instance, err = wasm.New(ctx)
|
||||
imports, err := wasm.EmptyImports()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
instance, err = wasm.New(ctx, imports)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package validator
|
|||
|
||||
import (
|
||||
"github.com/meshplus/bitxhub/internal/ledger"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/wasm/wasmlib"
|
||||
"github.com/meshplus/bitxhub/internal/validator/validatorlib"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -22,11 +22,11 @@ func NewFabV14Validator(ledger ledger.Ledger, logger logrus.FieldLogger) *FabV14
|
|||
|
||||
// Verify will check whether the transaction info is valid
|
||||
func (vlt *FabV14Validator) Verify(address, from string, proof []byte, validators string) (bool, error) {
|
||||
vInfo, err := wasmlib.UnmarshalValidatorInfo([]byte(validators))
|
||||
vInfo, err := validatorlib.UnmarshalValidatorInfo([]byte(validators))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
err = wasmlib.ValidateV14(proof, []byte(vInfo.Policy), vInfo.ConfByte, vInfo.Cid)
|
||||
err = validatorlib.ValidateV14(proof, []byte(vInfo.Policy), vInfo.ConfByte, vInfo.Cid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package wasmlib
|
||||
package validatorlib
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
|
@ -1,13 +1,8 @@
|
|||
package wasmlib
|
||||
package validatorlib
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// extern int32_t fabric_validate_v13(void *context, long long proof_ptr, long long validator_ptr);
|
||||
import "C"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
mb "github.com/hyperledger/fabric-protos-go/msp"
|
||||
|
@ -16,28 +11,8 @@ import (
|
|||
"github.com/hyperledger/fabric/common/cauthdsl"
|
||||
"github.com/hyperledger/fabric/msp"
|
||||
"github.com/hyperledger/fabric/protoutil"
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||
)
|
||||
|
||||
//export fabric_validate_v13
|
||||
func fabric_validate_v13(context unsafe.Pointer, proof_ptr int64, validator_ptr int64) int32 {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
data := ctx.Data().(map[int]int)
|
||||
memory := ctx.Memory()
|
||||
proof := memory.Data()[proof_ptr : proof_ptr+int64(data[int(proof_ptr)])]
|
||||
validator := memory.Data()[validator_ptr : validator_ptr+int64(data[int(validator_ptr)])]
|
||||
vInfo, err := UnmarshalValidatorInfo(validator)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
err = ValidateV14(proof, []byte(vInfo.Policy), vInfo.ConfByte, vInfo.Cid)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
type valiadationArtifacts struct {
|
||||
rwset []byte
|
||||
prp []byte
|
||||
|
@ -210,11 +185,3 @@ func (ds *dynamicDeserializer) DeserializeIdentity(serializedIdentity []byte) (m
|
|||
func (ds *dynamicDeserializer) IsWellFormed(identity *mb.SerializedIdentity) error {
|
||||
return ds.mspm.IsWellFormed(identity)
|
||||
}
|
||||
|
||||
func (im *Imports) importFabricV13() {
|
||||
var err error
|
||||
im.imports, err = im.imports.Append("fabric_validate_v13", fabric_validate_v13, C.fabric_validate_v13)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package validatorlib
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// extern int32_t fabric_validate_v13(void *context, long long proof_ptr, long long validator_ptr);
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||
)
|
||||
|
||||
//export fabric_validate_v13
|
||||
func fabric_validate_v13(context unsafe.Pointer, proof_ptr int64, validator_ptr int64) int32 {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
data := ctx.Data().(map[int]int)
|
||||
memory := ctx.Memory()
|
||||
proof := memory.Data()[proof_ptr : proof_ptr+int64(data[int(proof_ptr)])]
|
||||
validator := memory.Data()[validator_ptr : validator_ptr+int64(data[int(validator_ptr)])]
|
||||
vInfo, err := UnmarshalValidatorInfo(validator)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
err = ValidateV14(proof, []byte(vInfo.Policy), vInfo.ConfByte, vInfo.Cid)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
func (im *Imports) importFabricV13() {
|
||||
var err error
|
||||
im.imports, err = im.imports.Append("fabric_validate_v13", fabric_validate_v13, C.fabric_validate_v13)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package wasmlib
|
||||
package validatorlib
|
||||
|
||||
import (
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
"github.com/meshplus/bitxhub/internal/ledger"
|
||||
"github.com/meshplus/bitxhub/internal/validator/validatorlib"
|
||||
"github.com/meshplus/bitxhub/pkg/vm"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/wasm"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -60,7 +61,11 @@ func (vlt *WasmValidator) initRule(address, from string, proof []byte, validator
|
|||
}
|
||||
|
||||
wasmCtx := vm.NewContext(vlt.tx, 0, vlt.tx.Data, vlt.ledger, vlt.logger)
|
||||
wasm, err := wasm.New(wasmCtx)
|
||||
imports, err := validatorlib.New()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
wasm, err := wasm.New(wasmCtx, imports)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
"github.com/meshplus/bitxhub/pkg/vm"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/wasm/wasmlib"
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||
)
|
||||
|
||||
|
@ -23,18 +22,13 @@ var _ vm.VM = (*Wasm)(nil)
|
|||
|
||||
var instances = make(map[string]wasmer.Instance)
|
||||
|
||||
func getInstance(code []byte) (wasmer.Instance, error) {
|
||||
func getInstance(code []byte, imports *wasmer.Imports) (wasmer.Instance, error) {
|
||||
ret := sha256.Sum256(code)
|
||||
v, ok := instances[string(ret[:])]
|
||||
if ok {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
imports, err := wasmlib.New()
|
||||
if err != nil {
|
||||
return wasmer.Instance{}, err
|
||||
}
|
||||
|
||||
instance, err := wasmer.NewInstanceWithImports(code, imports)
|
||||
if err != nil {
|
||||
return wasmer.Instance{}, err
|
||||
|
@ -66,7 +60,7 @@ type Contract struct {
|
|||
}
|
||||
|
||||
// New creates a wasm vm instance
|
||||
func New(ctx *vm.Context) (*Wasm, error) {
|
||||
func New(ctx *vm.Context, imports *wasmer.Imports) (*Wasm, error) {
|
||||
wasm := &Wasm{
|
||||
ctx: ctx,
|
||||
}
|
||||
|
@ -90,7 +84,7 @@ func New(ctx *vm.Context) (*Wasm, error) {
|
|||
return wasm, fmt.Errorf("contract byte is empty")
|
||||
}
|
||||
|
||||
instance, err := getInstance(contract.Code)
|
||||
instance, err := getInstance(contract.Code, imports)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -101,6 +95,10 @@ func New(ctx *vm.Context) (*Wasm, error) {
|
|||
return wasm, nil
|
||||
}
|
||||
|
||||
func EmptyImports() (*wasmer.Imports, error) {
|
||||
return wasmer.NewImports(), nil
|
||||
}
|
||||
|
||||
// Run let the wasm vm excute or deploy the smart contract which depends on whether the callee is empty
|
||||
func (w *Wasm) Run(input []byte) (ret []byte, err error) {
|
||||
if w.ctx.Callee == (types.Address{}) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
"github.com/meshplus/bitxhub/internal/ledger"
|
||||
"github.com/meshplus/bitxhub/internal/validator/validatorlib"
|
||||
"github.com/meshplus/bitxhub/pkg/storage/leveldb"
|
||||
"github.com/meshplus/bitxhub/pkg/vm"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -117,7 +118,9 @@ func initFabricContext(t *testing.T, name string) *vm.Context {
|
|||
|
||||
func TestDeploy(t *testing.T) {
|
||||
ctx := initCreateContext(t, "create")
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(t, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = wasm.deploy()
|
||||
|
@ -126,7 +129,9 @@ func TestDeploy(t *testing.T) {
|
|||
|
||||
func TestExecute(t *testing.T) {
|
||||
ctx := initCreateContext(t, "execute")
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(t, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(t, err)
|
||||
|
||||
ret, err := wasm.deploy()
|
||||
|
@ -150,7 +155,9 @@ func TestExecute(t *testing.T) {
|
|||
TransactionData: data,
|
||||
Ledger: ctx.Ledger,
|
||||
}
|
||||
wasm1, err := New(ctx1)
|
||||
imports1, err := validatorlib.New()
|
||||
require.Nil(t, err)
|
||||
wasm1, err := New(ctx1, imports1)
|
||||
require.Nil(t, err)
|
||||
|
||||
result, err := wasm1.Run(payload)
|
||||
|
@ -160,7 +167,9 @@ func TestExecute(t *testing.T) {
|
|||
|
||||
func TestWasm_RunFabValidation(t *testing.T) {
|
||||
ctx := initFabricContext(t, "execute")
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(t, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(t, err)
|
||||
|
||||
ret, err := wasm.deploy()
|
||||
|
@ -188,7 +197,9 @@ func TestWasm_RunFabValidation(t *testing.T) {
|
|||
TransactionData: data,
|
||||
Ledger: ctx.Ledger,
|
||||
}
|
||||
wasm1, err := New(ctx1)
|
||||
imports1, err := validatorlib.New()
|
||||
require.Nil(t, err)
|
||||
wasm1, err := New(ctx1, imports1)
|
||||
require.Nil(t, err)
|
||||
|
||||
result, err := wasm1.Run(payload)
|
||||
|
@ -220,7 +231,9 @@ func BenchmarkRunFabValidation(b *testing.B) {
|
|||
TransactionData: data,
|
||||
Ledger: ldg,
|
||||
}
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(b, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(b, err)
|
||||
|
||||
ret, err := wasm.deploy()
|
||||
|
@ -246,7 +259,9 @@ func BenchmarkRunFabValidation(b *testing.B) {
|
|||
Ledger: ctx.Ledger,
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
wasm1, err := New(ctx1)
|
||||
imports1, err := validatorlib.New()
|
||||
require.Nil(b, err)
|
||||
wasm1, err := New(ctx1, imports1)
|
||||
require.Nil(b, err)
|
||||
|
||||
result, err := wasm1.Run(payload)
|
||||
|
@ -259,7 +274,9 @@ func BenchmarkRunFabValidation(b *testing.B) {
|
|||
|
||||
func TestWasm_RunValidation(t *testing.T) {
|
||||
ctx := initValidationContext(t, "execute")
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(t, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(t, err)
|
||||
|
||||
ret, err := wasm.deploy()
|
||||
|
@ -285,7 +302,9 @@ func TestWasm_RunValidation(t *testing.T) {
|
|||
TransactionData: data,
|
||||
Ledger: ctx.Ledger,
|
||||
}
|
||||
wasm1, err := New(ctx1)
|
||||
imports1, err := validatorlib.New()
|
||||
require.Nil(t, err)
|
||||
wasm1, err := New(ctx1, imports1)
|
||||
require.Nil(t, err)
|
||||
|
||||
result, err := wasm1.Run(payload)
|
||||
|
@ -295,7 +314,9 @@ func TestWasm_RunValidation(t *testing.T) {
|
|||
|
||||
func TestWasm_RunWithoutMethod(t *testing.T) {
|
||||
ctx := initCreateContext(t, "execute_without_method")
|
||||
wasm, err := New(ctx)
|
||||
imports, err := EmptyImports()
|
||||
require.Nil(t, err)
|
||||
wasm, err := New(ctx, imports)
|
||||
require.Nil(t, err)
|
||||
|
||||
ret, err := wasm.deploy()
|
||||
|
@ -319,7 +340,9 @@ func TestWasm_RunWithoutMethod(t *testing.T) {
|
|||
TransactionData: data,
|
||||
Ledger: ctx.Ledger,
|
||||
}
|
||||
wasm1, err := New(ctx1)
|
||||
imports1, err := validatorlib.New()
|
||||
require.Nil(t, err)
|
||||
wasm1, err := New(ctx1, imports1)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = wasm1.Run(payload)
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package wasmlib
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
m "github.com/hyperledger/fabric-protos-go/msp"
|
||||
"github.com/hyperledger/fabric/protoutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetPolicyEnvelope(t *testing.T) {
|
||||
_, err := GetPolicyEnvelope("OR(AND('A.member', 'B.member'), OR('C.admin', 'D.member'))")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestPayloadUnmarshal(t *testing.T) {
|
||||
bytes, err := ioutil.ReadFile("../testdata/proof")
|
||||
require.Nil(t, err)
|
||||
cap, err := protoutil.UnmarshalChaincodeActionPayload(bytes)
|
||||
|
||||
require.Nil(t, err)
|
||||
|
||||
prp := cap.Action.ProposalResponsePayload
|
||||
signatureSet := []*protoutil.SignedData{}
|
||||
for _, endorsement := range cap.Action.Endorsements {
|
||||
data := make([]byte, len(prp)+len(endorsement.Endorser))
|
||||
copy(data, prp)
|
||||
copy(data[len(prp):], endorsement.Endorser)
|
||||
|
||||
signatureSet = append(signatureSet, &protoutil.SignedData{
|
||||
// set the data that is signed; concatenation of proposal response bytes and endorser ID
|
||||
Data: data,
|
||||
// set the identity that signs the message: it's the endorser
|
||||
Identity: endorsement.Endorser,
|
||||
// set the signature
|
||||
Signature: endorsement.Signature})
|
||||
}
|
||||
sId := &m.SerializedIdentity{}
|
||||
err = proto.Unmarshal(signatureSet[0].Identity, sId)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestUnmarshalValidatorInfo(t *testing.T) {
|
||||
vBytes, err := ioutil.ReadFile("../testdata/validator")
|
||||
require.Nil(t, err)
|
||||
_, err = UnmarshalValidatorInfo(vBytes)
|
||||
require.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestValidateV14(t *testing.T) {
|
||||
vBytes, err := ioutil.ReadFile("../testdata/validator")
|
||||
require.Nil(t, err)
|
||||
proof, err := ioutil.ReadFile("../testdata/proof")
|
||||
require.Nil(t, err)
|
||||
v, err := UnmarshalValidatorInfo(vBytes)
|
||||
require.Nil(t, err)
|
||||
err = ValidateV14(proof, []byte(v.Policy), v.ConfByte, v.Cid)
|
||||
require.Nil(t, err)
|
||||
}
|
Loading…
Reference in New Issue