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
eaaeeb54
Commit
eaaeeb54
authored
Dec 19, 2018
by
vipwzw
Committed by
33cn
Dec 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update chain33
parent
60e4efbc
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1201 additions
and
50 deletions
+1201
-50
init.go
plugin/consensus/init/init.go
+0
-8
init.go
plugin/crypto/init/init.go
+0
-5
init.go
plugin/dapp/init/init.go
+0
-21
init.go
plugin/store/init/init.go
+0
-6
.travis.yml
vendor/github.com/33cn/chain33/.travis.yml
+5
-5
db.go
vendor/github.com/33cn/chain33/common/db/db.go
+1
-2
db_test.go
vendor/github.com/33cn/chain33/common/db/db_test.go
+24
-0
go_level_db_test.go
vendor/github.com/33cn/chain33/common/db/go_level_db_test.go
+12
-0
list_helper.go
vendor/github.com/33cn/chain33/common/db/list_helper.go
+0
-1
count.go
vendor/github.com/33cn/chain33/common/db/table/count.go
+93
-0
count_test.go
vendor/github.com/33cn/chain33/common/db/table/count_test.go
+36
-0
error.go
vendor/github.com/33cn/chain33/common/db/table/error.go
+17
-0
query.go
vendor/github.com/33cn/chain33/common/db/table/query.go
+113
-0
table.go
vendor/github.com/33cn/chain33/common/db/table/table.go
+457
-0
table_test.go
vendor/github.com/33cn/chain33/common/db/table/table_test.go
+439
-0
utils.go
...thub.com/33cn/chain33/system/dapp/commands/types/utils.go
+1
-1
eventprocess.go
...or/github.com/33cn/chain33/system/mempool/eventprocess.go
+1
-1
util.go
vendor/github.com/33cn/chain33/util/util.go
+2
-0
No files found.
plugin/consensus/init/init.go
View file @
eaaeeb54
package
init
package
init
import
(
_
"github.com/33cn/plugin/plugin/consensus/para"
//auto gen
_
"github.com/33cn/plugin/plugin/consensus/pbft"
//auto gen
_
"github.com/33cn/plugin/plugin/consensus/raft"
//auto gen
_
"github.com/33cn/plugin/plugin/consensus/tendermint"
//auto gen
_
"github.com/33cn/plugin/plugin/consensus/ticket"
//auto gen
)
plugin/crypto/init/init.go
View file @
eaaeeb54
package
init
package
init
import
(
_
"github.com/33cn/plugin/plugin/crypto/ecdsa"
//auto gen
_
"github.com/33cn/plugin/plugin/crypto/sm2"
//auto gen
)
plugin/dapp/init/init.go
View file @
eaaeeb54
package
init
package
init
import
(
_
"github.com/33cn/plugin/plugin/dapp/blackwhite"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/cert"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/evm"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/game"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/hashlock"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/lottery"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/multisig"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/norm"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/paracross"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/pokerbull"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/privacy"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/relay"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/retrieve"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/ticket"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/token"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/trade"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/unfreeze"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/valnode"
//auto gen
)
plugin/store/init/init.go
View file @
eaaeeb54
package
init
package
init
import
(
_
"github.com/33cn/plugin/plugin/store/kvdb"
//auto gen
_
"github.com/33cn/plugin/plugin/store/kvmvcc"
//auto gen
_
"github.com/33cn/plugin/plugin/store/mpt"
//auto gen
)
vendor/github.com/33cn/chain33/.travis.yml
View file @
eaaeeb54
...
@@ -6,9 +6,9 @@ dist: xenial
...
@@ -6,9 +6,9 @@ dist: xenial
notifications
:
notifications
:
email
:
false
email
:
false
jobs
:
matrix
:
include
:
include
:
-
stag
e
:
check_fmt
-
nam
e
:
check_fmt
sudo
:
require
sudo
:
require
go
:
go
:
-
"
1.9"
-
"
1.9"
...
@@ -23,13 +23,13 @@ jobs:
...
@@ -23,13 +23,13 @@ jobs:
-
make checkgofmt && make fmt_go
-
make checkgofmt && make fmt_go
-
make linter
-
make linter
-
stag
e
:
unit-test
-
nam
e
:
unit-test
go
:
"
1.9.x"
go
:
"
1.9.x"
install
:
skip
install
:
skip
script
:
script
:
-
make test
-
make test
-
stag
e
:
coverage
-
nam
e
:
coverage
if
:
branch = master
if
:
branch = master
go
:
go
:
-
"
1.9.x"
-
"
1.9.x"
...
@@ -41,7 +41,7 @@ jobs:
...
@@ -41,7 +41,7 @@ jobs:
after_success
:
after_success
:
-
bash <(curl -s https://codecov.io/bash)
-
bash <(curl -s https://codecov.io/bash)
-
stag
e
:
deploy
-
nam
e
:
deploy
sudo
:
required
sudo
:
required
services
:
services
:
-
docker
-
docker
...
...
vendor/github.com/33cn/chain33/common/db/db.go
View file @
eaaeeb54
...
@@ -8,7 +8,6 @@ package db
...
@@ -8,7 +8,6 @@ package db
import
(
import
(
"bytes"
"bytes"
"errors"
"fmt"
"fmt"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
...
@@ -16,7 +15,7 @@ import (
...
@@ -16,7 +15,7 @@ import (
)
)
//ErrNotFoundInDb error
//ErrNotFoundInDb error
var
ErrNotFoundInDb
=
errors
.
New
(
"ErrNotFoundInDb"
)
var
ErrNotFoundInDb
=
types
.
ErrNotFound
//Lister 列表接口
//Lister 列表接口
type
Lister
interface
{
type
Lister
interface
{
...
...
vendor/github.com/33cn/chain33/common/db/db_test.go
View file @
eaaeeb54
...
@@ -11,6 +11,7 @@ import (
...
@@ -11,6 +11,7 @@ import (
"fmt"
"fmt"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
...
@@ -234,3 +235,26 @@ func testDBIteratorDel(t *testing.T, db DB) {
...
@@ -234,3 +235,26 @@ func testDBIteratorDel(t *testing.T, db DB) {
batch
.
Write
()
batch
.
Write
()
}
}
}
}
func
testLevelDBBatch
(
t
*
testing
.
T
,
db
DB
)
{
batch
:=
db
.
NewBatch
(
false
)
batch
.
Set
([]
byte
(
"hello"
),
[]
byte
(
"world"
))
err
:=
batch
.
Write
()
assert
.
Nil
(
t
,
err
)
v
,
err
:=
db
.
Get
([]
byte
(
"hello"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
v
,
[]
byte
(
"world"
))
//set and del
batch
.
Set
([]
byte
(
"hello1"
),
[]
byte
(
"world"
))
batch
.
Set
([]
byte
(
"hello2"
),
[]
byte
(
"world"
))
batch
.
Set
([]
byte
(
"hello3"
),
[]
byte
(
"world"
))
batch
.
Set
([]
byte
(
"hello4"
),
[]
byte
(
"world"
))
batch
.
Set
([]
byte
(
"hello5"
),
[]
byte
(
"world"
))
batch
.
Delete
([]
byte
(
"hello1"
))
err
=
batch
.
Write
()
assert
.
Nil
(
t
,
err
)
v
,
err
=
db
.
Get
([]
byte
(
"hello1"
))
assert
.
Equal
(
t
,
err
,
types
.
ErrNotFound
)
assert
.
Nil
(
t
,
v
)
}
vendor/github.com/33cn/chain33/common/db/go_level_db_test.go
View file @
eaaeeb54
...
@@ -43,6 +43,18 @@ func TestGoLevelDBIteratorDel(t *testing.T) {
...
@@ -43,6 +43,18 @@ func TestGoLevelDBIteratorDel(t *testing.T) {
testDBIteratorDel
(
t
,
leveldb
)
testDBIteratorDel
(
t
,
leveldb
)
}
}
func
TestLevelDBBatch
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"goleveldb"
)
require
.
NoError
(
t
,
err
)
t
.
Log
(
dir
)
leveldb
,
err
:=
NewGoLevelDB
(
"goleveldb"
,
dir
,
128
)
require
.
NoError
(
t
,
err
)
defer
leveldb
.
Close
()
testLevelDBBatch
(
t
,
leveldb
)
}
// leveldb边界测试
// leveldb边界测试
func
TestGoLevelDBBoundary
(
t
*
testing
.
T
)
{
func
TestGoLevelDBBoundary
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"goleveldb"
)
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"goleveldb"
)
...
...
vendor/github.com/33cn/chain33/common/db/list_helper.go
View file @
eaaeeb54
...
@@ -55,7 +55,6 @@ func (db *ListHelper) List(prefix, key []byte, count, direction int32) (values [
...
@@ -55,7 +55,6 @@ func (db *ListHelper) List(prefix, key []byte, count, direction int32) (values [
return
db
.
IteratorScanFromFirst
(
prefix
,
count
)
return
db
.
IteratorScanFromFirst
(
prefix
,
count
)
}
}
return
db
.
IteratorScanFromLast
(
prefix
,
count
)
return
db
.
IteratorScanFromLast
(
prefix
,
count
)
}
}
if
count
==
1
&&
direction
==
ListSeek
{
if
count
==
1
&&
direction
==
ListSeek
{
it
:=
db
.
db
.
Iterator
(
prefix
,
nil
,
true
)
it
:=
db
.
db
.
Iterator
(
prefix
,
nil
,
true
)
...
...
vendor/github.com/33cn/chain33/common/db/table/count.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
table
import
(
"math"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
)
//Count 计数器
type
Count
struct
{
prefix
string
name
string
kvdb
db
.
KV
num
int64
keydata
[]
byte
}
//NewCount 创建一个计数器
func
NewCount
(
prefix
string
,
name
string
,
kvdb
db
.
KV
)
*
Count
{
keydata
:=
[]
byte
(
prefix
+
"#"
+
name
)
return
&
Count
{
prefix
:
prefix
,
name
:
name
,
kvdb
:
kvdb
,
keydata
:
keydata
,
num
:
math
.
MinInt64
,
}
}
func
(
c
*
Count
)
getKey
()
[]
byte
{
return
c
.
keydata
}
//Save 保存kv
func
(
c
*
Count
)
Save
()
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
{
if
c
.
num
==
math
.
MinInt64
{
return
nil
,
nil
}
var
i
types
.
Int64
i
.
Data
=
c
.
num
item
:=
&
types
.
KeyValue
{
Key
:
c
.
getKey
(),
Value
:
types
.
Encode
(
&
i
)}
kvs
=
append
(
kvs
,
item
)
return
}
//Get count
func
(
c
*
Count
)
Get
()
(
int64
,
error
)
{
if
c
.
num
==
math
.
MinInt64
{
data
,
err
:=
c
.
kvdb
.
Get
(
c
.
getKey
())
if
err
==
types
.
ErrNotFound
{
c
.
num
=
0
}
else
if
err
!=
nil
{
return
0
,
err
}
var
num
types
.
Int64
err
=
types
.
Decode
(
data
,
&
num
)
if
err
!=
nil
{
return
0
,
err
}
c
.
num
=
num
.
Data
}
return
c
.
num
,
nil
}
//Inc 增加1
func
(
c
*
Count
)
Inc
()
(
num
int64
,
err
error
)
{
c
.
num
,
err
=
c
.
Get
()
if
err
!=
nil
{
return
0
,
err
}
c
.
num
++
return
c
.
num
,
nil
}
//Dec 减少1
func
(
c
*
Count
)
Dec
()
(
num
int64
,
err
error
)
{
c
.
num
,
err
=
c
.
Get
()
if
err
!=
nil
{
return
0
,
err
}
c
.
num
--
return
c
.
num
,
nil
}
//Set 这个操作要谨慎使用
func
(
c
*
Count
)
Set
(
i
int64
)
{
c
.
num
=
i
}
vendor/github.com/33cn/chain33/common/db/table/count_test.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
table
import
(
"testing"
"github.com/stretchr/testify/assert"
)
func
TestCount
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
count
:=
NewCount
(
"prefix"
,
"name#hello"
,
kvdb
)
count
.
Inc
()
count
.
Dec
()
count
.
Inc
()
i
,
err
:=
count
.
Get
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
i
,
int64
(
1
))
kvs
,
err
:=
count
.
Save
()
assert
.
Nil
(
t
,
err
)
setKV
(
leveldb
,
kvs
)
count
=
NewCount
(
"prefix"
,
"name#hello"
,
kvdb
)
i
,
err
=
count
.
Get
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
i
,
int64
(
1
))
count
.
Set
(
2
)
i
,
err
=
count
.
Get
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
i
,
int64
(
2
))
}
vendor/github.com/33cn/chain33/common/db/table/error.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
table
import
"errors"
//table 中的错误处理
var
(
ErrEmptyPrimaryKey
=
errors
.
New
(
"ErrEmptyPrimaryKey"
)
ErrPrimaryKey
=
errors
.
New
(
"ErrPrimaryKey"
)
ErrIndexKey
=
errors
.
New
(
"ErrIndexKey"
)
ErrTooManyIndex
=
errors
.
New
(
"ErrTooManyIndex"
)
ErrTablePrefixOrTableName
=
errors
.
New
(
"ErrTablePrefixOrTableName"
)
ErrDupPrimaryKey
=
errors
.
New
(
"ErrDupPrimaryKey"
)
)
vendor/github.com/33cn/chain33/common/db/table/query.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
table
import
(
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
)
//Query 列表查询结构
type
Query
struct
{
table
*
Table
kvdb
db
.
KVDB
}
//ListIndex 根据索引查询列表
//index 用哪个index
//prefix 必须要符合的前缀, 可以为空
//primaryKey 开始查询的位置(不包含数据本身)
//count 最多取的数量
//direction 方向
func
(
query
*
Query
)
ListIndex
(
indexName
string
,
prefix
[]
byte
,
primaryKey
[]
byte
,
count
,
direction
int32
)
(
rows
[]
*
Row
,
err
error
)
{
if
indexName
==
""
{
return
query
.
ListPrimary
(
prefix
,
primaryKey
,
count
,
direction
)
}
p
:=
query
.
table
.
indexPrefix
(
indexName
)
var
k
[]
byte
if
len
(
primaryKey
)
>
0
{
row
,
err
:=
query
.
table
.
GetData
(
primaryKey
)
if
err
!=
nil
{
return
nil
,
err
}
key
,
err
:=
query
.
table
.
index
(
row
,
indexName
)
if
err
!=
nil
{
return
nil
,
err
}
//如果存在prefix
if
prefix
!=
nil
{
p2
:=
commonPrefix
(
prefix
,
key
)
if
len
(
p2
)
!=
len
(
prefix
)
{
return
nil
,
types
.
ErrNotFound
}
p
=
append
(
p
,
p2
...
)
}
k
=
query
.
table
.
getIndexKey
(
indexName
,
key
,
row
.
Primary
)
}
else
{
//这个情况下 k == nil
p
=
append
(
p
,
prefix
...
)
}
values
,
err
:=
query
.
kvdb
.
List
(
p
,
k
,
count
,
direction
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
value
:=
range
values
{
row
,
err
:=
query
.
table
.
GetData
(
value
)
if
err
!=
nil
{
return
nil
,
err
}
rows
=
append
(
rows
,
row
)
}
return
rows
,
nil
}
//ListPrimary list primary data
func
(
query
*
Query
)
ListPrimary
(
prefix
[]
byte
,
primaryKey
[]
byte
,
count
,
direction
int32
)
(
rows
[]
*
Row
,
err
error
)
{
p
:=
query
.
table
.
primaryPrefix
()
var
k
[]
byte
if
primaryKey
!=
nil
{
if
prefix
!=
nil
{
p2
:=
commonPrefix
(
prefix
,
primaryKey
)
if
len
(
p2
)
!=
len
(
prefix
)
{
return
nil
,
types
.
ErrNotFound
}
p
=
append
(
p
,
p2
...
)
}
k
=
append
(
p
,
primaryKey
...
)
}
else
{
p
=
append
(
p
,
prefix
...
)
}
values
,
err
:=
query
.
kvdb
.
List
(
p
,
k
,
count
,
direction
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
value
:=
range
values
{
row
,
err
:=
query
.
table
.
getRow
(
value
)
if
err
!=
nil
{
return
nil
,
err
}
rows
=
append
(
rows
,
row
)
}
return
rows
,
nil
}
func
commonPrefix
(
key1
,
key2
[]
byte
)
[]
byte
{
l1
:=
len
(
key1
)
l2
:=
len
(
key2
)
l
:=
min
(
l1
,
l2
)
for
i
:=
0
;
i
<
l
;
i
++
{
if
key1
[
i
]
!=
key2
[
i
]
{
return
key1
[
:
i
]
}
}
return
key1
[
0
:
l
]
}
func
min
(
a
,
b
int
)
int
{
if
a
<
b
{
return
a
}
return
b
}
vendor/github.com/33cn/chain33/common/db/table/table.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//Package table 实现一个基于kv的关系型数据库的表格功能
package
table
import
(
"bytes"
"encoding/binary"
"fmt"
"strings"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
)
//设计结构:
/*
核心: 平衡
save:
数据保存:
tableprefix + tablename + Primary -> data
index:
tableprefix + tablemetaname + index + primary -> primary
read:
list by Primary -> 直接读出数据
list by index
根据index 先计算要读出的 primary list
从数据table读出数据(根据 primary key)
del:
利用 primaryKey + index 删除所有的 数据 和 索引
*/
//指出是 添加 还是 删除 行
//primary key auto 的del 需要指定 primary key
const
(
None
=
iota
Add
Del
)
//meta key
const
meta
=
"#m#"
const
data
=
"#d#"
//RowMeta 定义行的操作
type
RowMeta
interface
{
CreateRow
()
*
Row
SetPayload
(
types
.
Message
)
error
Get
(
key
string
)
([]
byte
,
error
)
}
//Row 行操作
type
Row
struct
{
Ty
int
Primary
[]
byte
Data
types
.
Message
}
func
encodeInt64
(
p
int64
)
([]
byte
,
error
)
{
buf
:=
new
(
bytes
.
Buffer
)
err
:=
binary
.
Write
(
buf
,
binary
.
LittleEndian
,
p
)
if
err
!=
nil
{
return
nil
,
err
}
return
buf
.
Bytes
(),
nil
}
func
decodeInt64
(
p
[]
byte
)
(
int64
,
error
)
{
buf
:=
bytes
.
NewBuffer
(
p
)
var
i
int64
err
:=
binary
.
Read
(
buf
,
binary
.
LittleEndian
,
&
i
)
if
err
!=
nil
{
return
0
,
err
}
return
i
,
nil
}
//Encode row
func
(
row
*
Row
)
Encode
()
([]
byte
,
error
)
{
b
,
err
:=
encodeInt64
(
int64
(
len
(
row
.
Primary
)))
if
err
!=
nil
{
return
nil
,
err
}
b
=
append
(
b
,
row
.
Primary
...
)
b
=
append
(
b
,
types
.
Encode
(
row
.
Data
)
...
)
return
b
,
nil
}
//DecodeRow from data
func
DecodeRow
(
data
[]
byte
)
([]
byte
,
[]
byte
,
error
)
{
if
len
(
data
)
<=
8
{
return
nil
,
nil
,
types
.
ErrDecode
}
l
,
err
:=
decodeInt64
(
data
[
:
8
])
if
err
!=
nil
{
return
nil
,
nil
,
err
}
if
len
(
data
)
<
int
(
l
)
+
8
{
return
nil
,
nil
,
types
.
ErrDecode
}
return
data
[
8
:
int
(
l
)
+
8
],
data
[
int
(
l
)
+
8
:
],
nil
}
//Table 定一个表格, 并且添加 primary key, index key
type
Table
struct
{
meta
RowMeta
rows
[]
*
Row
rowmap
map
[
string
]
*
Row
kvdb
db
.
KV
opt
*
Option
autoinc
*
Count
dataprefix
string
metaprefix
string
}
//Option table 的选项
type
Option
struct
{
Prefix
string
Name
string
Primary
string
Index
[]
string
}
//NewTable 新建一个表格
//primary 可以为: auto, 由系统自动创建
//index 可以为nil
func
NewTable
(
rowmeta
RowMeta
,
kvdb
db
.
KV
,
opt
*
Option
)
(
*
Table
,
error
)
{
if
len
(
opt
.
Index
)
>
16
{
return
nil
,
ErrTooManyIndex
}
for
_
,
index
:=
range
opt
.
Index
{
if
strings
.
Contains
(
index
,
"#"
)
{
return
nil
,
ErrIndexKey
}
}
if
opt
.
Primary
==
""
{
opt
.
Primary
=
"auto"
}
if
_
,
err
:=
getPrimaryKey
(
rowmeta
,
opt
.
Primary
);
err
!=
nil
{
return
nil
,
err
}
//不允许有#
if
strings
.
Contains
(
opt
.
Prefix
,
"#"
)
||
strings
.
Contains
(
opt
.
Name
,
"#"
)
{
return
nil
,
ErrTablePrefixOrTableName
}
dataprefix
:=
opt
.
Prefix
+
"#"
+
opt
.
Name
+
data
metaprefix
:=
opt
.
Prefix
+
"#"
+
opt
.
Name
+
meta
count
:=
NewCount
(
opt
.
Prefix
,
opt
.
Name
+
"#autoinc#"
,
kvdb
)
return
&
Table
{
meta
:
rowmeta
,
kvdb
:
kvdb
,
rowmap
:
make
(
map
[
string
]
*
Row
),
opt
:
opt
,
autoinc
:
count
,
dataprefix
:
dataprefix
,
metaprefix
:
metaprefix
},
nil
}
func
getPrimaryKey
(
meta
RowMeta
,
primary
string
)
([]
byte
,
error
)
{
if
primary
==
""
{
return
nil
,
ErrEmptyPrimaryKey
}
if
strings
.
Contains
(
primary
,
"#"
)
{
return
nil
,
ErrPrimaryKey
}
if
primary
!=
"auto"
{
key
,
err
:=
meta
.
Get
(
primary
)
return
key
,
err
}
return
nil
,
nil
}
func
(
table
*
Table
)
addRowCache
(
row
*
Row
)
{
table
.
rowmap
[
string
(
row
.
Primary
)]
=
row
table
.
rows
=
append
(
table
.
rows
,
row
)
}
func
(
table
*
Table
)
findRow
(
primary
[]
byte
)
(
*
Row
,
error
)
{
if
row
,
ok
:=
table
.
rowmap
[
string
(
primary
)];
ok
{
return
row
,
nil
}
return
table
.
GetData
(
primary
)
}
func
(
table
*
Table
)
checkIndex
(
data
types
.
Message
)
error
{
err
:=
table
.
meta
.
SetPayload
(
data
)
if
err
!=
nil
{
return
err
}
if
_
,
err
:=
getPrimaryKey
(
table
.
meta
,
table
.
opt
.
Primary
);
err
!=
nil
{
return
err
}
for
i
:=
0
;
i
<
len
(
table
.
opt
.
Index
);
i
++
{
_
,
err
:=
table
.
meta
.
Get
(
table
.
opt
.
Index
[
i
])
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
(
table
*
Table
)
getPrimaryAuto
()
([]
byte
,
error
)
{
i
,
err
:=
table
.
autoinc
.
Inc
()
if
err
!=
nil
{
return
nil
,
err
}
return
[]
byte
(
pad
(
i
)),
nil
}
//primaryKey 获取主键
//1. auto 的情况下,只能自增。
//2. 没有auto的情况下从数据中取
func
(
table
*
Table
)
primaryKey
(
data
types
.
Message
)
(
primaryKey
[]
byte
,
err
error
)
{
if
table
.
opt
.
Primary
==
"auto"
{
primaryKey
,
err
=
table
.
getPrimaryAuto
()
if
err
!=
nil
{
return
nil
,
err
}
}
else
{
primaryKey
,
err
=
table
.
getPrimaryFromData
(
data
)
}
return
}
func
(
table
*
Table
)
getPrimaryFromData
(
data
types
.
Message
)
(
primaryKey
[]
byte
,
err
error
)
{
err
=
table
.
meta
.
SetPayload
(
data
)
if
err
!=
nil
{
return
nil
,
err
}
primaryKey
,
err
=
getPrimaryKey
(
table
.
meta
,
table
.
opt
.
Primary
)
if
err
!=
nil
{
return
nil
,
err
}
return
}
//Replace 如果有重复的,那么替换
func
(
table
*
Table
)
Replace
(
data
types
.
Message
)
error
{
if
err
:=
table
.
checkIndex
(
data
);
err
!=
nil
{
return
err
}
primaryKey
,
err
:=
table
.
primaryKey
(
data
)
if
err
!=
nil
{
return
err
}
//如果是auto的情况,一定是添加
if
table
.
opt
.
Primary
==
"auto"
{
table
.
addRowCache
(
&
Row
{
Data
:
data
,
Primary
:
primaryKey
,
Ty
:
Add
})
return
nil
}
//如果没有找到行, 那么添加
row
,
err
:=
table
.
findRow
(
primaryKey
)
if
err
==
types
.
ErrNotFound
{
table
.
addRowCache
(
&
Row
{
Data
:
data
,
Primary
:
primaryKey
,
Ty
:
Add
})
return
nil
}
//更新数据
delrow
:=
*
row
delrow
.
Ty
=
Del
//update 是一个del 和 update 的组合
table
.
addRowCache
(
&
delrow
)
table
.
addRowCache
(
&
Row
{
Data
:
data
,
Primary
:
primaryKey
,
Ty
:
Add
})
return
nil
}
//Add 在表格中添加一行
func
(
table
*
Table
)
Add
(
data
types
.
Message
)
error
{
if
err
:=
table
.
checkIndex
(
data
);
err
!=
nil
{
return
err
}
primaryKey
,
err
:=
table
.
primaryKey
(
data
)
if
err
!=
nil
{
return
err
}
//find in cache + db
_
,
err
=
table
.
findRow
(
primaryKey
)
if
err
!=
types
.
ErrNotFound
{
return
ErrDupPrimaryKey
}
//检查cache中是否有重复,有重复也返回错误
table
.
addRowCache
(
&
Row
{
Data
:
data
,
Primary
:
primaryKey
,
Ty
:
Add
})
return
nil
}
//Update 更新数据库
func
(
table
*
Table
)
Update
(
primaryKey
[]
byte
,
newdata
types
.
Message
)
(
err
error
)
{
if
err
:=
table
.
checkIndex
(
newdata
);
err
!=
nil
{
return
err
}
p1
,
err
:=
table
.
getPrimaryFromData
(
newdata
)
if
err
!=
nil
{
return
err
}
if
!
bytes
.
Equal
(
p1
,
primaryKey
)
{
return
types
.
ErrInvalidParam
}
row
,
err
:=
table
.
findRow
(
primaryKey
)
//查询发生错误
if
err
!=
nil
{
return
err
}
delrow
:=
*
row
delrow
.
Ty
=
Del
//update 是一个del 和 update 的组合
table
.
addRowCache
(
&
delrow
)
table
.
addRowCache
(
&
Row
{
Data
:
newdata
,
Primary
:
primaryKey
,
Ty
:
Add
})
return
nil
}
//Del 在表格中删除一行(包括删除索引)
func
(
table
*
Table
)
Del
(
primaryKey
[]
byte
)
error
{
row
,
err
:=
table
.
findRow
(
primaryKey
)
if
err
!=
nil
{
return
err
}
delrow
:=
*
row
delrow
.
Ty
=
Del
table
.
addRowCache
(
&
delrow
)
return
nil
}
//getDataKey data key 构造
func
(
table
*
Table
)
getDataKey
(
primaryKey
[]
byte
)
[]
byte
{
return
append
([]
byte
(
table
.
dataprefix
),
primaryKey
...
)
}
//GetIndexKey data key 构造
func
(
table
*
Table
)
getIndexKey
(
indexName
string
,
index
,
primaryKey
[]
byte
)
[]
byte
{
key
:=
table
.
indexPrefix
(
indexName
)
key
=
append
(
key
,
index
...
)
key
=
append
(
key
,
[]
byte
(
"#"
)
...
)
key
=
append
(
key
,
primaryKey
...
)
return
key
}
func
(
table
*
Table
)
primaryPrefix
()
[]
byte
{
return
[]
byte
(
table
.
dataprefix
)
}
func
(
table
*
Table
)
indexPrefix
(
indexName
string
)
[]
byte
{
key
:=
append
([]
byte
(
table
.
metaprefix
),
[]
byte
(
indexName
+
"#"
)
...
)
return
key
}
func
(
table
*
Table
)
index
(
row
*
Row
,
indexName
string
)
([]
byte
,
error
)
{
err
:=
table
.
meta
.
SetPayload
(
row
.
Data
)
if
err
!=
nil
{
return
nil
,
err
}
return
table
.
meta
.
Get
(
indexName
)
}
func
(
table
*
Table
)
getData
(
primaryKey
[]
byte
)
([]
byte
,
error
)
{
key
:=
table
.
getDataKey
(
primaryKey
)
value
,
err
:=
table
.
kvdb
.
Get
(
key
)
if
err
!=
nil
{
return
nil
,
err
}
return
value
,
nil
}
//GetData 根据主键获取数据
func
(
table
*
Table
)
GetData
(
primaryKey
[]
byte
)
(
*
Row
,
error
)
{
value
,
err
:=
table
.
getData
(
primaryKey
)
if
err
!=
nil
{
return
nil
,
err
}
return
table
.
getRow
(
value
)
}
func
(
table
*
Table
)
getRow
(
value
[]
byte
)
(
*
Row
,
error
)
{
primary
,
data
,
err
:=
DecodeRow
(
value
)
if
err
!=
nil
{
return
nil
,
err
}
row
:=
table
.
meta
.
CreateRow
()
row
.
Primary
=
primary
err
=
types
.
Decode
(
data
,
row
.
Data
)
if
err
!=
nil
{
return
nil
,
err
}
return
row
,
nil
}
//Save 保存表格
func
(
table
*
Table
)
Save
()
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
{
for
_
,
row
:=
range
table
.
rows
{
kvlist
,
err
:=
table
.
saveRow
(
row
)
if
err
!=
nil
{
return
nil
,
err
}
kvs
=
append
(
kvs
,
kvlist
...
)
}
kvlist
,
err
:=
table
.
autoinc
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
kvs
=
append
(
kvs
,
kvlist
...
)
//del cache
table
.
rowmap
=
make
(
map
[
string
]
*
Row
)
table
.
rows
=
nil
return
kvs
,
nil
}
func
pad
(
i
int64
)
string
{
return
fmt
.
Sprintf
(
"%020d"
,
i
)
}
func
(
table
*
Table
)
saveRow
(
row
*
Row
)
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
{
if
row
.
Ty
==
Del
{
return
table
.
delRow
(
row
)
}
return
table
.
addRow
(
row
)
}
func
(
table
*
Table
)
delRow
(
row
*
Row
)
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
{
deldata
:=
&
types
.
KeyValue
{
Key
:
table
.
getDataKey
(
row
.
Primary
)}
kvs
=
append
(
kvs
,
deldata
)
for
_
,
index
:=
range
table
.
opt
.
Index
{
indexkey
,
err
:=
table
.
index
(
row
,
index
)
if
err
!=
nil
{
return
nil
,
err
}
delindex
:=
&
types
.
KeyValue
{
Key
:
table
.
getIndexKey
(
index
,
indexkey
,
row
.
Primary
)}
kvs
=
append
(
kvs
,
delindex
)
}
return
kvs
,
nil
}
func
(
table
*
Table
)
addRow
(
row
*
Row
)
(
kvs
[]
*
types
.
KeyValue
,
err
error
)
{
data
,
err
:=
row
.
Encode
()
if
err
!=
nil
{
return
nil
,
err
}
adddata
:=
&
types
.
KeyValue
{
Key
:
table
.
getDataKey
(
row
.
Primary
),
Value
:
data
}
kvs
=
append
(
kvs
,
adddata
)
for
_
,
index
:=
range
table
.
opt
.
Index
{
indexkey
,
err
:=
table
.
index
(
row
,
index
)
if
err
!=
nil
{
return
nil
,
err
}
addindex
:=
&
types
.
KeyValue
{
Key
:
table
.
getIndexKey
(
index
,
indexkey
,
row
.
Primary
),
Value
:
row
.
Primary
}
kvs
=
append
(
kvs
,
addindex
)
}
return
kvs
,
nil
}
//GetQuery 获取查询结构
func
(
table
*
Table
)
GetQuery
(
kvdb
db
.
KVDB
)
*
Query
{
return
&
Query
{
table
:
table
,
kvdb
:
kvdb
}
}
vendor/github.com/33cn/chain33/common/db/table/table_test.go
0 → 100644
View file @
eaaeeb54
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
table
import
(
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert"
)
func
TestTransactinList
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
opt
:=
&
Option
{
Prefix
:
"prefix"
,
Name
:
"name"
,
Primary
:
"Hash"
,
Index
:
[]
string
{
"From"
,
"To"
},
}
table
,
err
:=
NewTable
(
NewTransactionRow
(),
kvdb
,
opt
)
assert
.
Nil
(
t
,
err
)
addr1
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx1
)
assert
.
Nil
(
t
,
err
)
tx2
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx2
)
assert
.
Nil
(
t
,
err
)
addr2
,
priv
:=
util
.
Genaddress
()
tx3
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx3
)
assert
.
Nil
(
t
,
err
)
tx4
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx4
)
assert
.
Nil
(
t
,
err
)
//添加一个无效的类型
err
=
table
.
Add
(
nil
)
assert
.
Equal
(
t
,
types
.
ErrTypeAsset
,
err
)
kvs
,
err
:=
table
.
Save
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
kvs
),
12
)
//save to database
setKV
(
leveldb
,
kvs
)
//测试查询
query
:=
table
.
GetQuery
(
kvdb
)
rows
,
err
:=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
),
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
if
bytes
.
Compare
(
tx1
.
Hash
(),
tx2
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx1
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx2
,
rows
[
1
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx1
,
rows
[
1
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx2
,
rows
[
0
]
.
Data
))
}
//prefix full
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
),
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
if
bytes
.
Compare
(
tx3
.
Hash
(),
tx4
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
1
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
1
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
}
//prefix part
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
if
bytes
.
Compare
(
tx3
.
Hash
(),
tx4
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
1
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
1
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
}
//count
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
nil
,
1
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
if
bytes
.
Compare
(
tx3
.
Hash
(),
tx4
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
}
primary
:=
rows
[
0
]
.
Primary
//primary
rows
,
err
=
query
.
ListIndex
(
"From"
,
nil
,
primary
,
1
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
if
bytes
.
Compare
(
tx3
.
Hash
(),
tx4
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
}
//prefix + primary
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
primary
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
if
bytes
.
Compare
(
tx3
.
Hash
(),
tx4
.
Hash
())
>
0
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
}
else
{
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
}
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
[
0
:
10
]),
primary
,
0
,
0
)
assert
.
Equal
(
t
,
types
.
ErrNotFound
,
err
)
assert
.
Equal
(
t
,
0
,
len
(
rows
))
//ListPrimary all
rows
,
err
=
query
.
ListPrimary
(
nil
,
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
4
,
len
(
rows
))
primary
=
rows
[
0
]
.
Primary
rows
,
err
=
query
.
ListPrimary
(
primary
[
0
:
10
],
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
rows
,
err
=
query
.
ListPrimary
(
nil
,
primary
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
3
,
len
(
rows
))
}
func
TestTransactinListAuto
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
opt
:=
&
Option
{
Prefix
:
"prefix"
,
Name
:
"name"
,
Primary
:
""
,
Index
:
[]
string
{
"From"
,
"To"
},
}
table
,
err
:=
NewTable
(
NewTransactionRow
(),
kvdb
,
opt
)
assert
.
Nil
(
t
,
err
)
addr1
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx1
)
assert
.
Nil
(
t
,
err
)
tx2
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx2
)
assert
.
Nil
(
t
,
err
)
addr2
,
priv
:=
util
.
Genaddress
()
tx3
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx3
)
assert
.
Nil
(
t
,
err
)
tx4
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx4
)
assert
.
Nil
(
t
,
err
)
//添加一个无效的类型
err
=
table
.
Add
(
nil
)
assert
.
Equal
(
t
,
types
.
ErrTypeAsset
,
err
)
kvs
,
err
:=
table
.
Save
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
kvs
),
13
)
//save to database
setKV
(
leveldb
,
kvs
)
//测试查询
query
:=
table
.
GetQuery
(
kvdb
)
rows
,
err
:=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
),
nil
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx1
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx2
,
rows
[
1
]
.
Data
))
//prefix full
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
),
nil
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
1
]
.
Data
))
//prefix part
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
nil
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
2
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
1
]
.
Data
))
//count
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
nil
,
1
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx3
,
rows
[
0
]
.
Data
))
primary
:=
rows
[
0
]
.
Primary
//primary
rows
,
err
=
query
.
ListIndex
(
"From"
,
nil
,
primary
,
1
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
//prefix + primary
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr2
[
0
:
10
]),
primary
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
assert
.
Equal
(
t
,
true
,
proto
.
Equal
(
tx4
,
rows
[
0
]
.
Data
))
rows
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
[
0
:
10
]),
primary
,
0
,
db
.
ListASC
)
assert
.
Equal
(
t
,
types
.
ErrNotFound
,
err
)
assert
.
Equal
(
t
,
0
,
len
(
rows
))
//ListPrimary all
rows
,
err
=
query
.
ListPrimary
(
nil
,
nil
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
4
,
len
(
rows
))
primary
=
rows
[
0
]
.
Primary
rows
,
err
=
query
.
ListPrimary
(
primary
,
nil
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
1
,
len
(
rows
))
rows
,
err
=
query
.
ListPrimary
(
nil
,
primary
,
0
,
db
.
ListASC
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
3
,
len
(
rows
))
}
func
mergeDup
(
kvs
[]
*
types
.
KeyValue
)
(
kvset
[]
*
types
.
KeyValue
)
{
maplist
:=
make
(
map
[
string
]
*
types
.
KeyValue
)
for
_
,
kv
:=
range
kvs
{
if
item
,
ok
:=
maplist
[
string
(
kv
.
Key
)];
ok
{
item
.
Value
=
kv
.
Value
//更新item 的value
}
else
{
maplist
[
string
(
kv
.
Key
)]
=
kv
kvset
=
append
(
kvset
,
kv
)
}
}
return
kvset
}
func
setKV
(
kvdb
db
.
DB
,
kvs
[]
*
types
.
KeyValue
)
{
batch
:=
kvdb
.
NewBatch
(
true
)
for
i
:=
0
;
i
<
len
(
kvs
);
i
++
{
if
kvs
[
i
]
.
Value
==
nil
{
batch
.
Delete
(
kvs
[
i
]
.
Key
)
continue
}
batch
.
Set
(
kvs
[
i
]
.
Key
,
kvs
[
i
]
.
Value
)
}
err
:=
batch
.
Write
()
if
err
!=
nil
{
panic
(
err
)
}
}
func
printKV
(
kvs
[]
*
types
.
KeyValue
)
{
for
i
:=
0
;
i
<
len
(
kvs
);
i
++
{
fmt
.
Println
(
"KV"
,
i
,
string
(
kvs
[
i
]
.
Key
),
common
.
ToHex
(
kvs
[
i
]
.
Value
))
}
}
func
TestRow
(
t
*
testing
.
T
)
{
rowmeta
:=
NewTransactionRow
()
row
:=
rowmeta
.
CreateRow
()
_
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
row
.
Data
=
tx1
row
.
Primary
=
tx1
.
Hash
()
data
,
err
:=
row
.
Encode
()
assert
.
Nil
(
t
,
err
)
primary
,
protodata
,
err
:=
DecodeRow
(
data
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
primary
,
row
.
Primary
)
var
tx
types
.
Transaction
err
=
types
.
Decode
(
protodata
,
&
tx
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
proto
.
Equal
(
&
tx
,
tx1
),
true
)
}
func
TestDel
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
opt
:=
&
Option
{
Prefix
:
"prefix"
,
Name
:
"name"
,
Primary
:
"Hash"
,
Index
:
[]
string
{
"From"
,
"To"
},
}
table
,
err
:=
NewTable
(
NewTransactionRow
(),
kvdb
,
opt
)
assert
.
Nil
(
t
,
err
)
addr1
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx1
)
assert
.
Nil
(
t
,
err
)
_
,
priv
=
util
.
Genaddress
()
tx2
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx2
)
assert
.
Nil
(
t
,
err
)
//删除掉一个
err
=
table
.
Del
(
tx1
.
Hash
())
assert
.
Nil
(
t
,
err
)
//save 然后从列表中读取
kvs
,
err
:=
table
.
Save
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
kvs
),
9
)
//save to database
setKV
(
leveldb
,
kvs
)
//printKV(kvs)
query
:=
table
.
GetQuery
(
kvdb
)
rows
,
err
:=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
[
0
:
10
]),
nil
,
0
,
0
)
assert
.
Equal
(
t
,
types
.
ErrNotFound
,
err
)
assert
.
Equal
(
t
,
0
,
len
(
rows
))
}
func
printAllKey
(
db
db
.
DB
)
{
it
:=
db
.
Iterator
(
nil
,
nil
,
false
)
defer
it
.
Close
()
for
it
.
Rewind
();
it
.
Valid
();
it
.
Next
()
{
fmt
.
Println
(
"db.allkey"
,
string
(
it
.
Key
()))
}
}
func
TestUpdate
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
opt
:=
&
Option
{
Prefix
:
"prefix"
,
Name
:
"name"
,
Primary
:
"Hash"
,
Index
:
[]
string
{
"From"
,
"To"
},
}
table
,
err
:=
NewTable
(
NewTransactionRow
(),
kvdb
,
opt
)
assert
.
Nil
(
t
,
err
)
_
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx1
)
assert
.
Nil
(
t
,
err
)
err
=
table
.
Update
([]
byte
(
"hello"
),
tx1
)
assert
.
Equal
(
t
,
err
,
types
.
ErrInvalidParam
)
tx1
.
Signature
=
nil
err
=
table
.
Update
(
tx1
.
Hash
(),
tx1
)
assert
.
Nil
(
t
,
err
)
kvs
,
err
:=
table
.
Save
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
kvs
),
9
)
//save to database
setKV
(
leveldb
,
kvs
)
query
:=
table
.
GetQuery
(
kvdb
)
rows
,
err
:=
query
.
ListIndex
(
"From"
,
[]
byte
(
tx1
.
From
()),
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
rows
[
0
]
.
Data
.
(
*
types
.
Transaction
)
.
From
(),
tx1
.
From
())
}
func
TestReplace
(
t
*
testing
.
T
)
{
dir
,
leveldb
,
kvdb
:=
getdb
()
defer
dbclose
(
dir
,
leveldb
)
opt
:=
&
Option
{
Prefix
:
"prefix"
,
Name
:
"name"
,
Primary
:
"Hash"
,
Index
:
[]
string
{
"From"
,
"To"
},
}
table
,
err
:=
NewTable
(
NewTransactionRow
(),
kvdb
,
opt
)
assert
.
Nil
(
t
,
err
)
addr1
,
priv
:=
util
.
Genaddress
()
tx1
:=
util
.
CreateNoneTx
(
priv
)
err
=
table
.
Add
(
tx1
)
assert
.
Nil
(
t
,
err
)
err
=
table
.
Add
(
tx1
)
assert
.
Equal
(
t
,
err
,
ErrDupPrimaryKey
)
//不改变hash,改变签名
tx1
.
Signature
=
nil
err
=
table
.
Replace
(
tx1
)
assert
.
Nil
(
t
,
err
)
//save 然后从列表中读取
kvs
,
err
:=
table
.
Save
()
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
len
(
kvs
),
9
)
//save to database
setKV
(
leveldb
,
kvs
)
query
:=
table
.
GetQuery
(
kvdb
)
_
,
err
=
query
.
ListIndex
(
"From"
,
[]
byte
(
addr1
[
0
:
10
]),
nil
,
0
,
0
)
assert
.
Equal
(
t
,
err
,
types
.
ErrNotFound
)
rows
,
err
:=
query
.
ListIndex
(
"From"
,
[]
byte
(
tx1
.
From
()),
nil
,
0
,
0
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
rows
[
0
]
.
Data
.
(
*
types
.
Transaction
)
.
From
(),
tx1
.
From
())
}
type
TransactionRow
struct
{
*
types
.
Transaction
}
func
NewTransactionRow
()
*
TransactionRow
{
return
&
TransactionRow
{
Transaction
:
&
types
.
Transaction
{}}
}
func
(
tx
*
TransactionRow
)
CreateRow
()
*
Row
{
return
&
Row
{
Data
:
&
types
.
Transaction
{}}
}
func
(
tx
*
TransactionRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
txdata
,
ok
:=
data
.
(
*
types
.
Transaction
);
ok
{
tx
.
Transaction
=
txdata
return
nil
}
return
types
.
ErrTypeAsset
}
func
(
tx
*
TransactionRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
if
key
==
"Hash"
{
return
tx
.
Hash
(),
nil
}
else
if
key
==
"From"
{
return
[]
byte
(
tx
.
From
()),
nil
}
else
if
key
==
"To"
{
return
[]
byte
(
tx
.
To
),
nil
}
return
nil
,
types
.
ErrNotFound
}
func
getdb
()
(
string
,
db
.
DB
,
db
.
KVDB
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"goleveldb"
)
if
err
!=
nil
{
panic
(
err
)
}
leveldb
,
err
:=
db
.
NewGoLevelDB
(
"goleveldb"
,
dir
,
128
)
if
err
!=
nil
{
panic
(
err
)
}
return
dir
,
leveldb
,
db
.
NewKVDB
(
leveldb
)
}
func
dbclose
(
dir
string
,
dbm
db
.
DB
)
{
os
.
RemoveAll
(
dir
)
dbm
.
Close
()
}
vendor/github.com/33cn/chain33/system/dapp/commands/types/utils.go
View file @
eaaeeb54
...
@@ -105,7 +105,7 @@ func CreateRawTx(cmd *cobra.Command, to string, amount float64, note string, isW
...
@@ -105,7 +105,7 @@ func CreateRawTx(cmd *cobra.Command, to string, amount float64, note string, isW
transfer
.
Ty
=
cty
.
CoinsActionTransfer
transfer
.
Ty
=
cty
.
CoinsActionTransfer
}
}
}
else
{
}
else
{
v
:=
&
cty
.
CoinsAction_Withdraw
{
Withdraw
:
&
types
.
AssetsWithdraw
{
Amount
:
amountInt64
,
Note
:
[]
byte
(
note
),
ExecName
:
execName
}}
v
:=
&
cty
.
CoinsAction_Withdraw
{
Withdraw
:
&
types
.
AssetsWithdraw
{
Amount
:
amountInt64
,
Note
:
[]
byte
(
note
),
ExecName
:
execName
,
To
:
to
}}
transfer
.
Value
=
v
transfer
.
Value
=
v
transfer
.
Ty
=
cty
.
CoinsActionWithdraw
transfer
.
Ty
=
cty
.
CoinsActionWithdraw
}
}
...
...
vendor/github.com/33cn/chain33/system/mempool/eventprocess.go
View file @
eaaeeb54
...
@@ -97,7 +97,7 @@ func (mem *Mempool) eventProcess() {
...
@@ -97,7 +97,7 @@ func (mem *Mempool) eventProcess() {
func
(
mem
*
Mempool
)
eventTx
(
msg
queue
.
Message
)
{
func
(
mem
*
Mempool
)
eventTx
(
msg
queue
.
Message
)
{
if
!
mem
.
getSync
()
{
if
!
mem
.
getSync
()
{
msg
.
Reply
(
mem
.
client
.
NewMessage
(
""
,
types
.
EventReply
,
&
types
.
Reply
{
Msg
:
[]
byte
(
types
.
ErrNotSync
.
Error
())}))
msg
.
Reply
(
mem
.
client
.
NewMessage
(
""
,
types
.
EventReply
,
&
types
.
Reply
{
Msg
:
[]
byte
(
types
.
ErrNotSync
.
Error
())}))
mlog
.
Error
(
"wrong tx"
,
"err"
,
types
.
ErrNotSync
.
Error
())
mlog
.
Debug
(
"wrong tx"
,
"err"
,
types
.
ErrNotSync
.
Error
())
}
else
{
}
else
{
checkedMsg
:=
mem
.
checkTxs
(
msg
)
checkedMsg
:=
mem
.
checkTxs
(
msg
)
select
{
select
{
...
...
vendor/github.com/33cn/chain33/util/util.go
View file @
eaaeeb54
...
@@ -111,7 +111,9 @@ func CreateTxWithExecer(priv crypto.PrivKey, execer string) *types.Transaction {
...
@@ -111,7 +111,9 @@ func CreateTxWithExecer(priv crypto.PrivKey, execer string) *types.Transaction {
tx
:=
&
types
.
Transaction
{
Execer
:
[]
byte
(
execer
),
Payload
:
[]
byte
(
"none"
)}
tx
:=
&
types
.
Transaction
{
Execer
:
[]
byte
(
execer
),
Payload
:
[]
byte
(
"none"
)}
tx
.
To
=
address
.
ExecAddress
(
execer
)
tx
.
To
=
address
.
ExecAddress
(
execer
)
tx
,
_
=
types
.
FormatTx
(
execer
,
tx
)
tx
,
_
=
types
.
FormatTx
(
execer
,
tx
)
if
priv
!=
nil
{
tx
.
Sign
(
types
.
SECP256K1
,
priv
)
tx
.
Sign
(
types
.
SECP256K1
,
priv
)
}
return
tx
return
tx
}
}
...
...
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