Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
8030c504
Unverified
Commit
8030c504
authored
Jan 03, 2019
by
33cn
Committed by
GitHub
Jan 03, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #198 from vipwzw/js
Js(增加table 和 account的支持)
parents
86b5aa01
52221b3b
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
740 additions
and
154 deletions
+740
-154
1.html
plugin/dapp/js/executor/1.html
+45
-0
Makefile
plugin/dapp/js/executor/Makefile
+3
-0
account.go
plugin/dapp/js/executor/account.go
+0
-0
const.go
plugin/dapp/js/executor/const.go
+0
-0
exec.go
plugin/dapp/js/executor/exec.go
+12
-6
exec_del_local.go
plugin/dapp/js/executor/exec_del_local.go
+2
-1
exec_local.go
plugin/dapp/js/executor/exec_local.go
+4
-3
gen.sh
plugin/dapp/js/executor/gen.sh
+11
-0
js.go
plugin/dapp/js/executor/js.go
+95
-9
jsvm.go
plugin/dapp/js/executor/jsvm.go
+46
-8
jsvm_test.go
plugin/dapp/js/executor/jsvm_test.go
+10
-62
key.go
plugin/dapp/js/executor/key.go
+7
-4
runtime.go
plugin/dapp/js/executor/runtime.go
+0
-39
runtime.js
plugin/dapp/js/executor/runtime.js
+0
-0
table.go
plugin/dapp/js/executor/table.go
+349
-0
test.js
plugin/dapp/js/executor/test.js
+49
-0
js.go
plugin/dapp/js/types/js.go
+4
-1
genesis.go
vendor/github.com/33cn/chain33/account/genesis.go
+19
-6
table.go
vendor/github.com/33cn/chain33/common/db/table/table.go
+11
-1
table_test.go
vendor/github.com/33cn/chain33/common/db/table/table_test.go
+1
-1
util.go
vendor/github.com/33cn/chain33/system/dapp/util.go
+8
-0
util_test.go
vendor/github.com/33cn/chain33/system/dapp/util_test.go
+9
-3
chain33.go
vendor/github.com/33cn/chain33/util/cli/chain33.go
+15
-9
util.go
vendor/github.com/33cn/chain33/util/util.go
+22
-0
util_test.go
vendor/github.com/33cn/chain33/util/util_test.go
+18
-1
No files found.
plugin/dapp/js/executor/1.html
0 → 100644
View file @
8030c504
<script
src=
"runtime.js"
></script>
<script
src=
"test.js"
></script>
<script>
//demo database function
var
statedb
=
{}
var
localdb
=
{}
function
getlocaldb
(
key
)
{
return
localdb
[
key
]
}
function
setlocaldb
(
kvs
)
{
for
(
var
i
=
0
;
i
<
kvs
.
length
;
i
++
)
{
localdb
[
kvs
[
i
].
key
]
=
kvs
[
i
].
value
}
}
function
listdb
(
prefix
,
key
,
count
,
direction
)
{
var
i
=
0
var
data
=
[]
for
(
k
in
localdb
)
{
if
(
k
.
startsWith
(
prefix
)
&&
typeof
localdb
[
k
]
==
"string"
)
{
i
++
data
.
push
({
key
:
k
,
value
:
localdb
[
k
]})
if
(
i
==
count
)
{
break
}
}
}
return
data
}
function
getstatedb
(
key
)
{
return
statedb
[
key
]
}
function
setstatedb
(
kvs
)
{
for
(
var
i
=
0
;
i
<
kvs
.
length
;
i
++
)
{
statedb
[
kvs
[
i
].
key
]
=
kvs
[
i
].
value
}
}
var
ret
=
callcode
(
"{}"
,
"execlocal_hello"
,
"{}"
,
[])
console
.
log
(
ret
)
</script>
\ No newline at end of file
plugin/dapp/js/executor/Makefile
0 → 100644
View file @
8030c504
all
:
./gen.sh
\ No newline at end of file
plugin/dapp/js/executor/account.go
0 → 100644
View file @
8030c504
This diff is collapsed.
Click to expand it.
plugin/dapp/js/executor/const.go
View file @
8030c504
This diff is collapsed.
Click to expand it.
plugin/dapp/js/executor/exec.go
View file @
8030c504
...
@@ -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
))
...
@@ -23,28 +26,31 @@ func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index i
...
@@ -23,28 +26,31 @@ func (c *js) Exec_Create(payload *jsproto.Create, tx *types.Transaction, index i
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvs
,
logs
,
err
:=
parseJsReturn
(
jsvalue
)
kvs
,
logs
,
err
:=
parseJsReturn
(
c
.
prefix
,
jsvalue
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvc
.
AddList
(
kvs
)
kvc
.
AddList
NoPrefix
(
kvs
)
r
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvc
.
KVList
(),
Logs
:
logs
}
r
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvc
.
KVList
(),
Logs
:
logs
}
return
r
,
nil
return
r
,
nil
}
}
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
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvs
,
logs
,
err
:=
parseJsReturn
(
jsvalue
)
kvs
,
logs
,
err
:=
parseJsReturn
(
c
.
prefix
,
jsvalue
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvc
.
AddList
(
kvs
)
kvc
.
AddList
NoPrefix
(
kvs
)
r
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvc
.
KVList
(),
Logs
:
logs
}
r
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvc
.
KVList
(),
Logs
:
logs
}
return
r
,
nil
return
r
,
nil
}
}
plugin/dapp/js/executor/exec_del_local.go
View file @
8030c504
...
@@ -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
()
...
...
plugin/dapp/js/executor/exec_local.go
View file @
8030c504
...
@@ -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,18 +13,18 @@ func (c *js) ExecLocal_Create(payload *jsproto.Create, tx *types.Transaction, re
...
@@ -12,18 +13,18 @@ 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
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvs
,
_
,
err
:=
parseJsReturn
(
jsvalue
)
kvs
,
_
,
err
:=
parseJsReturn
(
c
.
prefix
,
jsvalue
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
kvc
.
AddList
(
kvs
)
kvc
.
AddList
NoPrefix
(
kvs
)
kvc
.
AddRollbackKV
()
kvc
.
AddRollbackKV
()
r
:=
&
types
.
LocalDBSet
{}
r
:=
&
types
.
LocalDBSet
{}
r
.
KV
=
kvc
.
KVList
()
r
.
KV
=
kvc
.
KVList
()
...
...
plugin/dapp/js/executor/gen.sh
0 → 100755
View file @
8030c504
#!/bin/sh
{
printf
'package executor\n\nvar callcode = `\n'
cat
"runtime.js"
printf
'`\n'
printf
'var jscode = `\n'
cat
"test.js"
printf
'`\n'
printf
'var _ = jscode\n'
}
>
const.go
plugin/dapp/js/executor/js.go
View file @
8030c504
...
@@ -2,6 +2,7 @@ package executor
...
@@ -2,6 +2,7 @@ package executor
import
(
import
(
"encoding/json"
"encoding/json"
"fmt"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common"
drivers
"github.com/33cn/chain33/system/dapp"
drivers
"github.com/33cn/chain33/system/dapp"
...
@@ -25,6 +26,7 @@ func init() {
...
@@ -25,6 +26,7 @@ func init() {
panic
(
err
)
panic
(
err
)
}
}
execaddressFunc
(
basevm
)
execaddressFunc
(
basevm
)
registerTableFunc
(
basevm
)
}
}
//Init 插件初始化
//Init 插件初始化
...
@@ -104,6 +106,12 @@ func (u *js) callVM(prefix string, payload *jsproto.Call, tx *types.Transaction,
...
@@ -104,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
{
...
@@ -111,6 +119,7 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) {
...
@@ -111,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
}
}
...
@@ -119,7 +128,11 @@ func jslogs(receiptData *types.ReceiptData) ([]string, error) {
...
@@ -119,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
}
}
...
@@ -141,14 +154,21 @@ func (u *js) getContext(tx *types.Transaction, index int64) *blockContext {
...
@@ -141,14 +154,21 @@ func (u *js) getContext(tx *types.Transaction, index int64) *blockContext {
}
}
}
}
func
(
u
*
js
)
get
statedbFunc
(
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
)
}
}
...
@@ -156,14 +176,21 @@ func (u *js) getstatedbFunc(vm *otto.Otto, name string) {
...
@@ -156,14 +176,21 @@ func (u *js) getstatedbFunc(vm *otto.Otto, name string) {
})
})
}
}
func
(
u
*
js
)
get
localdbFunc
(
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
)
}
}
...
@@ -173,7 +200,7 @@ func (u *js) getlocaldbFunc(vm *otto.Otto, name string) {
...
@@ -173,7 +200,7 @@ func (u *js) getlocaldbFunc(vm *otto.Otto, name string) {
func
(
u
*
js
)
execnameFunc
(
vm
*
otto
.
Otto
,
name
string
)
{
func
(
u
*
js
)
execnameFunc
(
vm
*
otto
.
Otto
,
name
string
)
{
vm
.
Set
(
"execname"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
vm
.
Set
(
"execname"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
return
okReturn
(
vm
,
name
)
return
okReturn
(
vm
,
types
.
ExecName
(
"user.js."
+
name
)
)
})
})
}
}
...
@@ -225,10 +252,12 @@ func (u *js) createVM(name string, tx *types.Transaction, index int) (*otto.Otto
...
@@ -225,10 +252,12 @@ 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
.
get
statedbFunc
(
vm
,
name
)
u
.
statedbFunc
(
vm
,
name
)
u
.
get
localdbFunc
(
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
.
newTableFunc
(
vm
,
name
)
return
vm
,
nil
return
vm
,
nil
}
}
...
@@ -244,13 +273,23 @@ func listReturn(vm *otto.Otto, value []string) otto.Value {
...
@@ -244,13 +273,23 @@ func listReturn(vm *otto.Otto, value []string) otto.Value {
return
newObject
(
vm
)
.
setValue
(
"value"
,
value
)
.
value
()
return
newObject
(
vm
)
.
setValue
(
"value"
,
value
)
.
value
()
}
}
func
receiptReturn
(
vm
*
otto
.
Otto
,
receipt
*
types
.
Receipt
)
otto
.
Value
{
kvs
:=
createKVObject
(
vm
,
receipt
.
KV
)
logs
:=
createLogsObject
(
vm
,
receipt
.
Logs
)
return
newObject
(
vm
)
.
setValue
(
"kvs"
,
kvs
)
.
setValue
(
"logs"
,
logs
)
.
value
()
}
type
object
struct
{
type
object
struct
{
vm
*
otto
.
Otto
vm
*
otto
.
Otto
obj
*
otto
.
Object
obj
*
otto
.
Object
}
}
func
newObject
(
vm
*
otto
.
Otto
)
*
object
{
func
newObject
(
vm
*
otto
.
Otto
)
*
object
{
obj
,
err
:=
vm
.
Object
(
"({})"
)
return
newObjectString
(
vm
,
"({})"
)
}
func
newObjectString
(
vm
*
otto
.
Otto
,
value
string
)
*
object
{
obj
,
err
:=
vm
.
Object
(
value
)
if
err
!=
nil
{
if
err
!=
nil
{
panic
(
err
)
panic
(
err
)
}
}
...
@@ -281,6 +320,53 @@ func (o *object) value() otto.Value {
...
@@ -281,6 +320,53 @@ 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
{
obj
:=
newObjectString
(
vm
,
"([])"
)
for
i
:=
0
;
i
<
len
(
kvs
);
i
++
{
item
:=
newObject
(
vm
)
.
setValue
(
"key"
,
string
(
kvs
[
i
]
.
Key
))
item
.
setValue
(
"value"
,
string
(
kvs
[
i
]
.
Value
))
item
.
setValue
(
"prefix"
,
true
)
obj
.
setValue
(
fmt
.
Sprint
(
i
),
item
)
}
return
obj
.
value
()
}
func
createLogsObject
(
vm
*
otto
.
Otto
,
logs
[]
*
types
.
ReceiptLog
)
otto
.
Value
{
obj
:=
newObjectString
(
vm
,
"([])"
)
for
i
:=
0
;
i
<
len
(
logs
);
i
++
{
item
:=
newObject
(
vm
)
.
setValue
(
"ty"
,
logs
[
i
]
.
Ty
)
item
.
setValue
(
"log"
,
string
(
logs
[
i
]
.
Log
))
item
.
setValue
(
"format"
,
"proto"
)
obj
.
setValue
(
fmt
.
Sprint
(
i
),
item
)
}
return
obj
.
value
()
}
func
accountReturn
(
vm
*
otto
.
Otto
,
acc
*
types
.
Account
)
otto
.
Value
{
obj
:=
newObject
(
vm
)
obj
.
setValue
(
"currency"
,
acc
.
Currency
)
obj
.
setValue
(
"balance"
,
acc
.
Balance
)
obj
.
setValue
(
"frozen"
,
acc
.
Frozen
)
obj
.
setValue
(
"addr"
,
acc
.
Addr
)
return
obj
.
value
()
}
func
(
u
*
js
)
getstatedb
(
key
string
)
(
value
string
,
err
error
)
{
func
(
u
*
js
)
getstatedb
(
key
string
)
(
value
string
,
err
error
)
{
s
,
err
:=
u
.
GetStateDB
()
.
Get
([]
byte
(
key
))
s
,
err
:=
u
.
GetStateDB
()
.
Get
([]
byte
(
key
))
value
=
string
(
s
)
value
=
string
(
s
)
...
...
plugin/dapp/js/executor/jsvm.go
View file @
8030c504
...
@@ -24,7 +24,7 @@ type blockContext struct {
...
@@ -24,7 +24,7 @@ type blockContext struct {
Index
int64
`json:"index"`
Index
int64
`json:"index"`
}
}
func
parseJsReturn
(
jsvalue
*
otto
.
Object
)
(
kvlist
[]
*
types
.
KeyValue
,
logs
[]
*
types
.
ReceiptLog
,
err
error
)
{
func
parseJsReturn
(
prefix
[]
byte
,
jsvalue
*
otto
.
Object
)
(
kvlist
[]
*
types
.
KeyValue
,
logs
[]
*
types
.
ReceiptLog
,
err
error
)
{
//kvs
//kvs
obj
,
err
:=
getObject
(
jsvalue
,
"kvs"
)
obj
,
err
:=
getObject
(
jsvalue
,
"kvs"
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -42,7 +42,7 @@ func parseJsReturn(jsvalue *otto.Object) (kvlist []*types.KeyValue, logs []*type
...
@@ -42,7 +42,7 @@ func parseJsReturn(jsvalue *otto.Object) (kvlist []*types.KeyValue, logs []*type
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
kv
,
err
:=
parseKV
(
data
)
kv
,
err
:=
parseKV
(
prefix
,
data
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
...
@@ -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
{
return
nil
,
nil
,
err
}
format
,
err
:=
getString
(
data
,
"format"
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
ty
,
err
:=
getInt
(
data
,
"ty"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
nil
,
err
return
nil
,
nil
,
err
}
}
l
:=
&
types
.
ReceiptLog
{
if
format
==
"json"
{
Ty
:
ptypes
.
TyLogJs
,
Log
:
types
.
Encode
(
&
jsproto
.
JsLog
{
Data
:
data
})}
l
:=
&
types
.
ReceiptLog
{
logs
=
append
(
logs
,
l
)
Ty
:
ptypes
.
TyLogJs
,
Log
:
types
.
Encode
(
&
jsproto
.
JsLog
{
Data
:
logdata
})}
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
}
}
...
@@ -80,6 +101,14 @@ func getString(data *otto.Object, key string) (string, error) {
...
@@ -80,6 +101,14 @@ func getString(data *otto.Object, key string) (string, error) {
return
v
.
ToString
()
return
v
.
ToString
()
}
}
func
getBool
(
data
*
otto
.
Object
,
key
string
)
(
bool
,
error
)
{
v
,
err
:=
data
.
Get
(
key
)
if
err
!=
nil
{
return
false
,
err
}
return
v
.
ToBoolean
()
}
func
getInt
(
data
*
otto
.
Object
,
key
string
)
(
int64
,
error
)
{
func
getInt
(
data
*
otto
.
Object
,
key
string
)
(
int64
,
error
)
{
v
,
err
:=
data
.
Get
(
key
)
v
,
err
:=
data
.
Get
(
key
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -99,7 +128,7 @@ func getObject(data *otto.Object, key string) (*otto.Object, error) {
...
@@ -99,7 +128,7 @@ func getObject(data *otto.Object, key string) (*otto.Object, error) {
return
v
.
Object
(),
nil
return
v
.
Object
(),
nil
}
}
func
parseKV
(
data
*
otto
.
Object
)
(
kv
*
types
.
KeyValue
,
err
error
)
{
func
parseKV
(
prefix
[]
byte
,
data
*
otto
.
Object
)
(
kv
*
types
.
KeyValue
,
err
error
)
{
key
,
err
:=
getString
(
data
,
"key"
)
key
,
err
:=
getString
(
data
,
"key"
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -108,6 +137,13 @@ func parseKV(data *otto.Object) (kv *types.KeyValue, err error) {
...
@@ -108,6 +137,13 @@ func parseKV(data *otto.Object) (kv *types.KeyValue, err error) {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
hasprefix
,
err
:=
getBool
(
data
,
"prefix"
)
if
err
!=
nil
{
return
nil
,
err
}
if
!
hasprefix
{
key
=
string
(
prefix
)
+
key
}
return
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)},
nil
return
&
types
.
KeyValue
{
Key
:
[]
byte
(
key
),
Value
:
[]
byte
(
value
)},
nil
}
}
...
@@ -143,6 +179,8 @@ func rewriteString(dat map[string]interface{}) map[string]interface{} {
...
@@ -143,6 +179,8 @@ func rewriteString(dat map[string]interface{}) map[string]interface{} {
return
dat
return
dat
}
}
const
maxjsint
int64
=
9007199254740991
func
jssafe
(
n
json
.
Number
)
interface
{}
{
func
jssafe
(
n
json
.
Number
)
interface
{}
{
if
strings
.
Contains
(
string
(
n
),
"."
)
{
//float
if
strings
.
Contains
(
string
(
n
),
"."
)
{
//float
return
n
return
n
...
@@ -152,7 +190,7 @@ func jssafe(n json.Number) interface{} {
...
@@ -152,7 +190,7 @@ func jssafe(n json.Number) interface{} {
return
n
return
n
}
}
//javascript can not parse
//javascript can not parse
if
i
>=
9007199254740991
||
i
<=
-
9007199254740991
{
if
i
>=
maxjsint
||
i
<=
-
maxjsint
{
return
string
(
n
)
return
string
(
n
)
}
}
return
n
return
n
...
...
plugin/dapp/js/executor/jsvm_test.go
View file @
8030c504
...
@@ -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
,
"js
vm
"
,
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
,
"js
vm
"
,
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
),
""
)
}
}
}
}
...
@@ -138,7 +138,7 @@ func TestBigInt(t *testing.T) {
...
@@ -138,7 +138,7 @@ func TestBigInt(t *testing.T) {
call
,
tx
:=
callCodeTx
(
"test"
,
"hello"
,
s
)
call
,
tx
:=
callCodeTx
(
"test"
,
"hello"
,
s
)
data
,
err
:=
e
.
callVM
(
"exec"
,
call
,
tx
,
0
,
nil
)
data
,
err
:=
e
.
callVM
(
"exec"
,
call
,
tx
,
0
,
nil
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
kvs
,
_
,
err
:=
parseJsReturn
(
data
)
kvs
,
_
,
err
:=
parseJsReturn
(
[]
byte
(
"user.jsvm.test"
),
data
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
`{"balance":"9223372036854775807","balance1":"-9223372036854775808","balance2":9007199254740990,"balance3":-9007199254740990}`
,
string
(
kvs
[
0
]
.
Value
))
assert
.
Equal
(
t
,
`{"balance":"9223372036854775807","balance1":"-9223372036854775808","balance2":9007199254740990,"balance3":-9007199254740990}`
,
string
(
kvs
[
0
]
.
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-js
vm
-code-a"
))
assert
.
Equal
(
t
,
calcRollbackKey
([]
byte
(
"a"
)),
[]
byte
(
"LODB-js-rollback-a"
))
assert
.
Equal
(
t
,
calcRollbackKey
([]
byte
(
"a"
)),
[]
byte
(
"LODB-js
vm
-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)
}
`
plugin/dapp/js/executor/key.go
View file @
8030c504
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
...
)
}
}
plugin/dapp/js/executor/runtime.go
View file @
8030c504
...
@@ -18,45 +18,6 @@ func execaddressFunc(vm *otto.Otto) {
...
@@ -18,45 +18,6 @@ func execaddressFunc(vm *otto.Otto) {
}
}
/*
/*
//chain33 相关的账户操作函数 (操作某个execer 下面的 symbol)
function Account(execer, symbol) {
this.execer = execer
this.symbol = symbol
}
func Receipt(kvs, logs) {
this.kvs = kvs
this.logs = logs
}
var obj = new Account(execer, symbol)
//init 函数才能使用的两个函数(或者增发)
genesis_init(obj, addr string, amount int64)
genesis_exec_init(obj, execer, addr string, amount int64)
load_account(obj, addr) Account
get_balance(obj, addr, execer) Account
transfer(obj, from, to, amount) Receipt
transfer_to_exec(obj, execer, addr, amount) Receipt
withdraw(obj, execer, addr, amount) Receipt
exec_frozen(obj, addr) Receipt
exec_active(obj, addr) Receipt
exec_transfer(obj, from, to, amount) Receipt
exec_deposit(obj, addr, amount) Receipt
exec_withdraw(obj, addr, amount) Receipt
//table
//要开发一个适合json的table, row 就是一个 js object
//handle := new_table(config)
//table_add(handle, row)
//table_replace(handle, row)
//table_del(handle, row)
//table_savekvs(handle)
//table_close(handle)
//join table 的操作(接口完全相同)
//handle3 := new_table(newcofifg{config1, config2})
//获取系统随机数的接口
//获取系统随机数的接口
//randnum
//randnum
...
...
plugin/dapp/js/executor/runtime.js
0 → 100644
View file @
8030c504
This diff is collapsed.
Click to expand it.
plugin/dapp/js/executor/table.go
0 → 100644
View file @
8030c504
package
executor
import
(
"encoding/json"
"fmt"
"strings"
"sync"
"sync/atomic"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"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/robertkrimen/otto"
)
//json 表格相关的实现
//用户可以存入一个json字符串
//json 定义index 以及 format
/* table ->
{
"#tablename" : "table1",
"#primary" : "abc",
"abc" : "%18d",
"index1" : "%s",
"index2" : "%s",
}
默认值配置
{
"abc" : 0,
"index1" : "",
"index2" : "",
}
*/
var
globalTableHandle
sync
.
Map
var
globalHanldeID
int64
//NewTable 创建一个新的表格, 返回handle
func
(
u
*
js
)
newTable
(
name
,
config
,
defaultvalue
string
)
(
id
int64
,
err
error
)
{
for
{
id
=
atomic
.
AddInt64
(
&
globalHanldeID
,
1
)
%
maxjsint
if
_
,
ok
:=
globalTableHandle
.
Load
(
id
);
ok
{
continue
}
if
id
<
0
{
atomic
.
StoreInt64
(
&
globalHanldeID
,
0
)
continue
}
break
}
row
,
err
:=
NewJSONRow
(
config
,
defaultvalue
)
if
err
!=
nil
{
return
0
,
err
}
var
kvdb
db
.
KV
var
prefix
[]
byte
if
row
.
config
[
"#db"
]
==
"localdb"
{
kvdb
=
u
.
GetLocalDB
()
_
,
prefix
=
calcAllPrefix
(
name
)
}
else
if
row
.
config
[
"#db"
]
==
"statedb"
{
kvdb
=
u
.
GetStateDB
()
prefix
,
_
=
calcAllPrefix
(
name
)
}
else
{
return
0
,
ptypes
.
ErrDBType
}
var
indexs
[]
string
for
k
:=
range
row
.
config
{
if
k
[
0
]
==
'#'
{
continue
}
indexs
=
append
(
indexs
,
k
)
}
opt
:=
&
table
.
Option
{
Prefix
:
string
(
prefix
),
Name
:
row
.
config
[
"#tablename"
],
Primary
:
row
.
config
[
"#primary"
],
Index
:
indexs
,
}
t
,
err
:=
table
.
NewTable
(
row
,
kvdb
,
opt
)
if
err
!=
nil
{
return
0
,
err
}
globalTableHandle
.
Store
(
id
,
t
)
return
id
,
nil
}
func
(
u
*
js
)
newTableFunc
(
vm
*
otto
.
Otto
,
name
string
)
{
vm
.
Set
(
"table_new"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
config
,
err
:=
call
.
Argument
(
0
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
defaultvalue
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
id
,
err
:=
u
.
newTable
(
name
,
config
,
defaultvalue
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
newObject
(
vm
)
.
setValue
(
"id"
,
id
)
.
value
()
})
}
//CloseTable 关闭表格释放内存
func
closeTable
(
id
int64
)
error
{
_
,
ok
:=
globalTableHandle
.
Load
(
id
)
if
!
ok
{
return
types
.
ErrNotFound
}
globalTableHandle
.
Delete
(
id
)
return
nil
}
func
getTable
(
id
int64
)
(
*
table
.
Table
,
error
)
{
if
value
,
ok
:=
globalTableHandle
.
Load
(
id
);
ok
{
return
value
.
(
*
table
.
Table
),
nil
}
return
nil
,
types
.
ErrNotFound
}
func
getSaver
(
id
int64
)
(
saver
,
error
)
{
if
value
,
ok
:=
globalTableHandle
.
Load
(
id
);
ok
{
return
value
.
(
saver
),
nil
}
return
nil
,
types
.
ErrNotFound
}
func
registerTableFunc
(
vm
*
otto
.
Otto
)
{
tableAddFunc
(
vm
)
tableReplaceFunc
(
vm
)
tableDelFunc
(
vm
)
tableCloseFunc
(
vm
)
tableSave
(
vm
)
tableJoinFunc
(
vm
)
}
func
tableAddFunc
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"table_add"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
id
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
tab
,
err
:=
getTable
(
id
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
json
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
err
=
tab
.
Add
(
&
jsproto
.
JsLog
{
Data
:
json
})
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
okReturn
(
vm
,
"ok"
)
})
}
func
tableReplaceFunc
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"table_replace"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
id
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
tab
,
err
:=
getTable
(
id
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
json
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
err
=
tab
.
Replace
(
&
jsproto
.
JsLog
{
Data
:
json
})
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
okReturn
(
vm
,
"ok"
)
})
}
func
tableDelFunc
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"table_del"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
id
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
tab
,
err
:=
getTable
(
id
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
row
,
err
:=
call
.
Argument
(
1
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
err
=
tab
.
DelRow
(
&
jsproto
.
JsLog
{
Data
:
row
})
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
okReturn
(
vm
,
"ok"
)
})
}
type
saver
interface
{
Save
()
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
}
func
tableSave
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"table_save"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
id
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
tab
,
err
:=
getSaver
(
id
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
kvs
,
err
:=
tab
.
Save
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
newObject
(
vm
)
.
setValue
(
"kvs"
,
createKVObject
(
vm
,
kvs
))
.
value
()
})
}
func
tableCloseFunc
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"table_close"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
id
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
err
=
closeTable
(
id
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
return
okReturn
(
vm
,
"ok"
)
})
}
func
tableJoinFunc
(
vm
*
otto
.
Otto
)
{
vm
.
Set
(
"new_join_table"
,
func
(
call
otto
.
FunctionCall
)
otto
.
Value
{
left
,
err
:=
call
.
Argument
(
0
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
lefttab
,
err
:=
getTable
(
left
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
right
,
err
:=
call
.
Argument
(
1
)
.
ToInteger
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
righttab
,
err
:=
getTable
(
right
)
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
index
,
err
:=
call
.
Argument
(
2
)
.
ToString
()
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
join
,
err
:=
table
.
NewJoinTable
(
lefttab
,
righttab
,
strings
.
Split
(
index
,
","
))
if
err
!=
nil
{
return
errReturn
(
vm
,
err
)
}
var
id
int64
for
{
id
=
atomic
.
AddInt64
(
&
globalHanldeID
,
1
)
%
maxjsint
if
_
,
ok
:=
globalTableHandle
.
Load
(
id
);
ok
{
continue
}
if
id
<
0
{
atomic
.
StoreInt64
(
&
globalHanldeID
,
0
)
continue
}
break
}
globalTableHandle
.
Store
(
id
,
join
)
return
newObject
(
vm
)
.
setValue
(
"id"
,
id
)
.
value
()
})
}
/*
table
要开发一个适合json的table, row 就是一个 js object
handle := new_table(config, defaultvalue)
table_add(handle, row)
table_replace(handle, row)
table_del(handle, row)
table_save(handle)
table_close(handle)
handle := new_join_table(left, right, listofjoinindex)
*/
//join table 的操作(接口完全相同)
//handle3 := new_table(newcofifg{config1, config2})
//JSONRow meta
type
JSONRow
struct
{
*
jsproto
.
JsLog
config
map
[
string
]
string
data
map
[
string
]
interface
{}
}
//NewJSONRow 创建一个row
func
NewJSONRow
(
config
string
,
defaultvalue
string
)
(
*
JSONRow
,
error
)
{
row
:=
&
JSONRow
{}
row
.
config
=
make
(
map
[
string
]
string
)
err
:=
json
.
Unmarshal
([]
byte
(
config
),
row
.
config
)
if
err
!=
nil
{
return
nil
,
err
}
row
.
JsLog
=
&
jsproto
.
JsLog
{
Data
:
defaultvalue
}
err
=
row
.
parse
()
if
err
!=
nil
{
return
nil
,
err
}
return
row
,
nil
}
//CreateRow 创建一行
func
(
row
*
JSONRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
jsproto
.
JsLog
{}}
}
func
(
row
*
JSONRow
)
parse
()
error
{
row
.
data
=
make
(
map
[
string
]
interface
{})
return
json
.
Unmarshal
([]
byte
(
row
.
JsLog
.
Data
),
row
.
data
)
}
//SetPayload 设置行的内容
func
(
row
*
JSONRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
rowdata
,
ok
:=
data
.
(
*
jsproto
.
JsLog
);
ok
{
row
.
JsLog
=
rowdata
return
row
.
parse
()
}
return
types
.
ErrTypeAsset
}
//Get value of row
func
(
row
*
JSONRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
format
,
ok
:=
row
.
config
[
key
];
ok
{
if
data
,
ok
:=
row
.
data
[
key
];
ok
{
return
[]
byte
(
fmt
.
Sprintf
(
format
,
data
)),
nil
}
}
return
nil
,
types
.
ErrNotFound
}
plugin/dapp/js/executor/test.js
0 → 100644
View file @
8030c504
//数据结构设计
//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
)
}
plugin/dapp/js/types/js.go
View file @
8030c504
...
@@ -30,7 +30,7 @@ var (
...
@@ -30,7 +30,7 @@ var (
)
)
//JsX 插件名字
//JsX 插件名字
var
JsX
=
"js"
var
JsX
=
"js
vm
"
//错误常量
//错误常量
var
(
var
(
...
@@ -44,6 +44,9 @@ var (
...
@@ -44,6 +44,9 @@ var (
ErrInvalidFuncPrefix
=
errors
.
New
(
"chain33.js: invalid function prefix format"
)
ErrInvalidFuncPrefix
=
errors
.
New
(
"chain33.js: invalid function prefix format"
)
//ErrFuncNotFound 函数没有找到
//ErrFuncNotFound 函数没有找到
ErrFuncNotFound
=
errors
.
New
(
"chain33.js: invalid function name not found"
)
ErrFuncNotFound
=
errors
.
New
(
"chain33.js: invalid function name not found"
)
ErrSymbolName
=
errors
.
New
(
"chain33.js: ErrSymbolName"
)
ErrExecerName
=
errors
.
New
(
"chain33.js: ErrExecerName"
)
ErrDBType
=
errors
.
New
(
"chain33.js: ErrDBType"
)
)
)
func
init
()
{
func
init
()
{
...
...
vendor/github.com/33cn/chain33/account/genesis.go
View file @
8030c504
...
@@ -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
)
...
...
vendor/github.com/33cn/chain33/common/db/table/table.go
View file @
8030c504
...
@@ -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
.
T
y
==
Add
{
if
row
t
y
==
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
...
)
...
...
vendor/github.com/33cn/chain33/common/db/table/table_test.go
View file @
8030c504
...
@@ -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)
...
...
vendor/github.com/33cn/chain33/system/dapp/util.go
View file @
8030c504
...
@@ -105,6 +105,14 @@ func (c *KVCreator) AddNoPrefix(key, value []byte) *KVCreator {
...
@@ -105,6 +105,14 @@ func (c *KVCreator) AddNoPrefix(key, value []byte) *KVCreator {
return
c
.
addnoprefix
(
key
,
value
,
true
)
return
c
.
addnoprefix
(
key
,
value
,
true
)
}
}
//AddListNoPrefix only add KVList
func
(
c
*
KVCreator
)
AddListNoPrefix
(
list
[]
*
types
.
KeyValue
)
*
KVCreator
{
for
_
,
kv
:=
range
list
{
c
.
addnoprefix
(
kv
.
Key
,
kv
.
Value
,
true
)
}
return
c
}
//AddList only add KVList
//AddList only add KVList
func
(
c
*
KVCreator
)
AddList
(
list
[]
*
types
.
KeyValue
)
*
KVCreator
{
func
(
c
*
KVCreator
)
AddList
(
list
[]
*
types
.
KeyValue
)
*
KVCreator
{
for
_
,
kv
:=
range
list
{
for
_
,
kv
:=
range
list
{
...
...
vendor/github.com/33cn/chain33/system/dapp/util_test.go
View file @
8030c504
...
@@ -28,15 +28,21 @@ func TestKVCreator(t *testing.T) {
...
@@ -28,15 +28,21 @@ func TestKVCreator(t *testing.T) {
{
Key
:
[]
byte
(
"l1"
),
Value
:
[]
byte
(
"vl1"
)},
{
Key
:
[]
byte
(
"l1"
),
Value
:
[]
byte
(
"vl1"
)},
{
Key
:
[]
byte
(
"l2"
),
Value
:
[]
byte
(
"vl2"
)},
{
Key
:
[]
byte
(
"l2"
),
Value
:
[]
byte
(
"vl2"
)},
})
})
creator
.
AddListNoPrefix
([]
*
types
.
KeyValue
{
{
Key
:
[]
byte
(
"l1"
),
Value
:
[]
byte
(
"vl1"
)},
{
Key
:
[]
byte
(
"l2"
),
Value
:
[]
byte
(
"vl2"
)},
})
creator
.
Add
([]
byte
(
"c1"
),
nil
)
creator
.
Add
([]
byte
(
"c1"
),
nil
)
creator
.
Add
([]
byte
(
"l2"
),
nil
)
creator
.
Add
([]
byte
(
"l2"
),
nil
)
creator
.
AddRollbackKV
()
creator
.
AddRollbackKV
()
assert
.
Equal
(
t
,
7
,
len
(
creator
.
KVList
()))
assert
.
Equal
(
t
,
9
,
len
(
creator
.
KVList
()))
util
.
SaveKVList
(
ldb
,
creator
.
KVList
())
util
.
SaveKVList
(
ldb
,
creator
.
KVList
())
kvs
,
err
:=
creator
.
GetRollbackKVList
()
kvs
,
err
:=
creator
.
GetRollbackKVList
()
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
6
,
len
(
kvs
))
assert
.
Equal
(
t
,
8
,
len
(
kvs
))
assert
.
Equal
(
t
,
[]
byte
(
"b"
),
kvs
[
5
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
"b"
),
kvs
[
7
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
6
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
5
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
4
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
4
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
3
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
3
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
2
]
.
Value
)
assert
.
Equal
(
t
,
[]
byte
(
nil
),
kvs
[
2
]
.
Value
)
...
...
vendor/github.com/33cn/chain33/util/cli/chain33.go
View file @
8030c504
...
@@ -130,7 +130,12 @@ func RunChain33(name string) {
...
@@ -130,7 +130,12 @@ func RunChain33(name string) {
q
:=
queue
.
New
(
"channel"
)
q
:=
queue
.
New
(
"channel"
)
log
.
Info
(
"loading mempool module"
)
log
.
Info
(
"loading mempool module"
)
mem
:=
mempool
.
New
(
cfg
.
Mempool
,
sub
.
Mempool
)
var
mem
queue
.
Module
if
!
types
.
IsPara
()
{
mem
=
mempool
.
New
(
cfg
.
Mempool
,
sub
.
Mempool
)
}
else
{
mem
=
&
util
.
MockModule
{
Key
:
"mempool"
}
}
mem
.
SetQueueClient
(
q
.
Client
())
mem
.
SetQueueClient
(
q
.
Client
())
log
.
Info
(
"loading execs module"
)
log
.
Info
(
"loading execs module"
)
...
@@ -150,12 +155,15 @@ func RunChain33(name string) {
...
@@ -150,12 +155,15 @@ func RunChain33(name string) {
cs
:=
consensus
.
New
(
cfg
.
Consensus
,
sub
.
Consensus
)
cs
:=
consensus
.
New
(
cfg
.
Consensus
,
sub
.
Consensus
)
cs
.
SetQueueClient
(
q
.
Client
())
cs
.
SetQueueClient
(
q
.
Client
())
var
network
*
p2p
.
P2p
log
.
Info
(
"loading p2p module"
)
if
cfg
.
P2P
.
Enable
{
var
network
queue
.
Module
log
.
Info
(
"loading p2p module"
)
if
cfg
.
P2P
.
Enable
&&
!
types
.
IsPara
()
{
network
=
p2p
.
New
(
cfg
.
P2P
)
network
=
p2p
.
New
(
cfg
.
P2P
)
network
.
SetQueueClient
(
q
.
Client
())
}
else
{
network
=
&
util
.
MockModule
{
Key
:
"p2p"
}
}
}
network
.
SetQueueClient
(
q
.
Client
())
//jsonrpc, grpc, channel 三种模式
//jsonrpc, grpc, channel 三种模式
rpcapi
:=
rpc
.
New
(
cfg
.
RPC
)
rpcapi
:=
rpc
.
New
(
cfg
.
RPC
)
rpcapi
.
SetQueueClient
(
q
.
Client
())
rpcapi
.
SetQueueClient
(
q
.
Client
())
...
@@ -169,10 +177,8 @@ func RunChain33(name string) {
...
@@ -169,10 +177,8 @@ func RunChain33(name string) {
chain
.
Close
()
chain
.
Close
()
log
.
Info
(
"begin close mempool module"
)
log
.
Info
(
"begin close mempool module"
)
mem
.
Close
()
mem
.
Close
()
if
cfg
.
P2P
.
Enable
{
log
.
Info
(
"begin close P2P module"
)
log
.
Info
(
"begin close P2P module"
)
network
.
Close
()
network
.
Close
()
}
log
.
Info
(
"begin close execs module"
)
log
.
Info
(
"begin close execs module"
)
exec
.
Close
()
exec
.
Close
()
log
.
Info
(
"begin close store module"
)
log
.
Info
(
"begin close store module"
)
...
...
vendor/github.com/33cn/chain33/util/util.go
View file @
8030c504
...
@@ -453,3 +453,25 @@ func PrintKV(kvs []*types.KeyValue) {
...
@@ -453,3 +453,25 @@ func PrintKV(kvs []*types.KeyValue) {
fmt
.
Printf
(
"KV %d %s(%s)
\n
"
,
i
,
string
(
kvs
[
i
]
.
Key
),
common
.
ToHex
(
kvs
[
i
]
.
Value
))
fmt
.
Printf
(
"KV %d %s(%s)
\n
"
,
i
,
string
(
kvs
[
i
]
.
Key
),
common
.
ToHex
(
kvs
[
i
]
.
Value
))
}
}
}
}
// MockModule struct
type
MockModule
struct
{
Key
string
}
// SetQueueClient method
func
(
m
*
MockModule
)
SetQueueClient
(
client
queue
.
Client
)
{
go
func
()
{
client
.
Sub
(
m
.
Key
)
for
msg
:=
range
client
.
Recv
()
{
msg
.
Reply
(
client
.
NewMessage
(
m
.
Key
,
types
.
EventReply
,
&
types
.
Reply
{
IsOk
:
false
,
Msg
:
[]
byte
(
fmt
.
Sprintf
(
"mock %s module not handle message %v"
,
m
.
Key
,
msg
.
Ty
))}))
}
}()
}
// Wait for ready
func
(
m
*
MockModule
)
Wait
()
{}
// Close method
func
(
m
*
MockModule
)
Close
()
{}
vendor/github.com/33cn/chain33/util/util_test.go
View file @
8030c504
...
@@ -8,7 +8,7 @@ import (
...
@@ -8,7 +8,7 @@ import (
"testing"
"testing"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
...
@@ -187,3 +187,20 @@ func TestDB(t *testing.T) {
...
@@ -187,3 +187,20 @@ func TestDB(t *testing.T) {
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
value
,
[]
byte
(
"b"
))
assert
.
Equal
(
t
,
value
,
[]
byte
(
"b"
))
}
}
func
TestMockModule
(
t
*
testing
.
T
)
{
q
:=
queue
.
New
(
"channel"
)
client
:=
q
.
Client
()
memKey
:=
"mempool"
mem
:=
&
MockModule
{
Key
:
memKey
}
mem
.
SetQueueClient
(
client
)
msg
:=
client
.
NewMessage
(
memKey
,
types
.
EventTx
,
&
types
.
Transaction
{})
client
.
Send
(
msg
,
true
)
resp
,
err
:=
client
.
Wait
(
msg
)
assert
.
Nil
(
t
,
err
)
reply
,
ok
:=
resp
.
GetData
()
.
(
*
types
.
Reply
)
assert
.
Equal
(
t
,
ok
,
true
)
assert
.
Equal
(
t
,
reply
.
GetIsOk
(),
false
)
assert
.
Equal
(
t
,
reply
.
GetMsg
(),
[]
byte
(
"mock mempool module not handle message 1"
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment