Commit 7d84bc46 authored by kingwang's avatar kingwang Committed by 33cn

update 0308

parent ff84df1a
......@@ -435,7 +435,7 @@ func genPrefixEdge(prefix []byte) (r []byte) {
return r
}
// Mint gitt铸币
// Mint 铸币
func (acc *DB) Mint(addr string, amount int64) (*types.Receipt, error) {
if !types.CheckAmount(amount) {
return nil, types.ErrAmount
......
......@@ -5,9 +5,6 @@
package blockchain
import (
"bytes"
"github.com/33cn/chain33/common/merkle"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
......@@ -15,127 +12,5 @@ import (
//执行区块将变成一个私有的函数
func execBlock(client queue.Client, prevStateRoot []byte, block *types.Block, errReturn bool, sync bool) (*types.BlockDetail, []*types.Transaction, error) {
//发送执行交易给execs模块
//通过consensus module 再次检查
chainlog.Debug("ExecBlock", "height------->", block.Height, "ntx", len(block.Txs))
beg := types.Now()
defer func() {
chainlog.Info("ExecBlock", "height", block.Height, "ntx", len(block.Txs), "writebatchsync", sync, "cost", types.Since(beg))
}()
if errReturn && block.Height > 0 && !block.CheckSign() {
//block的来源不是自己的mempool,而是别人的区块
return nil, nil, types.ErrSign
}
//tx交易去重处理, 这个地方要查询数据库,需要一个更快的办法
cacheTxs := types.TxsToCache(block.Txs)
oldtxscount := len(cacheTxs)
var err error
cacheTxs, err = util.CheckTxDup(client, cacheTxs, block.Height)
if err != nil {
return nil, nil, err
}
newtxscount := len(cacheTxs)
if oldtxscount != newtxscount && errReturn {
return nil, nil, types.ErrTxDup
}
chainlog.Debug("ExecBlock", "prevtx", oldtxscount, "newtx", newtxscount)
block.TxHash = merkle.CalcMerkleRootCache(cacheTxs)
block.Txs = types.CacheToTxs(cacheTxs)
//println("1")
receipts, err := util.ExecTx(client, prevStateRoot, block)
if err != nil {
return nil, nil, err
}
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
for i := 0; i < len(receipts.Receipts); i++ {
receipt := receipts.Receipts[i]
if receipt.Ty == types.ExecErr {
chainlog.Error("exec tx err", "err", receipt)
if errReturn { //认为这个是一个错误的区块
return nil, nil, types.ErrBlockExec
}
deltxlist[i] = true
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)
}
}
}
//check TxHash
calcHash := merkle.CalcMerkleRoot(block.Txs)
if errReturn && !bytes.Equal(calcHash, block.TxHash) {
return nil, nil, types.ErrCheckTxHash
}
block.TxHash = calcHash
//删除无效的交易
var deltx []*types.Transaction
if len(deltxlist) > 0 {
var newtx []*types.Transaction
for i := 0; i < len(block.Txs); i++ {
if deltxlist[i] {
deltx = append(deltx, block.Txs[i])
} else {
newtx = append(newtx, block.Txs[i])
}
}
block.Txs = newtx
block.TxHash = merkle.CalcMerkleRoot(block.Txs)
}
var detail types.BlockDetail
calcHash, err = util.ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync)
if err != nil {
return nil, nil, err
}
//println("2")
if errReturn && !bytes.Equal(block.StateHash, calcHash) {
err = util.ExecKVSetRollback(client, calcHash)
if err != nil {
chainlog.Error("execBlock-->ExecKVSetRollback", "err", err)
}
if len(rdata) > 0 {
for i, rd := range rdata {
rd.OutputReceiptDetails(block.Txs[i].Execer, chainlog)
}
}
return nil, nil, types.ErrCheckStateHash
}
block.StateHash = calcHash
detail.Block = block
detail.Receipts = rdata
if detail.Block.Height > 0 {
err := util.CheckBlock(client, &detail)
if err != nil {
chainlog.Debug("CheckBlock-->", "err=", err)
return nil, deltx, err
}
}
//println("3")
//save to db
// 写数据库失败时需要及时返回错误,防止错误数据被写入localdb中CHAIN33-567
err = util.ExecKVSetCommit(client, block.StateHash)
if err != nil {
return nil, nil, err
}
detail.KV = kvset
detail.PrevStatusHash = prevStateRoot
//get receipts
//save kvset and get state hash
//ulog.Debug("blockdetail-->", "detail=", detail)
//println("4")
return &detail, deltx, nil
return util.ExecBlock(client, prevStateRoot, block, errReturn, sync, true)
}
......@@ -226,6 +226,10 @@ func (chain *BlockChain) ProcGetBlockDetailsMsg(requestblock *types.ReqBlocks) (
//ProcAddBlockMsg 处理从peer对端同步过来的block消息
func (chain *BlockChain) ProcAddBlockMsg(broadcast bool, blockdetail *types.BlockDetail, pid string) (*types.BlockDetail, error) {
beg := types.Now()
defer func() {
chainlog.Info("ProcAddBlockMsg", "cost", types.Since(beg))
}()
block := blockdetail.Block
if block == nil {
chainlog.Error("ProcAddBlockMsg input block is null")
......
......@@ -25,7 +25,7 @@ func TestReindex(t *testing.T) {
chain := mock33.GetBlockChain()
db := chain.GetDB()
kvs := getAllKeys(db)
assert.Equal(t, len(kvs), 20)
assert.Equal(t, len(kvs), 22)
defer mock33.Close()
txs := util.GenCoinsTxs(mock33.GetGenesisKey(), 10)
for i := 0; i < len(txs); i++ {
......
......@@ -97,11 +97,31 @@ func pow2(d int) (p int) {
return p
}
func calcLevel(n int) int {
if n == 1 {
return 1
}
level := 0
for n > 1 {
if n&1 != 0 {
n++
}
n = n / 2
level++
}
return level
}
func getMerkleRootPad(hashes [][]byte, step int) []byte {
level1 := log2(len(hashes))
level1 := calcLevel(len(hashes))
level2 := log2(step)
root := getMerkleRoot(hashes)
var root []byte
cache := make([]byte, 64)
if len(hashes) == 1 {
root = GetHashFromTwoHash(cache, hashes[0], hashes[0])
} else {
root = getMerkleRoot(hashes)
}
for i := 0; i < level2-level1; i++ {
root = GetHashFromTwoHash(cache, root, root)
}
......
......@@ -331,9 +331,17 @@ func BenchmarkGetMerkelRoot2(b *testing.B) {
}
}
var testlen = 14
func TestGetMerkelRoot1(t *testing.T) {
for i := 0; i < 2000; i++ {
ok := testGetMerkelRoot1(t, i)
if !ok {
t.Error("calc merkel root error", i)
return
}
}
}
func testGetMerkelRoot1(t *testing.T, testlen int) bool {
var hashlist [][]byte
for i := 0; i < testlen; i++ {
key := sha256.Sum256([]byte(fmt.Sprint(i)))
......@@ -347,7 +355,10 @@ func TestGetMerkelRoot1(t *testing.T) {
hashlist = append(hashlist, key[:])
}
hash2 := getMerkleRoot(hashlist)
assert.Equal(t, hash1, hash2)
if !bytes.Equal(hash1, hash2) {
println("failed1")
return false
}
hashlist = nil
for i := 0; i < testlen; i++ {
......@@ -355,7 +366,11 @@ func TestGetMerkelRoot1(t *testing.T) {
hashlist = append(hashlist, key[:])
}
hash3, _, _ := Computation(hashlist, 1, 0)
assert.Equal(t, hash1, hash3)
if !bytes.Equal(hash1, hash3) {
println("failed2")
return false
}
return true
}
func TestLog2(t *testing.T) {
......
......@@ -188,7 +188,7 @@ func TestExecBlock2(t *testing.T) {
txs := util.GenCoinsTxs(genkey, 2)
block2 := util.CreateNewBlock(block, txs)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true, false)
if err != nil {
t.Error(err)
return
......@@ -205,7 +205,7 @@ func TestExecBlock2(t *testing.T) {
go func() {
txs := util.GenCoinsTxs(genkey, 2)
block3 := util.CreateNewBlock(block2, txs)
detail, _, err := util.ExecBlock(mock33.GetClient(), block2.StateHash, block3, false, true)
detail, _, err := util.ExecBlock(mock33.GetClient(), block2.StateHash, block3, false, true, false)
assert.Nil(t, err)
for _, Receipt := range detail.Receipts {
if Receipt.GetTy() != 2 {
......@@ -234,7 +234,7 @@ func TestSameTx(t *testing.T) {
newblock.Txs = append(newblock.Txs, newblock.Txs[2])
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
assert.Equal(t, hash1, newblock.TxHash)
_, _, err := util.ExecBlock(mock33.GetClient(), nil, newblock, true, true)
_, _, err := util.ExecBlock(mock33.GetClient(), nil, newblock, true, true, false)
assert.Equal(t, types.ErrTxDup, err)
//情况2
......@@ -244,15 +244,17 @@ func TestSameTx(t *testing.T) {
newblock.Txs = append(newblock.Txs, newblock.Txs[4:]...)
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
assert.Equal(t, hash1, newblock.TxHash)
_, _, err = util.ExecBlock(mock33.GetClient(), nil, newblock, true, true)
_, _, err = util.ExecBlock(mock33.GetClient(), nil, newblock, true, true, false)
assert.Equal(t, types.ErrTxDup, err)
}
func TestExecBlock(t *testing.T) {
mock33 := newMockNode()
defer mock33.Close()
block := util.CreateCoinsBlock(mock33.GetGenesisKey(), 1)
util.ExecBlock(mock33.GetClient(), nil, block, false, true)
mock33.WaitHeight(0)
block0 := mock33.GetBlock(0)
block := util.CreateCoinsBlock(mock33.GetGenesisKey(), 10)
util.ExecBlock(mock33.GetClient(), block0.StateHash, block, false, true, false)
}
//区块执行性能更好的一个测试
......@@ -274,7 +276,7 @@ func BenchmarkExecBlock(b *testing.B) {
assert.Equal(b, int64(10000000000000000), account.Balance)
b.ResetTimer()
for i := 0; i < b.N; i++ {
util.ExecBlock(mock33.GetClient(), block0.StateHash, block, false, true)
util.ExecBlock(mock33.GetClient(), block0.StateHash, block, false, true, false)
}
}
......@@ -363,7 +365,7 @@ func TestExecLocalSameTime1(t *testing.T) {
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
block2 := util.CreateNewBlock(block, txs)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true, false)
if err != nil {
t.Error(err)
return
......@@ -393,7 +395,7 @@ func TestExecLocalSameTime0(t *testing.T) {
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
block2 := util.CreateNewBlock(block, txs)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true, false)
if err != nil {
t.Error(err)
return
......@@ -426,7 +428,7 @@ func TestExecLocalSameTimeSetErrKey(t *testing.T) {
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
txs = append(txs, util.CreateTxWithExecer(priv1, "demo2"))
block2 := util.CreateNewBlock(block, txs)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true)
detail, _, err := util.ExecBlock(mock33.GetClient(), block.StateHash, block2, false, true, false)
if err != nil {
t.Error(err)
return
......
......@@ -5,10 +5,13 @@
package solo
import (
"sync"
"testing"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/util/testnode"
"github.com/stretchr/testify/assert"
//加载系统内置store, 不要依赖plugin
_ "github.com/33cn/chain33/system/dapp/init"
......@@ -31,3 +34,35 @@ func TestSolo(t *testing.T) {
}
mock33.WaitHeight(2)
}
func BenchmarkSolo(b *testing.B) {
cfg, subcfg := testnode.GetDefaultConfig()
solocfg, err := types.ModifySubConfig(subcfg.Consensus["solo"], "waitTxMs", 1000)
assert.Nil(b, err)
subcfg.Consensus["solo"] = solocfg
mock33 := testnode.NewWithConfig(cfg, subcfg, nil)
defer mock33.Close()
txs := util.GenCoinsTxs(mock33.GetGenesisKey(), int64(b.N))
var last []byte
var mu sync.Mutex
b.ResetTimer()
done := make(chan struct{}, 10)
for i := 0; i < 10; i++ {
go func(index int) {
for n := index; n < b.N; n += 10 {
reply, err := mock33.GetAPI().SendTx(txs[n])
if err != nil {
assert.Nil(b, err)
}
mu.Lock()
last = reply.GetMsg()
mu.Unlock()
}
done <- struct{}{}
}(i)
}
for i := 0; i < 10; i++ {
<-done
}
mock33.WaitTx(last)
}
......@@ -76,13 +76,7 @@ func (c *CoinsType) GetTypeMap() map[string]int32 {
//DecodePayloadValue 为了性能考虑,coins 是最常用的合约,我们这里不用反射吗,做了特殊化的优化
func (c *CoinsType) DecodePayloadValue(tx *types.Transaction) (string, reflect.Value, error) {
if txc, ok := types.TxCacheGet(tx); ok {
return txc.GetPayloadValue()
}
txc := types.NewTransactionCache(tx)
name, value, err := c.decodePayloadValue(tx)
txc.SetPayloadValue(name, value, err)
types.TxCacheSet(tx, txc)
return name, value, err
}
......
package types
var gbuffer *buffer
//系统并非线程安全
func init() {
gbuffer = newBuffer(20 * 1024 * 1024)
}
//Buffer 一个连续的byte 空间,永远不会被释放
type buffer struct {
data []byte
offset int
}
//新建一个buffer 对象
func newBuffer(total int) *buffer {
return &buffer{data: make([]byte, total), offset: 0}
}
//BufferReset 重置buffer
func BufferReset() {
gbuffer.offset = 0
}
//BufferAlloc 部分空间
func BufferAlloc(size int) []byte {
if gbuffer.offset+size > 0 {
return make([]byte, size)
}
b := gbuffer.data[gbuffer.offset : gbuffer.offset+size]
gbuffer.offset += size
return b
}
//BufferAllocCap alloc cap
func BufferAllocCap(size int) []byte {
if gbuffer.offset+size > 0 {
return make([]byte, 0, size)
}
b := gbuffer.data[gbuffer.offset:gbuffer.offset]
gbuffer.offset += size
return b
}
package types
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAlloc(t *testing.T) {
BufferReset()
data := BufferAlloc(10)
assert.Equal(t, 10, len(data))
data2 := BufferAlloc(10)
assert.Equal(t, 10, len(data2))
data3 := BufferAllocCap(10)
assert.Equal(t, 0, len(data3))
data4 := BufferAllocCap(10)
assert.Equal(t, 0, len(data4))
for i := range data {
data[i] = 1
}
for i := range data2 {
data2[i] = 2
}
for i := range data {
assert.Equal(t, byte(1), data[i])
}
for i := range data2 {
assert.Equal(t, byte(2), data2[i])
}
}
func BenchmarkAlloc(b *testing.B) {
BufferReset()
data := make([][]byte, b.N)
for i := 0; i < b.N; i++ {
a := BufferAlloc(10)
if a == nil {
panic("alloc")
}
data[i] = a
}
}
func BenchmarkAllocMake(b *testing.B) {
data := make([][]byte, b.N)
for i := 0; i < b.N; i++ {
a := make([]byte, 10)
if a == nil {
panic("alloc")
}
data[i] = a
}
}
......@@ -508,13 +508,7 @@ func (base *ExecTypeBase) DecodePayload(tx *Transaction) (Message, error) {
//DecodePayloadValue 解析tx交易中的payload具体Value值
func (base *ExecTypeBase) DecodePayloadValue(tx *Transaction) (string, reflect.Value, error) {
if txc, ok := txCache.Get(tx); ok {
return txc.(*TransactionCache).GetPayloadValue()
}
txc := NewTransactionCache(tx)
name, value, err := base.decodePayloadValue(tx)
txc.SetPayloadValue(name, value, err)
txCache.Add(tx, txc)
return name, value, err
}
......
......@@ -207,3 +207,10 @@ func TestParseExpire(t *testing.T) {
assert.Equal(t, int64(123000000000), exp)
}
func BenchmarkHash(b *testing.B) {
tx := &Transaction{Payload: []byte("xxxxxxxxxxxxdggrgrgrgrgrgrgrrhthththhth"), Execer: []byte("hello")}
for i := 0; i < b.N; i++ {
tx.Hash()
}
}
......@@ -43,7 +43,7 @@ singleMode=true
batchsync=false
isRecordBlockSequence=true
isParaChain=false
enableTxQuickIndex=false
enableTxQuickIndex=true
[p2p]
seeds=[]
......@@ -68,9 +68,9 @@ grpcFuncWhitelist=["*"]
[mempool]
name="timeline"
poolCacheSize=10240
poolCacheSize=102400
minTxFee=100000
maxTxNumPerAccount=10000
maxTxNumPerAccount=100000
[consensus]
name="solo"
......@@ -89,7 +89,7 @@ futureBlockTime = 16
ticketFrozenTime = 5
ticketWithdrawTime = 10
ticketMinerWaitTime = 2
maxTxNumber = 1600
maxTxNumber = 10000
targetTimespan = 2304
targetTimePerBlock = 16
......
......@@ -32,7 +32,7 @@ func init() {
rand.Seed(types.Now().UnixNano())
}
var chainlog = log15.New("module", "util")
var ulog = log15.New("module", "util")
//GetParaExecName : 如果 name 没有 paraName 前缀,那么加上这个前缀
func GetParaExecName(paraName string, name string) string {
......@@ -220,15 +220,15 @@ func CreateCoinsBlock(priv crypto.PrivKey, n int64) *types.Block {
}
// ExecBlock : just exec block
func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, errReturn bool, sync bool) (*types.BlockDetail, []*types.Transaction, error) {
func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, errReturn, sync, checkblock bool) (*types.BlockDetail, []*types.Transaction, error) {
//发送执行交易给execs模块
//通过consensus module 再次检查
ulog := chainlog
ulog.Debug("ExecBlock", "height------->", block.Height, "ntx", len(block.Txs))
beg := types.Now()
defer func() {
ulog.Info("ExecBlock", "height", block.Height, "ntx", len(block.Txs), "writebatchsync", sync, "cost", types.Since(beg))
}()
if errReturn && block.Height > 0 && !block.CheckSign() {
//block的来源不是自己的mempool,而是别人的区块
return nil, nil, types.ErrSign
......@@ -241,18 +241,21 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
if err != nil {
return nil, nil, err
}
ulog.Info("ExecBlock", "CheckTxDup", types.Since(beg))
beg = types.Now()
newtxscount := len(cacheTxs)
if oldtxscount != newtxscount && errReturn {
return nil, nil, types.ErrTxDup
}
ulog.Debug("ExecBlock", "prevtx", oldtxscount, "newtx", newtxscount)
block.TxHash = merkle.CalcMerkleRootCache(cacheTxs)
block.Txs = types.CacheToTxs(cacheTxs)
//println("1")
receipts, err := ExecTx(client, prevStateRoot, block)
if err != nil {
return nil, nil, err
}
ulog.Info("ExecBlock", "ExecTx", types.Since(beg))
beg = types.Now()
var kvset []*types.KeyValue
var deltxlist = make(map[int]bool)
var rdata []*types.ReceiptData //save to db receipt log
......@@ -270,34 +273,45 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
kvset = append(kvset, receipt.KV...)
}
kvset = DelDupKey(kvset)
//check TxHash
calcHash := merkle.CalcMerkleRoot(block.Txs)
if errReturn && !bytes.Equal(calcHash, block.TxHash) {
return nil, nil, types.ErrCheckTxHash
}
block.TxHash = calcHash
//删除无效的交易
var deltx []*types.Transaction
if len(deltxlist) > 0 {
var newtx []*types.Transaction
index := 0
for i := 0; i < len(block.Txs); i++ {
if deltxlist[i] {
deltx = append(deltx, block.Txs[i])
} else {
newtx = append(newtx, block.Txs[i])
continue
}
block.Txs[index] = block.Txs[i]
cacheTxs[index] = cacheTxs[i]
index++
}
block.Txs = newtx
block.TxHash = merkle.CalcMerkleRoot(block.Txs)
block.Txs = block.Txs[0:index]
cacheTxs = cacheTxs[0:index]
}
//交易有执行不成功的,报错(TxHash一定不同)
if len(deltx) > 0 && errReturn {
return nil, nil, types.ErrCheckTxHash
}
//检查block的txhash值
calcHash := merkle.CalcMerkleRootCache(cacheTxs)
if errReturn && !bytes.Equal(calcHash, block.TxHash) {
return nil, nil, types.ErrCheckTxHash
}
ulog.Info("ExecBlock", "CalcMerkleRootCache", types.Since(beg))
beg = types.Now()
block.TxHash = calcHash
var detail types.BlockDetail
calcHash, err = ExecKVMemSet(client, prevStateRoot, block.Height, kvset, sync)
if err != nil {
return nil, nil, err
}
//println("2")
if errReturn && !bytes.Equal(block.StateHash, calcHash) {
ExecKVSetRollback(client, calcHash)
err = ExecKVSetRollback(client, calcHash)
if err != nil {
ulog.Error("execBlock-->ExecKVSetRollback", "err", err)
}
if len(rdata) > 0 {
for i, rd := range rdata {
rd.OutputReceiptDetails(block.Txs[i].Execer, ulog)
......@@ -308,7 +322,22 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
block.StateHash = calcHash
detail.Block = block
detail.Receipts = rdata
ExecKVSetCommit(client, block.StateHash)
if detail.Block.Height > 0 && checkblock {
err := CheckBlock(client, &detail)
if err != nil {
ulog.Debug("CheckBlock-->", "err=", err)
return nil, deltx, err
}
}
ulog.Info("ExecBlock", "CheckBlock", types.Since(beg))
beg = types.Now()
// 写数据库失败时需要及时返回错误,防止错误数据被写入localdb中CHAIN33-567
err = ExecKVSetCommit(client, block.StateHash)
if err != nil {
return nil, nil, err
}
detail.KV = kvset
detail.PrevStatusHash = prevStateRoot
return &detail, deltx, nil
}
......@@ -362,7 +391,7 @@ func ExecAndCheckBlock2(qclient queue.Client, block *types.Block, txs []*types.T
//ExecAndCheckBlockCB :
func ExecAndCheckBlockCB(qclient queue.Client, block *types.Block, txs []*types.Transaction, cb func(int, *types.ReceiptData) error) (*types.Block, error) {
block2 := CreateNewBlock(block, txs)
detail, deltx, err := ExecBlock(qclient, block.StateHash, block2, false, true)
detail, deltx, err := ExecBlock(qclient, block.StateHash, block2, false, true, false)
if err != nil {
return nil, err
}
......@@ -410,7 +439,7 @@ func ResetDatadir(cfg *types.Config, datadir string) string {
}
datadir = filepath.Join(dir, datadir[6:])
}
chainlog.Info("current user data dir is ", "dir", datadir)
ulog.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)
......
......@@ -40,31 +40,35 @@ func (c *Cache) Purge() {
// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) {
c.lock.Lock()
defer c.lock.Unlock()
return c.lru.Add(key, value)
evicted = c.lru.Add(key, value)
c.lock.Unlock()
return evicted
}
// Get looks up a key's value from the cache.
func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
c.lock.Lock()
defer c.lock.Unlock()
return c.lru.Get(key)
value, ok = c.lru.Get(key)
c.lock.Unlock()
return value, ok
}
// Contains checks if a key is in the cache, without updating the
// recent-ness or deleting it for being stale.
func (c *Cache) Contains(key interface{}) bool {
c.lock.RLock()
defer c.lock.RUnlock()
return c.lru.Contains(key)
containKey := c.lru.Contains(key)
c.lock.RUnlock()
return containKey
}
// Peek returns the key value (or undefined if not found) without updating
// the "recently used"-ness of the key.
func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
c.lock.RLock()
defer c.lock.RUnlock()
return c.lru.Peek(key)
value, ok = c.lru.Peek(key)
c.lock.RUnlock()
return value, ok
}
// ContainsOrAdd checks if a key is in the cache without updating the
......@@ -98,13 +102,15 @@ func (c *Cache) RemoveOldest() {
// Keys returns a slice of the keys in the cache, from oldest to newest.
func (c *Cache) Keys() []interface{} {
c.lock.RLock()
defer c.lock.RUnlock()
return c.lru.Keys()
keys := c.lru.Keys()
c.lock.RUnlock()
return keys
}
// Len returns the number of items in the cache.
func (c *Cache) Len() int {
c.lock.RLock()
defer c.lock.RUnlock()
return c.lru.Len()
length := c.lru.Len()
c.lock.RUnlock()
return length
}
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