Commit cfe8db8f authored by vipwzw's avatar vipwzw Committed by 33cn

update chain33

parent fa8f3f88
......@@ -117,7 +117,7 @@ fmt: fmt_proto fmt_shell ## go fmt
.PHONY: fmt_proto fmt_shell
fmt_proto: ## go fmt protobuf file
#@find . -name '*.proto' -not -path "./vendor/*" | xargs clang-format -i
@find . -name '*.proto' -not -path "./vendor/*" | xargs clang-format -i
fmt_shell: ## check shell file
find . -name '*.sh' -not -path "./vendor/*" | xargs shfmt -w -s -i 4 -ci -bn
......
......@@ -47,6 +47,7 @@ func GetLocalDBKeyList() [][]byte {
return [][]byte{
blockLastHeight, bodyPerfix, LastSequence, headerPerfix, heightToHeaderPerfix,
hashPerfix, tdPerfix, heightToHashKeyPerfix, seqToHashKey, HashToSeqPerfix,
seqCBPrefix, seqCBLastNumPrefix,
}
}
......@@ -1057,3 +1058,49 @@ func (bs *BlockStore) SetUpgradeMeta(meta *types.UpgradeMeta) error {
storeLog.Info("SetUpgradeMeta", "meta", meta)
return bs.db.SetSync(version.LocalDBMeta, verByte)
}
//isRecordBlockSequence配置的合法性检测
func (bs *BlockStore) isRecordBlockSequenceValid() {
storeLog.Error("isRecordBlockSequenceValid")
lastHeight := bs.Height()
lastSequence, err := bs.LoadBlockLastSequence()
if err != nil {
if err != types.ErrHeightNotExist {
storeLog.Error("isRecordBlockSequenceValid", "LoadBlockLastSequence err", err)
panic(err)
}
}
//使能isRecordBlockSequence时的检测
if isRecordBlockSequence {
//中途开启isRecordBlockSequence报错
if lastSequence == -1 && lastHeight != -1 {
storeLog.Error("isRecordBlockSequenceValid", "lastHeight", lastHeight, "lastSequence", lastSequence)
panic("isRecordBlockSequence is true must Synchronizing data from zero block")
}
//lastSequence 必须大于等于lastheight
if lastHeight > lastSequence {
storeLog.Error("isRecordBlockSequenceValid", "lastHeight", lastHeight, "lastSequence", lastSequence)
panic("lastSequence must greater than or equal to lastHeight")
}
//通过lastSequence获取对应的blockhash != lastHeader.hash 报错
if lastSequence != -1 {
blockSequence, err := bs.GetBlockSequence(lastSequence)
if err != nil {
storeLog.Error("isRecordBlockSequenceValid", "lastSequence", lastSequence, "GetBlockSequence err", err)
panic(err)
}
lastHeader := bs.LastHeader()
if !bytes.Equal(lastHeader.Hash, blockSequence.Hash) {
storeLog.Error("isRecordBlockSequenceValid:", "lastHeight", lastHeight, "lastSequence", lastSequence, "lastHeader.Hash", common.ToHex(lastHeader.Hash), "blockSequence.Hash", common.ToHex(blockSequence.Hash))
panic("The hash values of lastSequence and lastHeight are different.")
}
}
return
}
//去使能isRecordBlockSequence时的检测
if lastSequence != -1 {
storeLog.Error("isRecordBlockSequenceValid", "lastSequence", lastSequence)
panic("can not disable isRecordBlockSequence")
}
}
......@@ -222,6 +222,10 @@ func (chain *BlockChain) GetOrphanPool() *OrphanPool {
//InitBlockChain 区块链初始化
func (chain *BlockChain) InitBlockChain() {
//isRecordBlockSequence配置的合法性检测
if !chain.cfg.IsParaChain {
chain.blockStore.isRecordBlockSequenceValid()
}
//先缓存最新的128个block信息到cache中
curheight := chain.GetBlockHeight()
if types.IsEnable("TxHeight") {
......@@ -402,9 +406,10 @@ func (chain *BlockChain) InitIndexAndBestView() {
height = 0
}
for ; height <= curheight; height++ {
header, _ := chain.blockStore.GetBlockHeaderByHeight(height)
header, err := chain.blockStore.GetBlockHeaderByHeight(height)
if header == nil {
return
chainlog.Error("InitIndexAndBestView GetBlockHeaderByHeight", "height", height, "err", err)
panic("InitIndexAndBestView fail!")
}
newNode := newBlockNodeByHeader(false, header, "self", -1)
......
......@@ -93,6 +93,9 @@ func (chain *BlockChain) ProcAddBlockSeqCB(cb *types.BlockSeqCB) error {
return types.ErrInvalidParam
}
if !isRecordBlockSequence {
return types.ErrRecordBlockSequence
}
if chain.blockStore.seqCBNum() >= MaxSeqCB && !chain.blockStore.isSeqCBExist(cb.Name) {
return types.ErrTooManySeqCB
}
......
......@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package commands 扫描chain33项目下plugin中所有的插件,根据扫描到的结果重新更新共识、执行器和数据操作的初始化文件 init.go
*/
package commands
import (
......@@ -19,7 +16,7 @@ import (
func UpdateInitCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "updateinit",
Short: "Update chain33 plugin consensus、dapp、store init.go file",
Short: "Update chain33 plugin consensus、dapp、store、mempool init.go file",
Run: updateInit,
}
cmd.Flags().StringP("path", "p", "plugin", "path of plugin")
......
# type字段仅支持 consensus dapp store
[blackwhite]
type = "dapp"
gitrepo = "gitlab.33.cn/sanghg/blackwhite"
# type字段仅支持 consensus dapp store mempool
[mempool-price]
type = "mempool"
gitrepo = "github.com/33cn/plugin/plugin/mempool/price"
version=""
syntax = "proto3";
package accounts;
message DemoAction {
oneof value {
DemoCreate create = 1;
DemoRun play = 2;
DemoClose show = 3;
}
int32 ty = 6;
}
message DemoCreate {
[ consensus - ticket ] string name = 1;
}
message DemoRun {
string name = 1;
}
message DemoClose {
string name = 1;
}
\ No newline at end of file
......@@ -51,5 +51,11 @@ Package main chain33开发者工具,主要提供以下功能:
-n --name 执行器的项目名和类名,必填参数
-p --propfile 导入执行器类型的proto3协议模板,如果不填默认为config/执行器名称.proto
-t --templatepath 生成执行器项目的模板文件,不填默认为config/template下的所有文件
更新初始化文件:
扫描指定path目录下所有的插件,根据扫描到的结果重新更新consensus、dapp和、store、mempool的初始化文件 init.go
使用方式:./tools updateinit -p $(YourPluginPath)
例子:./tools updateinit -p /GOPATH/src/github.com/33cn/chain33/cmd/tools/plugin
*/
package main
......@@ -295,6 +295,7 @@ clean:
@rm -rf plugin/dapp/init
@rm -rf plugin/crypto/init
@rm -rf plugin/store/init
@rm -rf plugin/mempool/init
`
// 生成 .travis.yml 文件模板
......@@ -308,7 +309,7 @@ go:
// 生成 plugin/plugin.toml的文件模板
CpftPluginToml = `
# type字段仅支持 consensus dapp store
# type字段仅支持 consensus dapp store mempool
[dapp-ticket]
gitrepo = "github.com/33cn/plugin/plugin/dapp/ticket"
......@@ -326,6 +327,12 @@ gitrepo = "github.com/33cn/plugin/plugin/dapp/token"
[dapp-trade]
gitrepo = "github.com/33cn/plugin/plugin/dapp/trade"
[mempool-price]
gitrepo = "github.com/33cn/plugin/plugin/mempool/price"
[mempool-score]
gitrepo = "github.com/33cn/plugin/plugin/mempool/score"
`
// 项目 cli/main.go 文件模板
CpftCliMain = `package main
......
......@@ -23,6 +23,7 @@ const (
consensusFolderName = "consensus"
storeFolderName = "store"
cryptoFolderName = "crypto"
mempoolFolderName = "mempool"
)
type pluginConfigItem struct {
......@@ -91,6 +92,7 @@ func (im *importPackageStrategy) initData() error {
consensusItems := make([]*pluginItem, 0)
storeItems := make([]*pluginItem, 0)
cryptoItems := make([]*pluginItem, 0)
mempoolItems := make([]*pluginItem, 0)
//read current plugin dir
//(分成两级,并且去掉了 init 目录)
......@@ -141,6 +143,8 @@ func (im *importPackageStrategy) initData() error {
storeItems = append(storeItems, item)
case cryptoFolderName:
cryptoItems = append(cryptoItems, item)
case mempoolFolderName:
mempoolItems = append(mempoolItems, item)
default:
fmt.Printf("type %s is not supported.\n", cfgItem.Type)
return errors.New("config error")
......@@ -150,6 +154,7 @@ func (im *importPackageStrategy) initData() error {
im.items[consensusFolderName] = consensusItems
im.items[storeFolderName] = storeItems
im.items[cryptoFolderName] = cryptoItems
im.items[mempoolFolderName] = mempoolItems
im.projRootPath = ""
im.projPluginPath, _ = im.getParam("path")
return nil
......@@ -201,11 +206,11 @@ func (im *importPackageStrategy) generateImportFile() error {
importStrs := map[string]string{}
for name, plugins := range im.items {
for _, item := range plugins {
importStrs[name] += fmt.Sprintf("\r\n_ \"%s\" //auto gen", item.gitRepo)
importStrs[name] += fmt.Sprintf("\n_ \"%s\" //auto gen", item.gitRepo)
}
}
for key, value := range importStrs {
content := fmt.Sprintf("package init\r\n\r\nimport(%s\r\n)", value)
content := fmt.Sprintf("package init\n\nimport(%s\n)", value)
initFile := fmt.Sprintf("%s/%s/init/init.go", im.projPluginPath, key)
util.MakeDir(initFile)
......
......@@ -11,6 +11,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/33cn/chain33/cmd/tools/tasks"
)
......@@ -21,6 +22,7 @@ type updateInitStrategy struct {
dappRootPath string
storeRootPath string
cryptoRootPath string
mempoolRootPath string
}
func (up *updateInitStrategy) Run() error {
......@@ -35,12 +37,15 @@ func (up *updateInitStrategy) Run() error {
func (up *updateInitStrategy) initMember() error {
path, err := up.getParam("path")
packname, _ := up.getParam("packname")
if err != nil || path == "" {
gopath := os.Getenv("GOPATH")
if err != nil || path == "" {
if len(gopath) > 0 {
path = filepath.Join(gopath, "/src/github.com/33cn/chain33/plugin/")
}
}
if packname == "" {
packname = strings.Replace(path, gopath+"/src/", "", 1)
}
if len(path) == 0 {
return errors.New("Chain33 Plugin Not Existed")
}
......@@ -48,10 +53,12 @@ func (up *updateInitStrategy) initMember() error {
up.dappRootPath = fmt.Sprintf("%s/dapp/", path)
up.storeRootPath = fmt.Sprintf("%s/store/", path)
up.cryptoRootPath = fmt.Sprintf("%s/crypto/", path)
up.mempoolRootPath = fmt.Sprintf("%s/mempool/", path)
mkdir(up.consRootPath)
mkdir(up.dappRootPath)
mkdir(up.storeRootPath)
mkdir(up.cryptoRootPath)
mkdir(up.mempoolRootPath)
buildInit(path, packname)
return nil
}
......@@ -76,7 +83,9 @@ import (
_ "${packname}/crypto/init" //crypto init
_ "${packname}/dapp/init" //dapp init
_ "${packname}/store/init" //store init
)`)
_ "${packname}/mempool/init" //mempool init
)
`)
data = bytes.Replace(data, []byte("${packname}"), []byte(packname), -1)
ioutil.WriteFile(path, data, 0666)
}
......@@ -114,6 +123,9 @@ func (up *updateInitStrategy) buildTask() tasks.Task {
&tasks.UpdateInitFileTask{
Folder: up.cryptoRootPath,
},
&tasks.UpdateInitFileTask{
Folder: up.mempoolRootPath,
},
)
task := taskSlice[0]
......
......@@ -183,11 +183,11 @@ func (c *CreateDappSourceTask) createExecDelLocalFile() error {
// 组成规则是 TyLog+ActionName + ActionMemberName
func (c *CreateDappSourceTask) buildActionLogTypeText() (text string, err error) {
items := fmt.Sprintf("TyLog%sUnknown = iota\r\n", c.ExecuteName)
items := fmt.Sprintf("TyLog%sUnknown = iota\n", c.ExecuteName)
for _, info := range c.actionInfos {
items += fmt.Sprintf("TyLog%s%s\r\n", c.ExecuteName, info.memberName)
items += fmt.Sprintf("TyLog%s%s\n", c.ExecuteName, info.memberName)
}
text = fmt.Sprintf("const (\r\n%s)\r\n", items)
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
......@@ -195,9 +195,9 @@ func (c *CreateDappSourceTask) buildActionLogTypeText() (text string, err error)
func (c *CreateDappSourceTask) buildActionIDText() (text string, err error) {
var items string
for index, info := range c.actionInfos {
items += fmt.Sprintf("%sAction%s = %d\r\n", c.ExecuteName, info.memberName, index)
items += fmt.Sprintf("%sAction%s = %d\n", c.ExecuteName, info.memberName, index)
}
text = fmt.Sprintf("const (\r\n%s)\r\n", items)
text = fmt.Sprintf("const (\n%s)\n", items)
return
}
......@@ -205,15 +205,15 @@ func (c *CreateDappSourceTask) buildActionIDText() (text string, err error) {
func (c *CreateDappSourceTask) buildLogMapText() (text string, err error) {
var items string
for _, info := range c.actionInfos {
items += fmt.Sprintf("\"%s\": %sAction%s,\r\n", info.memberName, c.ExecuteName, info.memberName)
items += fmt.Sprintf("\"%s\": %sAction%s,\n", info.memberName, c.ExecuteName, info.memberName)
}
text = fmt.Sprintf("map[string]int32{\r\n%s}", items)
text = fmt.Sprintf("map[string]int32{\n%s}", items)
return
}
// 返回 map[string]*types.LogInfo
func (c *CreateDappSourceTask) buidTypeMapText() (text string, err error) {
text = fmt.Sprintf("map[int64]*types.LogInfo{\r\n}")
text = fmt.Sprintf("map[int64]*types.LogInfo{\n}")
return
}
......
......@@ -7,7 +7,10 @@ package tasks
import (
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
"github.com/33cn/chain33/util"
)
......@@ -54,6 +57,17 @@ func (up *UpdateInitFileTask) Execute() error {
func (up *UpdateInitFileTask) init() error {
up.initFile = fmt.Sprintf("%sinit/init.go", up.Folder)
up.itemDatas = make([]*itemData, 0)
gopath := os.Getenv("GOPATH")
if len(gopath) == 0 {
return errors.New("GOPATH Not Existed")
}
// 获取所有文件
files, _ := ioutil.ReadDir(up.Folder)
for _, file := range files {
if file.IsDir() && file.Name() != "init" {
up.itemDatas = append(up.itemDatas, &itemData{strings.Replace(up.Folder, gopath+"/src/", "", 1) + file.Name()})
}
}
return nil
}
......@@ -63,9 +77,9 @@ func (up *UpdateInitFileTask) genInitFile() error {
}
var importStr, content string
for _, item := range up.itemDatas {
importStr += fmt.Sprintf("_ \"%s\"\r\n", item.path)
importStr += fmt.Sprintf("_ \"%s\"\n", item.path)
}
content = fmt.Sprintf("package init \r\n\r\nimport (\r\n%s)", importStr)
content = fmt.Sprintf("package init \n\nimport (\n%s)\n", importStr)
util.DeleteFile(up.initFile)
_, err := util.WriteStringToFile(up.initFile, content)
......
......@@ -85,7 +85,8 @@ type Batch interface {
Set(key, value []byte)
Delete(key []byte)
Write() error
ValueSize() int // amount of data in the batch
ValueSize() int // size of data in the batch
ValueLen() int // amount of data in the batch
Reset() // Reset resets the batch for reuse
}
......
......@@ -279,24 +279,28 @@ type GoBadgerDBBatch struct {
batch *badger.Txn
//wop *opt.WriteOptions
size int
len int
}
//NewBatch new
func (db *GoBadgerDB) NewBatch(sync bool) Batch {
batch := db.db.NewTransaction(true)
return &GoBadgerDBBatch{db, batch, 0}
return &GoBadgerDBBatch{db, batch, 0, 0}
}
//Set set
func (mBatch *GoBadgerDBBatch) Set(key, value []byte) {
mBatch.batch.Set(key, value)
mBatch.size += len(value)
mBatch.size += len(key)
mBatch.len += len(value)
}
//Delete 设置
func (mBatch *GoBadgerDBBatch) Delete(key []byte) {
mBatch.batch.Delete(key)
mBatch.size++
mBatch.size += len(key)
mBatch.len++
}
//Write 写入
......@@ -315,10 +319,16 @@ func (mBatch *GoBadgerDBBatch) ValueSize() int {
return mBatch.size
}
//ValueLen batch数量
func (mBatch *GoBadgerDBBatch) ValueLen() int {
return mBatch.len
}
//Reset 重置
func (mBatch *GoBadgerDBBatch) Reset() {
if nil != mBatch.db && nil != mBatch.db.db {
mBatch.batch = mBatch.db.db.NewTransaction(true)
}
mBatch.size = 0
mBatch.len = 0
}
......@@ -234,23 +234,27 @@ type goLevelDBBatch struct {
batch *leveldb.Batch
wop *opt.WriteOptions
size int
len int
}
//NewBatch new
func (db *GoLevelDB) NewBatch(sync bool) Batch {
batch := new(leveldb.Batch)
wop := &opt.WriteOptions{Sync: sync}
return &goLevelDBBatch{db, batch, wop, 0}
return &goLevelDBBatch{db, batch, wop, 0, 0}
}
func (mBatch *goLevelDBBatch) Set(key, value []byte) {
mBatch.batch.Put(key, value)
mBatch.size += len(key)
mBatch.size += len(value)
mBatch.len += len(value)
}
func (mBatch *goLevelDBBatch) Delete(key []byte) {
mBatch.batch.Delete(key)
mBatch.size++
mBatch.size += len(key)
mBatch.len++
}
func (mBatch *goLevelDBBatch) Write() error {
......@@ -266,7 +270,13 @@ func (mBatch *goLevelDBBatch) ValueSize() int {
return mBatch.size
}
//ValueLen batch数量
func (mBatch *goLevelDBBatch) ValueLen() int {
return mBatch.len
}
func (mBatch *goLevelDBBatch) Reset() {
mBatch.batch.Reset()
mBatch.len = 0
mBatch.size = 0
}
......@@ -253,6 +253,7 @@ type memBatch struct {
db *GoMemDB
writes []kv
size int
len int
}
//NewBatch new
......@@ -264,11 +265,14 @@ func (b *memBatch) Set(key, value []byte) {
//println("-b-", string(key)[0:4], common.ToHex(key))
b.writes = append(b.writes, kv{CopyBytes(key), CopyBytes(value)})
b.size += len(value)
b.size += len(key)
b.len += len(value)
}
func (b *memBatch) Delete(key []byte) {
b.writes = append(b.writes, kv{CopyBytes(key), CopyBytes(nil)})
b.size++
b.size += len(key)
b.len++
}
func (b *memBatch) Write() error {
......@@ -291,7 +295,13 @@ func (b *memBatch) ValueSize() int {
return b.size
}
//ValueLen batch数量
func (b *memBatch) ValueLen() int {
return b.len
}
func (b *memBatch) Reset() {
b.writes = b.writes[:0]
b.size = 0
b.len = 0
}
......@@ -456,6 +456,7 @@ type PegasusBatch struct {
table pegasus.TableConnector
batchset map[string][]byte
batchdel map[string][]byte
size int
}
//NewBatch new
......@@ -467,6 +468,8 @@ func (db *PegasusDB) NewBatch(sync bool) Batch {
func (db *PegasusBatch) Set(key, value []byte) {
db.batchset[string(key)] = value
delete(db.batchdel, string(key))
db.size += len(value)
db.size += len(key)
}
//Delete 删除
......@@ -474,6 +477,7 @@ func (db *PegasusBatch) Delete(key []byte) {
db.batchset[string(key)] = []byte("")
delete(db.batchset, string(key))
db.batchdel[string(key)] = key
db.size += len(key)
}
// 注意本方法的实现逻辑,因为ssdb没有提供删除和更新同时进行的批量操作;
......@@ -556,6 +560,11 @@ func (db *PegasusBatch) Write() error {
//ValueSize value批长度
func (db *PegasusBatch) ValueSize() int {
return db.size
}
//ValueLen batch数量
func (db *PegasusBatch) ValueLen() int {
return len(db.batchset)
}
......@@ -563,6 +572,7 @@ func (db *PegasusBatch) ValueSize() int {
func (db *PegasusBatch) Reset() {
db.batchset = make(map[string][]byte)
db.batchdel = make(map[string][]byte)
db.size = 0
}
func getHashKey(key []byte) []byte {
......
......@@ -457,6 +457,7 @@ type ssDBBatch struct {
db *GoSSDB
batchset map[string][]byte
batchdel map[string]bool
size int
}
//NewBatch new
......@@ -467,12 +468,15 @@ func (db *GoSSDB) NewBatch(sync bool) Batch {
func (db *ssDBBatch) Set(key, value []byte) {
db.batchset[string(key)] = value
delete(db.batchdel, string(key))
db.size += len(value)
db.size += len(key)
}
func (db *ssDBBatch) Delete(key []byte) {
db.batchset[string(key)] = []byte{}
delete(db.batchset, string(key))
db.batchdel[string(key)] = true
db.size += len(key)
}
// 注意本方法的实现逻辑,因为ssdb没有提供删除和更新同时进行的批量操作;
......@@ -507,10 +511,16 @@ func (db *ssDBBatch) Write() error {
}
func (db *ssDBBatch) ValueSize() int {
return db.size
}
//ValueLen batch数量
func (db *ssDBBatch) ValueLen() int {
return len(db.batchset)
}
func (db *ssDBBatch) Reset() {
db.batchset = make(map[string][]byte)
db.batchdel = make(map[string]bool)
db.size = 0
}
......@@ -22,7 +22,7 @@ type Count struct {
//NewCount 创建一个计数器
func NewCount(prefix string, name string, kvdb db.KV) *Count {
keydata := []byte(prefix + "#" + name)
keydata := []byte(prefix + sep + name)
return &Count{
prefix: prefix,
name: name,
......
......@@ -14,4 +14,5 @@ var (
ErrTooManyIndex = errors.New("ErrTooManyIndex")
ErrTablePrefixOrTableName = errors.New("ErrTablePrefixOrTableName")
ErrDupPrimaryKey = errors.New("ErrDupPrimaryKey")
ErrNilValue = errors.New("ErrNilValue")
)
This diff is collapsed.
package table
import (
"fmt"
"testing"
protodata "github.com/33cn/chain33/common/db/table/proto"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/33cn/chain33/types"
)
func TestJoin(t *testing.T) {
dir, leveldb, kvdb := getdb()
defer dbclose(dir, leveldb)
table1, err := NewTable(NewGameRow(), kvdb, optgame)
assert.Nil(t, err)
table2, err := NewTable(NewGameAddrRow(), kvdb, optgameaddr)
assert.Nil(t, err)
tablejoin, err := NewJoinTable(table2, table1, []string{"addr#status", "#status"})
assert.Nil(t, err)
assert.Equal(t, tablejoin.GetLeft(), table2) //table2
assert.Equal(t, tablejoin.GetRight(), table1) //table1
assert.Equal(t, tablejoin.MustGetTable("gameaddr"), table2) //table2
assert.Equal(t, tablejoin.MustGetTable("game"), table1) //table1
rightdata := &protodata.Game{GameID: "gameid1", Status: 1}
tablejoin.MustGetTable("game").Replace(rightdata)
leftdata := &protodata.GameAddr{GameID: "gameid1", Addr: "addr1", Txhash: "hash1"}
tablejoin.MustGetTable("gameaddr").Replace(leftdata)
kvs, err := tablejoin.Save()
assert.Nil(t, err)
assert.Equal(t, 7, len(kvs))
setKV(leveldb, kvs)
//query table
//每个表的查询,用 tablejoin.MustGetTable("gameaddr")
//join query 用 tablejoin.Query
rows, err := tablejoin.ListIndex("addr#status", JoinKey([]byte("addr1"), []byte("1")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
rows, err = tablejoin.ListIndex("#status", JoinKey(nil, []byte("1")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
rightdata = &protodata.Game{GameID: "gameid1", Status: 2}
tablejoin.MustGetTable("game").Replace(rightdata)
kvs, err = tablejoin.Save()
assert.Nil(t, err)
assert.Equal(t, 7, len(kvs))
setKV(leveldb, kvs)
rows, err = tablejoin.ListIndex("addr#status", JoinKey([]byte("addr1"), []byte("2")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
rows, err = tablejoin.ListIndex("#status", JoinKey(nil, []byte("2")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
rightdata = &protodata.Game{GameID: "gameid1", Status: 2}
tablejoin.MustGetTable("game").Replace(rightdata)
kvs, err = tablejoin.Save()
assert.Nil(t, err)
assert.Equal(t, 0, len(kvs))
leftdata = &protodata.GameAddr{GameID: "gameid1", Addr: "addr2", Txhash: "hash1"}
tablejoin.MustGetTable("gameaddr").Replace(leftdata)
kvs, err = tablejoin.Save()
assert.Nil(t, err)
assert.Equal(t, 5, len(kvs))
setKV(leveldb, kvs)
//改回到全部是1的情况
rightdata = &protodata.Game{GameID: "gameid1", Status: 1}
tablejoin.MustGetTable("game").Replace(rightdata)
leftdata = &protodata.GameAddr{GameID: "gameid1", Addr: "addr1", Txhash: "hash1"}
tablejoin.MustGetTable("gameaddr").Replace(leftdata)
kvs, err = tablejoin.Save()
assert.Nil(t, err)
assert.Equal(t, 10, len(kvs))
setKV(leveldb, kvs)
rows, err = tablejoin.ListIndex("addr#status", JoinKey([]byte("addr1"), []byte("1")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
rows, err = tablejoin.ListIndex("#status", JoinKey(nil, []byte("1")), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Left, leftdata))
assert.Equal(t, true, proto.Equal(rows[0].Data.(*JoinData).Right, rightdata))
}
/*
table game
data: Game
index: addr,status,index,type
*/
var optgame = &Option{
Prefix: "LODB",
Name: "game",
Primary: "gameID",
Index: []string{"status"},
}
//GameRow table meta 结构
type GameRow struct {
*protodata.Game
}
//NewGameRow 新建一个meta 结构
func NewGameRow() *GameRow {
return &GameRow{Game: &protodata.Game{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func (tx *GameRow) CreateRow() *Row {
return &Row{Data: &protodata.Game{}}
}
//SetPayload 设置数据
func (tx *GameRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*protodata.Game); ok {
tx.Game = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (tx *GameRow) Get(key string) ([]byte, error) {
if key == "gameID" {
return []byte(tx.GameID), nil
} else if key == "status" {
return []byte(fmt.Sprint(tx.Status)), nil
}
return nil, types.ErrNotFound
}
/*
table struct
data: GameAddr
index: addr,status,index,type
*/
var optgameaddr = &Option{
Prefix: "LODB",
Name: "gameaddr",
Primary: "txhash",
Index: []string{"gameID", "addr"},
}
//GameAddrRow table meta 结构
type GameAddrRow struct {
*protodata.GameAddr
}
//NewGameAddrRow 新建一个meta 结构
func NewGameAddrRow() *GameAddrRow {
return &GameAddrRow{GameAddr: &protodata.GameAddr{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存eventid)
func (tx *GameAddrRow) CreateRow() *Row {
return &Row{Data: &protodata.GameAddr{}}
}
//SetPayload 设置数据
func (tx *GameAddrRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*protodata.GameAddr); ok {
tx.GameAddr = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (tx *GameAddrRow) Get(key string) ([]byte, error) {
if key == "gameID" {
return []byte(tx.GameID), nil
} else if key == "addr" {
return []byte(tx.Addr), nil
} else if key == "txhash" {
return []byte(tx.Txhash), nil
}
return nil, types.ErrNotFound
}
#!/bin/sh
protoc --go_out=plugins=grpc:. ./*.proto --proto_path=.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: game.proto
package proto
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Game struct {
GameID string `protobuf:"bytes,1,opt,name=gameID,proto3" json:"gameID,omitempty"`
Status int64 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Game) Reset() { *m = Game{} }
func (m *Game) String() string { return proto.CompactTextString(m) }
func (*Game) ProtoMessage() {}
func (*Game) Descriptor() ([]byte, []int) {
return fileDescriptor_game_c30dd93766b91ef0, []int{0}
}
func (m *Game) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Game.Unmarshal(m, b)
}
func (m *Game) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Game.Marshal(b, m, deterministic)
}
func (dst *Game) XXX_Merge(src proto.Message) {
xxx_messageInfo_Game.Merge(dst, src)
}
func (m *Game) XXX_Size() int {
return xxx_messageInfo_Game.Size(m)
}
func (m *Game) XXX_DiscardUnknown() {
xxx_messageInfo_Game.DiscardUnknown(m)
}
var xxx_messageInfo_Game proto.InternalMessageInfo
func (m *Game) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *Game) GetStatus() int64 {
if m != nil {
return m.Status
}
return 0
}
type GameAddr struct {
Txhash string `protobuf:"bytes,1,opt,name=txhash,proto3" json:"txhash,omitempty"`
GameID string `protobuf:"bytes,2,opt,name=gameID,proto3" json:"gameID,omitempty"`
Addr string `protobuf:"bytes,3,opt,name=addr,proto3" json:"addr,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GameAddr) Reset() { *m = GameAddr{} }
func (m *GameAddr) String() string { return proto.CompactTextString(m) }
func (*GameAddr) ProtoMessage() {}
func (*GameAddr) Descriptor() ([]byte, []int) {
return fileDescriptor_game_c30dd93766b91ef0, []int{1}
}
func (m *GameAddr) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GameAddr.Unmarshal(m, b)
}
func (m *GameAddr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GameAddr.Marshal(b, m, deterministic)
}
func (dst *GameAddr) XXX_Merge(src proto.Message) {
xxx_messageInfo_GameAddr.Merge(dst, src)
}
func (m *GameAddr) XXX_Size() int {
return xxx_messageInfo_GameAddr.Size(m)
}
func (m *GameAddr) XXX_DiscardUnknown() {
xxx_messageInfo_GameAddr.DiscardUnknown(m)
}
var xxx_messageInfo_GameAddr proto.InternalMessageInfo
func (m *GameAddr) GetTxhash() string {
if m != nil {
return m.Txhash
}
return ""
}
func (m *GameAddr) GetGameID() string {
if m != nil {
return m.GameID
}
return ""
}
func (m *GameAddr) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
func init() {
proto.RegisterType((*Game)(nil), "proto.Game")
proto.RegisterType((*GameAddr)(nil), "proto.GameAddr")
}
func init() { proto.RegisterFile("game.proto", fileDescriptor_game_c30dd93766b91ef0) }
var fileDescriptor_game_c30dd93766b91ef0 = []byte{
// 131 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4a, 0x4f, 0xcc, 0x4d,
0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0x66, 0x5c, 0x2c, 0xee, 0x89,
0xb9, 0xa9, 0x42, 0x62, 0x5c, 0x6c, 0x20, 0x49, 0x4f, 0x17, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce,
0x20, 0x28, 0x0f, 0x24, 0x5e, 0x5c, 0x92, 0x58, 0x52, 0x5a, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1,
0x1c, 0x04, 0xe5, 0x29, 0xf9, 0x71, 0x71, 0x80, 0xf4, 0x39, 0xa6, 0xa4, 0x14, 0x81, 0xd4, 0x94,
0x54, 0x64, 0x24, 0x16, 0x67, 0xc0, 0xf4, 0x42, 0x78, 0x48, 0x66, 0x32, 0xa1, 0x98, 0x29, 0xc4,
0xc5, 0x92, 0x98, 0x92, 0x52, 0x24, 0xc1, 0x0c, 0x16, 0x05, 0xb3, 0x9d, 0xd8, 0xa3, 0x20, 0x0e,
0x4a, 0x62, 0x03, 0x53, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x93, 0x12, 0xbb, 0xac,
0x00, 0x00, 0x00,
}
syntax = "proto3";
package proto;
option go_package = "proto";
message Game {
string gameID = 1;
int64 status = 2;
}
message GameAddr {
string txhash = 1;
string gameID = 2;
string addr = 3;
}
\ No newline at end of file
......@@ -9,12 +9,53 @@ import (
"github.com/33cn/chain33/types"
)
type tabler interface {
getMeta() RowMeta
getOpt() *Option
indexPrefix(string) []byte
GetData([]byte) (*Row, error)
index(*Row, string) ([]byte, error)
getIndexKey(string, []byte, []byte) []byte
primaryPrefix() []byte
getRow(value []byte) (*Row, error)
}
//Query 列表查询结构
type Query struct {
table *Table
table tabler
kvdb db.KVDB
}
//List 通过某个数据,查询
func (query *Query) List(indexName string, data types.Message, primaryKey []byte, count, direction int32) (rows []*Row, err error) {
var prefix []byte
if data != nil {
query.table.getMeta().SetPayload(data)
querykey := indexName
if isPrimaryIndex(indexName) {
querykey = query.table.getOpt().Primary
}
prefix, err = query.table.getMeta().Get(querykey)
if err != nil {
return nil, err
}
}
return query.ListIndex(indexName, prefix, primaryKey, count, direction)
}
//ListOne 通过某个数据,查询一行
func (query *Query) ListOne(indexName string, data types.Message, primaryKey []byte) (row *Row, err error) {
rows, err := query.List(indexName, data, primaryKey, 1, db.ListDESC)
if err != nil {
return nil, err
}
return rows[0], nil
}
func isPrimaryIndex(indexName string) bool {
return indexName == "" || indexName == "auto" || indexName == "primary"
}
//ListIndex 根据索引查询列表
//index 用哪个index
//prefix 必须要符合的前缀, 可以为空
......@@ -22,8 +63,8 @@ type Query struct {
//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)
if isPrimaryIndex(indexName) || indexName == query.table.getOpt().Primary {
return query.listPrimary(prefix, primaryKey, count, direction)
}
p := query.table.indexPrefix(indexName)
var k []byte
......@@ -60,11 +101,14 @@ func (query *Query) ListIndex(indexName string, prefix []byte, primaryKey []byte
}
rows = append(rows, row)
}
if len(rows) == 0 {
return nil, types.ErrNotFound
}
return rows, nil
}
//ListPrimary list primary data
func (query *Query) ListPrimary(prefix []byte, primaryKey []byte, count, direction int32) (rows []*Row, err error) {
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 {
......@@ -90,6 +134,9 @@ func (query *Query) ListPrimary(prefix []byte, primaryKey []byte, count, directi
}
rows = append(rows, row)
}
if len(rows) == 0 {
return nil, types.ErrNotFound
}
return rows, nil
}
......
......@@ -115,20 +115,43 @@ func TestTransactinList(t *testing.T) {
} else {
assert.Equal(t, true, proto.Equal(tx3, rows[0].Data))
}
//List data
rows, err = query.List("From", tx3, 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)
rows, err = query.ListIndex("primary", nil, nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 4, len(rows))
//ListPrimary all
rows, err = query.List("primary", nil, nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 4, len(rows))
row, err := query.ListOne("primary", nil, nil)
assert.Nil(t, err)
assert.Equal(t, row, rows[0])
primary = rows[0].Primary
rows, err = query.ListPrimary(primary[0:10], nil, 0, 0)
rows, err = query.ListIndex("auto", primary, nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
rows, err = query.List("", rows[0].Data, nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
rows, err = query.ListPrimary(nil, primary, 0, 0)
rows, err = query.ListIndex("", nil, primary, 0, 0)
assert.Nil(t, err)
assert.Equal(t, 3, len(rows))
}
......@@ -207,16 +230,16 @@ func TestTransactinListAuto(t *testing.T) {
assert.Equal(t, types.ErrNotFound, err)
assert.Equal(t, 0, len(rows))
//ListPrimary all
rows, err = query.ListPrimary(nil, nil, 0, db.ListASC)
rows, err = query.ListIndex("", 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)
rows, err = query.ListIndex("", primary, nil, 0, db.ListASC)
assert.Nil(t, err)
assert.Equal(t, 1, len(rows))
rows, err = query.ListPrimary(nil, primary, 0, db.ListASC)
rows, err = query.ListIndex("", nil, primary, 0, db.ListASC)
assert.Nil(t, err)
assert.Equal(t, 3, len(rows))
}
......@@ -235,6 +258,7 @@ func mergeDup(kvs []*types.KeyValue) (kvset []*types.KeyValue) {
}
func setKV(kvdb db.DB, kvs []*types.KeyValue) {
//printKV(kvs)
batch := kvdb.NewBatch(true)
for i := 0; i < len(kvs); i++ {
if kvs[i].Value == nil {
......@@ -251,7 +275,7 @@ func setKV(kvdb db.DB, kvs []*types.KeyValue) {
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))
fmt.Printf("KV %d %s(%s)\n", i, string(kvs[i].Key), common.ToHex(kvs[i].Value))
}
}
......@@ -301,7 +325,7 @@ func TestDel(t *testing.T) {
//save 然后从列表中读取
kvs, err := table.Save()
assert.Nil(t, err)
assert.Equal(t, len(kvs), 9)
assert.Equal(t, len(kvs), 6)
//save to database
setKV(leveldb, kvs)
//printKV(kvs)
......@@ -343,7 +367,7 @@ func TestUpdate(t *testing.T) {
assert.Nil(t, err)
kvs, err := table.Save()
assert.Nil(t, err)
assert.Equal(t, len(kvs), 9)
assert.Equal(t, len(kvs), 3)
//save to database
setKV(leveldb, kvs)
query := table.GetQuery(kvdb)
......@@ -372,22 +396,23 @@ func TestReplace(t *testing.T) {
assert.Equal(t, err, ErrDupPrimaryKey)
//不改变hash,改变签名
tx1.Signature = nil
err = table.Replace(tx1)
tx2 := *tx1
tx2.Signature = nil
err = table.Replace(&tx2)
assert.Nil(t, err)
//save 然后从列表中读取
kvs, err := table.Save()
assert.Nil(t, err)
assert.Equal(t, len(kvs), 9)
assert.Equal(t, 3, len(kvs))
//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)
rows, err := query.ListIndex("From", []byte(tx2.From()), nil, 0, 0)
assert.Nil(t, err)
assert.Equal(t, rows[0].Data.(*types.Transaction).From(), tx1.From())
assert.Equal(t, rows[0].Data.(*types.Transaction).From(), tx2.From())
}
type TransactionRow struct {
......
......@@ -7,6 +7,8 @@ package executor
import (
"bytes"
"github.com/pkg/errors"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
)
......@@ -61,37 +63,46 @@ func isAllowKeyWrite(key, realExecer []byte, tx *types.Transaction, height int64
}
func isAllowLocalKey(execer []byte, key []byte) error {
if err := isAllowLocalKey2(execer, key); err != nil {
err := isAllowLocalKey2(execer, key)
if err != nil {
realexec := types.GetRealExecName(execer)
if bytes.Equal(realexec, execer) {
return err
if !bytes.Equal(realexec, execer) {
err2 := isAllowLocalKey2(realexec, key)
err = errors.Wrapf(err2, "1st check err: %s. 2nd check err", err.Error())
}
if err != nil {
elog.Error("isAllowLocalKey failed", "err", err.Error())
return errors.Cause(err)
}
return isAllowLocalKey2(realexec, key)
}
return nil
}
func isAllowLocalKey2(execer []byte, key []byte) error {
if len(execer) < 1 {
return types.ErrLocalPrefix
return errors.Wrap(types.ErrLocalPrefix, "execer empty")
}
minkeylen := len(types.LocalPrefix) + len(execer) + 2
if len(key) <= minkeylen {
elog.Error("isAllowLocalKey too short", "key", string(key), "exec", string(execer))
return types.ErrLocalKeyLen
err := errors.Wrapf(types.ErrLocalKeyLen, "isAllowLocalKey too short. key=%s exec=%s", string(key), string(execer))
return err
}
if key[minkeylen-1] != '-' {
elog.Error("isAllowLocalKey prefix last char is not '-'", "key", string(key), "exec", string(execer),
"minkeylen", minkeylen)
return types.ErrLocalPrefix
err := errors.Wrapf(types.ErrLocalPrefix,
"isAllowLocalKey prefix last char is not '-'. key=%s exec=%s minkeylen=%d title=%s",
string(key), string(execer), minkeylen, types.GetTitle())
return err
}
if !bytes.HasPrefix(key, types.LocalPrefix) {
elog.Error("isAllowLocalKey common prefix not match", "key", string(key), "exec", string(execer))
return types.ErrLocalPrefix
err := errors.Wrapf(types.ErrLocalPrefix, "isAllowLocalKey common prefix not match. key=%s exec=%s",
string(key), string(execer))
return err
}
if !bytes.HasPrefix(key[len(types.LocalPrefix)+1:], execer) {
elog.Error("isAllowLocalKey key prefix not match", "key", string(key), "exec", string(execer))
return types.ErrLocalPrefix
err := errors.Wrapf(types.ErrLocalPrefix, "isAllowLocalKey key prefix not match. key=%s exec=%s",
string(key), string(execer))
return err
}
return nil
}
......@@ -134,6 +134,8 @@ func TestKeyLocalAllow(t *testing.T) {
assert.Equal(t, err, types.ErrLocalPrefix)
err = isAllowLocalKey([]byte("user.p.para.paracross"), []byte("LODB-user.p.para.paracross-xxxx"))
assert.Nil(t, err)
err = isAllowLocalKey([]byte("user.p.para.user.wasm.abc"), []byte("LODB-user.p.para.user.wasm.abc-xxxx"))
assert.Nil(t, err)
err = isAllowLocalKey([]byte("user.p.para.paracross"), []byte("LODB-paracross-xxxx"))
assert.Nil(t, err)
}
......@@ -53,6 +53,36 @@ func (c *channelClient) CreateRawTransaction(param *types.CreateTx) ([]byte, err
return types.CallCreateTx(execer, "", param)
}
func (c *channelClient) ReWriteRawTx(param *types.ReWriteRawTx) ([]byte, error) {
if param == nil || param.Tx == "" {
log.Error("ReWriteRawTx", "Error", types.ErrInvalidParam)
return nil, types.ErrInvalidParam
}
tx, err := decodeTx(param.Tx)
if err != nil {
return nil, err
}
if param.Execer != nil {
tx.Execer = param.Execer
}
if param.To != "" {
tx.To = param.To
}
if param.Fee != 0 {
tx.Fee = param.Fee
}
if param.Expire != "" {
expire, err := types.ParseExpire(param.Expire)
if err != nil {
return nil, err
}
tx.Expire = expire
}
return types.FormatTxEncode(string(tx.Execer), tx)
}
// CreateRawTxGroup create rawtransaction for group
func (c *channelClient) CreateRawTxGroup(param *types.CreateTransactionGroup) ([]byte, error) {
if param == nil || len(param.Txs) <= 1 {
......
......@@ -36,6 +36,15 @@ func (g *Grpc) CreateRawTransaction(ctx context.Context, in *pb.CreateTx) (*pb.U
return &pb.UnsignTx{Data: reply}, nil
}
// ReWriteRawTx re-write raw tx parameters of grpc
func (g *Grpc) ReWriteRawTx(ctx context.Context, in *pb.ReWriteRawTx) (*pb.UnsignTx, error) {
reply, err := g.cli.ReWriteRawTx(in)
if err != nil {
return nil, err
}
return &pb.UnsignTx{Data: reply}, nil
}
// CreateTransaction create transaction of grpc
func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.UnsignTx, error) {
execer := pb.ExecName(string(in.Execer))
......
......@@ -1046,3 +1046,28 @@ func TestQueryTransaction(t *testing.T) {
//func Test_CreateTxGroup(t *testing.T) {
// testCreateTxGroupOk(t)
//}
func TestReWriteRawTx(t *testing.T) {
txHex1 := "0a05636f696e73122c18010a281080c2d72f222131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b7120a08d0630a696c0b3f78dd9ec083a2131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b71"
in := &types.ReWriteRawTx{
Tx: txHex1,
Execer: []byte("paracross"),
Fee: 29977777777,
Expire: "130s",
To: "aabbccdd",
}
data, err := g.ReWriteRawTx(getOkCtx(), in)
assert.Nil(t, err)
assert.NotNil(t, data.Data)
rtTx := hex.EncodeToString(data.Data)
assert.NotEqual(t, txHex1, rtTx)
tx := &types.Transaction{}
err = types.Decode(data.Data, tx)
assert.Nil(t, err)
assert.Equal(t, tx.Execer, []byte(in.Execer))
assert.Equal(t, tx.Fee, in.Fee)
assert.Equal(t, int64(130000000000), tx.Expire)
assert.Equal(t, in.To, tx.To)
}
......@@ -44,6 +44,24 @@ func (c *Chain33) CreateRawTransaction(in *rpctypes.CreateTx, result *interface{
return nil
}
// ReWriteRawTx re-write raw tx by jrpc
func (c *Chain33) ReWriteRawTx(in *rpctypes.ReWriteRawTx, result *interface{}) error {
inpb := &types.ReWriteRawTx{
Tx: in.Tx,
Execer: []byte(in.Execer),
To: in.To,
Fee: in.Fee,
Expire: in.Expire,
}
reply, err := c.cli.ReWriteRawTx(inpb)
if err != nil {
return err
}
*result = hex.EncodeToString(reply)
return nil
}
// CreateRawTxGroup create rawtransaction with group
func (c *Chain33) CreateRawTxGroup(in *types.CreateTransactionGroup, result *interface{}) error {
reply, err := c.cli.CreateRawTxGroup(in)
......
......@@ -403,6 +403,36 @@ func TestChain33_CreateRawTransaction(t *testing.T) {
assert.Nil(t, err)
}
func TestChain33_ReWriteRawTx(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
txHex1 := "0a05636f696e73122c18010a281080c2d72f222131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b7120a08d0630a696c0b3f78dd9ec083a2131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b71"
//txHex2 := "0a05636f696e73122d18010a29108084af5f222231484c53426e7437486e486a7857797a636a6f573863663259745550663337594d6320a08d0630dbc4cbf6fbc4e1d0533a2231484c53426e7437486e486a7857797a636a6f573863663259745550663337594d63"
reTx := &rpctypes.ReWriteRawTx{
Tx: txHex1,
Execer: "paracross",
Fee: 29977777777,
Expire: "130s",
To: "aabbccdd",
}
var testResult interface{}
err := testChain33.ReWriteRawTx(reTx, &testResult)
assert.Nil(t, err)
assert.NotNil(t, testResult)
assert.NotEqual(t, txHex1, testResult)
txData, err := hex.DecodeString(testResult.(string))
assert.Nil(t, err)
tx := &types.Transaction{}
err = types.Decode(txData, tx)
assert.Nil(t, err)
assert.Equal(t, tx.Execer, []byte(reTx.Execer))
assert.Equal(t, tx.Fee, reTx.Fee)
assert.Equal(t, int64(130000000000), tx.Expire)
assert.Equal(t, reTx.To, tx.To)
}
func TestChain33_CreateTxGroup(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
......
......@@ -373,3 +373,12 @@ type CreateTx struct {
ExecName string `json:"execName,omitempty"` //TransferToExec and Withdraw 的执行器
Execer string `json:"execer,omitempty"` //执行器名称
}
// ReWriteRawTx parameter
type ReWriteRawTx struct {
Tx string `json:"tx"`
Execer string `json:"execer"`
To string `json:"to"`
Fee int64 `json:"fee"`
Expire string `json:"expire"`
}
......@@ -35,6 +35,7 @@ func TxCmd() *cobra.Command {
GetRawTxCmd(),
DecodeTxCmd(),
GetAddrOverviewCmd(),
ReWriteRawTxCmd(),
)
return cmd
......@@ -303,3 +304,50 @@ func parseAddrOverview(view interface{}) (interface{}, error) {
}
return addrOverview, nil
}
// ReWriteRawTxCmd re-write raw transaction hex
func ReWriteRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "rewrite",
Short: "rewrite transaction parameters",
Run: reWriteRawTx,
}
addReWriteRawTxFlags(cmd)
return cmd
}
func addReWriteRawTxFlags(cmd *cobra.Command) {
cmd.Flags().StringP("tx", "s", "", "transaction hex")
cmd.MarkFlagRequired("tx")
cmd.Flags().StringP("execer", "x", "", "transaction execer (optional)")
cmd.Flags().StringP("to", "t", "", "to addr (optional)")
cmd.Flags().Float64P("fee", "f", 0, "transaction fee (optional)")
cmd.Flags().StringP("expire", "e", "120s", "expire time (optional)")
}
func reWriteRawTx(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
txHash, _ := cmd.Flags().GetString("tx")
execer, _ := cmd.Flags().GetString("execer")
to, _ := cmd.Flags().GetString("to")
fee, _ := cmd.Flags().GetFloat64("fee")
expire, _ := cmd.Flags().GetString("expire")
expire, err := commandtypes.CheckExpireOpt(expire)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
feeInt64 := int64(fee * 1e4)
params := rpctypes.ReWriteRawTx{
Tx: txHash,
Execer: execer,
To: to,
Fee: feeInt64 * 1e4,
Expire: expire,
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.ReWriteRawTx", params, nil)
ctx.RunWithoutMarshal()
}
// 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 types
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCheckExpireOpt(t *testing.T) {
expire := "0s"
str, err := CheckExpireOpt(expire)
assert.NoError(t, err)
assert.Equal(t, "0s", str)
expire = "14s"
str, err = CheckExpireOpt(expire)
assert.NoError(t, err)
assert.Equal(t, "120s", str)
expire = "14"
str, err = CheckExpireOpt(expire)
assert.NoError(t, err)
assert.Equal(t, "14", str)
expire = "H:123"
str, err = CheckExpireOpt(expire)
assert.NoError(t, err)
assert.Equal(t, "H:123", str)
}
......@@ -20,7 +20,10 @@ import (
// TODO: 暂时将插件中的类型引用起来,后续需要修改
"encoding/hex"
"errors"
"fmt"
"math"
"time"
)
// DecodeTransaction decode transaction function
......@@ -156,3 +159,56 @@ func getRealExecName(paraName string, name string) string {
}
return paraName + name
}
func parseTxHeight(expire string) error {
if len(expire) == 0 {
return errors.New("expire string should not be empty")
}
if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.Atoi(expire[2:])
if err != nil {
return err
}
if txHeight <= 0 {
//fmt.Printf("txHeight should be grate to 0")
return errors.New("txHeight should be grate to 0")
}
return nil
}
return errors.New("Invalid expire format. Should be one of {time:\"3600s/1min/1h\" block:\"123\" txHeight:\"H:123\"}")
}
// CheckExpireOpt parse expire option in command
func CheckExpireOpt(expire string) (string, error) {
//时间格式123s/1m/1h
expireTime, err := time.ParseDuration(expire)
if err == nil {
if expireTime < time.Minute*2 && expireTime != time.Second*0 {
expire = "120s"
fmt.Println("expire time must longer than 2 minutes, changed expire time into 2 minutes")
}
return expire, nil
}
//区块高度格式,123
blockInt, err := strconv.Atoi(expire)
if err == nil {
if blockInt <= 0 {
fmt.Printf("block height should be grate to 0")
return "", errors.New("block height should be grate to 0")
}
return expire, nil
}
//Txheight格式,H:123
err = parseTxHeight(expire)
if err != nil {
return "", err
}
return expire, err
}
......@@ -10,8 +10,6 @@ import (
"strconv"
"time"
"errors"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
commandtypes "github.com/33cn/chain33/system/dapp/commands/types"
......@@ -311,6 +309,10 @@ func addSignRawTxFlags(cmd *cobra.Command) {
cmd.Flags().StringP("key", "k", "", "private key (optional)")
cmd.Flags().StringP("addr", "a", "", "account address (optional)")
cmd.Flags().StringP("expire", "e", "120s", "transaction expire time")
cmd.Flags().Float64P("fee", "f", 0, "transaction fee (optional)")
cmd.Flags().StringP("execer", "x", "", "new transaction execer (optional)")
cmd.Flags().StringP("to", "t", "", "new to addr (optional)")
// A duration string is a possibly signed sequence of
// decimal numbers, each with optional fraction and a unit suffix,
// such as "300ms", "-1.5h" or "2h45m".
......@@ -342,77 +344,31 @@ func noBalanceTx(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal()
}
func parseTxHeight(expire string) error {
if len(expire) == 0 {
return errors.New("expire string should not be empty")
}
if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.Atoi(expire[2:])
if err != nil {
return err
}
if txHeight <= 0 {
//fmt.Printf("txHeight should be grate to 0")
return errors.New("txHeight should be grate to 0")
}
return nil
}
return errors.New("Invalid expire format. Should be one of {time:\"3600s/1min/1h\" block:\"123\" txHeight:\"H:123\"}")
}
func parseExpireOpt(expire string) (string, error) {
//时间格式123s/1m/1h
expireTime, err := time.ParseDuration(expire)
if err == nil {
if expireTime < time.Minute*2 && expireTime != time.Second*0 {
expire = "120s"
fmt.Println("expire time must longer than 2 minutes, changed expire time into 2 minutes")
}
return expire, nil
}
//区块高度格式,123
blockInt, err := strconv.Atoi(expire)
if err == nil {
if blockInt <= 0 {
fmt.Printf("block height should be grate to 0")
return "", errors.New("block height should be grate to 0")
}
return expire, nil
}
//Txheight格式,H:123
err = parseTxHeight(expire)
if err != nil {
return "", err
}
return expire, err
}
func signRawTx(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
data, _ := cmd.Flags().GetString("data")
key, _ := cmd.Flags().GetString("key")
addr, _ := cmd.Flags().GetString("addr")
index, _ := cmd.Flags().GetInt32("index")
execer, _ := cmd.Flags().GetString("execer")
to, _ := cmd.Flags().GetString("to")
fee, _ := cmd.Flags().GetFloat64("fee")
expire, _ := cmd.Flags().GetString("expire")
expire, err := parseExpireOpt(expire)
expire, err := commandtypes.CheckExpireOpt(expire)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
feeInt64 := int64(fee * 1e4)
params := types.ReqSignRawTx{
Addr: addr,
Privkey: key,
TxHex: data,
Expire: expire,
Index: index,
Fee: feeInt64 * 1e4,
NewExecer: []byte(execer),
NewToAddr: to,
}
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.SignRawTx", params, nil)
ctx.RunWithoutMarshal()
......
......@@ -22,7 +22,7 @@ type Node struct {
leftNode *Node
rightHash []byte
rightNode *Node
parentHash []byte
parentNode *Node
persisted bool
}
......@@ -53,7 +53,6 @@ func MakeNode(buf []byte, t *Tree) (node *Node, err error) {
node.height = storeNode.Height
node.size = storeNode.Size
node.key = storeNode.Key
node.parentHash = storeNode.ParentHash
//leaf(叶子节点保存数据)
if node.height == 0 {
......@@ -78,7 +77,7 @@ func (node *Node) _copy() *Node {
leftNode: node.leftNode,
rightHash: node.rightHash,
rightNode: node.rightNode,
parentHash: node.parentHash,
parentNode: node.parentNode,
persisted: false, // Going to be mutated, so it can't already be persisted.
}
}
......@@ -185,12 +184,12 @@ func (node *Node) Hash(t *Tree) []byte {
}
if enablePrune {
//加入parentHash、brotherHash
if node.leftNode != nil && node.leftNode.height != t.root.height { //只对倒数第二层做裁剪
node.leftNode.parentHash = node.hash
//加入parentNode
if node.leftNode != nil && node.leftNode.height != t.root.height {
node.leftNode.parentNode = node
}
if node.rightNode != nil && node.rightNode.height != t.root.height {
node.rightNode.parentHash = node.hash
node.rightNode.parentNode = node
}
}
}
......@@ -235,7 +234,6 @@ func (node *Node) storeNode(t *Tree) []byte {
storeNode.Value = nil
storeNode.LeftHash = nil
storeNode.RightHash = nil
storeNode.ParentHash = nil
//leafnode
if node.height == 0 {
......@@ -255,9 +253,6 @@ func (node *Node) storeNode(t *Tree) []byte {
}
storeNode.RightHash = node.rightHash
}
if enablePrune {
storeNode.ParentHash = node.parentHash
}
storeNodebytes, err := proto.Marshal(&storeNode)
if err != nil {
panic(err)
......
......@@ -317,6 +317,23 @@ func (ndb *nodeDB) GetBatch(sync bool) *nodeBatch {
return &nodeBatch{ndb.db.NewBatch(sync)}
}
// 获取叶子节点的所有父节点
func getHashNode(node *Node) (hashs [][]byte) {
for {
if node == nil {
return
}
parN := node.parentNode
if parN != nil {
hashs = append(hashs, parN.hash)
node = parN
} else {
break
}
}
return hashs
}
// SaveNode 保存节点
func (ndb *nodeDB) SaveNode(t *Tree, node *Node) {
ndb.mtx.Lock()
......@@ -333,10 +350,9 @@ func (ndb *nodeDB) SaveNode(t *Tree, node *Node) {
ndb.batch.Set(node.hash, storenode)
if enablePrune && node.height == 0 {
//save leafnode key&hash
k := genLeafCountKey(node.key, node.hash, t.blockHeight)
k := genLeafCountKey(node.key, node.hash, t.blockHeight, len(node.hash))
data := &types.PruneData{
Height: t.blockHeight,
Lenth: int32(len(node.hash)),
Hashs: getHashNode(node),
}
v, err := proto.Marshal(data)
if err != nil {
......
......@@ -634,6 +634,7 @@ type ReqRandHash struct {
ExecName string `protobuf:"bytes,1,opt,name=execName,proto3" json:"execName,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
BlockNum int64 `protobuf:"varint,3,opt,name=blockNum,proto3" json:"blockNum,omitempty"`
Hash []byte `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -685,6 +686,13 @@ func (m *ReqRandHash) GetBlockNum() int64 {
return 0
}
func (m *ReqRandHash) GetHash() []byte {
if m != nil {
return m.Hash
}
return nil
}
//*
//当前软件版本信息
type VersionInfo struct {
......@@ -773,33 +781,33 @@ func init() {
func init() { proto.RegisterFile("common.proto", fileDescriptor_555bd8c177793206) }
var fileDescriptor_555bd8c177793206 = []byte{
// 441 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x53, 0x5d, 0x6b, 0xdb, 0x30,
0x14, 0x25, 0x71, 0x93, 0xc6, 0xb7, 0x7e, 0x18, 0x66, 0x0c, 0xd3, 0xb5, 0x34, 0xd3, 0x36, 0xc8,
0xcb, 0x1a, 0x98, 0xc7, 0x7e, 0xc0, 0xd8, 0xc3, 0x42, 0x21, 0x03, 0xb5, 0x94, 0x31, 0xd8, 0x83,
0xe2, 0xca, 0xb1, 0x88, 0x2c, 0x39, 0x91, 0x3c, 0xea, 0x7f, 0x3f, 0xee, 0xb5, 0x92, 0x65, 0x94,
0x6d, 0x6f, 0xf7, 0xe8, 0xdc, 0x8f, 0x73, 0x8e, 0x31, 0x24, 0x85, 0xad, 0x6b, 0x6b, 0xae, 0x9b,
0x9d, 0xf5, 0x36, 0x1d, 0xf9, 0xae, 0x91, 0x8e, 0xbd, 0x83, 0x11, 0x97, 0x8d, 0xee, 0xd2, 0x14,
0x4e, 0x94, 0xfb, 0xba, 0xc9, 0x06, 0xd3, 0xc1, 0x6c, 0xc2, 0xa9, 0x4e, 0x9f, 0x41, 0x54, 0xbb,
0x75, 0x36, 0x9c, 0x0e, 0x66, 0x09, 0xc7, 0x92, 0x5d, 0x41, 0xcc, 0xe5, 0xf6, 0xd6, 0xef, 0x94,
0x59, 0xe3, 0xc8, 0x83, 0xf0, 0x82, 0x46, 0x62, 0x4e, 0x35, 0x7b, 0x05, 0x67, 0xb4, 0xef, 0x1f,
0x2d, 0x6f, 0x20, 0x39, 0x6a, 0x71, 0xe9, 0x73, 0x18, 0xe1, 0xbb, 0xcb, 0x06, 0xd3, 0x68, 0x16,
0xf3, 0x1e, 0xb0, 0x29, 0x8c, 0xb9, 0xdc, 0x2e, 0x8c, 0x4f, 0x5f, 0xc0, 0xb8, 0x92, 0x6a, 0x5d,
0x79, 0xda, 0x12, 0xf1, 0x80, 0xd8, 0x4b, 0x18, 0x2d, 0x8c, 0xff, 0xf8, 0xe1, 0x8f, 0x23, 0x51,
0x38, 0x72, 0x09, 0xa7, 0x5c, 0x6e, 0xbf, 0x08, 0x57, 0x21, 0x5d, 0x09, 0x57, 0x11, 0x9d, 0x70,
0xaa, 0x7b, 0x1f, 0x8d, 0xee, 0xfe, 0xda, 0x30, 0xa1, 0xf3, 0x4b, 0xa5, 0xd9, 0x6b, 0xb2, 0x8c,
0x8d, 0xd2, 0x91, 0x16, 0xaa, 0x48, 0x6c, 0xc2, 0x03, 0x62, 0x6f, 0x83, 0xed, 0xff, 0xb4, 0xbd,
0x87, 0xc9, 0x8d, 0xec, 0xee, 0x85, 0x6e, 0x25, 0x86, 0xbb, 0x91, 0x5d, 0x38, 0x8a, 0x25, 0x06,
0xf1, 0x13, 0xa9, 0x10, 0x78, 0x0f, 0xd8, 0x05, 0x8c, 0xef, 0x1e, 0x9f, 0xe8, 0x8c, 0x83, 0xce,
0x6f, 0x00, 0x77, 0xaa, 0x96, 0xb7, 0x5e, 0xf8, 0xd6, 0xa5, 0x19, 0x9c, 0x1a, 0xdf, 0xe0, 0x43,
0x68, 0xda, 0xc3, 0xf4, 0x02, 0x62, 0x6d, 0x0b, 0xa1, 0x89, 0x1b, 0x12, 0xf7, 0xfb, 0x81, 0x12,
0x54, 0x65, 0x99, 0x45, 0x21, 0x41, 0x55, 0x96, 0xec, 0x9c, 0x12, 0xb8, 0x91, 0xdd, 0x53, 0xa5,
0xec, 0x07, 0xda, 0xdd, 0x72, 0x61, 0x1e, 0x48, 0xd8, 0x39, 0x4c, 0xe4, 0xa3, 0x2c, 0x96, 0xe2,
0x70, 0xf7, 0x80, 0x8f, 0xbe, 0xde, 0xf0, 0xf8, 0xeb, 0xe1, 0xcc, 0x4a, 0xdb, 0x62, 0xb3, 0x6c,
0xeb, 0x70, 0xf6, 0x80, 0x99, 0x82, 0xb3, 0x7b, 0xb9, 0x73, 0xca, 0x9a, 0x85, 0x29, 0x2d, 0xe6,
0xe2, 0x95, 0xd7, 0xfb, 0xdd, 0x3d, 0x40, 0x55, 0xa2, 0x69, 0x82, 0x17, 0x2c, 0xd1, 0x7d, 0x51,
0x09, 0x65, 0xf2, 0x9c, 0x36, 0xc6, 0x7c, 0x0f, 0x91, 0x21, 0xb3, 0x9f, 0x57, 0xd9, 0x49, 0xcf,
0x04, 0xf8, 0xe9, 0xea, 0xfb, 0xe5, 0x5a, 0xf9, 0xaa, 0x5d, 0x5d, 0x17, 0xb6, 0x9e, 0xe7, 0x79,
0x61, 0xe6, 0x61, 0x68, 0x4e, 0x3f, 0xc8, 0x6a, 0x4c, 0xbf, 0x4b, 0xfe, 0x2b, 0x00, 0x00, 0xff,
0xff, 0xed, 0x88, 0x46, 0x30, 0x3e, 0x03, 0x00, 0x00,
// 445 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x53, 0x51, 0x6b, 0xdb, 0x30,
0x10, 0x26, 0x71, 0x93, 0xc6, 0x57, 0x3f, 0x0c, 0x33, 0x86, 0xe9, 0x5a, 0x9a, 0x69, 0x1b, 0xe4,
0x65, 0x0d, 0xcc, 0x63, 0x3f, 0x60, 0xec, 0x61, 0xa1, 0x90, 0x81, 0x5a, 0xca, 0xd8, 0x9b, 0xe2,
0xca, 0xb1, 0x88, 0x2c, 0xd9, 0x91, 0x32, 0xea, 0x7f, 0x3f, 0xee, 0xa2, 0x64, 0x1e, 0x65, 0xeb,
0xdb, 0xf7, 0xe9, 0xee, 0xf4, 0x7d, 0xf7, 0x09, 0x41, 0x52, 0xd8, 0xba, 0xb6, 0xe6, 0xba, 0xd9,
0x5a, 0x6f, 0xd3, 0x91, 0xef, 0x1a, 0xe9, 0xd8, 0x07, 0x18, 0x71, 0xd9, 0xe8, 0x2e, 0x4d, 0xe1,
0x44, 0xb9, 0xef, 0x9b, 0x6c, 0x30, 0x1d, 0xcc, 0x26, 0x9c, 0x70, 0xfa, 0x02, 0xa2, 0xda, 0xad,
0xb3, 0xe1, 0x74, 0x30, 0x4b, 0x38, 0x42, 0x76, 0x05, 0x31, 0x97, 0xed, 0xad, 0xdf, 0x2a, 0xb3,
0xc6, 0x91, 0x07, 0xe1, 0x05, 0x8d, 0xc4, 0x9c, 0x30, 0x7b, 0x03, 0x67, 0x74, 0xdf, 0x7f, 0x5a,
0xde, 0x41, 0xd2, 0x6b, 0x71, 0xe9, 0x4b, 0x18, 0xe1, 0xb9, 0xcb, 0x06, 0xd3, 0x68, 0x16, 0xf3,
0x3d, 0x61, 0x53, 0x18, 0x73, 0xd9, 0x2e, 0x8c, 0x4f, 0x5f, 0xc1, 0xb8, 0x92, 0x6a, 0x5d, 0x79,
0xba, 0x25, 0xe2, 0x81, 0xb1, 0xd7, 0x30, 0x5a, 0x18, 0xff, 0xf9, 0xd3, 0x5f, 0x22, 0x51, 0x10,
0xb9, 0x84, 0x53, 0x2e, 0xdb, 0x6f, 0xc2, 0x55, 0x58, 0xae, 0x84, 0xab, 0xa8, 0x9c, 0x70, 0xc2,
0xfb, 0x3d, 0x1a, 0xdd, 0xfd, 0xb3, 0x61, 0x42, 0xf2, 0x4b, 0xa5, 0xd9, 0x5b, 0x5a, 0x19, 0x1b,
0xa5, 0x23, 0x2f, 0x84, 0xc8, 0x6c, 0xc2, 0x03, 0x63, 0xef, 0xc3, 0xda, 0xcf, 0xb4, 0x7d, 0x84,
0xc9, 0x8d, 0xec, 0xee, 0x85, 0xde, 0x49, 0x0c, 0x77, 0x23, 0xbb, 0x20, 0x8a, 0x10, 0x83, 0xf8,
0x85, 0xa5, 0x10, 0xf8, 0x9e, 0xb0, 0x0b, 0x18, 0xdf, 0x3d, 0x3e, 0xf1, 0x19, 0x07, 0x9f, 0x3f,
0x00, 0xee, 0x54, 0x2d, 0x6f, 0xbd, 0xf0, 0x3b, 0x97, 0x66, 0x70, 0x6a, 0x7c, 0x83, 0x07, 0xa1,
0xe9, 0x40, 0xd3, 0x0b, 0x88, 0xb5, 0x2d, 0x84, 0xa6, 0xda, 0x90, 0x6a, 0x7f, 0x0e, 0x28, 0x41,
0x55, 0x96, 0x59, 0x14, 0x12, 0x54, 0x65, 0xc9, 0xce, 0x29, 0x81, 0x1b, 0xd9, 0x3d, 0x75, 0xca,
0x5a, 0x5c, 0xb7, 0xe5, 0xc2, 0x3c, 0x90, 0xb1, 0x73, 0x98, 0xc8, 0x47, 0x59, 0x2c, 0xc5, 0x51,
0xf7, 0xc8, 0x7b, 0xaf, 0x37, 0xec, 0xbf, 0x1e, 0xce, 0xac, 0xb4, 0x2d, 0x36, 0xcb, 0x5d, 0x1d,
0x64, 0x8f, 0xfc, 0xb8, 0xe8, 0x49, 0xef, 0x41, 0x14, 0x9c, 0xdd, 0xcb, 0xad, 0x53, 0xd6, 0x2c,
0x4c, 0x69, 0x31, 0x2b, 0xaf, 0xbc, 0x3e, 0xe8, 0xed, 0x09, 0x3a, 0x15, 0x4d, 0x13, 0xf6, 0x43,
0x88, 0x89, 0x14, 0x95, 0x50, 0x26, 0xcf, 0x49, 0x25, 0xe6, 0x07, 0x8a, 0x15, 0x0a, 0xe0, 0xeb,
0x8a, 0x74, 0x62, 0x7e, 0xa0, 0x5f, 0xae, 0x7e, 0x5e, 0xae, 0x95, 0xaf, 0x76, 0xab, 0xeb, 0xc2,
0xd6, 0xf3, 0x3c, 0x2f, 0xcc, 0x3c, 0x0c, 0xcd, 0xe9, 0xd3, 0xac, 0xc6, 0xf4, 0x85, 0xf2, 0xdf,
0x01, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x62, 0x19, 0x6f, 0x52, 0x03, 0x00, 0x00,
}
......@@ -210,7 +210,6 @@ type StoreNode struct {
RightHash []byte `protobuf:"bytes,4,opt,name=rightHash,proto3" json:"rightHash,omitempty"`
Height int32 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"`
Size int32 `protobuf:"varint,6,opt,name=size,proto3" json:"size,omitempty"`
ParentHash []byte `protobuf:"bytes,7,opt,name=parentHash,proto3" json:"parentHash,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -283,13 +282,6 @@ func (m *StoreNode) GetSize() int32 {
return 0
}
func (m *StoreNode) GetParentHash() []byte {
if m != nil {
return m.ParentHash
}
return nil
}
type LocalDBSet struct {
KV []*KeyValue `protobuf:"bytes,2,rep,name=KV,proto3" json:"KV,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
......@@ -888,10 +880,8 @@ func (m *StoreListReply) GetValues() [][]byte {
}
type PruneData struct {
// 对应keyHash下的区块高度
Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"`
// hash+prefix的长度
Lenth int32 `protobuf:"varint,2,opt,name=lenth,proto3" json:"lenth,omitempty"`
// 该叶子节点的所有父hash
Hashs [][]byte `protobuf:"bytes,1,rep,name=hashs,proto3" json:"hashs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -922,18 +912,11 @@ func (m *PruneData) XXX_DiscardUnknown() {
var xxx_messageInfo_PruneData proto.InternalMessageInfo
func (m *PruneData) GetHeight() int64 {
func (m *PruneData) GetHashs() [][]byte {
if m != nil {
return m.Height
return m.Hashs
}
return 0
}
func (m *PruneData) GetLenth() int32 {
if m != nil {
return m.Lenth
}
return 0
return nil
}
//用于存储db Pool数据的Value
......@@ -999,46 +982,45 @@ func init() {
func init() { proto.RegisterFile("db.proto", fileDescriptor_8817812184a13374) }
var fileDescriptor_8817812184a13374 = []byte{
// 647 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x6a, 0xdb, 0x4c,
0x10, 0x45, 0x92, 0x95, 0x48, 0x93, 0xf0, 0xc5, 0x88, 0xf0, 0x61, 0x42, 0xda, 0x18, 0x5d, 0xb9,
0x94, 0x3a, 0xa5, 0xbe, 0x2a, 0xf4, 0xa2, 0x0d, 0x81, 0xb4, 0xd8, 0x2d, 0x41, 0x06, 0x17, 0x7a,
0x51, 0xd8, 0xc8, 0xe3, 0x58, 0x44, 0xde, 0x75, 0xa5, 0x55, 0x89, 0xfa, 0x1a, 0x7d, 0x9a, 0xbe,
0x46, 0x9f, 0xa8, 0xec, 0xec, 0xea, 0x27, 0xc5, 0x89, 0x9b, 0xbb, 0x39, 0xe3, 0xf1, 0x9c, 0x33,
0x67, 0x67, 0x6c, 0xf0, 0xe6, 0x57, 0xc3, 0x75, 0x26, 0xa4, 0x08, 0x5c, 0x59, 0xae, 0x31, 0x3f,
0xda, 0x8f, 0xc5, 0x6a, 0x25, 0xb8, 0x4e, 0x86, 0x5f, 0xc1, 0x9b, 0x20, 0x5b, 0x7c, 0x12, 0x73,
0x0c, 0xba, 0xe0, 0xdc, 0x60, 0xd9, 0xb3, 0xfa, 0xd6, 0x60, 0x3f, 0x52, 0x61, 0x70, 0x08, 0xee,
0x77, 0x96, 0x16, 0xd8, 0xb3, 0x29, 0xa7, 0x41, 0xf0, 0x3f, 0xec, 0x2c, 0x31, 0xb9, 0x5e, 0xca,
0x9e, 0xd3, 0xb7, 0x06, 0x6e, 0x64, 0x50, 0x10, 0x40, 0x27, 0x4f, 0x7e, 0x60, 0xaf, 0x43, 0x59,
0x8a, 0xc3, 0x6f, 0xe0, 0x7f, 0xe0, 0x1c, 0x33, 0x22, 0x38, 0x02, 0x2f, 0xc5, 0x85, 0x7c, 0xcf,
0xf2, 0xa5, 0x61, 0xa9, 0x71, 0x70, 0x0c, 0x7e, 0xa6, 0xba, 0xd0, 0x87, 0x9a, 0xae, 0x49, 0x3c,
0x8a, 0xb2, 0x00, 0xff, 0xe3, 0xbb, 0xd9, 0xe4, 0x32, 0x13, 0x62, 0xa1, 0x29, 0xd9, 0xe2, 0x2e,
0xa5, 0xc6, 0xc1, 0x4b, 0x80, 0xa4, 0xd2, 0x96, 0xf7, 0xec, 0xbe, 0x33, 0xd8, 0x7b, 0xd5, 0x1d,
0x92, 0x4b, 0xc3, 0x5a, 0x74, 0xd4, 0xaa, 0x51, 0xdd, 0x32, 0x21, 0xb4, 0x46, 0x47, 0x77, 0xab,
0x70, 0xf8, 0xcb, 0x02, 0x7f, 0x2a, 0x45, 0x86, 0x8f, 0xf2, 0xb2, 0x6d, 0x89, 0xf3, 0x90, 0x25,
0x9d, 0xfb, 0x2d, 0x71, 0x37, 0x5a, 0xb2, 0xd3, 0x58, 0x12, 0x3c, 0x05, 0x58, 0xb3, 0x0c, 0xb9,
0x6e, 0xb5, 0x4b, 0xad, 0x5a, 0x99, 0xf0, 0x05, 0xc0, 0x44, 0xc4, 0x2c, 0x3d, 0x3f, 0x9b, 0xa2,
0x0c, 0x4e, 0xc0, 0x1e, 0xcf, 0x8c, 0x1f, 0x07, 0xc6, 0x8f, 0x31, 0x96, 0x33, 0x25, 0x38, 0xb2,
0xc7, 0xb3, 0xf0, 0x06, 0xf6, 0x4c, 0xf9, 0x24, 0xc9, 0xa5, 0x52, 0xb2, 0xce, 0x70, 0x91, 0xdc,
0x9a, 0x71, 0x0d, 0xaa, 0x3c, 0xb0, 0x1b, 0x0f, 0x8e, 0xc1, 0x9f, 0x27, 0x19, 0xc6, 0x32, 0x11,
0xdc, 0xbc, 0x64, 0x93, 0x50, 0x0e, 0xc5, 0xa2, 0xe0, 0xd2, 0xbc, 0xa6, 0x06, 0x61, 0xbf, 0xd6,
0x76, 0x81, 0x34, 0xdd, 0x0d, 0x96, 0xfa, 0xb5, 0xf6, 0x23, 0x8a, 0xc3, 0x67, 0x70, 0x40, 0x15,
0x11, 0xae, 0x53, 0xad, 0x52, 0x49, 0x22, 0x7f, 0xab, 0x42, 0x83, 0x42, 0x06, 0x1e, 0xbd, 0x91,
0x1a, 0xf3, 0x18, 0xfc, 0x5c, 0x32, 0x89, 0xad, 0xdd, 0x68, 0x12, 0x5b, 0x4d, 0xf8, 0x6b, 0x25,
0x9d, 0xca, 0xff, 0xf0, 0xad, 0xa1, 0x38, 0xc7, 0x74, 0x0b, 0x45, 0xd3, 0xc1, 0xbe, 0xd3, 0x61,
0x0a, 0xdd, 0x4a, 0xe4, 0xe7, 0x44, 0x2e, 0xa7, 0x25, 0x8f, 0x83, 0xe7, 0xe0, 0xe5, 0x2a, 0x97,
0xa3, 0xa4, 0x46, 0x8d, 0xa8, 0xaa, 0x34, 0xaa, 0x0b, 0x68, 0x05, 0x4a, 0x1e, 0x53, 0x5b, 0x2f,
0xa2, 0x38, 0x7c, 0x63, 0x64, 0x5d, 0x6c, 0x9d, 0xfc, 0x1e, 0x8b, 0xe9, 0xdb, 0xff, 0x60, 0xf1,
0xcf, 0xea, 0x0e, 0x68, 0x37, 0x1e, 0xa6, 0x3a, 0x04, 0x37, 0x97, 0x2c, 0x93, 0xd5, 0x4d, 0x10,
0x50, 0x7b, 0x83, 0x7c, 0x6e, 0xce, 0x41, 0x85, 0x8a, 0x2b, 0x2f, 0x16, 0x6a, 0xc3, 0xf4, 0x19,
0x18, 0xd4, 0x6c, 0x8c, 0x4b, 0x06, 0x6a, 0xa0, 0x06, 0x58, 0x89, 0xb9, 0xbe, 0x00, 0x27, 0xa2,
0x38, 0xfc, 0x6d, 0xc1, 0x7f, 0xb5, 0x2a, 0x9a, 0xa2, 0x21, 0xb7, 0x36, 0x90, 0xdb, 0x9b, 0xc8,
0x9d, 0xcd, 0xe4, 0x9d, 0x36, 0x79, 0x17, 0x1c, 0x5e, 0xac, 0x8c, 0x20, 0x15, 0x6e, 0x92, 0x13,
0xf4, 0x60, 0x97, 0xe3, 0xad, 0x1c, 0x63, 0x69, 0xae, 0xb1, 0x82, 0xb5, 0xfb, 0x5e, 0xe3, 0x7e,
0xcb, 0x6a, 0xff, 0x8e, 0xd5, 0xaf, 0xc1, 0xbf, 0xcc, 0x0a, 0x8e, 0xe7, 0x4c, 0xb2, 0xd6, 0x36,
0x59, 0xed, 0x6d, 0x52, 0x32, 0x53, 0xe4, 0x52, 0xff, 0xa8, 0xba, 0x91, 0x06, 0xe1, 0xc0, 0xd8,
0x41, 0x6f, 0x79, 0x29, 0x44, 0xda, 0x22, 0xb1, 0xda, 0x24, 0x67, 0x27, 0x5f, 0x9e, 0x5c, 0x27,
0x72, 0x59, 0x5c, 0x0d, 0x63, 0xb1, 0x3a, 0x1d, 0x8d, 0x62, 0x7e, 0x1a, 0x2f, 0x59, 0xc2, 0x47,
0xa3, 0x53, 0x5a, 0xc0, 0xab, 0x1d, 0xfa, 0x27, 0x19, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 0x30,
0x37, 0x20, 0x41, 0x6a, 0x06, 0x00, 0x00,
// 625 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x4d, 0x6b, 0xdb, 0x40,
0x10, 0x45, 0x92, 0x9d, 0x48, 0x93, 0xd0, 0x18, 0x11, 0x8a, 0x08, 0x29, 0x71, 0x75, 0x72, 0x29,
0x75, 0x4a, 0x7d, 0xed, 0xa1, 0x0d, 0x81, 0xb4, 0xd8, 0x2d, 0x41, 0x06, 0x17, 0x7a, 0x28, 0x28,
0xf2, 0x38, 0x12, 0xb1, 0x77, 0x5d, 0xed, 0xaa, 0x44, 0xfd, 0x1b, 0x3d, 0xf5, 0x6f, 0xf5, 0x17,
0x95, 0x9d, 0x5d, 0x7d, 0xa4, 0x38, 0x71, 0x73, 0xdb, 0x37, 0x1e, 0xcf, 0x7b, 0xf3, 0xe6, 0x81,
0xc0, 0x9d, 0x5f, 0x0d, 0xd7, 0x39, 0x97, 0xdc, 0xef, 0xca, 0x72, 0x8d, 0xe2, 0x68, 0x3f, 0xe1,
0xab, 0x15, 0x67, 0xba, 0x18, 0x7e, 0x03, 0x77, 0x82, 0xf1, 0xe2, 0x33, 0x9f, 0xa3, 0xdf, 0x03,
0xe7, 0x06, 0xcb, 0xc0, 0xea, 0x5b, 0x83, 0xfd, 0x48, 0x3d, 0xfd, 0x43, 0xe8, 0xfe, 0x88, 0x97,
0x05, 0x06, 0x36, 0xd5, 0x34, 0xf0, 0x9f, 0xc2, 0x4e, 0x8a, 0xd9, 0x75, 0x2a, 0x03, 0xa7, 0x6f,
0x0d, 0xba, 0x91, 0x41, 0xbe, 0x0f, 0x1d, 0x91, 0xfd, 0xc4, 0xa0, 0x43, 0x55, 0x7a, 0x87, 0xdf,
0xc1, 0xfb, 0xc8, 0x18, 0xe6, 0x44, 0x70, 0x04, 0xee, 0x12, 0x17, 0xf2, 0x43, 0x2c, 0x52, 0xc3,
0x52, 0x63, 0xff, 0x18, 0xbc, 0x5c, 0x4d, 0xa1, 0x1f, 0x35, 0x5d, 0x53, 0x78, 0x14, 0x65, 0x01,
0xde, 0xa7, 0xf7, 0xb3, 0xc9, 0x65, 0xce, 0xf9, 0x42, 0x53, 0xc6, 0x8b, 0xbb, 0x94, 0x1a, 0xfb,
0xaf, 0x01, 0xb2, 0x4a, 0x9b, 0x08, 0xec, 0xbe, 0x33, 0xd8, 0x7b, 0xd3, 0x1b, 0x92, 0x4b, 0xc3,
0x5a, 0x74, 0xd4, 0xea, 0x51, 0xd3, 0x72, 0xce, 0xb5, 0x46, 0x47, 0x4f, 0xab, 0x70, 0xf8, 0xdb,
0x02, 0x6f, 0x2a, 0x79, 0x8e, 0x8f, 0xf2, 0xb2, 0x6d, 0x89, 0xf3, 0x90, 0x25, 0x9d, 0xfb, 0x2d,
0xe9, 0x6e, 0xb4, 0x64, 0xa7, 0x65, 0xc9, 0x2b, 0x80, 0x09, 0x4f, 0xe2, 0xe5, 0xf9, 0xd9, 0x14,
0xa5, 0x7f, 0x02, 0xf6, 0x78, 0x66, 0xf6, 0x3d, 0x30, 0xfb, 0x8e, 0xb1, 0x9c, 0x29, 0x41, 0x91,
0x3d, 0x9e, 0x85, 0x37, 0xb0, 0x67, 0xda, 0x27, 0x99, 0x90, 0x8a, 0x69, 0x9d, 0xe3, 0x22, 0xbb,
0x35, 0xeb, 0x18, 0x54, 0xed, 0x68, 0x37, 0x3b, 0x1e, 0x83, 0x37, 0xcf, 0x72, 0x4c, 0x64, 0xc6,
0x99, 0xb9, 0x54, 0x53, 0x50, 0x0e, 0x24, 0xbc, 0x60, 0xd2, 0x5c, 0x4b, 0x83, 0xb0, 0x5f, 0x6b,
0xbb, 0x40, 0x52, 0x7f, 0x83, 0xa5, 0xbe, 0xc6, 0x7e, 0x44, 0xef, 0xf0, 0x05, 0x1c, 0x50, 0x47,
0x84, 0xeb, 0xa5, 0x56, 0xa9, 0x24, 0x91, 0x7f, 0x55, 0xa3, 0x41, 0x61, 0x0c, 0x2e, 0xdd, 0x40,
0xad, 0x79, 0x0c, 0x9e, 0x90, 0xb1, 0xc4, 0xd6, 0xed, 0x9b, 0xc2, 0x56, 0x13, 0xfe, 0x89, 0x9c,
0x53, 0xf9, 0x1b, 0xbe, 0x33, 0x14, 0xe7, 0xb8, 0xdc, 0x42, 0xd1, 0x4c, 0xb0, 0xef, 0x4c, 0x98,
0x42, 0xaf, 0x12, 0xf9, 0x25, 0x93, 0xe9, 0xb4, 0x64, 0x89, 0xff, 0x12, 0x5c, 0xa1, 0x6a, 0x02,
0x25, 0x0d, 0x6a, 0x44, 0x55, 0xad, 0x51, 0xdd, 0x40, 0x27, 0x2e, 0x59, 0x42, 0x63, 0xdd, 0x88,
0xde, 0xe1, 0x5b, 0x23, 0xeb, 0x62, 0xeb, 0xe6, 0xf7, 0x58, 0x4c, 0xff, 0xfe, 0x0f, 0x8b, 0x7f,
0x55, 0x39, 0xa7, 0x6c, 0x3c, 0x4c, 0x75, 0x08, 0x5d, 0x21, 0xe3, 0x5c, 0x56, 0x99, 0x27, 0xa0,
0x72, 0x83, 0x6c, 0x6e, 0xe2, 0xae, 0x9e, 0x8a, 0x4b, 0x14, 0x0b, 0x95, 0x30, 0x1d, 0x73, 0x83,
0x9a, 0xc4, 0x74, 0xc9, 0x40, 0x0d, 0xd4, 0x02, 0x2b, 0x3e, 0xd7, 0x09, 0x77, 0x22, 0x7a, 0x87,
0x7f, 0x2c, 0x78, 0x52, 0xab, 0xa2, 0x2d, 0x1a, 0x72, 0x6b, 0x03, 0xb9, 0xbd, 0x89, 0xdc, 0xd9,
0x4c, 0xde, 0x69, 0x93, 0xf7, 0xc0, 0x61, 0xc5, 0xca, 0x08, 0x52, 0xcf, 0x4d, 0x72, 0xfc, 0x00,
0x76, 0x19, 0xde, 0xca, 0x31, 0x96, 0xc1, 0x2e, 0x0d, 0xad, 0x60, 0xed, 0xbe, 0xdb, 0xb8, 0xdf,
0xb2, 0xda, 0xbb, 0x63, 0xf5, 0x73, 0xf0, 0x2e, 0xf3, 0x82, 0xe1, 0x79, 0x2c, 0x63, 0x25, 0x27,
0x8d, 0x45, 0x2a, 0x02, 0x8b, 0x7a, 0x34, 0x08, 0x07, 0x66, 0x6d, 0xba, 0xd9, 0x25, 0xe7, 0xcb,
0xd6, 0x30, 0xab, 0x3d, 0xec, 0xec, 0xe4, 0xeb, 0xb3, 0xeb, 0x4c, 0xa6, 0xc5, 0xd5, 0x30, 0xe1,
0xab, 0xd3, 0xd1, 0x28, 0x61, 0xa7, 0x49, 0x1a, 0x67, 0x6c, 0x34, 0x3a, 0xa5, 0xa0, 0x5d, 0xed,
0xd0, 0x17, 0x61, 0xf4, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x81, 0x98, 0x2a, 0x32, 0x06, 0x00,
0x00,
}
......@@ -174,4 +174,8 @@ var (
ErrCloneForkFrom = errors.New("ErrCloneForkFrom")
ErrCloneForkToExist = errors.New("ErrCloneForkToExist")
ErrQueryThistIsNotSet = errors.New("ErrQueryThistIsNotSet")
ErrHeightLessZero = errors.New("ErrHeightLessZero")
ErrHeightOverflow = errors.New("ErrHeightOverflow")
ErrRecordBlockSequence = errors.New("ErrRecordBlockSequence")
)
......@@ -69,6 +69,7 @@ message ReqRandHash {
string execName = 1;
int64 height = 2;
int64 blockNum = 3;
bytes hash = 4;
}
/**
......
......@@ -33,7 +33,6 @@ message StoreNode {
bytes rightHash = 4;
int32 height = 5;
int32 size = 6;
bytes parentHash = 7;
}
message LocalDBSet {
......@@ -102,12 +101,8 @@ message StoreListReply {
}
message PruneData {
// 对应keyHash下的区块高度
int64 height = 1;
// hash+prefix的长度
int32 lenth = 2;
// 该叶子节点的roothash
// bytes rHash = 3;
// 该叶子节点的所有父hash
repeated bytes hashs = 1;
}
//用于存储db Pool数据的Value
......
......@@ -125,7 +125,7 @@ service chain33 {
//获取指定区间的block加载序列号信息
rpc GetBlockSequences(ReqBlocks) returns (BlockSequences) {}
//get add block's sequence by hash
// get add block's sequence by hash
rpc GetSequenceByHash(ReqHash) returns (Int64) {}
//通过block hash 获取对应的blocks信息
......@@ -141,5 +141,5 @@ service chain33 {
rpc CreateNoBalanceTransaction(NoBalanceTx) returns (ReplySignRawTx) {}
// 获取随机HASH
rpc QueryRandNum(ReqRandHash) returns(ReplyHash) {}
rpc QueryRandNum(ReqRandHash) returns (ReplyHash) {}
}
......@@ -52,6 +52,14 @@ message CreateTx {
string execer = 9;
}
message ReWriteRawTx {
string tx = 1;
bytes execer = 2;
string to = 3;
string expire = 4;
int64 fee = 5;
}
message CreateTransactionGroup {
repeated string txs = 1;
}
......
......@@ -205,6 +205,9 @@ message ReqSignRawTx {
// 1:隐私交易
// int32 mode = 6;
string token = 7;
int64 fee = 8;
bytes newExecer = 9;
string newToAddr = 10;
}
message ReplySignRawTx {
......
......@@ -191,7 +191,7 @@ type Chain33Client interface {
GetLastBlockSequence(ctx context.Context, in *ReqNil, opts ...grpc.CallOption) (*Int64, error)
//获取指定区间的block加载序列号信息
GetBlockSequences(ctx context.Context, in *ReqBlocks, opts ...grpc.CallOption) (*BlockSequences, error)
//get add block's sequence by hash
// get add block's sequence by hash
GetSequenceByHash(ctx context.Context, in *ReqHash, opts ...grpc.CallOption) (*Int64, error)
//通过block hash 获取对应的blocks信息
GetBlockByHashes(ctx context.Context, in *ReqHashes, opts ...grpc.CallOption) (*BlockDetails, error)
......@@ -760,7 +760,7 @@ type Chain33Server interface {
GetLastBlockSequence(context.Context, *ReqNil) (*Int64, error)
//获取指定区间的block加载序列号信息
GetBlockSequences(context.Context, *ReqBlocks) (*BlockSequences, error)
//get add block's sequence by hash
// get add block's sequence by hash
GetSequenceByHash(context.Context, *ReqHash) (*Int64, error)
//通过block hash 获取对应的blocks信息
GetBlockByHashes(context.Context, *ReqHashes) (*BlockDetails, error)
......
......@@ -10,6 +10,8 @@ import (
"encoding/json"
"time"
"strconv"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
......@@ -601,3 +603,37 @@ func (tx *Transaction) IsWithdraw() bool {
}
return false
}
// ParseExpire parse expire to int from during or height
func ParseExpire(expire string) (int64, error) {
if len(expire) == 0 {
return 0, ErrInvalidParam
}
if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.ParseInt(expire[2:], 10, 64)
if err != nil {
return 0, err
}
if txHeight <= 0 {
//fmt.Printf("txHeight should be grate to 0")
return 0, ErrHeightLessZero
}
if txHeight+TxHeightFlag < txHeight {
return 0, ErrHeightOverflow
}
return txHeight + TxHeightFlag, nil
}
blockHeight, err := strconv.ParseInt(expire, 10, 64)
if err == nil {
return blockHeight, nil
}
expireTime, err := time.ParseDuration(expire)
if err == nil {
return int64(expireTime), nil
}
return 0, err
}
......@@ -12,6 +12,7 @@ import (
"github.com/33cn/chain33/common/crypto"
_ "github.com/33cn/chain33/system/crypto/init"
"github.com/stretchr/testify/assert"
)
func TestCreateGroupTx(t *testing.T) {
......@@ -135,3 +136,28 @@ func BenchmarkTxHash(b *testing.B) {
tx12.Hash()
}
}
func TestParseExpire(t *testing.T) {
expire := ""
_, err := ParseExpire(expire)
assert.Equal(t, ErrInvalidParam, err)
expire = "H:123"
exp, _ := ParseExpire(expire)
assert.Equal(t, int64(4611686018427388027), exp)
expire = "H:-2"
_, err = ParseExpire(expire)
assert.Equal(t, ErrHeightLessZero, err)
expire = "123"
exp, err = ParseExpire(expire)
assert.Nil(t, err)
assert.Equal(t, int64(123), exp)
expire = "123s"
exp, err = ParseExpire(expire)
assert.Nil(t, err)
assert.Equal(t, int64(123000000000), exp)
}
......@@ -20,7 +20,15 @@ var TestPrivkeyHex = []string{
"2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989",
}
//TestPrivkeyList :
/*
TestPrivkeyList : crypto.PrivKey list
addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
addr:14KEKbYtKKQm4wMthSK9J4La4nAiidGozt
addr:1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF
addr:1PUiGcbsccfxW3zuvHXZBJfznziph5miAo
addr:1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa
addr:1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX
*/
var TestPrivkeyList = []crypto.PrivKey{
HexToPrivkey("4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"),
HexToPrivkey("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944"),
......
......@@ -11,9 +11,6 @@ import (
"sync/atomic"
"time"
"errors"
"strconv"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
......@@ -26,39 +23,6 @@ import (
"github.com/golang/protobuf/proto"
)
func (wallet *Wallet) parseExpire(expire string) (int64, error) {
if len(expire) == 0 {
return 0, errors.New("Expire string should not be empty")
}
if expire[0] == 'H' && expire[1] == ':' {
txHeight, err := strconv.ParseInt(expire[2:], 10, 64)
if err != nil {
return 0, err
}
if txHeight <= 0 {
//fmt.Printf("txHeight should be grate to 0")
return 0, errors.New("txHeight should be grate to 0")
}
if txHeight+types.TxHeightFlag < txHeight {
return 0, errors.New("txHeight overflow")
}
return txHeight + types.TxHeightFlag, nil
}
blockHeight, err := strconv.ParseInt(expire, 10, 64)
if err == nil {
return blockHeight, nil
}
expireTime, err := time.ParseDuration(expire)
if err == nil {
return int64(expireTime), nil
}
return 0, err
}
// ProcSignRawTx 用钱包对交易进行签名
//input:
//type ReqSignRawTx struct {
......@@ -115,7 +79,18 @@ func (wallet *Wallet) ProcSignRawTx(unsigned *types.ReqSignRawTx) (string, error
if err != nil {
return "", err
}
expire, err := wallet.parseExpire(unsigned.GetExpire())
if unsigned.GetNewExecer() != nil {
tx.Execer = unsigned.NewExecer
}
if unsigned.NewToAddr != "" {
tx.To = unsigned.NewToAddr
}
if unsigned.Fee != 0 {
tx.Fee = unsigned.Fee
}
expire, err := types.ParseExpire(unsigned.GetExpire())
if err != nil {
return "", err
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment