parent
b10b7dab28
commit
f4a9218fd3
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/meshplus/bitxhub/pkg/vm"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/boltvm"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/wasm"
|
||||
"github.com/meshplus/bitxhub/pkg/vm/wasm/vmledger"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -298,7 +299,7 @@ func (exec *BlockExecutor) applyTransaction(i int, tx *pb.Transaction, opt *agen
|
|||
instance = boltvm.New(ctx, exec.validationEngine, exec.getContracts(opt))
|
||||
case pb.TransactionData_XVM:
|
||||
ctx := vm.NewContext(tx, uint64(i), data, exec.ledger, exec.logger)
|
||||
imports, err := wasm.EmptyImports()
|
||||
imports, err := vmledger.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package vmledger
|
||||
|
||||
import (
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||
)
|
||||
|
||||
type Imports struct {
|
||||
imports *wasmer.Imports
|
||||
}
|
||||
|
||||
func New() (*wasmer.Imports, error) {
|
||||
imports := &Imports{
|
||||
imports: wasmer.NewImports(),
|
||||
}
|
||||
imports.importLedger()
|
||||
|
||||
return imports.imports, nil
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package vmledger
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// extern long long unsigned int get_balance(void *context);
|
||||
// extern void set_balance(void *context, long long unsigned int value);
|
||||
// extern int32_t get_state(void *context, long long key_ptr);
|
||||
// extern void set_state(void *context, long long key_ptr, long long value_ptr);
|
||||
// extern void add_state(void *context, long long key_ptr, long long value_ptr);
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/meshplus/bitxhub/internal/ledger"
|
||||
"github.com/wasmerio/go-ext-wasm/wasmer"
|
||||
)
|
||||
|
||||
//export get_balance
|
||||
func get_balance(context unsafe.Pointer) uint64 {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
ctxMap := ctx.Data().(map[string]interface{})
|
||||
account := ctxMap["account"].(*ledger.Account)
|
||||
return account.GetBalance()
|
||||
}
|
||||
|
||||
//export set_balance
|
||||
func set_balance(context unsafe.Pointer, value uint64) {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
ctxMap := ctx.Data().(map[string]interface{})
|
||||
account := ctxMap["account"].(*ledger.Account)
|
||||
account.SetBalance(value)
|
||||
}
|
||||
|
||||
//export get_state
|
||||
func get_state(context unsafe.Pointer, key_ptr int64) int32 {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
ctxMap := ctx.Data().(map[string]interface{})
|
||||
data := ctxMap["argmap"].(map[int]int)
|
||||
alloc := ctxMap["alloc"].(func(...interface{}) (wasmer.Value, error))
|
||||
account := ctxMap["account"].(*ledger.Account)
|
||||
memory := ctx.Memory()
|
||||
key := memory.Data()[key_ptr : key_ptr+int64(data[int(key_ptr)])]
|
||||
ok, value := account.GetState(key)
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
lengthOfBytes := len(value)
|
||||
|
||||
allocResult, err := alloc(lengthOfBytes)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
inputPointer := allocResult.ToI32()
|
||||
mem := memory.Data()[inputPointer:]
|
||||
|
||||
var i int
|
||||
for i = 0; i < lengthOfBytes; i++ {
|
||||
mem[i] = value[i]
|
||||
}
|
||||
|
||||
mem[i] = 0
|
||||
data[int(inputPointer)] = len(value)
|
||||
|
||||
return inputPointer
|
||||
}
|
||||
|
||||
//export set_state
|
||||
func set_state(context unsafe.Pointer, key_ptr int64, value_ptr int64) {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
ctxMap := ctx.Data().(map[string]interface{})
|
||||
data := ctxMap["argmap"].(map[int]int)
|
||||
account := ctxMap["account"].(*ledger.Account)
|
||||
memory := ctx.Memory()
|
||||
key := memory.Data()[key_ptr : key_ptr+int64(data[int(key_ptr)])]
|
||||
value := memory.Data()[value_ptr : value_ptr+int64(data[int(value_ptr)])]
|
||||
account.SetState(key, value)
|
||||
}
|
||||
|
||||
//export add_state
|
||||
func add_state(context unsafe.Pointer, key_ptr int64, value_ptr int64) {
|
||||
ctx := wasmer.IntoInstanceContext(context)
|
||||
ctxMap := ctx.Data().(map[string]interface{})
|
||||
data := ctxMap["argmap"].(map[int]int)
|
||||
account := ctxMap["account"].(*ledger.Account)
|
||||
memory := ctx.Memory()
|
||||
key := memory.Data()[key_ptr : key_ptr+int64(data[int(key_ptr)])]
|
||||
value := memory.Data()[value_ptr : value_ptr+int64(data[int(value_ptr)])]
|
||||
account.AddState(key, value)
|
||||
}
|
||||
|
||||
func (im *Imports) importLedger() {
|
||||
var err error
|
||||
im.imports, err = im.imports.Append("get_balance", get_balance, C.get_balance)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
im.imports, err = im.imports.Append("set_balance", set_balance, C.set_balance)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
im.imports, err = im.imports.Append("get_state", get_state, C.get_state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
im.imports, err = im.imports.Append("set_state", set_state, C.set_state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
im.imports, err = im.imports.Append("add_state", add_state, C.add_state)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue