Commit 0b4fb39b authored by vipwzw's avatar vipwzw Committed by 33cn

update chain33

parent b513359b
......@@ -10,6 +10,7 @@ import (
_ "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/oracle" //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
......
......@@ -10,6 +10,7 @@ datadir*
.idea
.vscode
cmd/chain33/chain33
cmd/tools/tools
build/cert.pem
build/key.pem
build/chain33*
......
......@@ -11,7 +11,8 @@ import (
"github.com/33cn/chain33/cmd/tools/tasks"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
sysutil "github.com/33cn/chain33/util"
"github.com/pkg/errors"
)
......@@ -56,7 +57,7 @@ func (ad *advanceCreateExecProjStrategy) initMember() {
ad.execName = v
}
if v, err := ad.getParam(types.KeyActionName); err == nil {
ad.actionName, _ = util.MakeStringToUpper(v, 0, 1)
ad.actionName, _ = sysutil.MakeStringToUpper(v, 0, 1)
}
if v, err := ad.getParam(types.KeyProtobufFile); err == nil {
ad.propFile = v
......
......@@ -14,7 +14,7 @@ import (
"os/exec"
"strings"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
"github.com/BurntSushi/toml"
)
......
......@@ -5,7 +5,7 @@
package tasks
import (
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
// CheckFileExistedTask 检测文件是否存在
......
......@@ -11,7 +11,7 @@ import (
"strings"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
//CopyTemplateToOutputTask ...
......
......@@ -10,7 +10,8 @@ import (
"strings"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
sysutil "github.com/33cn/chain33/util"
)
type actionInfoItem struct {
......@@ -112,7 +113,7 @@ func (c *CreateDappSourceTask) readActionMemberNames() error {
memberType := strings.Replace(member[1], " ", "", -1)
memberName := strings.Replace(member[2], " ", "", -1)
// 根据proto生成pb.go的规则,成员变量首字母必须大写
memberName, _ = util.MakeStringToUpper(memberName, 0, 1)
memberName, _ = sysutil.MakeStringToUpper(memberName, 0, 1)
c.actionInfos = append(c.actionInfos, &actionInfoItem{
memberName: memberName,
memberType: memberType,
......
......@@ -10,7 +10,7 @@ import (
"fmt"
"strings"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
// CreateFileFromStrTemplateTask 从指定的模板字符串中创建目标文件的任务
......
......@@ -10,7 +10,7 @@ import (
"strings"
"github.com/33cn/chain33/cmd/tools/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
// ReplaceTargetTask 替换指定目录下所有文件的标志性文字
......
......@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
func TestReplaceTarget(t *testing.T) {
......
......@@ -12,7 +12,7 @@ import (
"os/exec"
"strings"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/cmd/tools/util"
)
type itemData struct {
......
......@@ -7,6 +7,7 @@ import (
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
)
var tablelog = log15.New("module", "db.table")
......@@ -214,7 +215,7 @@ func (join *JoinTable) Save() (kvs []*types.KeyValue, err error) {
return nil, err
}
kvs = append(kvs, rightkvs...)
return deldupKey(kvs), nil
return util.DelDupKey(kvs), nil
}
func (join *JoinTable) isLeftModify(row *Row) bool {
......
......@@ -14,6 +14,7 @@ import (
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/golang/protobuf/proto"
)
......@@ -486,31 +487,7 @@ func (table *Table) Save() (kvs []*types.KeyValue, err error) {
//del cache
table.rowmap = make(map[string]*Row)
table.rows = nil
return deldupKey(kvs), nil
}
func deldupKey(kvs []*types.KeyValue) []*types.KeyValue {
dupindex := make(map[string]int)
hasdup := false
for i, kv := range kvs {
if _, ok := dupindex[string(kv.Key)]; ok {
hasdup = true
}
dupindex[string(kv.Key)] = i
}
//没有重复的情况下,不需要重新处理
if !hasdup {
return kvs
}
index := 0
for i, kv := range kvs {
lastindex := dupindex[string(kv.Key)]
if i == lastindex {
kvs[index] = kv
index++
}
}
return kvs[0:index]
return util.DelDupKey(kvs), nil
}
func pad(i int64) string {
......
......@@ -18,13 +18,13 @@ import (
"net/http"
_ "net/http/pprof" //
"os"
"os/user"
"path/filepath"
"runtime"
"time"
"github.com/33cn/chain33/blockchain"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/limits"
......@@ -79,7 +79,7 @@ func RunChain33(name string) {
//set config: bityuan 用 bityuan.toml 这个配置文件
cfg, sub := types.InitCfg(*configPath)
if *datadir != "" {
resetDatadir(cfg, *datadir)
util.ResetDatadir(cfg, *datadir)
}
if *fixtime {
cfg.FixTime = *fixtime
......@@ -190,21 +190,6 @@ func RunChain33(name string) {
q.Start()
}
func resetDatadir(cfg *types.Config, datadir string) {
// Check in case of paths like "/something/~/something/"
if datadir[:2] == "~/" {
usr, _ := user.Current()
dir := usr.HomeDir
datadir = filepath.Join(dir, datadir[2:])
}
log.Info("current user data dir is ", "dir", datadir)
cfg.Log.LogFile = filepath.Join(datadir, cfg.Log.LogFile)
cfg.BlockChain.DbPath = filepath.Join(datadir, cfg.BlockChain.DbPath)
cfg.P2P.DbPath = filepath.Join(datadir, cfg.P2P.DbPath)
cfg.Wallet.DbPath = filepath.Join(datadir, cfg.Wallet.DbPath)
cfg.Store.DbPath = filepath.Join(datadir, cfg.Store.DbPath)
}
// 开启trace
func startTrace() {
......
......@@ -92,17 +92,29 @@ func ExecKVSetRollback(client queue.Client, hash []byte) error {
return nil
}
func checkTxDupInner(txs []*types.TransactionCache) (ret []*types.TransactionCache) {
dupMap := make(map[string]bool)
for _, tx := range txs {
hash := string(tx.Hash())
if _, ok := dupMap[hash]; ok {
continue
//DelDupTx 删除重复的交易
func DelDupTx(txs []*types.TransactionCache) (ret []*types.TransactionCache) {
dupindex := make(map[string]int)
hasdup := false
for i, tx := range txs {
if _, ok := dupindex[string(tx.Hash())]; ok {
hasdup = true
}
dupindex[string(tx.Hash())] = i
}
dupMap[hash] = true
ret = append(ret, tx)
//没有重复的情况下,不需要重新处理
if !hasdup {
return txs
}
return ret
index := 0
for i, tx := range txs {
lastindex := dupindex[string(tx.Hash())]
if i == lastindex {
txs[index] = tx
index++
}
}
return txs[0:index]
}
//CheckDupTx : check use txs []*types.Transaction and not []*types.TransactionCache
......@@ -125,7 +137,7 @@ func CheckDupTx(client queue.Client, txs []*types.Transaction, height int64) (tr
func CheckTxDup(client queue.Client, txs []*types.TransactionCache, height int64) (transactions []*types.TransactionCache, err error) {
var checkHashList types.TxHashList
if types.IsFork(height, "ForkCheckTxDup") {
txs = checkTxDupInner(txs)
txs = DelDupTx(txs)
}
for _, tx := range txs {
checkHashList.Hashes = append(checkHashList.Hashes, tx.Hash())
......@@ -171,3 +183,28 @@ func ReportErrEventToFront(logger log.Logger, client queue.Client, frommodule st
msg := client.NewMessage(tomodule, types.EventErrToFront, &reportErrEvent)
client.Send(msg, false)
}
//DelDupKey 删除重复的key
func DelDupKey(kvs []*types.KeyValue) []*types.KeyValue {
dupindex := make(map[string]int)
hasdup := false
for i, kv := range kvs {
if _, ok := dupindex[string(kv.Key)]; ok {
hasdup = true
}
dupindex[string(kv.Key)] = i
}
//没有重复的情况下,不需要重新处理
if !hasdup {
return kvs
}
index := 0
for i, kv := range kvs {
lastindex := dupindex[string(kv.Key)]
if i == lastindex {
kvs[index] = kv
index++
}
}
return kvs[0:index]
}
......@@ -36,7 +36,7 @@ defCacheSize=128
maxFetchBlockNum=128
timeoutSeconds=5
batchBlockNum=128
driver="memdb"
driver="leveldb"
dbPath="datadir"
dbCache=64
isStrongConsistency=false
......@@ -55,7 +55,7 @@ innerSeedEnable=true
useGithub=true
innerBounds=300
msgCacheSize=10240
driver="memdb"
driver="leveldb"
dbPath="datadir/addrbook"
dbCache=4
grpcLogFile="grpc33.log"
......@@ -126,7 +126,7 @@ count=10000
[store]
name="mavl"
driver="memdb"
driver="leveldb"
dbPath="datadir/mavltree"
dbCache=128
......@@ -136,7 +136,7 @@ enableMVCC=false
[wallet]
minFee=100000
driver="memdb"
driver="leveldb"
dbPath="wallet"
dbCache=16
signType="secp256k1"
......
......@@ -10,6 +10,7 @@ import (
"encoding/hex"
"fmt"
"math/rand"
"os"
"strings"
"sync"
"time"
......@@ -65,6 +66,7 @@ type Chain33Mock struct {
store queue.Module
rpc *rpc.RPC
cfg *types.Config
datadir string
lastsend []byte
}
......@@ -83,7 +85,8 @@ func newWithConfig(cfg *types.Config, sub *types.ConfigSubModule, mockapi client
types.Init(cfg.Title, cfg)
q := queue.New("channel")
types.Debug = false
mock := &Chain33Mock{cfg: cfg, q: q}
datadir := util.ResetDatadir(cfg, "$TEMP/")
mock := &Chain33Mock{cfg: cfg, q: q, datadir: datadir}
mock.random = rand.New(rand.NewSource(types.Now().UnixNano()))
mock.exec = executor.New(cfg.Exec, sub.Exec)
......@@ -256,6 +259,7 @@ func (mock *Chain33Mock) Close() {
mock.network.Close()
mock.client.Close()
mock.rpc.Close()
os.RemoveAll(mock.datadir)
chain33globalLock.Unlock()
}
......
......@@ -8,7 +8,10 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"math/rand"
"os/user"
"path/filepath"
"strings"
"testing"
"unicode"
......@@ -26,7 +29,7 @@ func init() {
rand.Seed(types.Now().UnixNano())
}
var chainlog = log15.New("module", "testnode")
var chainlog = log15.New("module", "util")
//GetParaExecName : 如果 name 没有 paraName 前缀,那么加上这个前缀
func GetParaExecName(paraName string, name string) string {
......@@ -39,7 +42,7 @@ func GetParaExecName(paraName string, name string) string {
// MakeStringToUpper : 将给定的in字符串从pos开始一共count个转换为大写字母
func MakeStringToUpper(in string, pos, count int) (out string, err error) {
l := len(in)
if pos < 0 || pos >= l || (pos+count) >= l {
if pos < 0 || pos >= l || (pos+count) >= l || count <= 0 {
err = fmt.Errorf("Invalid params. in=%s pos=%d count=%d", in, pos, count)
return
}
......@@ -54,7 +57,7 @@ func MakeStringToUpper(in string, pos, count int) (out string, err error) {
// MakeStringToLower : 将给定的in字符串从pos开始一共count个转换为小写字母
func MakeStringToLower(in string, pos, count int) (out string, err error) {
l := len(in)
if pos < 0 || pos >= l || (pos+count) >= l {
if pos < 0 || pos >= l || (pos+count) >= l || count <= 0 {
err = fmt.Errorf("Invalid params. in=%s pos=%d count=%d", in, pos, count)
return
}
......@@ -240,7 +243,6 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
block.Txs = types.CacheToTxs(cacheTxs)
receipts := ExecTx(client, prevStateRoot, block)
var maplist = make(map[string]*types.KeyValue)
var kvset []*types.KeyValue
var deltxlist = make(map[int]bool)
var rdata []*types.ReceiptData //save to db receipt log
......@@ -255,17 +257,9 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
continue
}
rdata = append(rdata, &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs})
//处理KV
kvs := receipt.KV
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)
}
}
kvset = append(kvset, receipt.KV...)
}
kvset = DelDupKey(kvset)
//check TxHash
calcHash := merkle.CalcMerkleRoot(block.Txs)
if errReturn && !bytes.Equal(calcHash, block.TxHash) {
......@@ -288,11 +282,7 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
}
var detail types.BlockDetail
//if kvset == nil {
// calcHash = prevStateRoot
//} else {
calcHash = ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync)
//}
if errReturn && !bytes.Equal(block.StateHash, calcHash) {
ExecKVSetRollback(client, calcHash)
if len(rdata) > 0 {
......@@ -305,10 +295,7 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
block.StateHash = calcHash
detail.Block = block
detail.Receipts = rdata
//save to db
//if kvset != nil {
ExecKVSetCommit(client, block.StateHash)
//}
return &detail, deltx, nil
}
......@@ -396,3 +383,27 @@ func ExecAndCheckBlockCB(qclient queue.Client, block *types.Block, txs []*types.
}
return detail.Block, nil
}
//ResetDatadir 重写datadir
func ResetDatadir(cfg *types.Config, datadir string) string {
// Check in case of paths like "/something/~/something/"
if datadir[:2] == "~/" {
usr, _ := user.Current()
dir := usr.HomeDir
datadir = filepath.Join(dir, datadir[2:])
}
if datadir[:6] == "$TEMP/" {
dir, err := ioutil.TempDir("", "chain33datadir-")
if err != nil {
panic(err)
}
datadir = filepath.Join(dir, datadir[6:])
}
chainlog.Info("current user data dir is ", "dir", datadir)
cfg.Log.LogFile = filepath.Join(datadir, cfg.Log.LogFile)
cfg.BlockChain.DbPath = filepath.Join(datadir, cfg.BlockChain.DbPath)
cfg.P2P.DbPath = filepath.Join(datadir, cfg.P2P.DbPath)
cfg.Wallet.DbPath = filepath.Join(datadir, cfg.Wallet.DbPath)
cfg.Store.DbPath = filepath.Join(datadir, cfg.Store.DbPath)
return datadir
}
......@@ -7,7 +7,12 @@ package util
import (
"testing"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
_ "github.com/33cn/chain33/system/dapp/coins/types"
)
func TestMakeStringUpper(t *testing.T) {
......@@ -37,3 +42,138 @@ func TestMakeStringLower(t *testing.T) {
_, err = MakeStringToLower(originStr, -1, 2)
assert.Error(t, err)
}
func TestResetDatadir(t *testing.T) {
cfg, _ := types.InitCfg("../cmd/chain33/chain33.toml")
datadir := ResetDatadir(cfg, "$TEMP/hello")
assert.Equal(t, datadir+"/datadir", cfg.BlockChain.DbPath)
cfg, _ = types.InitCfg("../cmd/chain33/chain33.toml")
datadir = ResetDatadir(cfg, "/TEMP/hello")
assert.Equal(t, datadir+"/datadir", cfg.BlockChain.DbPath)
cfg, _ = types.InitCfg("../cmd/chain33/chain33.toml")
datadir = ResetDatadir(cfg, "~/hello")
assert.Equal(t, datadir+"/datadir", cfg.BlockChain.DbPath)
}
func TestHexToPrivkey(t *testing.T) {
key := HexToPrivkey("4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01")
addr := address.PubKeyToAddress(key.PubKey().Bytes()).String()
assert.Equal(t, addr, "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv")
}
func TestGetParaExecName(t *testing.T) {
s := GetParaExecName("user.p.hello.", "world")
assert.Equal(t, "user.p.hello.world", s)
s = GetParaExecName("user.p.hello.", "user.p.2.world")
assert.Equal(t, "user.p.2.world", s)
}
func TestUpperLower(t *testing.T) {
out, err := MakeStringToUpper("hello", 0, 1)
assert.Nil(t, err)
assert.Equal(t, "Hello", out)
out, err = MakeStringToUpper("Hello", 0, 1)
assert.Nil(t, err)
assert.Equal(t, "Hello", out)
_, err = MakeStringToUpper("Hello", -1, 1)
assert.NotNil(t, err)
_, err = MakeStringToUpper("Hello", 1, -1)
assert.NotNil(t, err)
out, err = MakeStringToLower("hello", 0, 1)
assert.Nil(t, err)
assert.Equal(t, "hello", out)
out, err = MakeStringToLower("Hello", 0, 1)
assert.Nil(t, err)
assert.Equal(t, "hello", out)
_, err = MakeStringToLower("Hello", -1, 1)
assert.NotNil(t, err)
_, err = MakeStringToLower("Hello", 1, -1)
assert.NotNil(t, err)
}
func TestGenTx(t *testing.T) {
txs := GenNoneTxs(TestPrivkeyList[0], 2)
assert.Equal(t, 2, len(txs))
assert.Equal(t, "none", string(txs[0].Execer))
assert.Equal(t, "none", string(txs[1].Execer))
txs = GenCoinsTxs(TestPrivkeyList[0], 2)
assert.Equal(t, 2, len(txs))
assert.Equal(t, "coins", string(txs[0].Execer))
assert.Equal(t, "coins", string(txs[1].Execer))
txs = GenTxsTxHeigt(TestPrivkeyList[0], 2, 10)
assert.Equal(t, 2, len(txs))
assert.Equal(t, "coins", string(txs[0].Execer))
assert.Equal(t, "coins", string(txs[1].Execer))
assert.Equal(t, types.TxHeightFlag+10+20, txs[0].Expire)
}
func TestGenBlock(t *testing.T) {
block2 := CreateNoneBlock(TestPrivkeyList[0], 2)
assert.Equal(t, 2, len(block2.Txs))
block2 = CreateCoinsBlock(TestPrivkeyList[0], 2)
assert.Equal(t, 2, len(block2.Txs))
txs := GenNoneTxs(TestPrivkeyList[0], 2)
newblock := CreateNewBlock(block2, txs)
assert.Equal(t, newblock.Height, block2.Height+1)
assert.Equal(t, newblock.ParentHash, block2.Hash())
}
func TestDelDupKey(t *testing.T) {
kvs := []*types.KeyValue{
{Key: []byte("hello"), Value: []byte("world")},
{Key: []byte("hello1"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world2")},
}
result := []*types.KeyValue{
{Key: []byte("hello1"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world2")},
}
kvs = DelDupKey(kvs)
assert.Equal(t, kvs, result)
kvs = []*types.KeyValue{
{Key: []byte("hello1"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world2")},
}
result = []*types.KeyValue{
{Key: []byte("hello1"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world2")},
}
kvs = DelDupKey(kvs)
assert.Equal(t, kvs, result)
}
func TestDelDupTx(t *testing.T) {
txs := GenNoneTxs(TestPrivkeyList[0], 2)
assert.Equal(t, 2, len(txs))
assert.Equal(t, "none", string(txs[0].Execer))
assert.Equal(t, "none", string(txs[1].Execer))
result := txs
txs = append(txs, txs...)
txcache := make([]*types.TransactionCache, len(txs))
for i := 0; i < len(txcache); i++ {
txcache[i] = &types.TransactionCache{Transaction: txs[i]}
}
txcacheresult := make([]*types.TransactionCache, len(result))
for i := 0; i < len(result); i++ {
txcacheresult[i] = &types.TransactionCache{Transaction: result[i]}
txcacheresult[i].Hash()
}
txcache = DelDupTx(txcache)
assert.Equal(t, txcache, txcacheresult)
}
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