Commit aa055772 authored by kingwang's avatar kingwang Committed by 33cn

update chain33 08/12

parent 34c30c13
......@@ -24,24 +24,22 @@ import (
//var
var (
blockLastHeight = []byte("blockLastHeight")
bodyPrefix = []byte("Body:")
LastSequence = []byte("LastSequence")
headerPrefix = []byte("Header:")
heightToHeaderPrefix = []byte("HH:")
hashPrefix = []byte("Hash:")
tdPrefix = []byte("TD:")
heightToHashKeyPrefix = []byte("Height:")
seqToHashKey = []byte("Seq:")
HashToSeqPrefix = []byte("HashToSeq:")
seqCBPrefix = []byte("SCB:")
seqCBLastNumPrefix = []byte("SCBL:")
paraSeqToHashKey = []byte("ParaSeq:")
HashToParaSeqPrefix = []byte("HashToParaSeq:")
LastParaSequence = []byte("LastParaSequence")
storeLog = chainlog.New("submodule", "store")
AddBlock int64 = 1
DelBlock int64 = 2
blockLastHeight = []byte("blockLastHeight")
bodyPrefix = []byte("Body:")
LastSequence = []byte("LastSequence")
headerPrefix = []byte("Header:")
heightToHeaderPrefix = []byte("HH:")
hashPrefix = []byte("Hash:")
tdPrefix = []byte("TD:")
heightToHashKeyPrefix = []byte("Height:")
seqToHashKey = []byte("Seq:")
HashToSeqPrefix = []byte("HashToSeq:")
seqCBPrefix = []byte("SCB:")
seqCBLastNumPrefix = []byte("SCBL:")
paraSeqToHashKey = []byte("ParaSeq:")
HashToParaSeqPrefix = []byte("HashToParaSeq:")
LastParaSequence = []byte("LastParaSequence")
storeLog = chainlog.New("submodule", "store")
)
//GetLocalDBKeyList 获取本地键值列表
......@@ -590,7 +588,7 @@ func (bs *BlockStore) SaveBlock(storeBatch dbm.Batch, blockdetail *types.BlockDe
if bs.saveSequence || bs.isParaChain {
//存储记录block序列执行的type add
lastSequence, err = bs.saveBlockSequence(storeBatch, hash, height, AddBlock, sequence)
lastSequence, err = bs.saveBlockSequence(storeBatch, hash, height, types.AddBlock, sequence)
if err != nil {
storeLog.Error("SaveBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err)
return lastSequence, err
......@@ -619,7 +617,7 @@ func (bs *BlockStore) DelBlock(storeBatch dbm.Batch, blockdetail *types.BlockDet
if bs.saveSequence || bs.isParaChain {
//存储记录block序列执行的type del
lastSequence, err := bs.saveBlockSequence(storeBatch, hash, height, DelBlock, sequence)
lastSequence, err := bs.saveBlockSequence(storeBatch, hash, height, types.DelBlock, sequence)
if err != nil {
storeLog.Error("DelBlock SaveBlockSequence", "height", height, "hash", common.ToHex(hash), "error", err)
return lastSequence, err
......@@ -1029,7 +1027,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
sequenceBytes := types.Encode(&types.Int64{Data: newSequence})
// hash->seq 只记录add block时的hash和seq对应关系
if Type == AddBlock {
if Type == types.AddBlock {
storeBatch.Set(calcHashToSequenceKey(hash, bs.isParaChain), sequenceBytes)
}
......@@ -1054,7 +1052,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
// hash->seq 只记录add block时的hash和seq对应关系
sequenceBytes := types.Encode(&types.Int64{Data: mainSeq})
if Type == AddBlock {
if Type == types.AddBlock {
storeBatch.Set(calcHashToMainSequenceKey(hash), sequenceBytes)
}
storeBatch.Set(LastSequence, sequenceBytes)
......@@ -1301,7 +1299,7 @@ func (bs *BlockStore) CreateSequences(batchSize int64) {
// seq->hash
var blockSequence types.BlockSequence
blockSequence.Hash = header.Hash
blockSequence.Type = AddBlock
blockSequence.Type = types.AddBlock
BlockSequenceByte, err := proto.Marshal(&blockSequence)
if err != nil {
storeLog.Error("CreateSequences Marshal BlockSequence", "height", i, "hash", common.ToHex(header.Hash), "error", err)
......
......@@ -601,7 +601,7 @@ func testGetBlockSequences(t *testing.T, chain *blockchain.BlockChain) {
Sequences, err := chain.GetBlockSequences(&reqBlock)
if err == nil && Sequences != nil {
for _, sequence := range Sequences.Items {
if sequence.Type != blockchain.AddBlock {
if sequence.Type != types.AddBlock {
t.Error("testGetBlockSequences sequence type check error")
}
}
......
......@@ -23,22 +23,29 @@ func (chain *BlockChain) GetParaTxByTitle(seq *types.ReqParaTxByTitle) (*types.P
return nil, err
}
//获取区块的seq信息
req := &types.ReqBlocks{Start: seq.Start, End: seq.End, IsDetail: false, Pid: []string{}}
sequences, err := chain.GetBlockSequences(req)
if err != nil {
filterlog.Error("GetParaTxByTitle:GetBlockSequences", "err", err.Error())
return nil, err
//对获取区块的起始和结束值做校验,最多一次取1000个区块,防止取的数据过大导致内存异常
if seq.End > seq.Start && (seq.End-seq.Start > types.MaxBlockCountPerTime) {
seq.End = seq.Start + types.MaxBlockCountPerTime - 1
}
//通过区块hash获取区块信息
var reqHashes types.ReqHashes
for _, item := range sequences.Items {
if item != nil {
reqHashes.Hashes = append(reqHashes.Hashes, item.GetHash())
var sequences *types.BlockSequences
if seq.IsSeq {
req := &types.ReqBlocks{Start: seq.Start, End: seq.End, IsDetail: false, Pid: []string{}}
sequences, err = chain.GetBlockSequences(req)
if err != nil {
filterlog.Error("GetParaTxByTitle:GetBlockSequences", "err", err.Error())
return nil, err
}
for _, item := range sequences.Items {
if item != nil {
reqHashes.Hashes = append(reqHashes.Hashes, item.GetHash())
}
}
} else {
reqHashes = chain.getBlockHashes(seq.Start, seq.End)
}
//通过区块hash获取区块信息
blocks, err := chain.GetBlockByHashes(reqHashes.Hashes)
if err != nil {
filterlog.Error("GetParaTxByTitle:GetBlockByHashes", "err", err)
......@@ -51,7 +58,11 @@ func (chain *BlockChain) GetParaTxByTitle(seq *types.ReqParaTxByTitle) (*types.P
for i, block := range blocks.Items {
if block != nil {
paraTx = block.FilterParaTxsByTitle(seq.Title)
paraTx.Type = sequences.Items[i].GetType()
if seq.IsSeq {
paraTx.Type = sequences.Items[i].GetType()
} else {
paraTx.Type = types.AddBlock
}
} else {
paraTx = nil
}
......@@ -60,13 +71,24 @@ func (chain *BlockChain) GetParaTxByTitle(seq *types.ReqParaTxByTitle) (*types.P
return &paraTxs, err
}
//checkInputParam 入参检测,主要检测seq的end的值已经title是否合法
func (chain *BlockChain) checkInputParam(seq *types.ReqParaTxByTitle) error {
//checkInputParam 入参检测,主要检测req的end的值以及title是否合法
func (chain *BlockChain) checkInputParam(req *types.ReqParaTxByTitle) error {
var err error
var lastblock int64
//入参数校验
blockLastSeq, err := chain.blockStore.LoadBlockLastSequence()
if err != nil || seq.End > blockLastSeq || blockLastSeq < 0 || !strings.HasPrefix(seq.Title, types.ParaKeyX) {
filterlog.Error("checkInputParam", "blockLastSeq", blockLastSeq, "seq", seq, "err", err)
if req.GetStart() > req.GetEnd() {
chainlog.Error("checkInputParam input must Start <= End:", "Start", req.Start, "End", req.End)
return types.ErrEndLessThanStartHeight
}
//需要区分是通过seq/height来获取平行链交易
if req.IsSeq {
lastblock, err = chain.blockStore.LoadBlockLastSequence()
} else {
lastblock = chain.GetBlockHeight()
}
if err != nil || req.End > lastblock || lastblock < 0 || !strings.HasPrefix(req.Title, types.ParaKeyX) {
filterlog.Error("checkInputParam", "lastblock", lastblock, "req", req, "err", err)
return types.ErrInvalidParam
}
return nil
......
......@@ -142,17 +142,36 @@ func TestGetParaTxByTitle(t *testing.T) {
time.Sleep(sendTxWait)
}
var req types.ReqParaTxByTitle
//通过seq获取para交易
req.Start = 0
req.End = curheight
req.Title = "user.p.hyb."
testgetParaTxByTitle(t, blockchain, &req, false, false, nil)
req.IsSeq = true
testgetParaTxByTitle(t, blockchain, &req, 0)
//通过height获取para交易
req.IsSeq = false
testgetParaTxByTitle(t, blockchain, &req, 0)
//通过height获取para交易
req.IsSeq = false
req.End = curheight + 1
testgetParaTxByTitle(t, blockchain, &req, 1)
chainlog.Info("TestGetParaTxByTitle end --------------------")
}
func testgetParaTxByTitle(t *testing.T, blockchain *blockchain.BlockChain, req *types.ReqParaTxByTitle, isGroup bool, haveMainTx bool, hashs []string) {
func testgetParaTxByTitle(t *testing.T, blockchain *blockchain.BlockChain, req *types.ReqParaTxByTitle, flag int) {
count := req.End - req.Start + 1
ParaTxDetails, err := blockchain.GetParaTxByTitle(req)
require.NoError(t, err)
if flag == 0 {
require.NoError(t, err)
}
if flag == 1 {
assert.Equal(t, err, types.ErrInvalidParam)
return
}
itemsLen := len(ParaTxDetails.Items)
assert.Equal(t, count, int64(itemsLen))
for i, txDetail := range ParaTxDetails.Items {
if txDetail != nil {
......
......@@ -481,6 +481,14 @@ func (chain *BlockChain) delParaChainBlockDetail(msg *queue.Message) {
func (chain *BlockChain) addParaChainBlockDetail(msg *queue.Message) {
parablockDetail := msg.Data.(*types.ParaChainBlockDetail)
//根据配置chain.cfgBatchSync和parablockDetail.IsSync
//来决定写数据库时是否需要刷盘,主要是为了同步阶段提高执行区块的效率
if !parablockDetail.IsSync && !chain.cfgBatchSync {
atomic.CompareAndSwapInt32(&chain.isbatchsync, 1, 0)
} else {
atomic.CompareAndSwapInt32(&chain.isbatchsync, 0, 1)
}
chainlog.Debug("EventAddParaChainBlockDetail", "height", parablockDetail.Blockdetail.Block.Height, "hash", common.HashHex(parablockDetail.Blockdetail.Block.Hash()))
// 平行链上P2P模块关闭,不用广播区块
blockDetail, err := chain.ProcAddParaChainBlockMsg(false, parablockDetail, "self")
......
......@@ -10,11 +10,18 @@ import (
)
//GetBlockByHashes 通过blockhash 获取对应的block信息
//从数据库获取区块不能太多,防止内存异常。一次最多获取100M区块数据从数据库
func (chain *BlockChain) GetBlockByHashes(hashes [][]byte) (respblocks *types.BlockDetails, err error) {
var blocks types.BlockDetails
size := 0
for _, hash := range hashes {
block, err := chain.LoadBlockByHash(hash)
if err == nil && block != nil {
size += block.Size()
if size > types.MaxBlockSizePerTime {
chainlog.Error("GetBlockByHashes:overflow", "MaxBlockSizePerTime", types.MaxBlockSizePerTime)
return &blocks, nil
}
blocks.Items = append(blocks.Items, block)
} else {
blocks.Items = append(blocks.Items, nil)
......@@ -264,3 +271,18 @@ func (chain *BlockChain) ProcAddBlockMsg(broadcast bool, blockdetail *types.Bloc
chainlog.Debug("ProcAddBlockMsg result:", "height", blockdetail.Block.Height, "ismain", ismain, "isorphan", isorphan, "hash", common.ToHex(blockdetail.Block.Hash()), "err", err)
return blockdetail, err
}
//getBlockHashes 获取指定height区间对应的blockhashes
func (chain *BlockChain) getBlockHashes(startheight, endheight int64) types.ReqHashes {
var reqHashes types.ReqHashes
for i := startheight; i <= endheight; i++ {
hash, err := chain.blockStore.GetBlockHashByHeight(i)
if hash == nil || err != nil {
storeLog.Error("getBlockHashesByHeight", "height", i, "error", err)
reqHashes.Hashes = append(reqHashes.Hashes, nil)
} else {
reqHashes.Hashes = append(reqHashes.Hashes, hash)
}
}
return reqHashes
}
......@@ -50,6 +50,16 @@ func (chain *BlockChain) Rollback() {
if err != nil {
panic(fmt.Sprintln("rollback LoadBlockByHeight err :", err))
}
if chain.cfg.RollbackSave { //本地保存临时区块
lastHeightSave := false
if i == startHeight {
lastHeightSave = true
}
err = chain.WriteBlockToDbTemp(blockdetail.Block, lastHeightSave)
if err != nil {
panic(fmt.Sprintln("rollback WriteBlockToDbTemp fail", "height", blockdetail.Block.Height, "error ", err))
}
}
sequence := int64(-1)
if chain.isParaChain {
// 获取平行链的seq
......@@ -64,17 +74,6 @@ func (chain *BlockChain) Rollback() {
}
// 删除storedb中的状态高度
chain.sendDelStore(blockdetail.Block.StateHash, blockdetail.Block.Height)
// 删除之后,本地保存临时区块
if chain.cfg.RollbackSave {
lastHeightSave := false
if i == startHeight {
lastHeightSave = true
}
err = chain.WriteBlockToDbTemp(blockdetail.Block, lastHeightSave)
if err != nil {
panic(fmt.Sprintln("rollback WriteBlockToDbTemp fail", "height", blockdetail.Block.Height, "error ", err))
}
}
chainlog.Info("chain rollback ", "height: ", i, "blockheight", blockdetail.Block.Height, "hash", common.ToHex(blockdetail.Block.Hash()), "state hash", common.ToHex(blockdetail.Block.StateHash))
}
}
......
......@@ -5,9 +5,12 @@
package blockchain
import (
"fmt"
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestTask(t *testing.T) {
......@@ -69,27 +72,18 @@ func TestTaskTimeOut(t *testing.T) {
t.Log("task not start")
return
}
defer task.Cancel()
timeoutHeight := make(chan int64, 1)
timeoutcb := func(height int64) {
timeOutProc(height)
fmt.Println("timeout:height", height)
timeoutHeight <- height
}
task.Start(1, 10, nil, timeoutcb)
task.Start(1, 11, nil, timeoutcb)
perm := rand.Perm(10)
for i := 0; i < len(perm); i++ {
time.Sleep(time.Millisecond * 10)
task.Done(int64(perm[i]) + 1)
if i < len(perm)-1 && !task.InProgress() {
task.Cancel()
t.Log("task not done, but InProgress is false")
return
}
if i == len(perm)-1 && task.InProgress() {
task.Cancel()
t.Log("task is done, but InProgress is true")
return
}
}
}
func timeOutProc(height int64) {
chainlog.Info("timeOutProc", "height", height)
h := <-timeoutHeight
assert.Equal(t, h, int64(11))
}
......@@ -5,6 +5,7 @@
package commands
import (
"bytes"
"encoding/json"
"fmt"
"os"
......@@ -27,15 +28,16 @@ func StatCmd() *cobra.Command {
}
cmd.AddCommand(
GetTotalCoinsCmd(),
GetExecBalanceCmd(),
getTotalCoinsCmd(),
getExecBalanceCmd(),
totalFeeCmd(),
)
return cmd
}
// GetTotalCoinsCmd get total coins
func GetTotalCoinsCmd() *cobra.Command {
// getTotalCoinsCmd get total coins
func getTotalCoinsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "total_coins",
Short: "Get total amount of a token (default: bty of current height)",
......@@ -57,43 +59,32 @@ func totalCoins(cmd *cobra.Command, args []string) {
height, _ := cmd.Flags().GetInt64("height")
actual, _ := cmd.Flags().GetString("actual")
if height == -1 {
rpc, err := jsonclient.NewJSONClient(rpcAddr)
rpc, err := jsonclient.NewJSONClient(rpcAddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var stateHashHex string
if height < 0 {
header, err := getLastBlock(rpc)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res rpctypes.Header
err = rpc.Call("Chain33.GetLastHeader", nil, &res)
height = header.Height
stateHashHex = header.StateHash
} else {
blocks, err := getBlocks(height, height, rpc)
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintf(os.Stderr, "GetBlocksErr:%s", err.Error())
return
}
height = res.Height
stateHashHex = blocks.Items[0].Block.StateHash
}
// 获取高度statehash
params := rpctypes.BlockParam{
Start: height,
End: height,
//Isdetail: false,
Isdetail: true,
}
rpc, err := jsonclient.NewJSONClient(rpcAddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res rpctypes.BlockDetails
err = rpc.Call("Chain33.GetBlocks", params, &res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
stateHash, err := common.FromHex(res.Items[0].Block.StateHash)
stateHash, err := common.FromHex(stateHashHex)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
......@@ -104,32 +95,14 @@ func totalCoins(cmd *cobra.Command, args []string) {
resp := commandtypes.GetTotalCoinsResult{}
if symbol == "bty" {
//查询高度blockhash
params := types.ReqInt{Height: height}
var res1 rpctypes.ReplyHash
err = rpc.Call("Chain33.GetBlockHash", params, &res1)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
blockHash, err := common.FromHex(res1.Hash)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
//查询手续费
key := append([]byte("TotalFeeKey:"), blockHash...)
params2 := types.LocalDBGet{Keys: [][]byte{key}}
var res2 types.TotalFee
err = rpc.Call("Chain33.QueryTotalFee", params2, &res2)
//查询历史总手续费
fee, err := queryTotalFeeWithHeight(height, rpc)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
resp.TxCount = res2.TxCount
resp.TxCount = fee.TxCount
var issueCoins int64
//只适用bty主网计算
if height < 2270000 {
......@@ -137,7 +110,7 @@ func totalCoins(cmd *cobra.Command, args []string) {
} else { //挖矿产量降低30->8
issueCoins = 22*2269999 + height*8
}
totalAmount = (317430000+issueCoins)*types.Coin - res2.Fee
totalAmount = (317430000+issueCoins)*types.Coin - fee.Fee
resp.TotalAmount = strconv.FormatFloat(float64(totalAmount)/float64(types.Coin), 'f', 4, 64)
} else {
var req types.ReqString
......@@ -210,8 +183,8 @@ func totalCoins(cmd *cobra.Command, args []string) {
fmt.Println(string(data))
}
// GetExecBalanceCmd get exec-addr balance of specific addr
func GetExecBalanceCmd() *cobra.Command {
// getExecBalanceCmd get exec-addr balance of specific addr
func getExecBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "exec_balance",
Short: "Get the exec amount of a token of one address (default: all exec-addr bty of current height of one addr)",
......@@ -238,43 +211,30 @@ func execBalance(cmd *cobra.Command, args []string) {
execAddr, _ := cmd.Flags().GetString("exec_addr")
height, _ := cmd.Flags().GetInt64("height")
if height == -1 {
rpc, err := jsonclient.NewJSONClient(rpcAddr)
rpc, err := jsonclient.NewJSONClient(rpcAddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var stateHashHex string
if height < 0 {
header, err := getLastBlock(rpc)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res rpctypes.Header
err = rpc.Call("Chain33.GetLastHeader", nil, &res)
stateHashHex = header.StateHash
} else {
blocks, err := getBlocks(height, height, rpc)
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintf(os.Stderr, "GetBlocksErr:%s", err.Error())
return
}
height = res.Height
}
// 获取高度statehash
params := rpctypes.BlockParam{
Start: height,
End: height,
//Isdetail: false,
Isdetail: true,
stateHashHex = blocks.Items[0].Block.StateHash
}
rpc, err := jsonclient.NewJSONClient(rpcAddr)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
var res rpctypes.BlockDetails
err = rpc.Call("Chain33.GetBlocks", params, &res)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
stateHash, err := common.FromHex(res.Items[0].Block.StateHash)
stateHash, err := common.FromHex(stateHashHex)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
......@@ -293,7 +253,6 @@ func execBalance(cmd *cobra.Command, args []string) {
ExecAddr: []byte(execAddr),
Execer: exec,
}
reqParam.StateHash = stateHash
if len(execAddr) > 0 {
reqParam.Count = 1 //由于精确匹配一条记录,所以这里设定为1
......@@ -366,3 +325,152 @@ func convertReplyToResult(reply *types.ReplyGetExecBalance, result *commandtypes
result.ExecBalances = append(result.ExecBalances, item)
}
}
// totalFeeCmd query total fee command
func totalFeeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "total_fee",
Short: "query total transaction fee, support specific block height interval [start, end]",
Run: totalFee,
}
cmd.Flags().Int64P("start_height", "s", 0, "start block height, default 0")
cmd.Flags().Int64P("end_height", "e", -1, "end block height, default current block height")
return cmd
}
func totalFee(cmd *cobra.Command, args []string) {
rpcAddr, _ := cmd.Flags().GetString("rpc_laddr")
start, _ := cmd.Flags().GetInt64("start_height")
end, _ := cmd.Flags().GetInt64("end_height")
var startFeeAmount, endFeeAmount int64
rpc, err := jsonclient.NewJSONClient(rpcAddr)
if err != nil {
fmt.Fprintf(os.Stderr, "NewJsonClientErr:%s\n", err.Error())
return
}
if start < 0 {
start = 0
}
if start > 0 {
totalFee, err := queryTotalFeeWithHeight(start-1, rpc)
if err != nil {
fmt.Fprintf(os.Stderr, "QueryStartFeeErr:%s\n", err.Error())
return
}
startFeeAmount = totalFee.Fee
}
if end < 0 {
//last block fee
currentHeight, totalFee, err := queryCurrentTotalFee(rpc)
if err != nil {
fmt.Fprintf(os.Stderr, "QueryCurrentTotalFeeErr:%s\n", err.Error())
return
}
endFeeAmount = totalFee.Fee
end = currentHeight
} else {
totalFee, err := queryTotalFeeWithHeight(end, rpc)
if err != nil {
fmt.Fprintf(os.Stderr, "QueryEndFeeErr:%s\n", err.Error())
return
}
endFeeAmount = totalFee.Fee
}
fee := endFeeAmount - startFeeAmount
if fee < 0 {
fee = 0
}
resp := fmt.Sprintf(`{"startHeight":%d,"endHeight":%d, "totalFee":%s}`, start, end, commandtypes.FormatAmountValue2Display(fee))
buf := &bytes.Buffer{}
err = json.Indent(buf, []byte(resp), "", " ")
if err != nil {
fmt.Fprintf(os.Stderr, "JsonIndentResultErr:%s\n", err.Error())
return
}
fmt.Println(buf.String())
}
//get last block header
func getLastBlock(rpc *jsonclient.JSONClient) (*rpctypes.Header, error) {
res := &rpctypes.Header{}
err := rpc.Call("Chain33.GetLastHeader", nil, &res)
if err != nil {
return nil, err
}
return res, nil
}
//get block hash with height
func getBlockHash(height int64, rpc *jsonclient.JSONClient) (string, error) {
params := types.ReqInt{Height: height}
var res rpctypes.ReplyHash
err := rpc.Call("Chain33.GetBlockHash", params, &res)
if err != nil {
return "", err
}
return res.Hash, nil
}
func queryCurrentTotalFee(rpc *jsonclient.JSONClient) (int64, *types.TotalFee, error) {
header, err := getLastBlock(rpc)
if err != nil {
return 0, nil, err
}
fee, err := queryTotalFeeWithHash(header.Hash, rpc)
if err != nil {
return 0, nil, err
}
return header.Height, fee, nil
}
func queryTotalFeeWithHeight(height int64, rpc *jsonclient.JSONClient) (*types.TotalFee, error) {
hash, err := getBlockHash(height, rpc)
if err != nil {
return nil, err
}
fee, err := queryTotalFeeWithHash(hash, rpc)
if err != nil {
return nil, err
}
return fee, nil
}
func queryTotalFeeWithHash(blockHash string, rpc *jsonclient.JSONClient) (*types.TotalFee, error) {
hash, err := common.FromHex(blockHash)
if err != nil {
return nil, err
}
//查询手续费
params := types.LocalDBGet{Keys: [][]byte{hash[:]}}
res := &types.TotalFee{}
err = rpc.Call("Chain33.QueryTotalFee", params, &res)
if err != nil {
return nil, err
}
return res, nil
}
func getBlocks(start, end int64, rpc *jsonclient.JSONClient) (*rpctypes.BlockDetails, error) {
// 获取blocks
params := rpctypes.BlockParam{
Start: start,
End: end,
//Isdetail: false,
Isdetail: true,
}
res := &rpctypes.BlockDetails{}
err := rpc.Call("Chain33.GetBlocks", params, &res)
if err != nil {
return nil, err
}
return res, nil
}
......@@ -171,14 +171,14 @@ func addWalletListTxsFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("count", "c", 0, "number of transactions")
cmd.MarkFlagRequired("count")
cmd.Flags().Int32P("direction", "d", 1, "query direction (0: pre page, 1: next page)")
cmd.Flags().Int32P("direction", "d", 0, "query direction (0: pre page, 1: next page)")
}
func walletListTxs(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
txHash, _ := cmd.Flags().GetString("from")
count, _ := cmd.Flags().GetInt32("count")
direction, _ := cmd.Flags().GetInt32("dir")
direction, _ := cmd.Flags().GetInt32("direction")
params := rpctypes.ReqWalletTransactionList{
FromTx: txHash,
Count: count,
......
......@@ -116,6 +116,9 @@ func NewTree(db dbm.DB, sync bool) *Tree {
// 使能情况下非空创建当前整tree的缓存
if enableMemTree && memTree == nil {
memTree = NewTreeMap(50 * 10000)
if tkCloseCacheLen == 0 {
tkCloseCacheLen = 10 * 10000
}
tkCloseCache = NewTreeARC(int(tkCloseCacheLen))
}
return &Tree{
......
......@@ -244,3 +244,8 @@ func (blockDetail *BlockDetail) filterParaTxGroup(tx *Transaction, index int) ([
}
return txDetails, endIdx
}
// Size 获取blockDetail的Size
func (blockDetail *BlockDetail) Size() int {
return Size(blockDetail)
}
......@@ -1531,9 +1531,11 @@ func (m *BlockSequences) GetItems() []*BlockSequence {
//平行链区块详细信息
// blockdetail : 区块详细信息
// sequence :区块序列号
// isSync:写数据库时是否需要刷盘
type ParaChainBlockDetail struct {
Blockdetail *BlockDetail `protobuf:"bytes,1,opt,name=blockdetail,proto3" json:"blockdetail,omitempty"`
Sequence int64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"`
IsSync bool `protobuf:"varint,3,opt,name=isSync,proto3" json:"isSync,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -1578,6 +1580,13 @@ func (m *ParaChainBlockDetail) GetSequence() int64 {
return 0
}
func (m *ParaChainBlockDetail) GetIsSync() bool {
if m != nil {
return m.IsSync
}
return false
}
// 定义para交易结构
type ParaTxDetails struct {
Items []*ParaTxDetail `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
......@@ -1749,6 +1758,7 @@ type ReqParaTxByTitle struct {
Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
IsSeq bool `protobuf:"varint,4,opt,name=isSeq,proto3" json:"isSeq,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -1800,6 +1810,13 @@ func (m *ReqParaTxByTitle) GetTitle() string {
return ""
}
func (m *ReqParaTxByTitle) GetIsSeq() bool {
if m != nil {
return m.IsSeq
}
return false
}
func init() {
proto.RegisterType((*Header)(nil), "types.Header")
proto.RegisterType((*Block)(nil), "types.Block")
......@@ -1839,86 +1856,87 @@ func init() {
func init() { proto.RegisterFile("blockchain.proto", fileDescriptor_e9ac6287ce250c9a) }
var fileDescriptor_e9ac6287ce250c9a = []byte{
// 1287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xdd, 0x6e, 0x1b, 0xc5,
0x17, 0xd7, 0xfa, 0x23, 0xb1, 0x8f, 0xed, 0xfc, 0xd3, 0xf9, 0x1b, 0x64, 0x45, 0x40, 0xdd, 0xa1,
0x14, 0x53, 0x8a, 0x8b, 0x1a, 0x54, 0x2a, 0x04, 0x12, 0x24, 0x45, 0x6a, 0x9a, 0x52, 0xc2, 0xc4,
0xcd, 0x05, 0x77, 0xdb, 0xf5, 0x24, 0x5e, 0xd5, 0xde, 0xdd, 0xec, 0xcc, 0x1a, 0x9b, 0x47, 0x40,
0xe2, 0x11, 0x78, 0x01, 0xc4, 0x3b, 0xf1, 0x2a, 0xe8, 0x9c, 0x99, 0xf1, 0x7e, 0x90, 0x14, 0x7a,
0xc9, 0xdd, 0x9c, 0xaf, 0x39, 0xbf, 0xf9, 0xcd, 0x9c, 0x73, 0x76, 0x61, 0xf7, 0xe5, 0x3c, 0x0e,
0x5e, 0x05, 0x33, 0x3f, 0x8c, 0xc6, 0x49, 0x1a, 0xeb, 0x98, 0x35, 0xf5, 0x3a, 0x91, 0x6a, 0xef,
0x86, 0x4e, 0xfd, 0x48, 0xf9, 0x81, 0x0e, 0x63, 0x6b, 0xd9, 0xeb, 0x06, 0xf1, 0x62, 0xe1, 0x24,
0xfe, 0x47, 0x0d, 0xb6, 0x9e, 0x48, 0x7f, 0x2a, 0x53, 0x36, 0x80, 0xed, 0xa5, 0x4c, 0x55, 0x18,
0x47, 0x03, 0x6f, 0xe8, 0x8d, 0xea, 0xc2, 0x89, 0xec, 0x3d, 0x80, 0xc4, 0x4f, 0x65, 0xa4, 0x9f,
0xf8, 0x6a, 0x36, 0xa8, 0x0d, 0xbd, 0x51, 0x57, 0x14, 0x34, 0xec, 0x6d, 0xd8, 0xd2, 0x2b, 0xb2,
0xd5, 0xc9, 0x66, 0x25, 0xf6, 0x0e, 0xb4, 0x95, 0xf6, 0xb5, 0x24, 0x53, 0x83, 0x4c, 0xb9, 0x02,
0xa3, 0x66, 0x32, 0xbc, 0x98, 0xe9, 0x41, 0x93, 0xd2, 0x59, 0x09, 0xa3, 0xe8, 0x38, 0x93, 0x70,
0x21, 0x07, 0x5b, 0x64, 0xca, 0x15, 0x88, 0x52, 0xaf, 0x0e, 0xe3, 0x2c, 0xd2, 0x83, 0xb6, 0x41,
0x69, 0x45, 0xc6, 0xa0, 0x31, 0xc3, 0x44, 0x40, 0x89, 0x68, 0x8d, 0xc8, 0xa7, 0xe1, 0xf9, 0x79,
0x18, 0x64, 0x73, 0xbd, 0x1e, 0x74, 0x86, 0xde, 0xa8, 0x27, 0x0a, 0x1a, 0x36, 0x86, 0xb6, 0x0a,
0x2f, 0x22, 0x5f, 0x67, 0xa9, 0x1c, 0xb4, 0x86, 0xde, 0xa8, 0xf3, 0x60, 0x77, 0x4c, 0xd4, 0x8d,
0x4f, 0x9d, 0x5e, 0xe4, 0x2e, 0xfc, 0xcf, 0x1a, 0x34, 0x0f, 0x10, 0xcb, 0x7f, 0x84, 0xad, 0x7f,
0x3a, 0xff, 0x1e, 0xb4, 0x16, 0x7e, 0x18, 0x51, 0xca, 0x2e, 0xa5, 0xdc, 0xc8, 0x18, 0x4b, 0x6b,
0x93, 0xb5, 0x47, 0x5b, 0x17, 0x34, 0x6f, 0xca, 0x1d, 0xbb, 0x0d, 0x75, 0xbd, 0x52, 0x83, 0xed,
0x61, 0x7d, 0xd4, 0x79, 0xc0, 0xac, 0xe7, 0x24, 0x7f, 0x9f, 0x02, 0xcd, 0xfc, 0x1e, 0x6c, 0x11,
0xc1, 0x8a, 0x71, 0x68, 0x86, 0x5a, 0x2e, 0xd4, 0xc0, 0xa3, 0x88, 0xae, 0x8d, 0x20, 0xab, 0x30,
0x26, 0xfe, 0x14, 0x80, 0xe4, 0x53, 0x79, 0x79, 0x78, 0x80, 0x2f, 0x20, 0xf2, 0x17, 0x92, 0x2e,
0xa4, 0x2d, 0x68, 0xcd, 0x76, 0xa1, 0xfe, 0x42, 0x3c, 0xa3, 0x6b, 0x68, 0x0b, 0x5c, 0x22, 0x93,
0x32, 0x0a, 0xe2, 0xa9, 0x24, 0xfe, 0xdb, 0xc2, 0x4a, 0xfc, 0x21, 0x74, 0xf2, 0xbd, 0x14, 0xfb,
0xb0, 0x9c, 0xfe, 0x46, 0x31, 0x3d, 0xb9, 0x38, 0x0c, 0x09, 0xb4, 0x9c, 0x12, 0xb3, 0x45, 0xd9,
0xc2, 0xbe, 0x08, 0x5c, 0xb2, 0x3b, 0x50, 0x57, 0xf2, 0x92, 0xf2, 0x77, 0x1e, 0xf4, 0x2b, 0x9b,
0x64, 0x32, 0x0a, 0xa4, 0x40, 0x07, 0x76, 0x17, 0xb6, 0xa6, 0x52, 0xfb, 0xe1, 0x9c, 0x50, 0xe5,
0x04, 0x91, 0xeb, 0x63, 0xb2, 0x08, 0xeb, 0xc1, 0x3f, 0x85, 0xb6, 0xdb, 0x41, 0xb1, 0xf7, 0xa1,
0xa1, 0xe4, 0xa5, 0x83, 0xf9, 0xbf, 0x4a, 0x06, 0x41, 0x46, 0xfe, 0xb5, 0xc5, 0x78, 0x12, 0x4e,
0x11, 0x63, 0x12, 0x4e, 0x2d, 0x49, 0xb8, 0x44, 0xa6, 0xe9, 0xc9, 0x58, 0x94, 0x15, 0xa6, 0xc9,
0xc4, 0x1f, 0x41, 0xb7, 0x00, 0x45, 0xb1, 0x51, 0x99, 0x9e, 0xab, 0xe0, 0x5a, 0x7e, 0xc6, 0xb0,
0x6d, 0x3a, 0x0c, 0x62, 0x2d, 0x05, 0xf5, 0x6c, 0x90, 0x31, 0x3b, 0xff, 0x27, 0x00, 0xd6, 0xff,
0x6a, 0xb4, 0x23, 0xd8, 0x9e, 0x19, 0xbb, 0xc5, 0xbb, 0x53, 0xda, 0x46, 0x09, 0x67, 0xe6, 0x33,
0xe8, 0x11, 0x9e, 0xef, 0x97, 0x32, 0x5d, 0x86, 0xf2, 0x27, 0x76, 0x0b, 0x1a, 0x68, 0xa3, 0xdd,
0xfe, 0x96, 0x9e, 0x4c, 0xc5, 0xfe, 0x52, 0x2b, 0xf7, 0x97, 0x3d, 0x68, 0x99, 0x4a, 0x95, 0x6a,
0x50, 0x1f, 0xd6, 0xb1, 0x56, 0x9c, 0xcc, 0x7f, 0xf7, 0xec, 0xe3, 0x31, 0x47, 0xcf, 0x19, 0xf5,
0xae, 0x65, 0x94, 0x8d, 0xa1, 0x95, 0xca, 0x40, 0x86, 0x89, 0xc6, 0x83, 0x14, 0x49, 0x14, 0x46,
0xfd, 0xd8, 0xd7, 0xbe, 0xd8, 0xf8, 0xb0, 0x9b, 0x50, 0x3b, 0x3e, 0xa3, 0xcc, 0xf9, 0x35, 0x1f,
0xcb, 0xf5, 0x99, 0x3f, 0xcf, 0xa4, 0xa8, 0x1d, 0x9f, 0xb1, 0x3b, 0xb0, 0x93, 0xa4, 0x72, 0x79,
0xaa, 0x7d, 0x9d, 0xa9, 0x42, 0x17, 0xa9, 0x68, 0xf9, 0x43, 0x68, 0x09, 0xb7, 0xe9, 0xdd, 0x02,
0x08, 0x73, 0x29, 0x3b, 0x65, 0x10, 0x39, 0x00, 0xfe, 0x14, 0xda, 0x27, 0x69, 0xb8, 0xf4, 0x83,
0xf5, 0xf1, 0x19, 0xfb, 0x0a, 0x93, 0x59, 0x61, 0x12, 0xbf, 0x92, 0x91, 0x0d, 0x7f, 0xcb, 0x86,
0x9f, 0x94, 0x8c, 0xa2, 0xe2, 0xcc, 0xd7, 0xb0, 0x53, 0xf6, 0x60, 0x7d, 0x68, 0x6a, 0xbb, 0x0f,
0x5e, 0xb5, 0x11, 0xcc, 0x75, 0x1c, 0x45, 0x53, 0xb9, 0xa2, 0xeb, 0x68, 0x0a, 0x27, 0x9a, 0x36,
0x3a, 0x2b, 0xb5, 0x51, 0x6a, 0xf9, 0x86, 0xa6, 0xc6, 0xb5, 0x34, 0x71, 0x05, 0x7d, 0x77, 0xfc,
0x6f, 0xa2, 0x69, 0x7e, 0xa2, 0x8f, 0x4b, 0x54, 0x78, 0x85, 0x70, 0xe7, 0x5e, 0xb8, 0x8c, 0x31,
0xb4, 0x37, 0x27, 0xb2, 0xcf, 0x70, 0xb7, 0x7a, 0x72, 0x91, 0xbb, 0xf0, 0x11, 0x30, 0xbb, 0xcb,
0xe1, 0x4c, 0x06, 0xaf, 0x26, 0xab, 0x67, 0xa1, 0xa2, 0x91, 0x25, 0xd3, 0xd4, 0x30, 0xdf, 0x16,
0xb4, 0xe6, 0x6b, 0xe8, 0x1c, 0xe2, 0x20, 0x37, 0x17, 0xc6, 0x6e, 0x43, 0x2f, 0xc8, 0x52, 0x1a,
0x1e, 0xa6, 0x11, 0x9b, 0xde, 0x52, 0x56, 0xb2, 0x21, 0x74, 0x16, 0x72, 0x91, 0xc4, 0xf1, 0xfc,
0x34, 0xfc, 0x59, 0xda, 0x97, 0x5b, 0x54, 0x31, 0x0e, 0xdd, 0x85, 0xba, 0xf8, 0x21, 0x93, 0x99,
0x24, 0x97, 0x3a, 0xb9, 0x94, 0x74, 0xdc, 0x87, 0xb6, 0x90, 0x97, 0xb6, 0xfd, 0xf6, 0xa1, 0xa9,
0xb4, 0x9f, 0xba, 0x84, 0x46, 0xc0, 0x72, 0x94, 0xd1, 0xd4, 0x26, 0xc0, 0x25, 0x96, 0x45, 0xa8,
0x1e, 0xe7, 0xad, 0xab, 0x25, 0x36, 0xb2, 0x2b, 0xde, 0x06, 0x1d, 0x0f, 0x97, 0xfc, 0x16, 0x74,
0xbe, 0x2b, 0xa0, 0x62, 0xd0, 0x50, 0x88, 0xc6, 0xe4, 0xa0, 0x35, 0xbf, 0x0b, 0xbb, 0x42, 0x26,
0xf3, 0x35, 0xe1, 0xb0, 0xe7, 0xcb, 0xa7, 0x9f, 0x57, 0x9c, 0x7e, 0xfc, 0x37, 0xcf, 0xb6, 0xc2,
0x83, 0x78, 0xba, 0x76, 0x13, 0xc6, 0x7b, 0xed, 0x84, 0x79, 0xe3, 0xba, 0x2b, 0xce, 0xc8, 0xfa,
0x6b, 0x67, 0x64, 0xa3, 0x3a, 0x23, 0xf9, 0x3d, 0x80, 0x23, 0x75, 0xe8, 0x67, 0x17, 0x33, 0xfd,
0x22, 0x41, 0xef, 0x23, 0x15, 0x90, 0x94, 0x25, 0x74, 0x92, 0x96, 0x28, 0x68, 0xf8, 0x23, 0xd8,
0x39, 0x52, 0xcf, 0x75, 0x72, 0x48, 0xcd, 0x7b, 0x1d, 0x05, 0x58, 0xd2, 0xa1, 0x8a, 0x74, 0x12,
0xd0, 0x9d, 0xac, 0xa3, 0xc0, 0x46, 0x55, 0xb4, 0xfc, 0x57, 0x0f, 0x7a, 0xf4, 0x6a, 0xbe, 0x5d,
0xc9, 0x20, 0xd3, 0x71, 0x8a, 0x8c, 0x4d, 0xd3, 0x70, 0x29, 0x53, 0x5b, 0x4f, 0x56, 0xc2, 0xd3,
0x9c, 0x67, 0x51, 0xf0, 0x1c, 0xe7, 0xa4, 0x19, 0x8a, 0x1b, 0xb9, 0xfc, 0x05, 0x52, 0xaf, 0x7e,
0x81, 0xf4, 0xa1, 0x99, 0xf8, 0xa9, 0xbf, 0xb0, 0x5d, 0xc5, 0x08, 0xa8, 0x95, 0x2b, 0x9d, 0xfa,
0xf4, 0x59, 0xd2, 0x15, 0x46, 0xe0, 0x9f, 0xdb, 0xce, 0xeb, 0x66, 0x1c, 0x5e, 0x34, 0xed, 0xea,
0x99, 0x8f, 0x33, 0xda, 0x90, 0x41, 0x63, 0xb2, 0x4e, 0xdc, 0x6b, 0xa5, 0x35, 0xff, 0x12, 0x76,
0x4a, 0x81, 0xd8, 0xa1, 0x4a, 0x33, 0xe3, 0xea, 0x11, 0x6a, 0x47, 0xc7, 0x0c, 0xfa, 0x27, 0x7e,
0xea, 0x13, 0x13, 0xc5, 0x76, 0xfc, 0x19, 0x74, 0xa8, 0xe7, 0xda, 0x09, 0xeb, 0x5d, 0x3b, 0x61,
0x8b, 0x6e, 0x48, 0x95, 0xb2, 0x09, 0x2c, 0xc6, 0x8d, 0xcc, 0xbf, 0x80, 0x1e, 0x66, 0x9a, 0xac,
0xdc, 0x3c, 0xfc, 0xa8, 0x0c, 0xf3, 0xff, 0xae, 0x19, 0x14, 0x9c, 0x1c, 0xca, 0x15, 0x74, 0x8b,
0x6a, 0xe4, 0x01, 0x9d, 0x5d, 0x11, 0xe0, 0x9a, 0x7d, 0x80, 0x0f, 0x1e, 0xc7, 0x92, 0x6d, 0x2e,
0x95, 0x59, 0x65, 0x8d, 0xec, 0x13, 0x68, 0x6b, 0x07, 0xa1, 0x32, 0x1a, 0x36, 0x59, 0x73, 0x0f,
0xfe, 0x8b, 0x07, 0xad, 0x4d, 0xda, 0x3e, 0x34, 0x43, 0x6a, 0xac, 0x1e, 0x7d, 0x16, 0x1a, 0x81,
0x71, 0xa8, 0xe9, 0x95, 0x4d, 0x7a, 0x55, 0x09, 0xd5, 0xf4, 0x8a, 0xdd, 0x83, 0x6d, 0x5b, 0x1d,
0x95, 0x8f, 0x95, 0x62, 0x01, 0x39, 0x17, 0x7c, 0x89, 0x49, 0x1a, 0xc7, 0xe7, 0x8a, 0xfa, 0x40,
0x57, 0x58, 0x89, 0x9f, 0x60, 0x9d, 0x5f, 0x1a, 0x26, 0x0e, 0xd6, 0x93, 0x50, 0xcf, 0xe5, 0xbf,
0x6e, 0x3a, 0x38, 0x2c, 0x30, 0xc0, 0x7e, 0xc2, 0x19, 0xe1, 0xe0, 0xe6, 0x8f, 0xef, 0x5e, 0x84,
0x7a, 0x96, 0xbd, 0x1c, 0x07, 0xf1, 0xe2, 0xfe, 0xfe, 0x7e, 0x10, 0xdd, 0xa7, 0x7f, 0xa2, 0xfd,
0xfd, 0xfb, 0x84, 0xef, 0xe5, 0x16, 0xfd, 0xf4, 0xec, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0x00,
0x7f, 0xd3, 0xa9, 0x30, 0x0d, 0x00, 0x00,
// 1307 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0x5f, 0x6f, 0x1b, 0x45,
0x10, 0xd7, 0xf9, 0x4f, 0x62, 0x8f, 0x9d, 0x90, 0x2e, 0x06, 0x59, 0x11, 0x50, 0x77, 0x29, 0xc5,
0x94, 0xe2, 0xa2, 0x06, 0x95, 0x0a, 0x81, 0x04, 0x49, 0x91, 0x9a, 0xa6, 0x94, 0xb0, 0x71, 0xf3,
0xc0, 0xdb, 0xf5, 0xbc, 0x89, 0x57, 0xb5, 0xef, 0x2e, 0xb7, 0x7b, 0xc1, 0xe6, 0x89, 0x67, 0x24,
0x3e, 0x02, 0x5f, 0x00, 0xf1, 0x9d, 0xf8, 0x2a, 0x68, 0x66, 0x77, 0x7d, 0x77, 0x26, 0x2d, 0xf4,
0x91, 0xb7, 0x9d, 0x3f, 0xbb, 0xf3, 0x9b, 0xdf, 0xee, 0xcc, 0xdc, 0xc1, 0xce, 0xf3, 0x59, 0x12,
0xbd, 0x88, 0xa6, 0xa1, 0x8a, 0x47, 0x69, 0x96, 0x98, 0x84, 0x35, 0xcd, 0x32, 0x95, 0x7a, 0xf7,
0x9a, 0xc9, 0xc2, 0x58, 0x87, 0x91, 0x51, 0x89, 0xb3, 0xec, 0x76, 0xa3, 0x64, 0x3e, 0xf7, 0x12,
0xff, 0xb3, 0x06, 0x1b, 0x8f, 0x64, 0x38, 0x91, 0x19, 0xeb, 0xc3, 0xe6, 0xa5, 0xcc, 0xb4, 0x4a,
0xe2, 0x7e, 0x30, 0x08, 0x86, 0x75, 0xe1, 0x45, 0xf6, 0x1e, 0x40, 0x1a, 0x66, 0x32, 0x36, 0x8f,
0x42, 0x3d, 0xed, 0xd7, 0x06, 0xc1, 0xb0, 0x2b, 0x4a, 0x1a, 0xf6, 0x36, 0x6c, 0x98, 0x05, 0xd9,
0xea, 0x64, 0x73, 0x12, 0x7b, 0x07, 0xda, 0xda, 0x84, 0x46, 0x92, 0xa9, 0x41, 0xa6, 0x42, 0x81,
0xbb, 0xa6, 0x52, 0x9d, 0x4f, 0x4d, 0xbf, 0x49, 0xe1, 0x9c, 0x84, 0xbb, 0x28, 0x9d, 0xb1, 0x9a,
0xcb, 0xfe, 0x06, 0x99, 0x0a, 0x05, 0xa2, 0x34, 0x8b, 0x83, 0x24, 0x8f, 0x4d, 0xbf, 0x6d, 0x51,
0x3a, 0x91, 0x31, 0x68, 0x4c, 0x31, 0x10, 0x50, 0x20, 0x5a, 0x23, 0xf2, 0x89, 0x3a, 0x3b, 0x53,
0x51, 0x3e, 0x33, 0xcb, 0x7e, 0x67, 0x10, 0x0c, 0xb7, 0x44, 0x49, 0xc3, 0x46, 0xd0, 0xd6, 0xea,
0x3c, 0x0e, 0x4d, 0x9e, 0xc9, 0x7e, 0x6b, 0x10, 0x0c, 0x3b, 0xf7, 0x76, 0x46, 0x44, 0xdd, 0xe8,
0xc4, 0xeb, 0x45, 0xe1, 0xc2, 0xff, 0xaa, 0x41, 0x73, 0x1f, 0xb1, 0xfc, 0x4f, 0xd8, 0xfa, 0xb7,
0xfc, 0x77, 0xa1, 0x35, 0x0f, 0x55, 0x4c, 0x21, 0xbb, 0x14, 0x72, 0x25, 0xe3, 0x5e, 0x5a, 0xdb,
0xa8, 0x5b, 0x74, 0x74, 0x49, 0xf3, 0xba, 0xdc, 0xb1, 0x9b, 0x50, 0x37, 0x0b, 0xdd, 0xdf, 0x1c,
0xd4, 0x87, 0x9d, 0x7b, 0xcc, 0x79, 0x8e, 0x8b, 0xf7, 0x29, 0xd0, 0xcc, 0xef, 0xc0, 0x06, 0x11,
0xac, 0x19, 0x87, 0xa6, 0x32, 0x72, 0xae, 0xfb, 0x01, 0xed, 0xe8, 0xba, 0x1d, 0x64, 0x15, 0xd6,
0xc4, 0x1f, 0x03, 0x90, 0x7c, 0x22, 0x2f, 0x0e, 0xf6, 0xf1, 0x05, 0xc4, 0xe1, 0x5c, 0xd2, 0x85,
0xb4, 0x05, 0xad, 0xd9, 0x0e, 0xd4, 0x9f, 0x89, 0x27, 0x74, 0x0d, 0x6d, 0x81, 0x4b, 0x64, 0x52,
0xc6, 0x51, 0x32, 0x91, 0xc4, 0x7f, 0x5b, 0x38, 0x89, 0xdf, 0x87, 0x4e, 0x71, 0x96, 0x66, 0x1f,
0x56, 0xc3, 0x5f, 0x2b, 0x87, 0x27, 0x17, 0x8f, 0x21, 0x85, 0x96, 0x57, 0x62, 0xb4, 0x38, 0x9f,
0xbb, 0x17, 0x81, 0x4b, 0x76, 0x0b, 0xea, 0x5a, 0x5e, 0x50, 0xfc, 0xce, 0xbd, 0xde, 0xda, 0x21,
0xb9, 0x8c, 0x23, 0x29, 0xd0, 0x81, 0xdd, 0x86, 0x8d, 0x89, 0x34, 0xa1, 0x9a, 0x11, 0xaa, 0x82,
0x20, 0x72, 0x7d, 0x48, 0x16, 0xe1, 0x3c, 0xf8, 0xa7, 0xd0, 0xf6, 0x27, 0x68, 0xf6, 0x3e, 0x34,
0xb4, 0xbc, 0xf0, 0x30, 0xdf, 0x58, 0x8b, 0x20, 0xc8, 0xc8, 0xbf, 0x76, 0x18, 0x8f, 0xd5, 0x04,
0x31, 0xa6, 0x6a, 0xe2, 0x48, 0xc2, 0x25, 0x32, 0x4d, 0x4f, 0xc6, 0xa1, 0x5c, 0x63, 0x9a, 0x4c,
0xfc, 0x01, 0x74, 0x4b, 0x50, 0x34, 0x1b, 0x56, 0xe9, 0xb9, 0x0a, 0xae, 0xe3, 0x67, 0x04, 0x9b,
0xb6, 0xc3, 0x20, 0xd6, 0xca, 0xa6, 0x2d, 0xb7, 0xc9, 0x9a, 0xbd, 0xff, 0x23, 0x00, 0xe7, 0x7f,
0x35, 0xda, 0x21, 0x6c, 0x4e, 0xad, 0xdd, 0xe1, 0xdd, 0xae, 0x1c, 0xa3, 0x85, 0x37, 0xf3, 0x29,
0x6c, 0x11, 0x9e, 0xef, 0x2f, 0x65, 0x76, 0xa9, 0xe4, 0x4f, 0xec, 0x06, 0x34, 0xd0, 0x46, 0xa7,
0xfd, 0x23, 0x3c, 0x99, 0xca, 0xfd, 0xa5, 0x56, 0xed, 0x2f, 0xbb, 0xd0, 0xb2, 0x95, 0x2a, 0x75,
0xbf, 0x3e, 0xa8, 0x63, 0xad, 0x78, 0x99, 0xff, 0x11, 0xb8, 0xc7, 0x63, 0x53, 0x2f, 0x18, 0x0d,
0x5e, 0xca, 0x28, 0x1b, 0x41, 0x2b, 0x93, 0x91, 0x54, 0xa9, 0xc1, 0x44, 0xca, 0x24, 0x0a, 0xab,
0x7e, 0x18, 0x9a, 0x50, 0xac, 0x7c, 0xd8, 0x75, 0xa8, 0x1d, 0x9d, 0x52, 0xe4, 0xe2, 0x9a, 0x8f,
0xe4, 0xf2, 0x34, 0x9c, 0xe5, 0x52, 0xd4, 0x8e, 0x4e, 0xd9, 0x2d, 0xd8, 0x4e, 0x33, 0x79, 0x79,
0x62, 0x42, 0x93, 0xeb, 0x52, 0x17, 0x59, 0xd3, 0xf2, 0xfb, 0xd0, 0x12, 0xfe, 0xd0, 0xdb, 0x25,
0x10, 0xf6, 0x52, 0xb6, 0xab, 0x20, 0x0a, 0x00, 0xfc, 0x31, 0xb4, 0x8f, 0x33, 0x75, 0x19, 0x46,
0xcb, 0xa3, 0x53, 0xf6, 0x15, 0x06, 0x73, 0xc2, 0x38, 0x79, 0x21, 0x63, 0xb7, 0xfd, 0x2d, 0xb7,
0xfd, 0xb8, 0x62, 0x14, 0x6b, 0xce, 0x7c, 0x09, 0xdb, 0x55, 0x0f, 0xd6, 0x83, 0xa6, 0x71, 0xe7,
0xe0, 0x55, 0x5b, 0xc1, 0x5e, 0xc7, 0x61, 0x3c, 0x91, 0x0b, 0xba, 0x8e, 0xa6, 0xf0, 0xa2, 0x6d,
0xa3, 0xd3, 0x4a, 0x1b, 0xa5, 0x96, 0x6f, 0x69, 0x6a, 0xbc, 0x94, 0x26, 0xae, 0xa1, 0xe7, 0xd3,
0xff, 0x26, 0x9e, 0x14, 0x19, 0x7d, 0x5c, 0xa1, 0x22, 0x28, 0x6d, 0xf7, 0xee, 0xa5, 0xcb, 0x18,
0x41, 0x7b, 0x95, 0x91, 0x7b, 0x86, 0x3b, 0xeb, 0x99, 0x8b, 0xc2, 0x85, 0x0f, 0x81, 0xb9, 0x53,
0x0e, 0xa6, 0x32, 0x7a, 0x31, 0x5e, 0x3c, 0x51, 0x9a, 0x46, 0x96, 0xcc, 0x32, 0xcb, 0x7c, 0x5b,
0xd0, 0x9a, 0x2f, 0xa1, 0x73, 0x80, 0x83, 0xdc, 0x5e, 0x18, 0xbb, 0x09, 0x5b, 0x51, 0x9e, 0xd1,
0xf0, 0xb0, 0x8d, 0xd8, 0xf6, 0x96, 0xaa, 0x92, 0x0d, 0xa0, 0x33, 0x97, 0xf3, 0x34, 0x49, 0x66,
0x27, 0xea, 0x67, 0xe9, 0x5e, 0x6e, 0x59, 0xc5, 0x38, 0x74, 0xe7, 0xfa, 0xfc, 0x87, 0x5c, 0xe6,
0x92, 0x5c, 0xea, 0xe4, 0x52, 0xd1, 0xf1, 0x10, 0xda, 0x42, 0x5e, 0xb8, 0xf6, 0xdb, 0x83, 0xa6,
0x36, 0x61, 0xe6, 0x03, 0x5a, 0x01, 0xcb, 0x51, 0xc6, 0x13, 0x17, 0x00, 0x97, 0x58, 0x16, 0x4a,
0x3f, 0x2c, 0x5a, 0x57, 0x4b, 0xac, 0x64, 0x5f, 0xbc, 0x0d, 0x4a, 0x0f, 0x97, 0xfc, 0x06, 0x74,
0xbe, 0x2b, 0xa1, 0x62, 0xd0, 0xd0, 0x88, 0xc6, 0xc6, 0xa0, 0x35, 0xbf, 0x0d, 0x3b, 0x42, 0xa6,
0xb3, 0x25, 0xe1, 0x70, 0xf9, 0x15, 0xd3, 0x2f, 0x28, 0x4f, 0x3f, 0xfe, 0x7b, 0xe0, 0x5a, 0xe1,
0x7e, 0x32, 0x59, 0xfa, 0x09, 0x13, 0xbc, 0x72, 0xc2, 0xbc, 0x76, 0xdd, 0x95, 0x67, 0x64, 0xfd,
0x95, 0x33, 0xb2, 0xb1, 0x3e, 0x23, 0xf9, 0x1d, 0x80, 0x43, 0x7d, 0x10, 0xe6, 0xe7, 0x53, 0xf3,
0x2c, 0x45, 0xef, 0x43, 0x1d, 0x91, 0x94, 0xa7, 0x94, 0x49, 0x4b, 0x94, 0x34, 0xfc, 0x01, 0x6c,
0x1f, 0xea, 0xa7, 0x26, 0x3d, 0xa0, 0xe6, 0xbd, 0x8c, 0x23, 0x2c, 0x69, 0xa5, 0x63, 0x93, 0x46,
0x74, 0x27, 0xcb, 0x38, 0x72, 0xbb, 0xd6, 0xb4, 0xfc, 0xb7, 0x00, 0xb6, 0xe8, 0xd5, 0x7c, 0xbb,
0x90, 0x51, 0x6e, 0x92, 0x0c, 0x19, 0x9b, 0x64, 0xea, 0x52, 0x66, 0xae, 0x9e, 0x9c, 0x84, 0xd9,
0x9c, 0xe5, 0x71, 0xf4, 0x14, 0xe7, 0xa4, 0x1d, 0x8a, 0x2b, 0xb9, 0xfa, 0x05, 0x52, 0x5f, 0xff,
0x02, 0xe9, 0x41, 0x33, 0x0d, 0xb3, 0x70, 0xee, 0xba, 0x8a, 0x15, 0x50, 0x2b, 0x17, 0x26, 0x0b,
0xe9, 0xb3, 0xa4, 0x2b, 0xac, 0xc0, 0x3f, 0x77, 0x9d, 0xd7, 0xcf, 0x38, 0xbc, 0x68, 0x3a, 0x35,
0xb0, 0x1f, 0x67, 0x74, 0x20, 0x83, 0xc6, 0x78, 0x99, 0xfa, 0xd7, 0x4a, 0x6b, 0xfe, 0x25, 0x6c,
0x57, 0x36, 0x62, 0x87, 0xaa, 0xcc, 0x8c, 0xab, 0x47, 0xa8, 0x1b, 0x1d, 0xbf, 0x04, 0xd0, 0x3b,
0x0e, 0xb3, 0x90, 0xa8, 0x28, 0xf7, 0xe3, 0xcf, 0xa0, 0x43, 0x4d, 0xd7, 0x8d, 0xd8, 0xe0, 0xa5,
0x23, 0xb6, 0xec, 0x86, 0x5c, 0x69, 0x17, 0xc1, 0x81, 0x5c, 0xc9, 0xc8, 0xaf, 0xd2, 0x78, 0x47,
0xee, 0xd1, 0x3b, 0x89, 0x7f, 0x01, 0x5b, 0x88, 0x60, 0xbc, 0xf0, 0x83, 0xf2, 0xa3, 0x2a, 0xfe,
0x37, 0x7d, 0x97, 0x28, 0x39, 0x79, 0xf8, 0x0b, 0xe8, 0x96, 0xd5, 0x48, 0x10, 0x3a, 0xfb, 0xea,
0xc0, 0x35, 0xfb, 0x00, 0x2b, 0x01, 0xe7, 0x95, 0xeb, 0x3a, 0x6b, 0x43, 0xcc, 0x19, 0xd9, 0x27,
0xd0, 0x36, 0x1e, 0xc2, 0xda, 0xcc, 0x58, 0x45, 0x2d, 0x3c, 0xf8, 0xaf, 0x01, 0xb4, 0x56, 0x61,
0x7b, 0xd0, 0x54, 0xd4, 0x71, 0x03, 0xfa, 0x5e, 0xb4, 0x02, 0xe3, 0x50, 0x33, 0x0b, 0x17, 0xf4,
0xaa, 0xda, 0xaa, 0x99, 0x05, 0xbb, 0x03, 0x9b, 0xae, 0x6c, 0xd6, 0xbe, 0x62, 0xca, 0x95, 0xe5,
0x5d, 0x90, 0xc2, 0x34, 0x4b, 0x92, 0x33, 0x4d, 0x0d, 0xa2, 0x2b, 0x9c, 0xc4, 0xcf, 0xb0, 0x01,
0x5c, 0x58, 0x26, 0xf6, 0x97, 0x63, 0x65, 0x66, 0xf2, 0x3f, 0x77, 0x23, 0x9c, 0x22, 0xb8, 0xc1,
0x7d, 0xdb, 0x59, 0x81, 0x32, 0xd2, 0x27, 0xf2, 0x82, 0x9e, 0x6e, 0x4b, 0x58, 0x61, 0xff, 0xfa,
0x8f, 0xef, 0x9e, 0x2b, 0x33, 0xcd, 0x9f, 0x8f, 0xa2, 0x64, 0x7e, 0x77, 0x6f, 0x2f, 0x8a, 0xef,
0xd2, 0x2f, 0xd4, 0xde, 0xde, 0x5d, 0x42, 0xfd, 0x7c, 0x83, 0xfe, 0x91, 0xf6, 0xfe, 0x0e, 0x00,
0x00, 0xff, 0xff, 0x56, 0x6a, 0x91, 0x86, 0x5f, 0x0d, 0x00, 0x00,
}
......@@ -61,7 +61,10 @@ const (
Float1E4 float64 = 10000.0
AirDropMinIndex uint32 = 100000000 //通过钱包的seed生成一个空投地址,最小index索引
AirDropMaxIndex uint32 = 101000000 //通过钱包的seed生成一个空投地址,最大index索引
MaxBlockCountPerTime int64 = 1000 //从数据库中一次性获取block的最大数 1000个
MaxBlockSizePerTime = 100000000 //从数据库中一次性获取block的最大size100M
AddBlock int64 = 1
DelBlock int64 = 2
)
//全局账户私钥/公钥
......
......@@ -203,9 +203,11 @@ message BlockSequences {
//平行链区块详细信息
// blockdetail : 区块详细信息
// sequence :区块序列号
// isSync:写数据库时是否需要刷盘
message ParaChainBlockDetail {
BlockDetail blockdetail = 1;
int64 sequence = 2;
bool isSync = 3;
}
// 定义para交易结构
......@@ -239,4 +241,5 @@ message ReqParaTxByTitle {
int64 start = 1;
int64 end = 2;
string title = 3;
bool isSeq = 4;
}
......@@ -202,10 +202,16 @@ func (store *Store) GetTxDetailByIter(TxList *types.ReqWalletTransactionList) (*
}
var txbytes [][]byte
//FromTx是空字符串时。默认从最新的交易开始取count个
//FromTx是空字符串时,
//Direction == 0从最新的交易开始倒序取count个
//Direction == 1从最早的交易开始正序取count个
if len(TxList.FromTx) == 0 {
list := store.NewListHelper()
txbytes = list.IteratorScanFromLast(CalcTxKey(""), TxList.Count)
if TxList.Direction == 0 {
txbytes = list.IteratorScanFromLast(CalcTxKey(""), TxList.Count)
} else {
txbytes = list.IteratorScanFromFirst(CalcTxKey(""), TxList.Count)
}
if len(txbytes) == 0 {
storelog.Error("GetTxDetailByIter IteratorScanFromLast does not exist tx!")
return nil, types.ErrTxNotExist
......
......@@ -415,9 +415,11 @@ func testProcImportPrivKey(t *testing.T, wallet *Wallet) {
func testProcWalletTxList(t *testing.T, wallet *Wallet) {
println("TestProcWalletTxList begin")
//倒序获取最新的三笔交易
txList := &types.ReqWalletTransactionList{
Count: 3,
Direction: 1,
Direction: 0,
FromTx: []byte(""),
}
msg := wallet.client.NewMessage("wallet", types.EventWalletTransactionList, txList)
......@@ -427,14 +429,26 @@ func testProcWalletTxList(t *testing.T, wallet *Wallet) {
walletTxDetails := resp.GetData().(*types.WalletTxDetails)
var FromTxstr string
index := make([]int64, 3)
if len(walletTxDetails.TxDetails) != 3 {
t.Error("testProcWalletTxList failed")
}
println("TestProcWalletTxList dir last-------")
for _, walletTxDetail := range walletTxDetails.TxDetails {
for i, walletTxDetail := range walletTxDetails.TxDetails {
println("TestProcWalletTxList", "Direction", txList.Direction, "WalletTxDetail", walletTxDetail.String())
index[i] = walletTxDetail.GetHeight()*100000 + walletTxDetail.GetIndex()
FromTxstr = fmt.Sprintf("%018d", walletTxDetail.GetHeight()*100000+walletTxDetail.GetIndex())
}
//倒序index值的判断,index[0]>index[1]>index[2]
if index[0] <= index[1] {
println("TestProcWalletTxList", "index[0]", index[0], "index[1]", index[1])
t.Error("testProcWalletTxList:Reverse check fail!")
}
if index[1] <= index[2] {
println("TestProcWalletTxList", "index[1]", index[1], "index[2]", index[2])
t.Error("testProcWalletTxList:Reverse check fail!")
}
txList.Direction = 1
txList.Count = 2
......@@ -466,6 +480,34 @@ func testProcWalletTxList(t *testing.T, wallet *Wallet) {
for _, walletTxDetail := range walletTxDetails.TxDetails {
println("TestProcWalletTxList", "Direction", txList.Direction, "WalletTxDetail", walletTxDetail.String())
}
//正序获取最早的三笔交易
txList = &types.ReqWalletTransactionList{
Count: 3,
Direction: 1,
FromTx: []byte(""),
}
msg = wallet.client.NewMessage("wallet", types.EventWalletTransactionList, txList)
wallet.client.Send(msg, true)
resp, err = wallet.client.Wait(msg)
require.NoError(t, err)
walletTxDetails = resp.GetData().(*types.WalletTxDetails)
if len(walletTxDetails.TxDetails) != 3 {
t.Error("testProcWalletTxList failed")
}
for i, walletTxDetail := range walletTxDetails.TxDetails {
index[i] = walletTxDetail.GetHeight()*100000 + walletTxDetail.GetIndex()
}
//正序index值的判断,index[0]<index[1]<index[2]
if index[0] >= index[1] {
println("TestProcWalletTxList", "index[0]", index[0], "index[1]", index[1])
t.Error("testProcWalletTxList:positive check fail!")
}
if index[1] >= index[2] {
println("TestProcWalletTxList", "index[1]", index[1], "index[2]", index[2])
t.Error("testProcWalletTxList:positive check fail!")
}
println("TestProcWalletTxList end")
println("--------------------------")
}
......
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