Commit 95061a25 authored by kingwang's avatar kingwang

add allow && change exec name to jsvm

parent 932ca951
<script src="runtime.js"></script>
<script src="test.js"></script>
<script>
callcode("{}", "execlocal_hello", "{}", [])
</script>
\ No newline at end of file
all:
./gen.sh
\ No newline at end of file
This diff is collapsed.
...@@ -8,7 +8,10 @@ import ( ...@@ -8,7 +8,10 @@ import (
) )
func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index int) (*types.Receipt, error) { func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index int) (*types.Receipt, error) {
execer := types.ExecName("user.js." + payload.Name) execer := types.ExecName("user." + ptypes.JsX + "." + payload.Name)
if string(tx.Execer) != execer {
return nil, types.ErrExecNameNotMatch
}
c.prefix = calcStatePrefix([]byte(execer)) c.prefix = calcStatePrefix([]byte(execer))
kvc := dapp.NewKVCreator(c.GetStateDB(), c.prefix, nil) kvc := dapp.NewKVCreator(c.GetStateDB(), c.prefix, nil)
_, err := kvc.GetNoPrefix(calcCodeKey(payload.Name)) _, err := kvc.GetNoPrefix(calcCodeKey(payload.Name))
...@@ -33,7 +36,10 @@ func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index i ...@@ -33,7 +36,10 @@ func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index i
} }
func (c *js) Exec_Call(payload *jsproto.Call, tx *types.Transaction, index int) (*types.Receipt, error) { func (c *js) Exec_Call(payload *jsproto.Call, tx *types.Transaction, index int) (*types.Receipt, error) {
execer := types.ExecName("user.js." + payload.Name) execer := types.ExecName("user." + ptypes.JsX + "." + payload.Name)
if string(tx.Execer) != execer {
return nil, types.ErrExecNameNotMatch
}
c.prefix = calcStatePrefix([]byte(execer)) c.prefix = calcStatePrefix([]byte(execer))
kvc := dapp.NewKVCreator(c.GetStateDB(), c.prefix, nil) kvc := dapp.NewKVCreator(c.GetStateDB(), c.prefix, nil)
jsvalue, err := c.callVM("exec", payload, tx, index, nil) jsvalue, err := c.callVM("exec", payload, tx, index, nil)
......
...@@ -3,6 +3,7 @@ package executor ...@@ -3,6 +3,7 @@ package executor
import ( import (
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
ptypes "github.com/33cn/plugin/plugin/dapp/js/types"
"github.com/33cn/plugin/plugin/dapp/js/types/jsproto" "github.com/33cn/plugin/plugin/dapp/js/types/jsproto"
) )
...@@ -12,7 +13,7 @@ func (c *js) ExecDelLocal_Create(payload *jsproto.Create, tx *types.Transaction, ...@@ -12,7 +13,7 @@ func (c *js) ExecDelLocal_Create(payload *jsproto.Create, tx *types.Transaction,
func (c *js) ExecDelLocal_Call(payload *jsproto.Call, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (c *js) ExecDelLocal_Call(payload *jsproto.Call, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
krollback := calcRollbackKey(tx.Hash()) krollback := calcRollbackKey(tx.Hash())
execer := types.ExecName("user.js." + payload.Name) execer := types.ExecName("user." + ptypes.JsX + "." + payload.Name)
c.prefix = calcLocalPrefix([]byte(execer)) c.prefix = calcLocalPrefix([]byte(execer))
kvc := dapp.NewKVCreator(c.GetLocalDB(), c.prefix, krollback) kvc := dapp.NewKVCreator(c.GetLocalDB(), c.prefix, krollback)
kvs, err := kvc.GetRollbackKVList() kvs, err := kvc.GetRollbackKVList()
......
...@@ -3,6 +3,7 @@ package executor ...@@ -3,6 +3,7 @@ package executor
import ( import (
"github.com/33cn/chain33/system/dapp" "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
ptypes "github.com/33cn/plugin/plugin/dapp/js/types"
"github.com/33cn/plugin/plugin/dapp/js/types/jsproto" "github.com/33cn/plugin/plugin/dapp/js/types/jsproto"
) )
...@@ -12,7 +13,7 @@ func (c *js) ExecLocal_Create(payload *jsproto.Create, tx *types.Transaction, re ...@@ -12,7 +13,7 @@ func (c *js) ExecLocal_Create(payload *jsproto.Create, tx *types.Transaction, re
func (c *js) ExecLocal_Call(payload *jsproto.Call, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (c *js) ExecLocal_Call(payload *jsproto.Call, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
k := calcRollbackKey(tx.Hash()) k := calcRollbackKey(tx.Hash())
execer := types.ExecName("user.js." + payload.Name) execer := types.ExecName("user." + ptypes.JsX + "." + payload.Name)
c.prefix = calcLocalPrefix([]byte(execer)) c.prefix = calcLocalPrefix([]byte(execer))
kvc := dapp.NewKVCreator(c.GetLocalDB(), c.prefix, k) kvc := dapp.NewKVCreator(c.GetLocalDB(), c.prefix, k)
jsvalue, err := c.callVM("execlocal", payload, tx, index, receiptData) jsvalue, err := c.callVM("execlocal", payload, tx, index, receiptData)
......
#!/bin/sh
echo "package executor\n\nvar callcode = \`" > const.go
cat runtime.js >> const.go
echo "\`" >> const.go
echo "var jscode = \`" >> const.go
cat test.js >> const.go
echo "\`" >> const.go
...@@ -106,6 +106,12 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction, ...@@ -106,6 +106,12 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
return jsvalue.Object(), nil return jsvalue.Object(), nil
} }
type jslogInfo struct {
Log string `json:"log"`
Ty int32 `json:"ty"`
Format string `json:"format"`
}
func jslogs(receiptData *types.ReceiptData) ([]string, error) { func jslogs(receiptData *types.ReceiptData) ([]string, error) {
data := make([]string, 0) data := make([]string, 0)
if receiptData == nil { if receiptData == nil {
...@@ -113,6 +119,7 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) { ...@@ -113,6 +119,7 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) {
} }
for i := 0; i < len(receiptData.Logs); i++ { for i := 0; i < len(receiptData.Logs); i++ {
logitem := receiptData.Logs[i] logitem := receiptData.Logs[i]
//只传递 json格式的日子,不传递 二进制的日志
if logitem.Ty != ptypes.TyLogJs { if logitem.Ty != ptypes.TyLogJs {
continue continue
} }
...@@ -121,7 +128,11 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) { ...@@ -121,7 +128,11 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
data = append(data, jslog.Data) item, err := json.Marshal(&jslogInfo{Log: jslog.Data, Ty: receiptData.Ty, Format: "json"})
if err != nil {
return nil, err
}
data = append(data, string(item))
} }
return data, nil return data, nil
} }
...@@ -143,14 +154,21 @@ func (u *js) getContext(tx *types.Transaction, index int64) *blockContext { ...@@ -143,14 +154,21 @@ func (u *js) getContext(tx *types.Transaction, index int64) *blockContext {
} }
} }
func (u *js) getstatedbFunc(vm *otto.Otto, name string) { func (u *js) statedbFunc(vm *otto.Otto, name string) {
prefix, _ := calcAllPrefix(name) prefix, _ := calcAllPrefix(name)
vm.Set("getstatedb", func(call otto.FunctionCall) otto.Value { vm.Set("getstatedb", func(call otto.FunctionCall) otto.Value {
key, err := call.Argument(0).ToString() key, err := call.Argument(0).ToString()
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
v, err := u.getstatedb(string(prefix) + key) hasprefix, err := call.Argument(1).ToBoolean()
if err != nil {
return errReturn(vm, err)
}
if !hasprefix {
key = string(prefix) + key
}
v, err := u.getstatedb(key)
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
...@@ -158,14 +176,21 @@ func (u *js) getstatedbFunc(vm *otto.Otto, name string) { ...@@ -158,14 +176,21 @@ func (u *js) getstatedbFunc(vm *otto.Otto, name string) {
}) })
} }
func (u *js) getlocaldbFunc(vm *otto.Otto, name string) { func (u *js) localdbFunc(vm *otto.Otto, name string) {
_, prefix := calcAllPrefix(name) _, prefix := calcAllPrefix(name)
vm.Set("getlocaldb", func(call otto.FunctionCall) otto.Value { vm.Set("getlocaldb", func(call otto.FunctionCall) otto.Value {
key, err := call.Argument(0).ToString() key, err := call.Argument(0).ToString()
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
v, err := u.getlocaldb(string(prefix) + key) hasprefix, err := call.Argument(1).ToBoolean()
if err != nil {
return errReturn(vm, err)
}
if !hasprefix {
key = string(prefix) + key
}
v, err := u.getlocaldb(key)
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
...@@ -227,8 +252,8 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto ...@@ -227,8 +252,8 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto
vm = cachevm.Copy() vm = cachevm.Copy()
} }
vm.Set("context", string(data)) vm.Set("context", string(data))
u.getstatedbFunc(vm, name) u.statedbFunc(vm, name)
u.getlocaldbFunc(vm, name) u.localdbFunc(vm, name)
u.listdbFunc(vm, name) u.listdbFunc(vm, name)
u.execnameFunc(vm, name) u.execnameFunc(vm, name)
u.registerAccountFunc(vm) u.registerAccountFunc(vm)
...@@ -295,6 +320,22 @@ func (o *object) value() otto.Value { ...@@ -295,6 +320,22 @@ func (o *object) value() otto.Value {
return v return v
} }
// Allow 允许哪些交易在本命执行器执行
func (u *js) Allow(tx *types.Transaction, index int) error {
err := u.DriverBase.Allow(tx, index)
if err == nil {
return nil
}
//增加新的规则:
//主链: user.jsvm.xxx 执行 jsvm 合约
//平行链: user.p.guodun.user.jsvm.xxx 执行 jsvm 合约
exec := types.GetParaExec(tx.Execer)
if u.AllowIsUserDot2(exec) {
return nil
}
return types.ErrNotAllow
}
func createKVObject(vm *otto.Otto, kvs []*types.KeyValue) otto.Value { func createKVObject(vm *otto.Otto, kvs []*types.KeyValue) otto.Value {
obj := newObjectString(vm, "([])") obj := newObjectString(vm, "([])")
for i := 0; i < len(kvs); i++ { for i := 0; i < len(kvs); i++ {
......
...@@ -61,13 +61,34 @@ func parseJsReturn(jsvalue *otto.Object) (kvlist []*types.KeyValue, logs []*type ...@@ -61,13 +61,34 @@ func parseJsReturn(jsvalue *otto.Object) (kvlist []*types.KeyValue, logs []*type
return nil, nil, err return nil, nil, err
} }
for i := 0; i < int(size); i++ { for i := 0; i < int(size); i++ {
data, err := getString(obj, fmt.Sprint(i)) data, err := getObject(obj, fmt.Sprint(i))
if err != nil {
return nil, nil, err
}
//
logdata, err := getString(data, "log")
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
format, err := getString(data, "format")
if err != nil {
return nil, nil, err
}
ty, err := getInt(data, "ty")
if err != nil {
return nil, nil, err
}
if format == "json" {
l := &types.ReceiptLog{ l := &types.ReceiptLog{
Ty: ptypes.TyLogJs, Log: types.Encode(&jsproto.JsLog{Data: data})} Ty: ptypes.TyLogJs, Log: types.Encode(&jsproto.JsLog{Data: logdata})}
logs = append(logs, l) logs = append(logs, l)
} else {
l := &types.ReceiptLog{
Ty: int32(ty),
Log: []byte(logdata),
}
logs = append(logs, l)
}
} }
return kvlist, logs, nil return kvlist, logs, nil
} }
......
...@@ -39,7 +39,7 @@ func createCodeTx(name, jscode string) (*jsproto.Create, *types.Transaction) { ...@@ -39,7 +39,7 @@ func createCodeTx(name, jscode string) (*jsproto.Create, *types.Transaction) {
Code: jscode, Code: jscode,
Name: name, Name: name,
} }
return data, &types.Transaction{Execer: []byte("js"), Payload: types.Encode(data)} return data, &types.Transaction{Execer: []byte("user." + ptypes.JsX + "." + name), Payload: types.Encode(data)}
} }
func callCodeTx(name, f, args string) (*jsproto.Call, *types.Transaction) { func callCodeTx(name, f, args string) (*jsproto.Call, *types.Transaction) {
...@@ -48,7 +48,7 @@ func callCodeTx(name, f, args string) (*jsproto.Call, *types.Transaction) { ...@@ -48,7 +48,7 @@ func callCodeTx(name, f, args string) (*jsproto.Call, *types.Transaction) {
Name: name, Name: name,
Args: args, Args: args,
} }
return data, &types.Transaction{Execer: []byte("js"), Payload: types.Encode(data)} return data, &types.Transaction{Execer: []byte("user." + ptypes.JsX + "." + name), Payload: types.Encode(data)}
} }
func TestCallcode(t *testing.T) { func TestCallcode(t *testing.T) {
...@@ -66,7 +66,7 @@ func TestCallcode(t *testing.T) { ...@@ -66,7 +66,7 @@ func TestCallcode(t *testing.T) {
err = json.Unmarshal(receipt.KV[2].Value, &data) err = json.Unmarshal(receipt.KV[2].Value, &data)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(1), data.Difficulty) assert.Equal(t, uint64(1), data.Difficulty)
assert.Equal(t, "js", data.DriverName) assert.Equal(t, ptypes.JsX, data.DriverName)
assert.Equal(t, int64(1), data.Height) assert.Equal(t, int64(1), data.Height)
assert.Equal(t, int64(0), data.Index) assert.Equal(t, int64(0), data.Index)
...@@ -76,12 +76,12 @@ func TestCallcode(t *testing.T) { ...@@ -76,12 +76,12 @@ func TestCallcode(t *testing.T) {
assert.Equal(t, string(kvset.KV[0].Value), `{"hello":"world"}`) assert.Equal(t, string(kvset.KV[0].Value), `{"hello":"world"}`)
assert.Equal(t, string(kvset.KV[1].Value), "execlocal") assert.Equal(t, string(kvset.KV[1].Value), "execlocal")
//test log is ok //test log is ok
assert.Equal(t, string(kvset.KV[2].Value), `[{"key1":"value1"},{"key2":"value2"}]`) assert.Equal(t, string(kvset.KV[2].Value), `[{"format":"json","log":"{\"key1\":\"value1\"}","ty":0},{"format":"json","log":"{\"key2\":\"value2\"}","ty":0}]`)
//test context //test context
err = json.Unmarshal(kvset.KV[3].Value, &data) err = json.Unmarshal(kvset.KV[3].Value, &data)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(1), data.Difficulty) assert.Equal(t, uint64(1), data.Difficulty)
assert.Equal(t, "js", data.DriverName) assert.Equal(t, "jsvm", data.DriverName)
assert.Equal(t, int64(1), data.Height) assert.Equal(t, int64(1), data.Height)
assert.Equal(t, int64(0), data.Index) assert.Equal(t, int64(0), data.Index)
...@@ -91,7 +91,7 @@ func TestCallcode(t *testing.T) { ...@@ -91,7 +91,7 @@ func TestCallcode(t *testing.T) {
err = json.Unmarshal([]byte(jsondata.(*jsproto.QueryResult).Data), &data) err = json.Unmarshal([]byte(jsondata.(*jsproto.QueryResult).Data), &data)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, uint64(1), data.Difficulty) assert.Equal(t, uint64(1), data.Difficulty)
assert.Equal(t, "js", data.DriverName) assert.Equal(t, "jsvm", data.DriverName)
assert.Equal(t, int64(1), data.Height) assert.Equal(t, int64(1), data.Height)
assert.Equal(t, int64(0), data.Index) assert.Equal(t, int64(0), data.Index)
//call rollback //call rollback
...@@ -100,7 +100,7 @@ func TestCallcode(t *testing.T) { ...@@ -100,7 +100,7 @@ func TestCallcode(t *testing.T) {
util.SaveKVList(ldb, kvset.KV) util.SaveKVList(ldb, kvset.KV)
assert.Equal(t, 5, len(kvset.KV)) assert.Equal(t, 5, len(kvset.KV))
for i := 0; i < len(kvset.KV); i++ { for i := 0; i < len(kvset.KV); i++ {
assert.Equal(t, kvset.KV[i].Value, []byte(nil)) assert.Equal(t, string(kvset.KV[i].Value), "")
} }
} }
...@@ -177,8 +177,8 @@ func TestRewriteJSON(t *testing.T) { ...@@ -177,8 +177,8 @@ func TestRewriteJSON(t *testing.T) {
func TestCalcLocalPrefix(t *testing.T) { func TestCalcLocalPrefix(t *testing.T) {
assert.Equal(t, calcLocalPrefix([]byte("a")), []byte("LODB-a-")) assert.Equal(t, calcLocalPrefix([]byte("a")), []byte("LODB-a-"))
assert.Equal(t, calcStatePrefix([]byte("a")), []byte("mavl-a-")) assert.Equal(t, calcStatePrefix([]byte("a")), []byte("mavl-a-"))
assert.Equal(t, calcCodeKey("a"), []byte("mavl-js-code-a")) assert.Equal(t, calcCodeKey("a"), []byte("mavl-jsvm-code-a"))
assert.Equal(t, calcRollbackKey([]byte("a")), []byte("LODB-js-rollback-a")) assert.Equal(t, calcRollbackKey([]byte("a")), []byte("LODB-jsvm-rollback-a"))
} }
func TestCacheMemUsage(t *testing.T) { func TestCacheMemUsage(t *testing.T) {
...@@ -206,55 +206,3 @@ func printMemUsage() { ...@@ -206,55 +206,3 @@ func printMemUsage() {
func bToMb(b uint64) uint64 { func bToMb(b uint64) uint64 {
return b / 1024 / 1024 return b / 1024 / 1024
} }
var jscode = `
//数据结构设计
//kvlist [{key:"key1", value:"value1"},{key:"key2", value:"value2"}]
//log 设计 {json data}
function Init(context) {
this.kvc = new kvcreator("init")
this.context = context
this.kvc.add("action", "init")
this.kvc.add("context", this.context)
return this.kvc.receipt()
}
function Exec(context) {
this.kvc = new kvcreator("exec")
this.context = context
}
function ExecLocal(context, logs) {
this.kvc = new kvcreator("local")
this.context = context
this.logs = logs
}
function Query(context) {
this.kvc = new kvcreator("query")
this.context = context
}
Exec.prototype.hello = function(args) {
this.kvc.add("args", args)
this.kvc.add("action", "exec")
this.kvc.add("context", this.context)
this.kvc.addlog({"key1": "value1"})
this.kvc.addlog({"key2": "value2"})
return this.kvc.receipt()
}
ExecLocal.prototype.hello = function(args) {
this.kvc.add("args", args)
this.kvc.add("action", "execlocal")
this.kvc.add("log", this.logs)
this.kvc.add("context", this.context)
return this.kvc.receipt()
}
//return a json string
Query.prototype.hello = function(args) {
var obj = getlocaldb("context")
return tojson(obj)
}
`
package executor package executor
import "github.com/33cn/chain33/types" import (
"github.com/33cn/chain33/types"
ptypes "github.com/33cn/plugin/plugin/dapp/js/types"
)
func calcLocalPrefix(execer []byte) []byte { func calcLocalPrefix(execer []byte) []byte {
s := append([]byte("LODB-"), execer...) s := append([]byte("LODB-"), execer...)
...@@ -15,16 +18,16 @@ func calcStatePrefix(execer []byte) []byte { ...@@ -15,16 +18,16 @@ func calcStatePrefix(execer []byte) []byte {
} }
func calcAllPrefix(name string) ([]byte, []byte) { func calcAllPrefix(name string) ([]byte, []byte) {
execer := types.ExecName("user.js." + name) execer := types.ExecName("user." + ptypes.JsX + "." + name)
state := calcStatePrefix([]byte(execer)) state := calcStatePrefix([]byte(execer))
local := calcLocalPrefix([]byte(execer)) local := calcLocalPrefix([]byte(execer))
return state, local return state, local
} }
func calcCodeKey(name string) []byte { func calcCodeKey(name string) []byte {
return append([]byte("mavl-js-code-"), []byte(name)...) return append([]byte("mavl-"+ptypes.JsX+"-code-"), []byte(name)...)
} }
func calcRollbackKey(hash []byte) []byte { func calcRollbackKey(hash []byte) []byte {
return append([]byte("LODB-js-rollback-"), hash...) return append([]byte("LODB-"+ptypes.JsX+"-rollback-"), hash...)
} }
This diff is collapsed.
...@@ -186,8 +186,7 @@ func tableDelFunc(vm *otto.Otto) { ...@@ -186,8 +186,7 @@ func tableDelFunc(vm *otto.Otto) {
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
err = tab.DelRow(&jsproto.JsLog{Data: row})
err = tab.DelRow(&jsproto.JsLog{Data: json})
if err != nil { if err != nil {
return errReturn(vm, err) return errReturn(vm, err)
} }
......
//数据结构设计
//kvlist [{key:"key1", value:"value1"},{key:"key2", value:"value2"}]
//log 设计 {json data}
function Init(context) {
this.kvc = new kvcreator("init")
this.context = context
this.kvc.add("action", "init")
this.kvc.add("context", this.context)
return this.kvc.receipt()
}
function Exec(context) {
this.kvc = new kvcreator("exec")
this.context = context
}
function ExecLocal(context, logs) {
this.kvc = new kvcreator("local")
this.context = context
this.logs = logs
}
function Query(context) {
this.kvc = new kvcreator("query")
this.context = context
}
Exec.prototype.hello = function(args) {
this.kvc.add("args", args)
this.kvc.add("action", "exec")
this.kvc.add("context", this.context)
this.kvc.addlog({"key1": "value1"})
this.kvc.addlog({"key2": "value2"})
return this.kvc.receipt()
}
ExecLocal.prototype.hello = function(args) {
this.kvc.add("args", args)
this.kvc.add("action", "execlocal")
this.kvc.add("log", this.logs)
this.kvc.add("context", this.context)
return this.kvc.receipt()
}
//return a json string
Query.prototype.hello = function(args) {
var obj = getlocaldb("context")
return tojson(obj)
}
...@@ -30,7 +30,7 @@ var ( ...@@ -30,7 +30,7 @@ var (
) )
//JsX 插件名字 //JsX 插件名字
var JsX = "js" var JsX = "jsvm"
//错误常量 //错误常量
var ( var (
......
...@@ -9,31 +9,44 @@ import ( ...@@ -9,31 +9,44 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
) )
func safeAdd(balance, amount int64) (int64, error) {
if balance+amount < amount || balance+amount > types.MaxTokenBalance {
return balance, types.ErrAmount
}
return balance + amount, nil
}
// GenesisInit 生成创世地址账户收据 // GenesisInit 生成创世地址账户收据
func (acc *DB) GenesisInit(addr string, amount int64) (*types.Receipt, error) { func (acc *DB) GenesisInit(addr string, amount int64) (receipt *types.Receipt, err error) {
accTo := acc.LoadAccount(addr) accTo := acc.LoadAccount(addr)
copyto := *accTo copyto := *accTo
accTo.Balance = accTo.GetBalance() + amount accTo.Balance, err = safeAdd(accTo.GetBalance(), amount)
if err != nil {
return nil, err
}
receiptBalanceTo := &types.ReceiptAccountTransfer{ receiptBalanceTo := &types.ReceiptAccountTransfer{
Prev: &copyto, Prev: &copyto,
Current: accTo, Current: accTo,
} }
acc.SaveAccount(accTo) acc.SaveAccount(accTo)
receipt := acc.genesisReceipt(accTo, receiptBalanceTo) receipt = acc.genesisReceipt(accTo, receiptBalanceTo)
return receipt, nil return receipt, nil
} }
// GenesisInitExec 生成创世地址执行器账户收据 // GenesisInitExec 生成创世地址执行器账户收据
func (acc *DB) GenesisInitExec(addr string, amount int64, execaddr string) (*types.Receipt, error) { func (acc *DB) GenesisInitExec(addr string, amount int64, execaddr string) (receipt *types.Receipt, err error) {
accTo := acc.LoadAccount(execaddr) accTo := acc.LoadAccount(execaddr)
copyto := *accTo copyto := *accTo
accTo.Balance = accTo.GetBalance() + amount accTo.Balance, err = safeAdd(accTo.GetBalance(), amount)
if err != nil {
return nil, err
}
receiptBalanceTo := &types.ReceiptAccountTransfer{ receiptBalanceTo := &types.ReceiptAccountTransfer{
Prev: &copyto, Prev: &copyto,
Current: accTo, Current: accTo,
} }
acc.SaveAccount(accTo) acc.SaveAccount(accTo)
receipt := acc.genesisReceipt(accTo, receiptBalanceTo) receipt = acc.genesisReceipt(accTo, receiptBalanceTo)
receipt2, err := acc.ExecDeposit(addr, execaddr, amount) receipt2, err := acc.ExecDeposit(addr, execaddr, amount)
if err != nil { if err != nil {
panic(err) panic(err)
......
...@@ -395,8 +395,9 @@ func (table *Table) Del(primaryKey []byte) error { ...@@ -395,8 +395,9 @@ func (table *Table) Del(primaryKey []byte) error {
return err return err
} }
if incache { if incache {
rowty := row.Ty
table.delRowCache(row) table.delRowCache(row)
if row.Ty == Add { if rowty == Add {
return nil return nil
} }
} }
...@@ -407,6 +408,15 @@ func (table *Table) Del(primaryKey []byte) error { ...@@ -407,6 +408,15 @@ func (table *Table) Del(primaryKey []byte) error {
return nil return nil
} }
//DelRow 删除一行
func (table *Table) DelRow(data types.Message) error {
primaryKey, err := table.primaryKey(data)
if err != nil {
return err
}
return table.Del(primaryKey)
}
//getDataKey data key 构造 //getDataKey data key 构造
func (table *Table) getDataKey(primaryKey []byte) []byte { func (table *Table) getDataKey(primaryKey []byte) []byte {
return append([]byte(table.dataprefix), primaryKey...) return append([]byte(table.dataprefix), primaryKey...)
......
...@@ -300,7 +300,7 @@ func TestDel(t *testing.T) { ...@@ -300,7 +300,7 @@ func TestDel(t *testing.T) {
//save 然后从列表中读取 //save 然后从列表中读取
kvs, err := table.Save() kvs, err := table.Save()
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, len(kvs), 6) assert.Equal(t, 3, len(kvs))
//save to database //save to database
util.SaveKVList(ldb, kvs) util.SaveKVList(ldb, kvs)
//printKV(kvs) //printKV(kvs)
......
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