Commit dba9374a authored by linj's avatar linj

Merge branch 'master' into token-mintage

parents 142abab3 bb1e9ab9
......@@ -12,10 +12,10 @@ import (
"sync"
"time"
log "github.com/33cn/chain33/common/log/log15"
//"github.com/33cn/chain33/common"
"encoding/hex"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/client/api"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
......@@ -733,7 +733,10 @@ func (client *client) WriteBlock(prev []byte, paraBlock *types.Block, seq int64)
parablockDetail := &types.ParaChainBlockDetail{Blockdetail: blockDetail, Sequence: seq}
msg := client.GetQueueClient().NewMessage("blockchain", types.EventAddParaChainBlockDetail, parablockDetail)
client.GetQueueClient().Send(msg, true)
err := client.GetQueueClient().Send(msg, true)
if err != nil {
return err
}
resp, err := client.GetQueueClient().Wait(msg)
if err != nil {
return err
......@@ -760,7 +763,10 @@ func (client *client) DelBlock(block *types.Block, seq int64) error {
panic("Parachain attempt to Delete GenesisBlock !")
}
msg := client.GetQueueClient().NewMessage("blockchain", types.EventGetBlocks, &types.ReqBlocks{Start: start, End: start, IsDetail: true, Pid: []string{""}})
client.GetQueueClient().Send(msg, true)
err := client.GetQueueClient().Send(msg, true)
if err != nil {
return err
}
resp, err := client.GetQueueClient().Wait(msg)
if err != nil {
return err
......@@ -769,7 +775,10 @@ func (client *client) DelBlock(block *types.Block, seq int64) error {
parablockDetail := &types.ParaChainBlockDetail{Blockdetail: blocks.Items[0], Sequence: seq}
msg = client.GetQueueClient().NewMessage("blockchain", types.EventDelParaChainBlockDetail, parablockDetail)
client.GetQueueClient().Send(msg, true)
err = client.GetQueueClient().Send(msg, true)
if err != nil {
return err
}
resp, err = client.GetQueueClient().Wait(msg)
if err != nil {
return err
......
......@@ -551,7 +551,11 @@ out:
break out
case <-time.NewTimer(time.Second * 2).C:
msg := client.paraClient.GetQueueClient().NewMessage("wallet", types.EventDumpPrivkey, req)
client.paraClient.GetQueueClient().Send(msg, true)
err := client.paraClient.GetQueueClient().Send(msg, true)
if err != nil {
plog.Error("para commit send msg", "err", err.Error())
break out
}
resp, err := client.paraClient.GetQueueClient().Wait(msg)
if err != nil {
plog.Error("para commit msg sign to wallet", "err", err.Error())
......
......@@ -485,6 +485,9 @@ func (client *Client) searchTargetTicket(parent, block *types.Block) (*ty.Ticket
client.ticketmu.Lock()
defer client.ticketmu.Unlock()
for ticketID, ticket := range client.ticketsMap {
if client.IsClosed() {
return nil, nil, nil, nil, "", nil
}
if ticket == nil {
tlog.Warn("Client searchTargetTicket ticket is nil", "ticketID", ticketID)
continue
......@@ -668,6 +671,10 @@ func (client *Client) updateBlock(block *types.Block, txHashList [][]byte) (*typ
// CreateBlock ticket create block func
func (client *Client) CreateBlock() {
for {
if client.IsClosed() {
tlog.Info("create block stop")
break
}
if !client.IsMining() || !(client.IsCaughtUp() || client.Cfg.ForceMining) {
tlog.Debug("createblock.ismining is disable or client is caughtup is false")
time.Sleep(time.Second)
......
......@@ -21,8 +21,11 @@ import (
"github.com/stretchr/testify/assert"
)
// 执行: go test -cover
func TestTicket(t *testing.T) {
testTicket(t)
}
func testTicket(t *testing.T) {
mock33 := testnode.New("testdata/chain33.cfg.toml", nil)
defer mock33.Close()
mock33.Listen()
......@@ -61,7 +64,7 @@ func TestTicket(t *testing.T) {
status, err = mock33.GetAPI().GetWalletStatus()
assert.Nil(t, err)
assert.Equal(t, true, status.IsAutoMining)
err = mock33.WaitHeight(100)
err = mock33.WaitHeight(50)
assert.Nil(t, err)
//查询票是否自动close,并且购买了新的票
req := &types.ReqWalletTransactionList{Count: 1000}
......
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// Package compiler wraps the Solidity compiler executable (solc).
package compiler
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os/exec"
"regexp"
"strconv"
"strings"
)
var versionRegexp = regexp.MustCompile(`([0-9]+)\.([0-9]+)\.([0-9]+)`)
// Contract contains information about a compiled contract, alongside its code and runtime code.
type Contract struct {
Code string `json:"code"`
RuntimeCode string `json:"runtime-code"`
Info ContractInfo `json:"info"`
}
// ContractInfo contains information about a compiled contract, including access
// to the ABI definition, source mapping, user and developer docs, and metadata.
//
// Depending on the source, language version, compiler version, and compiler
// options will provide information about how the contract was compiled.
type ContractInfo struct {
Source string `json:"source"`
Language string `json:"language"`
LanguageVersion string `json:"languageVersion"`
CompilerVersion string `json:"compilerVersion"`
CompilerOptions string `json:"compilerOptions"`
SrcMap string `json:"srcMap"`
SrcMapRuntime string `json:"srcMapRuntime"`
AbiDefinition interface{} `json:"abiDefinition"`
UserDoc interface{} `json:"userDoc"`
DeveloperDoc interface{} `json:"developerDoc"`
Metadata string `json:"metadata"`
}
// Solidity contains information about the solidity compiler.
type Solidity struct {
Path, Version, FullVersion string
Major, Minor, Patch int
}
// --combined-output format
type solcOutput struct {
Contracts map[string]struct {
BinRuntime string `json:"bin-runtime"`
SrcMapRuntime string `json:"srcmap-runtime"`
Bin, SrcMap, Abi, Devdoc, Userdoc, Metadata string
}
Version string
}
func (s *Solidity) makeArgs() []string {
p := []string{
"--combined-json", "bin,bin-runtime,srcmap,srcmap-runtime,abi,userdoc,devdoc",
"--optimize", // code optimizer switched on
}
if s.Major > 0 || s.Minor > 4 || s.Patch > 6 {
p[1] += ",metadata"
}
return p
}
// SolidityVersion runs solc and parses its version output.
func SolidityVersion(solc string) (*Solidity, error) {
if solc == "" {
solc = "solc"
}
var out bytes.Buffer
cmd := exec.Command(solc, "--version")
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return nil, err
}
matches := versionRegexp.FindStringSubmatch(out.String())
if len(matches) != 4 {
return nil, fmt.Errorf("can't parse solc version %q", out.String())
}
s := &Solidity{Path: cmd.Path, FullVersion: out.String(), Version: matches[0]}
if s.Major, err = strconv.Atoi(matches[1]); err != nil {
return nil, err
}
if s.Minor, err = strconv.Atoi(matches[2]); err != nil {
return nil, err
}
if s.Patch, err = strconv.Atoi(matches[3]); err != nil {
return nil, err
}
return s, nil
}
// CompileSolidityString builds and returns all the contracts contained within a source string.
func CompileSolidityString(solc, source string) (map[string]*Contract, error) {
if len(source) == 0 {
return nil, errors.New("solc: empty source string")
}
s, err := SolidityVersion(solc)
if err != nil {
return nil, err
}
args := append(s.makeArgs(), "--")
cmd := exec.Command(s.Path, append(args, "-")...)
cmd.Stdin = strings.NewReader(source)
return s.run(cmd, source)
}
// CompileSolidity compiles all given Solidity source files.
func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) {
if len(sourcefiles) == 0 {
return nil, errors.New("solc: no source files")
}
source, err := slurpFiles(sourcefiles)
if err != nil {
return nil, err
}
s, err := SolidityVersion(solc)
if err != nil {
return nil, err
}
args := append(s.makeArgs(), "--")
cmd := exec.Command(s.Path, append(args, sourcefiles...)...)
return s.run(cmd, source)
}
func (s *Solidity) run(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
var stderr, stdout bytes.Buffer
cmd.Stderr = &stderr
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("solc: %v\n%s", err, stderr.Bytes())
}
return ParseCombinedJSON(stdout.Bytes(), source, s.Version, s.Version, strings.Join(s.makeArgs(), " "))
}
// ParseCombinedJSON takes the direct output of a solc --combined-output run and
// parses it into a map of string contract name to Contract structs. The
// provided source, language and compiler version, and compiler options are all
// passed through into the Contract structs.
//
// The solc output is expected to contain ABI, source mapping, user docs, and dev docs.
//
// Returns an error if the JSON is malformed or missing data, or if the JSON
// embedded within the JSON is malformed.
func ParseCombinedJSON(combinedJSON []byte, source string, languageVersion string, compilerVersion string, compilerOptions string) (map[string]*Contract, error) {
var output solcOutput
if err := json.Unmarshal(combinedJSON, &output); err != nil {
return nil, err
}
// Compilation succeeded, assemble and return the contracts.
contracts := make(map[string]*Contract)
for name, info := range output.Contracts {
// Parse the individual compilation results.
var abi interface{}
if err := json.Unmarshal([]byte(info.Abi), &abi); err != nil {
return nil, fmt.Errorf("solc: error reading abi definition (%v)", err)
}
var userdoc interface{}
if err := json.Unmarshal([]byte(info.Userdoc), &userdoc); err != nil {
return nil, fmt.Errorf("solc: error reading user doc: %v", err)
}
var devdoc interface{}
if err := json.Unmarshal([]byte(info.Devdoc), &devdoc); err != nil {
return nil, fmt.Errorf("solc: error reading dev doc: %v", err)
}
contracts[name] = &Contract{
Code: "0x" + info.Bin,
RuntimeCode: "0x" + info.BinRuntime,
Info: ContractInfo{
Source: source,
Language: "Solidity",
LanguageVersion: languageVersion,
CompilerVersion: compilerVersion,
CompilerOptions: compilerOptions,
SrcMap: info.SrcMap,
SrcMapRuntime: info.SrcMapRuntime,
AbiDefinition: abi,
UserDoc: userdoc,
DeveloperDoc: devdoc,
Metadata: info.Metadata,
},
}
}
return contracts, nil
}
func slurpFiles(files []string) (string, error) {
var concat bytes.Buffer
for _, file := range files {
content, err := ioutil.ReadFile(file)
if err != nil {
return "", err
}
concat.Write(content)
}
return concat.String(), nil
}
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package compiler
import (
"os/exec"
"testing"
)
const (
testSource = `
pragma solidity >= 0.4.18;
contract test {
/// @notice Will multiply ` + "`a`" + ` by 7.
function multiply(uint a) public returns(uint d) {
return a * 7;
}
}
`
)
func skipWithoutSolc(t *testing.T) {
if _, err := exec.LookPath("solc"); err != nil {
t.Skip(err)
}
}
func TestCompiler(t *testing.T) {
skipWithoutSolc(t)
contracts, err := CompileSolidityString("", testSource)
if err != nil {
t.Fatalf("error compiling source. result is %v: %v", contracts, err)
}
if len(contracts) != 1 {
t.Errorf("one contract expected, got %d", len(contracts))
}
c, ok := contracts["test"]
if !ok {
c, ok = contracts["<stdin>:test"]
if !ok {
t.Fatal("info for contract 'test' not present in result")
}
}
if c.Code == "" {
t.Error("empty code")
}
if c.Info.Source != testSource {
t.Error("wrong source")
}
if c.Info.CompilerVersion == "" {
t.Error("empty version")
}
}
func TestCompileError(t *testing.T) {
skipWithoutSolc(t)
contracts, err := CompileSolidityString("", testSource[4:])
if err == nil {
t.Errorf("error expected compiling source. got none. result %v", contracts)
}
t.Logf("error: %v", err)
}
......@@ -11,6 +11,8 @@ import (
"os"
"time"
"github.com/33cn/plugin/plugin/dapp/evm/commands/compiler"
"strings"
"strconv"
......@@ -203,10 +205,12 @@ func createContractCmd() *cobra.Command {
func addCreateContractFlags(cmd *cobra.Command) {
addCommonFlags(cmd)
cmd.MarkFlagRequired("input")
cmd.Flags().StringP("alias", "s", "", "human readable contract alias name")
cmd.Flags().StringP("abi", "b", "", "bind the abi data")
cmd.Flags().StringP("sol", "", "", "sol file path")
cmd.Flags().StringP("solc", "", "solc", "solc compiler")
}
func createContract(cmd *cobra.Command, args []string) {
......@@ -219,15 +223,50 @@ func createContract(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
abi, _ := cmd.Flags().GetString("abi")
sol, _ := cmd.Flags().GetString("sol")
solc, _ := cmd.Flags().GetString("solc")
feeInt64 := uint64(fee*1e4) * 1e4
bCode, err := common.FromHex(code)
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
if !strings.EqualFold(sol, "") && !strings.EqualFold(code, "") && !strings.EqualFold(abi, "") {
fmt.Fprintln(os.Stderr, "--sol, --code and --abi shouldn't be used at the same time.")
return
}
action := evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: note, Alias: alias, Abi: abi}
var action evmtypes.EVMContractAction
if !strings.EqualFold(sol, "") {
if _, err := os.Stat(sol); os.IsNotExist(err) {
fmt.Fprintln(os.Stderr, "Sol file is not exist.")
return
}
contracts, err := compiler.CompileSolidity(solc, sol)
if err != nil {
fmt.Fprintln(os.Stderr, "Failed to build Solidity contract", err)
return
}
if len(contracts) > 1 {
fmt.Fprintln(os.Stderr, "There are too many contracts in the sol file.")
return
}
for _, contract := range contracts {
abi, _ := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
bCode, err := common.FromHex(contract.Code)
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return
}
action = evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: note, Alias: alias, Abi: string(abi)}
}
} else {
bCode, err := common.FromHex(code)
if err != nil {
fmt.Fprintln(os.Stderr, "parse evm code error", err)
return
}
action = evmtypes.EVMContractAction{Amount: 0, Code: bCode, GasLimit: 0, GasPrice: 0, Note: note, Alias: alias, Abi: abi}
}
data, err := createEvmTx(&action, types.ExecName(paraName+"evm"), caller, address.ExecAddress(types.ExecName(paraName+"evm")), expire, rpcLaddr, feeInt64)
......
......@@ -51,11 +51,17 @@ func (*signatureMock) Equals(crypto.Signature) bool {
return true
}
func formatByte32(b []byte) []byte {
var b32 [32]byte
copy(b32[:], b)
return b32[:]
}
type privKeyMock struct {
}
func (mock *privKeyMock) Bytes() []byte {
return []byte("1234")
return formatByte32([]byte("1234"))
}
func (mock *privKeyMock) Sign(msg []byte) crypto.Signature {
......@@ -82,7 +88,7 @@ func TestNewPrivacy(t *testing.T) {
}
func test_RecoverOnetimePriKey(t *testing.T) {
R := []byte("1234")
R := formatByte32([]byte("1234"))
pkm := privKeyMock{}
privKey, err := RecoverOnetimePriKey(R, &pkm, &pkm, 0)
assert.Nil(t, err)
......
......@@ -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
......@@ -472,3 +472,40 @@ func (acc *DB) mintReceipt(kv []*types.KeyValue, receipt proto.Message) *types.R
Logs: []*types.ReceiptLog{log1},
}
}
// Burn 然收
func (acc *DB) Burn(addr string, amount int64) (*types.Receipt, error) {
if !types.CheckAmount(amount) {
return nil, types.ErrAmount
}
accTo := acc.LoadAccount(addr)
if accTo.Balance < amount {
return nil, types.ErrNoBalance
}
copyAcc := *accTo
accTo.Balance = accTo.Balance - amount
receipt := &types.ReceiptAccountBurn{
Prev: &copyAcc,
Current: accTo,
}
kv := acc.GetKVSet(accTo)
acc.SaveKVSet(kv)
return acc.burnReceipt(kv, receipt), nil
}
func (acc *DB) burnReceipt(kv []*types.KeyValue, receipt proto.Message) *types.Receipt {
ty := int32(types.TyLogBurn)
log1 := &types.ReceiptLog{
Ty: ty,
Log: types.Encode(receipt),
}
return &types.Receipt{
Ty: types.ExecOk,
KV: kv,
Logs: []*types.ReceiptLog{log1},
}
}
......@@ -555,6 +555,33 @@ func TestGetExecBalance2(t *testing.T) {
*/
}
func TestGetBalance(t *testing.T) {
accCoin := NewCoinsAccount()
addr := "1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP"
fmt.Println("-------------TestGetExecBalance2---test case1---")
api := new(mocks.QueueProtocolAPI)
in := &types.ReqBalance{}
in.Addresses = append(in.Addresses, addr)
api.On("StoreList", mock.Anything).Return(&types.StoreListReply{}, nil)
api.On("GetLastHeader", mock.Anything).Return(&types.Header{StateHash: []byte("111111111111111111111")}, nil)
api.On("StoreGet", mock.Anything).Return(&types.StoreReplyValue{Values: make([][]byte, 1)}, nil)
_, err := accCoin.GetBalance(api, in)
assert.Nil(t, err)
fmt.Println("-------------TestGetExecBalance2---test case2---")
in.StateHash = "111111111111111111111"
_, err = accCoin.GetBalance(api, in)
assert.Nil(t, err)
fmt.Println("-------------TestGetExecBalance2---test case3---")
in.Execer = "coins"
//api.On("StoreList", mock.Anything).Return(nil, types.ErrInvalidParam)
_, err = accCoin.GetBalance(api, in)
t.Log(err)
assert.Nil(t, err)
}
func TestDB_Mint(t *testing.T) {
_, tokenCoin := GenerAccDb()
tokenCoin.GenerAccData()
......@@ -564,3 +591,14 @@ func TestDB_Mint(t *testing.T) {
t.Logf("Token mint addr balance [%d]", tokenCoin.LoadAccount(addr1).Balance)
require.Equal(t, int64(1000*1e8+10*1e8), tokenCoin.LoadAccount(addr1).Balance)
}
func TestDB_Burn(t *testing.T) {
_, tokenCoin := GenerAccDb()
tokenCoin.GenerAccData()
_, err := tokenCoin.Burn(addr1, 10*1e8)
require.NoError(t, err)
t.Logf("Token mint addr balance [%d]", tokenCoin.LoadAccount(addr1).Balance)
require.Equal(t, int64(1000*1e8-10*1e8), tokenCoin.LoadAccount(addr1).Balance)
}
......@@ -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++ {
......
......@@ -12,10 +12,9 @@ import (
"time"
"github.com/33cn/chain33/common/crypto"
_ "github.com/33cn/chain33/system/crypto/init"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
_ "github.com/33cn/chain33/system/crypto/init"
)
func genkey() crypto.PrivKey {
......@@ -105,3 +104,8 @@ func BenchmarkExecAddress(b *testing.B) {
duration = end - start
fmt.Println("duration without cache:", strconv.FormatInt(duration, 10))
}
func TestExecPubKey(t *testing.T) {
pubkey := ExecPubKey("test")
assert.True(t, len(pubkey) == 32)
}
......@@ -13,11 +13,37 @@ import (
"github.com/stretchr/testify/require"
)
func TestGet(t *testing.T) {
require := require.New(t)
name := crypto.GetName(1)
require.Equal("secp256k1", name)
name = crypto.GetName(2)
require.Equal("ed25519", name)
name = crypto.GetName(3)
require.Equal("sm2", name)
ty := crypto.GetType("secp256k1")
require.True(ty == 1)
ty = crypto.GetType("ed25519")
require.True(ty == 2)
ty = crypto.GetType("sm2")
require.True(ty == 3)
}
func TestRipemd160(t *testing.T) {
require := require.New(t)
b := crypto.Ripemd160([]byte("test"))
require.NotNil(b)
}
func TestAll(t *testing.T) {
testCrypto(t, "ed25519")
testFromBytes(t, "ed25519")
testCrypto(t, "secp256k1")
testFromBytes(t, "secp256k1")
testCrypto(t, "sm2")
testFromBytes(t, "sm2")
}
func testFromBytes(t *testing.T, name string) {
......
......@@ -24,6 +24,8 @@ import (
"os"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
const (
......@@ -341,3 +343,23 @@ func Example_mac() {
fmt.Printf("%x\n", h)
// ProtoToJson: 78de2974bd2711d5549ffd32b753ef0f5fa80a0db2556db60f0987eb8a9218ff
}
func TestNew(t *testing.T) {
d28 := Sum224(nil)
assert.True(t, len(d28) == 28)
d32 := Sum256(nil)
assert.True(t, len(d32) == 32)
d48 := Sum384(nil)
assert.True(t, len(d48) == 48)
d64 := Sum512(nil)
assert.True(t, len(d64) == 64)
d32 = KeccakSum256(nil)
assert.True(t, len(d32) == 32)
d32 = KeccakSum512(nil)
assert.True(t, len(d32) == 32)
}
......@@ -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) {
......
......@@ -75,5 +75,6 @@ func TestWalk(t *testing.T) {
assert.Equal(t, "222", iter.First().Value.(string))
assert.Equal(t, int64(1), iter.Last().Score)
assert.Equal(t, "111", iter.Last().Value.(string))
l.Print()
}
......@@ -32,6 +32,11 @@ func testDBGet(t *testing.T, db dbm.KV) {
v, err = db.Get([]byte("k1"))
assert.Nil(t, err)
assert.Equal(t, v, []byte("v11"))
stateDb := db.(*StateDB)
vs, err := stateDb.BatchGet([][]byte{[]byte("k1")})
assert.NoError(t, err)
assert.Equal(t, [][]byte{[]byte("v11")}, vs)
}
func TestStateDBTxGetOld(t *testing.T) {
......
......@@ -448,4 +448,7 @@ func (exec *Executor) procExecDelBlock(msg *queue.Message) {
// Close close executor
func (exec *Executor) Close() {
elog.Info("exec module closed")
if exec.client != nil {
exec.client.Close()
}
}
......@@ -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
......
package executor
import (
"testing"
"time"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/stretchr/testify/assert"
)
func TestPlugin(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
ctx := &executorCtx{
stateHash: nil,
height: 1,
blocktime: time.Now().Unix(),
difficulty: 1,
mainHash: nil,
parentHash: nil,
}
var txs []*types.Transaction
addr, priv := util.Genaddress()
tx := util.CreateCoinsTx(priv, addr, types.Coin)
tx.Sign(types.SECP256K1, priv)
txs = append(txs, tx)
for _, plugin := range globalPlugins {
detail := &types.BlockDetail{
Block: &types.Block{Txs: txs},
Receipts: []*types.ReceiptData{{}},
}
executor := newExecutor(ctx, &Executor{}, kvdb, txs, nil)
_, _, err := plugin.CheckEnable(executor, false)
assert.NoError(t, err)
kvs, err := plugin.ExecLocal(executor, detail)
assert.NoError(t, err)
for _, kv := range kvs {
err = kvdb.Set(kv.Key, kv.Value)
assert.NoError(t, err)
}
_, err = plugin.ExecDelLocal(executor, detail)
assert.NoError(t, err)
}
}
func TestPluginBase(t *testing.T) {
base := new(pluginBase)
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
ctx := &executorCtx{
stateHash: nil,
height: 0,
blocktime: time.Now().Unix(),
difficulty: 1,
mainHash: nil,
parentHash: nil,
}
executor := newExecutor(ctx, &Executor{}, kvdb, nil, nil)
_, _, err := base.checkFlag(executor, nil, true)
assert.NoError(t, err)
k := []byte("test")
v := types.Encode(&types.Int64{})
err = kvdb.Set(k, v)
assert.NoError(t, err)
_, _, err = base.checkFlag(executor, k, true)
assert.NoError(t, err)
}
......@@ -128,7 +128,10 @@ func (s *StateDB) get(key []byte) ([]byte, error) {
}
query := &types.StoreGet{StateHash: s.stateHash, Keys: [][]byte{key}}
msg := s.client.NewMessage("store", types.EventStoreGet, query)
s.client.Send(msg, true)
err := s.client.Send(msg, true)
if err != nil {
return nil, err
}
resp, err := s.client.Wait(msg)
if err != nil {
panic(err) //no happen for ever
......
......@@ -176,6 +176,9 @@ func (client *client) Close() {
client.wg.Wait()
atomic.StoreInt32(&client.isClosed, 1)
close(client.Recv())
for msg := range client.Recv() {
msg.Reply(client.NewMessage(msg.Topic, msg.Ty, types.ErrChannelClosed))
}
}
// CloseQueue 关闭消息队列
......
......@@ -10,6 +10,7 @@ import (
"time"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
)
func init() {
......@@ -187,11 +188,17 @@ func TestClientClose(t *testing.T) {
}()
msg := client.NewMessage("mempool", types.EventTx, "hello")
err := client.Send(msg, true)
if err == types.ErrChannelClosed {
return
}
if err != nil { //chan is closed
t.Error(err)
return
}
_, err = client.Wait(msg)
if err == types.ErrChannelClosed {
return
}
if err != nil {
t.Error(err)
return
......@@ -213,6 +220,44 @@ func TestPrintMessage(t *testing.T) {
t.Log(msg)
}
func TestMessage_ReplyErr(t *testing.T) {
q := New("channel")
assert.Equal(t, "channel", q.Name())
//接收消息
go func() {
client := q.Client()
client.Sub("mempool")
for msg := range client.Recv() {
if msg.Data == nil {
msg.ReplyErr("test", fmt.Errorf("test error"))
break
}
msg.Reply(NewMessage(0, "mempool", types.EventReply, types.Reply{IsOk: true, Msg: []byte("test ok")}))
}
}()
//发送消息
go func() {
client := q.Client()
msg := client.NewMessage("mempool", types.EventTx, "hello")
err := client.Send(msg, true)
if err != nil { //chan is closed
t.Error(err)
return
}
msg = client.NewMessage("mempool", types.EventTx, nil)
err = client.Send(msg, true)
if err != nil {
t.Error(err)
return
}
client.CloseQueue()
}()
q.Start()
}
func TestChanSubCallback(t *testing.T) {
q := New("channel")
client := q.Client()
......@@ -423,3 +468,53 @@ func BenchmarkChanSubCallback2(b *testing.B) {
client.Reply(msg)
}
}
func TestChannelClose(t *testing.T) {
//send timeout and recv timeout
q := New("channel")
//mempool
done := make(chan struct{}, 1)
go func() {
client := q.Client()
client.Sub("mempool")
for {
select {
case msg := <-client.Recv():
if msg == nil {
return
}
if msg.Ty == types.EventTx {
msg.Reply(client.NewMessage("mempool", types.EventReply, types.Reply{IsOk: true, Msg: []byte("word")}))
}
case <-done:
client.Close()
return
}
}
}()
client := q.Client()
go q.Start()
//rpc 模块 会向其他模块发送消息,自己本身不需要订阅消息
go func() {
done <- struct{}{}
}()
for i := 0; i < 10000; i++ {
msg := client.NewMessage("mempool", types.EventTx, "hello")
err := client.SendTimeout(msg, true, 0)
if err == types.ErrChannelClosed {
return
}
if err != nil {
t.Error(err)
return
}
_, err = client.Wait(msg)
if err == types.ErrChannelClosed {
return
}
if err != nil {
t.Error(err)
}
}
}
......@@ -5,9 +5,9 @@
package rpc
import (
"testing"
"encoding/hex"
"fmt"
"testing"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client/mocks"
......@@ -67,6 +67,12 @@ func testCreateRawTransactionTo(t *testing.T) {
client := newTestChannelClient()
rawtx, err := client.CreateRawTransaction(&tx)
assert.NoError(t, err)
reqDecode := &types.ReqDecodeRawTransaction{TxHex: hex.EncodeToString(rawtx)}
_, err = client.DecodeRawTransaction(reqDecode)
assert.NoError(t, err)
assert.Nil(t, err)
var mytx types.Transaction
err = types.Decode(rawtx, &mytx)
......@@ -343,21 +349,30 @@ func TestChannelClient_GetBalance(t *testing.T) {
testChannelClient_GetBalanceOther(t)
}
// func TestChannelClient_GetTotalCoins(t *testing.T) {
// client := newTestChannelClient()
// data, err := client.GetTotalCoins(nil)
// assert.NotNil(t, err)
// assert.Nil(t, data)
//
// // accountdb =
// token := &types.ReqGetTotalCoins{
// Symbol: "CNY",
// StateHash: []byte("1234"),
// StartKey: []byte("sad"),
// Count: 1,
// Execer: "coin",
// }
// data, err = client.GetTotalCoins(token)
// assert.NotNil(t, data)
// assert.Nil(t, err)
// }
func TestChannelClient_GetTotalCoins(t *testing.T) {
client := new(channelClient)
api := new(mocks.QueueProtocolAPI)
client.Init(&qmock.Client{}, api)
api.On("StoreGetTotalCoins", mock.Anything).Return(&types.ReplyGetTotalCoins{}, nil)
_, err := client.GetTotalCoins(&types.ReqGetTotalCoins{})
assert.NoError(t, err)
// accountdb =
//token := &types.ReqGetTotalCoins{
// Symbol: "CNY",
// StateHash: []byte("1234"),
// StartKey: []byte("sad"),
// Count: 1,
// Execer: "coin",
//}
//data, err = client.GetTotalCoins(token)
//assert.NotNil(t, data)
//assert.Nil(t, err)
}
func TestChannelClient_CreateNoBalanceTransaction(t *testing.T) {
client := new(channelClient)
in := &types.NoBalanceTx{}
_, err := client.CreateNoBalanceTransaction(in)
assert.NoError(t, err)
}
......@@ -1069,3 +1069,99 @@ func TestReWriteRawTx(t *testing.T) {
assert.Equal(t, int64(130000000000), tx.Expire)
assert.Equal(t, in.To, tx.To)
}
func TestGrpc_CreateNoBalanceTransaction(t *testing.T) {
_, err := g.CreateNoBalanceTransaction(getOkCtx(), &pb.NoBalanceTx{})
assert.NoError(t, err)
}
func TestGrpc_CreateRawTransaction(t *testing.T) {
_, err := g.CreateRawTransaction(getOkCtx(), &pb.CreateTx{})
assert.NoError(t, err)
}
func TestGrpc_CreateTransaction(t *testing.T) {
_, err := g.CreateTransaction(getOkCtx(), &pb.CreateTxIn{Execer: []byte("coins")})
assert.Equal(t, err, types.ErrActionNotSupport)
}
func TestGrpc_CreateRawTxGroup(t *testing.T) {
_, err := g.CreateRawTxGroup(getOkCtx(), &pb.CreateTransactionGroup{})
assert.Equal(t, types.ErrTxGroupCountLessThanTwo, err)
}
func TestGrpc_SendRawTransaction(t *testing.T) {
transfer := &types.Transaction{
Execer: []byte(types.ExecName("ticket")),
}
payload := types.Encode(transfer)
qapi.On("SendTx", mock.Anything).Return(nil, nil)
var param = &types.SignedTx{
Unsign: payload,
Sign: []byte("123"),
Pubkey: []byte("123"),
Ty: 1,
}
_, err := g.SendRawTransaction(getOkCtx(), param)
assert.NoError(t, err)
}
func TestGrpc_GetAddrOverview(t *testing.T) {
_, err := g.GetAddrOverview(getOkCtx(), &types.ReqAddr{})
assert.Equal(t, err, types.ErrInvalidAddress)
}
func TestGrpc_GetBalance(t *testing.T) {
qapi.On("StoreGet", mock.Anything).Return(nil, types.ErrInvalidParam)
_, err := g.GetBalance(getOkCtx(), &types.ReqBalance{})
assert.Equal(t, err, types.ErrInvalidParam)
}
func TestGrpc_GetAllExecBalance(t *testing.T) {
_, err := g.GetAllExecBalance(getOkCtx(), &pb.ReqAllExecBalance{})
assert.Equal(t, err, types.ErrInvalidAddress)
}
func TestGrpc_QueryConsensus(t *testing.T) {
qapi.On("QueryConsensus", mock.Anything).Return(&types.ReqString{Data: "test"}, nil)
_, err := g.QueryConsensus(getOkCtx(), &pb.ChainExecutor{})
assert.NoError(t, err)
}
func TestGrpc_ExecWallet(t *testing.T) {
qapi.On("ExecWallet", mock.Anything).Return(&types.ReqString{Data: "test"}, nil)
_, err := g.ExecWallet(getOkCtx(), &pb.ChainExecutor{})
assert.NoError(t, err)
}
func TestGrpc_GetLastBlockSequence(t *testing.T) {
qapi.On("GetLastBlockSequence", mock.Anything).Return(nil, nil)
_, err := g.GetLastBlockSequence(getOkCtx(), &types.ReqNil{})
assert.NoError(t, err)
}
func TestGrpc_GetBlockByHashes(t *testing.T) {
qapi.On("GetBlockByHashes", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
_, err := g.GetBlockByHashes(getOkCtx(), &types.ReqHashes{})
assert.NoError(t, err)
}
func TestGrpc_GetSequenceByHash(t *testing.T) {
qapi.On("GetSequenceByHash", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
_, err := g.GetSequenceByHash(getOkCtx(), &pb.ReqHash{})
assert.NoError(t, err)
}
func TestGrpc_SignRawTx(t *testing.T) {
qapi.On("SignRawTx", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
_, err := g.SignRawTx(getOkCtx(), &types.ReqSignRawTx{})
assert.NoError(t, err)
}
func TestGrpc_QueryRandNum(t *testing.T) {
qapi.On("Query", mock.Anything, mock.Anything, mock.Anything).Return(&pb.ReplyHash{Hash: []byte("test")}, nil)
_, err := g.QueryRandNum(getOkCtx(), &pb.ReqRandHash{})
assert.NoError(t, err)
}
......@@ -661,28 +661,27 @@ func TestChain33_QueryTransactionOk(t *testing.T) {
func TestChain33_GetBlocks(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
api.On("GetBlocks", &types.ReqBlocks{Pid: []string{""}}).Return(nil, errors.New("error value"))
api.On("GetBlocks", &types.ReqBlocks{Pid: []string{""}}).Return(&types.BlockDetails{Items: []*types.BlockDetail{{}}}, nil)
testChain33 := newTestChain33(api)
var testResult interface{}
data := rpctypes.BlockParam{}
err := testChain33.GetBlocks(data, &testResult)
t.Log(err)
assert.Equal(t, nil, testResult)
assert.NotNil(t, err)
assert.NoError(t, err)
mock.AssertExpectationsForObjects(t, api)
}
func TestChain33_GetLastHeader(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
api.On("GetBlocks", &types.ReqBlocks{Pid: []string{""}}).Return(nil, errors.New("error value"))
api.On("GetLastHeader", mock.Anything).Return(&types.Header{}, nil)
testChain33 := newTestChain33(api)
var testResult interface{}
data := rpctypes.BlockParam{}
err := testChain33.GetBlocks(data, &testResult)
data := &types.ReqNil{}
err := testChain33.GetLastHeader(data, &testResult)
t.Log(err)
assert.Equal(t, nil, testResult)
assert.NotNil(t, err)
assert.NotNil(t, &testResult)
assert.NoError(t, err)
mock.AssertExpectationsForObjects(t, api)
}
......@@ -691,13 +690,13 @@ func TestChain33_GetTxByAddr(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
api.On("GetTransactionByAddr", &types.ReqAddr{}).Return(nil, errors.New("error value"))
api.On("GetTransactionByAddr", mock.Anything).Return(&types.ReplyTxInfos{TxInfos: []*types.ReplyTxInfo{{}}}, nil)
var testResult interface{}
data := types.ReqAddr{}
err := testChain33.GetTxByAddr(data, &testResult)
t.Log(err)
assert.Equal(t, nil, testResult)
assert.NotNil(t, err)
assert.NotNil(t, testResult)
assert.NoError(t, err)
mock.AssertExpectationsForObjects(t, api)
}
......@@ -706,15 +705,14 @@ func TestChain33_GetTxByHashes(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
var parm types.ReqHashes
parm.Hashes = make([][]byte, 0)
api.On("GetTransactionByHash", &parm).Return(nil, errors.New("error value"))
api.On("GetTransactionByHash", mock.Anything).Return(&types.TransactionDetails{}, nil)
var testResult interface{}
data := rpctypes.ReqHashes{}
data.Hashes = append(data.Hashes, "0xdcf13a93e3bf58534c773e13d339894c18dafbd3ff273a9d1caa0c2bec8e8cd6")
err := testChain33.GetTxByHashes(data, &testResult)
t.Log(err)
assert.Equal(t, nil, testResult)
assert.NotNil(t, err)
assert.NotNil(t, testResult)
assert.NoError(t, err)
mock.AssertExpectationsForObjects(t, api)
}
......@@ -723,17 +721,29 @@ func TestChain33_GetMempool(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
api.On("GetMempool").Return(nil, errors.New("error value"))
api.On("GetMempool").Return(&types.ReplyTxList{Txs: []*types.Transaction{{}}}, nil)
var testResult interface{}
data := &types.ReqNil{}
err := testChain33.GetMempool(data, &testResult)
t.Log(err)
assert.Equal(t, nil, testResult)
assert.NotNil(t, err)
assert.NotNil(t, testResult)
assert.NoError(t, err)
mock.AssertExpectationsForObjects(t, api)
}
func TestChain33_GetAccountsV2(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
api.On("WalletGetAccountList", mock.Anything).Return(&types.WalletAccounts{Wallets: []*types.WalletAccount{{}}}, nil)
var testResult interface{}
err := testChain33.GetAccountsV2(nil, &testResult)
t.Log(err)
assert.NotNil(t, testResult)
assert.NoError(t, err)
}
func TestChain33_GetAccounts(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
testChain33 := newTestChain33(api)
......@@ -1345,3 +1355,121 @@ func TestChain33_GetBalance(t *testing.T) {
})
}
}
func TestChain33_CreateNoBalanceTransaction(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
chain33 := newTestChain33(api)
var result string
err := chain33.CreateNoBalanceTransaction(&types.NoBalanceTx{TxHex: "0a05636f696e73122c18010a281080c2d72f222131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b7120a08d0630a696c0b3f78dd9ec083a2131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b71"}, &result)
assert.NoError(t, err)
}
func TestChain33_ExecWallet(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
in := &rpctypes.ChainExecutor{}
api.On("ExecWallet", mock.Anything).Return(nil, nil)
err := client.ExecWallet(in, &testResult)
assert.NotNil(t, err)
}
func TestChain33_Query(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
in := rpctypes.Query4Jrpc{Execer: "coins"}
api.On("Query", mock.Anything).Return(nil, nil)
err := client.Query(in, &testResult)
assert.NotNil(t, err)
}
func TestChain33_DumpPrivkey(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("DumpPrivkey", mock.Anything).Return(nil, nil)
err := client.DumpPrivkey(types.ReqString{}, &testResult)
assert.NoError(t, err)
}
func TestChain33_GetTotalCoins(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("StoreGetTotalCoins", mock.Anything).Return(nil, nil)
err := client.GetTotalCoins(&types.ReqGetTotalCoins{}, &testResult)
assert.NoError(t, err)
}
func TestChain33_GetFatalFailure(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("GetFatalFailure", mock.Anything).Return(&types.Int32{}, nil)
err := client.GetFatalFailure(nil, &testResult)
assert.NoError(t, err)
}
func TestChain33_DecodeRawTransaction(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
//api.On("GetFatalFailure", mock.Anything).Return(&types.Int32{}, nil)
err := client.DecodeRawTransaction(&types.ReqDecodeRawTransaction{TxHex: "0a05636f696e73122c18010a281080c2d72f222131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b7120a08d0630a696c0b3f78dd9ec083a2131477444795771577233553637656a7663776d333867396e7a6e7a434b58434b71"}, &testResult)
assert.NoError(t, err)
}
func TestChain33_WalletCreateTx(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("WalletCreateTx", mock.Anything).Return(&types.Transaction{}, nil)
err := client.WalletCreateTx(types.ReqCreateTransaction{}, &testResult)
assert.NoError(t, err)
}
func TestChain33_CloseQueue(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("CloseQueue", mock.Anything).Return(nil, nil)
err := client.CloseQueue(nil, &testResult)
assert.True(t, testResult.(*types.Reply).IsOk)
assert.NoError(t, err)
}
func TestChain33_AddSeqCallBack(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("AddSeqCallBack", mock.Anything).Return(&types.Reply{}, nil)
err := client.AddSeqCallBack(nil, &testResult)
assert.NoError(t, err)
}
func TestChain33_ListSeqCallBack(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("ListSeqCallBack", mock.Anything).Return(&types.BlockSeqCBs{}, nil)
err := client.ListSeqCallBack(nil, &testResult)
assert.NoError(t, err)
}
func TestChain33_GetSeqCallBackLastNum(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult interface{}
api.On("GetSeqCallBackLastNum", mock.Anything).Return(&types.Int64{}, nil)
err := client.GetSeqCallBackLastNum(nil, &testResult)
assert.NoError(t, err)
}
func TestChain33_ConvertExectoAddr(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var testResult string
err := client.ConvertExectoAddr(rpctypes.ExecNameParm{ExecName: "coins"}, &testResult)
assert.NoError(t, err)
}
......@@ -145,6 +145,7 @@ func TestGrpc_Call(t *testing.T) {
rpcCfg.GrpcFuncWhitelist = []string{"*"}
InitCfg(rpcCfg)
api := new(mocks.QueueProtocolAPI)
_ = NewGrpcServer()
server := NewGRpcServer(&qmocks.Client{}, api)
assert.NotNil(t, server)
go server.Listen()
......@@ -180,3 +181,54 @@ func TestGrpc_Call(t *testing.T) {
server.Close()
mock.AssertExpectationsForObjects(t, api)
}
func TestRPC(t *testing.T) {
cfg := &types.RPC{
JrpcBindAddr: "8801",
GrpcBindAddr: "8802",
Whitlist: []string{"127.0.0.1"},
JrpcFuncBlacklist: []string{"CloseQueue"},
GrpcFuncBlacklist: []string{"CloseQueue"},
EnableTrace: true,
}
InitCfg(cfg)
rpc := New(cfg)
client := &qmocks.Client{}
rpc.SetQueueClient(client)
assert.Equal(t, client, rpc.GetQueueClient())
assert.NotNil(t, rpc.GRPC())
assert.NotNil(t, rpc.JRPC())
}
func TestCheckFuncList(t *testing.T) {
funcName := "abc"
jrpcFuncWhitelist = make(map[string]bool)
assert.False(t, checkJrpcFuncWhitelist(funcName))
jrpcFuncWhitelist["*"] = true
assert.True(t, checkJrpcFuncWhitelist(funcName))
delete(jrpcFuncWhitelist, "*")
jrpcFuncWhitelist[funcName] = true
assert.True(t, checkJrpcFuncWhitelist(funcName))
grpcFuncWhitelist = make(map[string]bool)
assert.False(t, checkGrpcFuncWhitelist(funcName))
grpcFuncWhitelist["*"] = true
assert.True(t, checkGrpcFuncWhitelist(funcName))
delete(grpcFuncWhitelist, "*")
grpcFuncWhitelist[funcName] = true
assert.True(t, checkGrpcFuncWhitelist(funcName))
jrpcFuncBlacklist = make(map[string]bool)
assert.False(t, checkJrpcFuncBlacklist(funcName))
jrpcFuncBlacklist[funcName] = true
assert.True(t, checkJrpcFuncBlacklist(funcName))
grpcFuncBlacklist = make(map[string]bool)
assert.False(t, checkGrpcFuncBlacklist(funcName))
grpcFuncBlacklist[funcName] = true
assert.True(t, checkGrpcFuncBlacklist(funcName))
}
......@@ -8,6 +8,7 @@ import (
"encoding/json"
"testing"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
......@@ -57,6 +58,34 @@ func TestDecodeTx(t *testing.T) {
assert.Nil(t, err)
}
func TestDecodeLog(t *testing.T) {
execer := []byte("coins")
log := &ReceiptLog{}
receipt := &ReceiptData{Ty: 2, Logs: []*ReceiptLog{log}}
_, err := DecodeLog(execer, receipt)
assert.NoError(t, err)
}
func TestConvertWalletTxDetailToJSON(t *testing.T) {
tx := &types.Transaction{Execer: []byte("coins")}
log := &types.ReceiptLog{Ty: 0, Log: []byte("test")}
receipt := &types.ReceiptData{Ty: 0, Logs: []*types.ReceiptLog{log}}
detail := &types.WalletTxDetail{Tx: tx, Receipt: receipt}
in := &types.WalletTxDetails{TxDetails: []*types.WalletTxDetail{detail}}
out := &WalletTxDetails{}
err := ConvertWalletTxDetailToJSON(in, out)
assert.NoError(t, err)
}
func TestServer(t *testing.T) {
api := &mocks.QueueProtocolAPI{}
ch := ChannelClient{QueueProtocolAPI: api}
ch.Init("test", nil, nil, nil)
db := ch.GetCoinsAccountDB()
assert.NotNil(t, db)
}
func TestDecodeTx2(t *testing.T) {
bdata, err := common.FromHex("0a05636f696e73121018010a0c108084af5f1a05310a320a3320e8b31b30b9b69483d7f9d3f04c3a22314b67453376617969715a4b6866684d66744e3776743267447639486f4d6b393431")
assert.Nil(t, err)
......
......@@ -45,6 +45,7 @@ type BaseClient struct {
client queue.Client
api client.QueueProtocolAPI
minerStart int32
isclosed int32
once sync.Once
Cfg *types.Consensus
currentBlock *types.Block
......@@ -146,10 +147,16 @@ func (bc *BaseClient) InitBlock() {
//Close 关闭
func (bc *BaseClient) Close() {
atomic.StoreInt32(&bc.minerStart, 0)
atomic.StoreInt32(&bc.isclosed, 1)
bc.client.Close()
log.Info("consensus base closed")
}
//IsClosed 是否已经关闭
func (bc *BaseClient) IsClosed() bool {
return atomic.LoadInt32(&bc.isclosed) == 1
}
//CheckTxDup 为了不引起交易检查时候产生的无序
func (bc *BaseClient) CheckTxDup(txs []*types.Transaction) (transactions []*types.Transaction) {
cacheTxs := types.TxsToCache(txs)
......@@ -172,7 +179,10 @@ func (bc *BaseClient) IsCaughtUp() bool {
panic("bc not bind message queue.")
}
msg := bc.client.NewMessage("blockchain", types.EventIsSync, nil)
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return false
}
resp, err := bc.client.Wait(msg)
if err != nil {
return false
......@@ -273,7 +283,10 @@ func (bc *BaseClient) RequestTx(listSize int, txHashList [][]byte) []*types.Tran
panic("bc not bind message queue.")
}
msg := bc.client.NewMessage("mempool", types.EventTxList, &types.TxHashList{Hashes: txHashList, Count: int64(listSize)})
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return nil
}
resp, err := bc.client.Wait(msg)
if err != nil {
return nil
......@@ -288,7 +301,10 @@ func (bc *BaseClient) RequestBlock(start int64) (*types.Block, error) {
}
reqblock := &types.ReqBlocks{Start: start, End: start, IsDetail: false, Pid: []string{""}}
msg := bc.client.NewMessage("blockchain", types.EventGetBlocks, reqblock)
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return nil, err
}
resp, err := bc.client.Wait(msg)
if err != nil {
return nil, err
......@@ -303,7 +319,10 @@ func (bc *BaseClient) RequestLastBlock() (*types.Block, error) {
panic("client not bind message queue.")
}
msg := bc.client.NewMessage("blockchain", types.EventGetLastBlock, nil)
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return nil, err
}
resp, err := bc.client.Wait(msg)
if err != nil {
return nil, err
......@@ -316,7 +335,10 @@ func (bc *BaseClient) RequestLastBlock() (*types.Block, error) {
func (bc *BaseClient) delMempoolTx(deltx []*types.Transaction) error {
hashList := buildHashList(deltx)
msg := bc.client.NewMessage("mempool", types.EventDelTxList, hashList)
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return err
}
resp, err := bc.client.Wait(msg)
if err != nil {
return err
......@@ -343,7 +365,10 @@ func (bc *BaseClient) WriteBlock(prev []byte, block *types.Block) error {
blockdetail := &types.BlockDetail{Block: block}
msg := bc.client.NewMessage("blockchain", types.EventAddBlockDetail, blockdetail)
bc.client.Send(msg, true)
err := bc.client.Send(msg, true)
if err != nil {
return err
}
resp, err := bc.client.Wait(msg)
if err != nil {
return err
......
......@@ -96,6 +96,9 @@ func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail
func (client *Client) CreateBlock() {
issleep := true
for {
if client.IsClosed() {
break
}
if !client.IsMining() || !client.IsCaughtUp() {
time.Sleep(client.sleepTime)
continue
......
......@@ -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
}
......
......@@ -9,6 +9,7 @@ import (
"testing"
"github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert"
)
......@@ -29,3 +30,37 @@ func TestTypeReflact(t *testing.T) {
assert.Equal(t, int64(10), val.Interface().(*types.AssetsTransfer).GetAmount())
}
}
func TestCoinsType(t *testing.T) {
ty := NewType()
payload := ty.GetPayload()
assert.Equal(t, &CoinsAction{}, payload.(*CoinsAction))
assert.Equal(t, "coins", ty.GetName())
assert.Equal(t, logmap, ty.GetLogMap())
assert.Equal(t, actionName, ty.GetTypeMap())
create := &types.CreateTx{}
tx, err := ty.RPC_Default_Process("transfer", create)
assert.NoError(t, err)
_, err = ty.GetAssets(tx)
assert.NoError(t, err)
}
func TestCoinsPb(t *testing.T) {
b := &proto.Buffer{}
ca := &CoinsAction{Value: &CoinsAction_Transfer{&types.AssetsTransfer{}}}
var err error
transfer := ca.GetTransfer()
assert.NotNil(t, transfer)
err = _CoinsAction_OneofMarshaler(ca, b)
assert.NoError(t, err)
ca.Value = &CoinsAction_Genesis{&types.AssetsGenesis{}}
genesis := ca.GetGenesis()
assert.NotNil(t, genesis)
err = _CoinsAction_OneofMarshaler(ca, b)
assert.NoError(t, err)
}
......@@ -7,6 +7,9 @@ package types
import (
"testing"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)
......@@ -26,9 +29,80 @@ func TestCheckExpireOpt(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "14", str)
expire = ""
_, err = CheckExpireOpt(expire)
assert.Error(t, err)
expire = "H:-123"
_, err = CheckExpireOpt(expire)
assert.Error(t, err)
expire = "-123"
_, err = CheckExpireOpt(expire)
assert.Error(t, err)
expire = "H:123"
str, err = CheckExpireOpt(expire)
assert.NoError(t, err)
assert.Equal(t, "H:123", str)
}
func TestDecodeTransaction(t *testing.T) {
tx := &rpctypes.Transaction{
Execer: "coins",
}
result := DecodeTransaction(tx)
assert.Equal(t, result.Execer, "coins")
}
func TestDecodeAccount(t *testing.T) {
precision := int64(1e8)
acc := &types.Account{
Currency: 2,
Balance: 3 * precision,
Frozen: 4 * precision,
Addr: "0x123",
}
accResult := DecodeAccount(acc, precision)
assert.Equal(t, &AccountResult{2, "3.0000", "4.0000", "0x123"}, accResult)
}
func TestCreateRawTx(t *testing.T) {
var err error
_, err = CreateRawTx(&cobra.Command{}, "", 0, "", false, "", "")
assert.Nil(t, err)
_, err = CreateRawTx(&cobra.Command{}, "", 0, "", false, "", "coins")
assert.Nil(t, err)
_, err = CreateRawTx(&cobra.Command{}, "", 0, "", true, "", "")
assert.Nil(t, err)
_, err = CreateRawTx(&cobra.Command{}, "", -1, "", false, "", "")
assert.Equal(t, types.ErrAmount, err)
_, err = CreateRawTx(&cobra.Command{}, "", 1e10, "", false, "", "")
assert.Equal(t, types.ErrAmount, err)
_, err = CreateRawTx(&cobra.Command{}, "", 0, "", false, "", "coins-")
assert.Equal(t, types.ErrExecNameNotMatch, err)
}
func TestGetExecAddr(t *testing.T) {
_, err := GetExecAddr("coins")
assert.Nil(t, err)
}
func TestFormatAmountValue2Display(t *testing.T) {
var amount int64 = 1e8
s := FormatAmountValue2Display(amount)
assert.Equal(t, "1.0000", s)
}
func TestGetAmountValue(t *testing.T) {
n := GetAmountValue(&cobra.Command{}, "")
assert.Equal(t, int64(0), n)
}
func TestGetRealExecName(t *testing.T) {
s := getRealExecName("user.p.fzmtest.", "user.p.game")
assert.Equal(t, "user.p.game", s)
s = getRealExecName("user.p.fzmtest.", "game")
assert.Equal(t, "user.p.fzmtest.game", s)
}
......@@ -120,3 +120,76 @@ func TestAllow(t *testing.T) {
assert.Equal(t, types.ErrNotAllow, demo.Allow(tx, 0))
assert.Equal(t, false, demo.IsFriend(nil, nil, nil))
}
func TestDriverBase(t *testing.T) {
demo := newdemoApp().(*demoApp)
demo.SetExecutorType(nil)
assert.Nil(t, demo.GetPayloadValue())
assert.Nil(t, demo.GetExecutorType())
assert.True(t, demo.ExecutorOrder() == 0)
assert.Nil(t, demo.GetFuncMap())
demo.SetIsFree(false)
assert.False(t, demo.IsFree())
tx := &types.Transaction{Execer: []byte("demo"), To: ExecAddress("demo"), GroupCount: 1}
t.Log("addr:", ExecAddress("demo"))
_, err := demo.ExecLocal(tx, nil, 0)
assert.NoError(t, err)
_, err = demo.ExecDelLocal(tx, nil, 0)
assert.NoError(t, err)
_, err = demo.Exec(tx, 0)
assert.NoError(t, err)
err = demo.CheckTx(tx, 0)
assert.NoError(t, err)
txs := []*types.Transaction{tx}
demo.SetTxs(txs)
assert.Equal(t, txs, demo.GetTxs())
_, err = demo.GetTxGroup(0)
assert.Equal(t, types.ErrTxGroupFormat, err)
demo.SetReceipt(nil)
assert.Nil(t, demo.GetReceipt())
demo.SetLocalDB(nil)
assert.Nil(t, demo.GetLocalDB())
assert.Nil(t, demo.GetStateDB())
assert.True(t, demo.GetHeight() == 0)
assert.True(t, demo.GetBlockTime() == 0)
assert.True(t, demo.GetDifficulty() == 0)
assert.Equal(t, "demo", demo.GetName())
assert.Equal(t, "demo", demo.GetCurrentExecName())
name := demo.GetActionName(tx)
assert.Equal(t, "unknown", name)
assert.True(t, demo.CheckSignatureData(tx, 0))
assert.NotNil(t, demo.GetCoinsAccount())
assert.False(t, demo.CheckReceiptExecOk())
err = CheckAddress("1HUiTRFvp6HvW6eacgV9EoBSgroRDiUsMs", 0)
assert.NoError(t, err)
}
func TestDriverBase_Query(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
demo := newdemoApp().(*demoApp)
demo.SetLocalDB(kvdb)
addr := &types.ReqAddr{Addr: "1HUiTRFvp6HvW6eacgV9EoBSgroRDiUsMs", Count: 1, Direction: 1}
kvdb.Set(types.CalcTxAddrHashKey(addr.GetAddr(), ""), types.Encode(&types.ReplyTxInfo{}))
_, err := demo.GetTxsByAddr(addr)
assert.Equal(t, types.ErrNotFound, err)
addr.Height = -1
_, err = demo.GetTxsByAddr(addr)
assert.NoError(t, err)
c, err := demo.GetPrefixCount(&types.ReqKey{Key: types.CalcTxAddrHashKey(addr.GetAddr(), "")})
assert.NoError(t, err)
assert.True(t, c.(*types.Int64).Data == 1)
_, err = demo.GetAddrTxsCount(&types.ReqKey{Key: types.CalcTxAddrHashKey(addr.GetAddr(), "")})
assert.NoError(t, err)
_, err = demo.Query("", nil)
assert.Equal(t, types.ErrActionNotSupport, err)
}
......@@ -205,3 +205,16 @@ func TestTokenFinisher(t *testing.T) {
assert.Equal(t, reply.Key, "token-finisher")
assert.Equal(t, reply.Value, "[1FCX9XJTZXvZteagTrefJEBPZMt8BFmdoi]")
}
func TestModify(t *testing.T) {
manager := new(Manage)
log := &types.ReceiptLog{Ty: 0, Log: types.Encode(&types.ReceiptConfig{Prev: &types.ConfigItem{}, Current: &types.ConfigItem{}})}
receipt := &types.ReceiptData{Logs: []*types.ReceiptLog{log}}
_, err := manager.ExecDelLocal_Modify(nil, nil, receipt, 0)
assert.NoError(t, err)
_, err = manager.ExecLocal_Modify(nil, nil, receipt, 0)
assert.NoError(t, err)
}
......@@ -75,6 +75,11 @@ func TestKVCreator(t *testing.T) {
assert.Equal(t, types.ErrNotFound, err)
_, err = creator.Get([]byte("c1"))
assert.Equal(t, types.ErrNotFound, err)
creator = NewKVCreator(kvdb, []byte("prefix-"), nil)
creator.AddKVListOnly([]*types.KeyValue{{Key: []byte("k"), Value: []byte("v")}})
creator.DelRollbackKV()
creator.AddToLogs(nil)
}
func TestHeightIndexStr(t *testing.T) {
......
......@@ -5,9 +5,8 @@
package store
import (
"testing"
"os"
"testing"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/queue"
......@@ -153,4 +152,40 @@ func TestBaseStore_Queue(t *testing.T) {
assert.NotNil(t, resp)
assert.Equal(t, int64(types.EventStoreDel), resp.Ty)
list := &types.StoreList{StateHash: EmptyRoot[:]}
msg = queueClinet.NewMessage("store", types.EventStoreList, list)
err = queueClinet.Send(msg, true)
assert.Nil(t, err)
resp, err = queueClinet.Wait(msg)
assert.Nil(t, err)
assert.NotNil(t, resp)
assert.Equal(t, int64(types.EventStoreListReply), resp.Ty)
}
func TestSubStore(t *testing.T) {
storelistQuery := NewStoreListQuery(&storeChild{}, &types.StoreList{StateHash: EmptyRoot[:], Mode: 1})
ok := storelistQuery.IterateCallBack([]byte("abc"), nil)
_ = storelistQuery.Run()
assert.True(t, ok)
storelistQuery = NewStoreListQuery(&storeChild{}, &types.StoreList{StateHash: EmptyRoot[:], Count: 2, Mode: 1})
ok = storelistQuery.IterateCallBack([]byte("abc"), nil)
assert.False(t, ok)
storelistQuery = NewStoreListQuery(&storeChild{}, &types.StoreList{StateHash: EmptyRoot[:], Suffix: []byte("bc"), Mode: 2})
ok = storelistQuery.IterateCallBack([]byte("abc"), nil)
assert.True(t, ok)
}
func TestRegAndLoad(t *testing.T) {
Reg("test", func(cfg *types.Store, sub []byte) queue.Module {
return nil
})
_, err := Load("test")
assert.NoError(t, err)
_, err = Load("test2")
assert.Equal(t, types.ErrNotFound, err)
}
......@@ -248,6 +248,53 @@ func (m *ReceiptAccountMint) GetCurrent() *Account {
return nil
}
type ReceiptAccountBurn struct {
Prev *Account `protobuf:"bytes,1,opt,name=prev,proto3" json:"prev,omitempty"`
Current *Account `protobuf:"bytes,2,opt,name=current,proto3" json:"current,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReceiptAccountBurn) Reset() { *m = ReceiptAccountBurn{} }
func (m *ReceiptAccountBurn) String() string { return proto.CompactTextString(m) }
func (*ReceiptAccountBurn) ProtoMessage() {}
func (*ReceiptAccountBurn) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{4}
}
func (m *ReceiptAccountBurn) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReceiptAccountBurn.Unmarshal(m, b)
}
func (m *ReceiptAccountBurn) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReceiptAccountBurn.Marshal(b, m, deterministic)
}
func (m *ReceiptAccountBurn) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReceiptAccountBurn.Merge(m, src)
}
func (m *ReceiptAccountBurn) XXX_Size() int {
return xxx_messageInfo_ReceiptAccountBurn.Size(m)
}
func (m *ReceiptAccountBurn) XXX_DiscardUnknown() {
xxx_messageInfo_ReceiptAccountBurn.DiscardUnknown(m)
}
var xxx_messageInfo_ReceiptAccountBurn proto.InternalMessageInfo
func (m *ReceiptAccountBurn) GetPrev() *Account {
if m != nil {
return m.Prev
}
return nil
}
func (m *ReceiptAccountBurn) GetCurrent() *Account {
if m != nil {
return m.Current
}
return nil
}
//查询一个地址列表在某个执行器中余额
type ReqBalance struct {
//地址列表
......@@ -266,7 +313,7 @@ func (m *ReqBalance) Reset() { *m = ReqBalance{} }
func (m *ReqBalance) String() string { return proto.CompactTextString(m) }
func (*ReqBalance) ProtoMessage() {}
func (*ReqBalance) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{4}
return fileDescriptor_8e28828dcb8d24f0, []int{5}
}
func (m *ReqBalance) XXX_Unmarshal(b []byte) error {
......@@ -334,7 +381,7 @@ func (m *Accounts) Reset() { *m = Accounts{} }
func (m *Accounts) String() string { return proto.CompactTextString(m) }
func (*Accounts) ProtoMessage() {}
func (*Accounts) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{5}
return fileDescriptor_8e28828dcb8d24f0, []int{6}
}
func (m *Accounts) XXX_Unmarshal(b []byte) error {
......@@ -374,7 +421,7 @@ func (m *ExecAccount) Reset() { *m = ExecAccount{} }
func (m *ExecAccount) String() string { return proto.CompactTextString(m) }
func (*ExecAccount) ProtoMessage() {}
func (*ExecAccount) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{6}
return fileDescriptor_8e28828dcb8d24f0, []int{7}
}
func (m *ExecAccount) XXX_Unmarshal(b []byte) error {
......@@ -421,7 +468,7 @@ func (m *AllExecBalance) Reset() { *m = AllExecBalance{} }
func (m *AllExecBalance) String() string { return proto.CompactTextString(m) }
func (*AllExecBalance) ProtoMessage() {}
func (*AllExecBalance) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{7}
return fileDescriptor_8e28828dcb8d24f0, []int{8}
}
func (m *AllExecBalance) XXX_Unmarshal(b []byte) error {
......@@ -473,7 +520,7 @@ func (m *ReqAllExecBalance) Reset() { *m = ReqAllExecBalance{} }
func (m *ReqAllExecBalance) String() string { return proto.CompactTextString(m) }
func (*ReqAllExecBalance) ProtoMessage() {}
func (*ReqAllExecBalance) Descriptor() ([]byte, []int) {
return fileDescriptor_8e28828dcb8d24f0, []int{8}
return fileDescriptor_8e28828dcb8d24f0, []int{9}
}
func (m *ReqAllExecBalance) XXX_Unmarshal(b []byte) error {
......@@ -534,6 +581,7 @@ func init() {
proto.RegisterType((*ReceiptExecAccountTransfer)(nil), "types.ReceiptExecAccountTransfer")
proto.RegisterType((*ReceiptAccountTransfer)(nil), "types.ReceiptAccountTransfer")
proto.RegisterType((*ReceiptAccountMint)(nil), "types.ReceiptAccountMint")
proto.RegisterType((*ReceiptAccountBurn)(nil), "types.ReceiptAccountBurn")
proto.RegisterType((*ReqBalance)(nil), "types.ReqBalance")
proto.RegisterType((*Accounts)(nil), "types.Accounts")
proto.RegisterType((*ExecAccount)(nil), "types.ExecAccount")
......@@ -544,32 +592,33 @@ func init() {
func init() { proto.RegisterFile("account.proto", fileDescriptor_8e28828dcb8d24f0) }
var fileDescriptor_8e28828dcb8d24f0 = []byte{
// 427 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0xcd, 0x6a, 0x14, 0x41,
0x10, 0xa6, 0xf7, 0x27, 0x9b, 0xa9, 0xd5, 0x80, 0x7d, 0x08, 0x4d, 0x30, 0x38, 0xf6, 0x69, 0x0e,
0xb2, 0x0b, 0x8e, 0x2f, 0x90, 0x80, 0xe0, 0x45, 0x84, 0xd6, 0x53, 0x2e, 0xd2, 0xd3, 0xa9, 0x75,
0x07, 0x27, 0x3d, 0x93, 0xee, 0x5e, 0x71, 0x7d, 0x00, 0x5f, 0x43, 0xf0, 0x49, 0xa5, 0x6b, 0x7b,
0xb2, 0xb3, 0x06, 0x25, 0x07, 0xc1, 0xdb, 0xd4, 0xf7, 0x55, 0xd5, 0xf7, 0x75, 0x55, 0x31, 0xf0,
0x58, 0x1b, 0xd3, 0x6e, 0x6c, 0x58, 0x74, 0xae, 0x0d, 0x2d, 0x9f, 0x86, 0x6d, 0x87, 0x5e, 0x7e,
0x86, 0xd9, 0xc5, 0x0e, 0xe7, 0x67, 0x70, 0x6c, 0x36, 0xce, 0xa1, 0x35, 0x5b, 0xc1, 0x72, 0x56,
0x4c, 0xd5, 0x5d, 0xcc, 0x05, 0xcc, 0x2a, 0xdd, 0x68, 0x6b, 0x50, 0x8c, 0x72, 0x56, 0x8c, 0x55,
0x1f, 0xf2, 0x53, 0x38, 0x5a, 0xb9, 0xf6, 0x1b, 0x5a, 0x31, 0x26, 0x22, 0x45, 0x9c, 0xc3, 0x44,
0x5f, 0x5f, 0x3b, 0x31, 0xc9, 0x59, 0x91, 0x29, 0xfa, 0x96, 0xdf, 0x19, 0x9c, 0x29, 0x34, 0x58,
0x77, 0xe1, 0xf5, 0x57, 0x34, 0x49, 0xf8, 0x83, 0xd3, 0xd6, 0xaf, 0xd0, 0x45, 0x03, 0x18, 0xe1,
0x58, 0xc6, 0xa8, 0xec, 0x2e, 0xe6, 0x12, 0x26, 0x9d, 0xc3, 0x2f, 0xa4, 0x3e, 0x7f, 0x79, 0xb2,
0x20, 0xf7, 0x8b, 0xd4, 0x41, 0x11, 0xc7, 0x0b, 0x98, 0xed, 0x0c, 0x07, 0xf2, 0x72, 0x3f, 0xad,
0xa7, 0xe5, 0x0a, 0x4e, 0x93, 0x8f, 0xdf, 0x3d, 0xf4, 0x3a, 0xec, 0x61, 0x3a, 0xa3, 0xbf, 0xeb,
0x54, 0xc0, 0x0f, 0x75, 0xde, 0xd6, 0x36, 0xfc, 0x63, 0x8d, 0x9f, 0x0c, 0x40, 0xe1, 0xed, 0x65,
0xda, 0xc7, 0x53, 0xc8, 0xe2, 0xac, 0xd1, 0x7b, 0xf4, 0x82, 0xe5, 0xe3, 0x22, 0x53, 0x7b, 0x20,
0x6e, 0x2b, 0x8e, 0x14, 0x1d, 0x75, 0xcd, 0x54, 0x8a, 0x62, 0x95, 0x0f, 0x3a, 0xe0, 0x1b, 0xed,
0xd7, 0x34, 0xbc, 0x4c, 0xed, 0x01, 0x7e, 0x0e, 0xa0, 0xbd, 0xc7, 0xf0, 0x31, 0x66, 0xa7, 0x8d,
0x66, 0x84, 0xc4, 0x35, 0xf2, 0xe7, 0xf0, 0x68, 0x47, 0xfb, 0xed, 0x4d, 0xd5, 0x36, 0x62, 0x4a,
0x09, 0x73, 0xc2, 0xde, 0x13, 0x24, 0x5f, 0xc0, 0x71, 0x32, 0xee, 0x79, 0x0e, 0x63, 0x6d, 0x0c,
0x79, 0xbb, 0xff, 0xac, 0x48, 0xc9, 0x77, 0x30, 0x1f, 0xdc, 0xc7, 0xc0, 0x34, 0x3b, 0x30, 0x5d,
0xc0, 0x2c, 0xdd, 0xf4, 0x9f, 0x66, 0x94, 0x68, 0x79, 0x05, 0x27, 0x17, 0x4d, 0x13, 0x7b, 0xf6,
0x63, 0xea, 0xcf, 0x93, 0xed, 0xcf, 0x93, 0xbf, 0x3a, 0x90, 0x15, 0x23, 0x32, 0xc8, 0x53, 0xcf,
0x01, 0xa3, 0x86, 0x69, 0xf2, 0x07, 0x83, 0x27, 0x0a, 0x6f, 0x1f, 0xd0, 0xff, 0x3f, 0x0d, 0xff,
0xf2, 0xd9, 0xd5, 0xf9, 0xa7, 0x3a, 0xac, 0x37, 0xd5, 0xc2, 0xb4, 0x37, 0xcb, 0xb2, 0x34, 0x76,
0x69, 0xd6, 0xba, 0xb6, 0x65, 0xb9, 0xa4, 0xb7, 0x55, 0x47, 0xf4, 0x4b, 0x28, 0x7f, 0x05, 0x00,
0x00, 0xff, 0xff, 0x1b, 0xce, 0xc2, 0x14, 0x23, 0x04, 0x00, 0x00,
// 434 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x54, 0xcd, 0x6e, 0x13, 0x31,
0x10, 0x96, 0xf3, 0xd3, 0x74, 0x27, 0x50, 0x09, 0x1f, 0x2a, 0xab, 0xa2, 0x62, 0xf1, 0x69, 0x0f,
0x28, 0x91, 0x58, 0x5e, 0xa0, 0x91, 0x90, 0xb8, 0x20, 0x24, 0xc3, 0xa9, 0x17, 0xe4, 0x75, 0x27,
0x24, 0x22, 0xf5, 0x6e, 0x6d, 0x2f, 0x22, 0x3c, 0x00, 0xaf, 0x81, 0xc4, 0x93, 0x22, 0x4f, 0xbc,
0xcd, 0x86, 0x0a, 0xd4, 0x03, 0xa8, 0xb7, 0x9d, 0xef, 0x1b, 0xcf, 0xf7, 0xd9, 0x33, 0xb3, 0xf0,
0x58, 0x1b, 0x53, 0xb7, 0x36, 0xcc, 0x1a, 0x57, 0x87, 0x9a, 0x8f, 0xc3, 0xb6, 0x41, 0x2f, 0x3f,
0xc3, 0xe4, 0x62, 0x87, 0xf3, 0x33, 0x38, 0x36, 0xad, 0x73, 0x68, 0xcd, 0x56, 0xb0, 0x9c, 0x15,
0x63, 0x75, 0x1b, 0x73, 0x01, 0x93, 0x4a, 0x6f, 0xb4, 0x35, 0x28, 0x06, 0x39, 0x2b, 0x86, 0xaa,
0x0b, 0xf9, 0x29, 0x1c, 0x2d, 0x5d, 0xfd, 0x0d, 0xad, 0x18, 0x12, 0x91, 0x22, 0xce, 0x61, 0xa4,
0xaf, 0xae, 0x9c, 0x18, 0xe5, 0xac, 0xc8, 0x14, 0x7d, 0xcb, 0xef, 0x0c, 0xce, 0x14, 0x1a, 0x5c,
0x37, 0xe1, 0xf5, 0x57, 0x34, 0x49, 0xf8, 0x83, 0xd3, 0xd6, 0x2f, 0xd1, 0x45, 0x03, 0x18, 0xe1,
0x78, 0x8c, 0xd1, 0xb1, 0xdb, 0x98, 0x4b, 0x18, 0x35, 0x0e, 0xbf, 0x90, 0xfa, 0xf4, 0xe5, 0xc9,
0x8c, 0xdc, 0xcf, 0x52, 0x05, 0x45, 0x1c, 0x2f, 0x60, 0xb2, 0x33, 0x1c, 0xc8, 0xcb, 0xdd, 0xb4,
0x8e, 0x96, 0x4b, 0x38, 0x4d, 0x3e, 0x7e, 0xf7, 0xd0, 0xe9, 0xb0, 0xfb, 0xe9, 0x0c, 0xfe, 0xae,
0x53, 0x01, 0x3f, 0xd4, 0x79, 0xbb, 0xb6, 0xe1, 0x7f, 0x6b, 0x2c, 0x5a, 0x67, 0xff, 0xb1, 0xc6,
0x4f, 0x06, 0xa0, 0xf0, 0x66, 0x91, 0x7a, 0xfe, 0x14, 0xb2, 0xd8, 0x4f, 0xf4, 0x1e, 0xbd, 0x60,
0xf9, 0xb0, 0xc8, 0xd4, 0x1e, 0x88, 0x13, 0x11, 0xdb, 0x86, 0x8e, 0xaa, 0x66, 0x2a, 0x45, 0xf1,
0x94, 0x0f, 0x3a, 0xe0, 0x1b, 0xed, 0x57, 0xd4, 0xa0, 0x4c, 0xed, 0x01, 0x7e, 0x0e, 0xa0, 0xbd,
0xc7, 0xf0, 0x31, 0x66, 0xa7, 0xa9, 0xc9, 0x08, 0x89, 0xa3, 0xc2, 0x9f, 0xc3, 0xa3, 0x1d, 0xed,
0xb7, 0xd7, 0x55, 0xbd, 0x11, 0x63, 0x4a, 0x98, 0x12, 0xf6, 0x9e, 0x20, 0xf9, 0x02, 0x8e, 0x93,
0x71, 0xcf, 0x73, 0x18, 0x6a, 0x63, 0xc8, 0xdb, 0xdd, 0x6b, 0x45, 0x4a, 0xbe, 0x83, 0x69, 0x6f,
0x06, 0x7b, 0xa6, 0xd9, 0x81, 0xe9, 0x02, 0x26, 0x69, 0x6f, 0xfe, 0xf4, 0x46, 0x89, 0x96, 0x97,
0x70, 0x72, 0xb1, 0xd9, 0xc4, 0x9a, 0xdd, 0x33, 0x75, 0x2b, 0xc0, 0xf6, 0x2b, 0xc0, 0x5f, 0x1d,
0xc8, 0x8a, 0x01, 0x19, 0xe4, 0xa9, 0x66, 0x8f, 0x51, 0xfd, 0x34, 0xf9, 0x83, 0xc1, 0x13, 0x85,
0x37, 0xf7, 0xa8, 0xff, 0x40, 0x8f, 0xbf, 0x78, 0x76, 0x79, 0xfe, 0x69, 0x1d, 0x56, 0x6d, 0x35,
0x33, 0xf5, 0xf5, 0xbc, 0x2c, 0x8d, 0x9d, 0x9b, 0x95, 0x5e, 0xdb, 0xb2, 0x9c, 0xd3, 0xdd, 0xaa,
0x23, 0xfa, 0xed, 0x94, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0x57, 0xdf, 0x86, 0xd3, 0x87, 0x04,
0x00, 0x00,
}
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
}
}
......@@ -104,6 +104,7 @@ const (
TyLogGenesisDeposit = 12
TyLogRollback = 13
TyLogMint = 14
TyLogBurn = 15
)
//SystemLog 系统log日志
......@@ -121,6 +122,8 @@ var SystemLog = map[int64]*LogInfo{
TyLogGenesisTransfer: {reflect.TypeOf(ReceiptAccountTransfer{}), "LogGenesisTransfer"},
TyLogGenesisDeposit: {reflect.TypeOf(ReceiptAccountTransfer{}), "LogGenesisDeposit"},
TyLogRollback: {reflect.TypeOf(LocalDBSet{}), "LogRollback"},
TyLogMint: {reflect.TypeOf(ReceiptAccountMint{}), "LogMint"},
TyLogBurn: {reflect.TypeOf(ReceiptAccountBurn{}), "LogBurn"},
}
//exec type
......
......@@ -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
}
......
......@@ -41,6 +41,11 @@ message ReceiptAccountMint {
Account current = 2;
}
message ReceiptAccountBurn {
Account prev = 1;
Account current = 2;
}
//查询一个地址列表在某个执行器中余额
message ReqBalance {
//地址列表
......@@ -75,4 +80,4 @@ message ReqAllExecBalance {
string stateHash = 3;
string asset_exec = 4;
string asset_symbol = 5;
}
\ No newline at end of file
}
......@@ -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()
}
}
......@@ -17,7 +17,10 @@ import (
func CheckBlock(client queue.Client, block *types.BlockDetail) error {
req := block
msg := client.NewMessage("consensus", types.EventCheckBlock, req)
client.Send(msg, true)
err := client.Send(msg, true)
if err != nil {
return err
}
resp, err := client.Wait(msg)
if err != nil {
return err
......@@ -43,7 +46,10 @@ func ExecTx(client queue.Client, prevStateRoot []byte, block *types.Block) (*typ
IsMempool: false,
}
msg := client.NewMessage("execs", types.EventExecTxList, list)
client.Send(msg, true)
err := client.Send(msg, true)
if err != nil {
return nil, err
}
resp, err := client.Wait(msg)
if err != nil {
return nil, err
......@@ -58,7 +64,10 @@ func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset
setwithsync := &types.StoreSetWithSync{Storeset: set, Sync: sync}
msg := client.NewMessage("store", types.EventStoreMemSet, setwithsync)
client.Send(msg, true)
err := client.Send(msg, true)
if err != nil {
return nil, err
}
resp, err := client.Wait(msg)
if err != nil {
return nil, err
......@@ -71,8 +80,11 @@ func ExecKVMemSet(client queue.Client, prevStateRoot []byte, height int64, kvset
func ExecKVSetCommit(client queue.Client, hash []byte) error {
req := &types.ReqHash{Hash: hash}
msg := client.NewMessage("store", types.EventStoreCommit, req)
client.Send(msg, true)
msg, err := client.Wait(msg)
err := client.Send(msg, true)
if err != nil {
return err
}
msg, err = client.Wait(msg)
if err != nil {
return err
}
......@@ -85,8 +97,11 @@ func ExecKVSetCommit(client queue.Client, hash []byte) error {
func ExecKVSetRollback(client queue.Client, hash []byte) error {
req := &types.ReqHash{Hash: hash}
msg := client.NewMessage("store", types.EventStoreRollback, req)
client.Send(msg, true)
msg, err := client.Wait(msg)
err := client.Send(msg, true)
if err != nil {
return err
}
msg, err = client.Wait(msg)
if err != nil {
return err
}
......@@ -190,25 +205,17 @@ func ReportErrEventToFront(logger log.Logger, client queue.Client, frommodule st
//DelDupKey 删除重复的key
func DelDupKey(kvs []*types.KeyValue) []*types.KeyValue {
dupindex := make(map[string]int)
hasdup := false
for i, kv := range kvs {
n := 0
for _, kv := range kvs {
skey := string(kv.Key)
if index, ok := dupindex[skey]; ok {
hasdup = true
kvs[index] = nil
}
dupindex[skey] = i
}
//没有重复的情况下,不需要重新处理
if !hasdup {
return kvs
}
index := 0
for _, kv := range kvs {
if kv != nil {
//重复的key 替换老的key
kvs[index] = kv
index++
} else {
dupindex[skey] = n
kvs[n] = kv
n++
}
}
return kvs[0:index]
return kvs[0:n]
}
......@@ -32,6 +32,9 @@ func TestStart(t *testing.T) {
cfg, _ := types.InitCfg("../cmd/chain33/chain33.test.toml")
health.Start(cfg.Health)
time.Sleep(time.Second * 3)
api.On("IsSync").Return(&types.Reply{IsOk: false}, nil)
health.Start(cfg.Health)
time.Sleep(time.Second * 3)
health.Close()
time.Sleep(time.Second * 1)
}
......
......@@ -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
......
......@@ -289,14 +289,23 @@ func (mock *Chain33Mock) Close() {
}
func (mock *Chain33Mock) closeNoLock() {
lognode.Info("network close")
mock.network.Close()
lognode.Info("network close")
mock.rpc.Close()
lognode.Info("rpc close")
mock.mem.Close()
lognode.Info("mem close")
mock.exec.Close()
lognode.Info("exec close")
mock.cs.Close()
lognode.Info("cs close")
mock.wallet.Close()
lognode.Info("wallet close")
mock.chain.Close()
lognode.Info("chain close")
mock.store.Close()
lognode.Info("store close")
mock.client.Close()
os.RemoveAll(mock.datadir)
}
......
......@@ -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)
......
......@@ -5,15 +5,20 @@
package util
import (
"errors"
"sync/atomic"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/queue"
qmocks "github.com/33cn/chain33/queue/mocks"
_ "github.com/33cn/chain33/system/crypto/secp256k1"
_ "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
_ "github.com/33cn/chain33/system/dapp/coins/types"
"github.com/stretchr/testify/mock"
)
func TestMakeStringUpper(t *testing.T) {
......@@ -139,8 +144,8 @@ func TestDelDupKey(t *testing.T) {
{Key: []byte("hello"), Value: []byte("world2")},
}
result := []*types.KeyValue{
{Key: []byte("hello1"), Value: []byte("world")},
{Key: []byte("hello"), Value: []byte("world2")},
{Key: []byte("hello1"), Value: []byte("world")},
}
kvs = DelDupKey(kvs)
assert.Equal(t, kvs, result)
......@@ -168,6 +173,7 @@ func BenchmarkDelDupKey(b *testing.B) {
kvs = append(kvs, &types.KeyValue{Key: key, Value: value})
}
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
testkv := make([]*types.KeyValue, len(kvs))
copy(testkv, kvs)
......@@ -225,3 +231,91 @@ func TestMockModule(t *testing.T) {
assert.Equal(t, reply.GetIsOk(), false)
assert.Equal(t, reply.GetMsg(), []byte("mock mempool module not handle message 1"))
}
func TestJSONPrint(t *testing.T) {
JSONPrint(t, &types.Reply{})
}
type testClient struct {
qmocks.Client
}
var gid int64
func (t *testClient) NewMessage(topic string, ty int64, data interface{}) *queue.Message {
id := atomic.AddInt64(&gid, 1)
return queue.NewMessage(id, topic, ty, data)
}
func (t *testClient) Wait(in *queue.Message) (*queue.Message, error) {
switch in.Ty {
case types.EventTxHashList:
return &queue.Message{Data: &types.TxHashList{}}, nil
case types.EventExecTxList:
return &queue.Message{Data: &types.Receipts{Receipts: []*types.Receipt{{Ty: 2}, {Ty: types.ExecErr}}}}, nil
case types.EventStoreMemSet:
return &queue.Message{Data: &types.ReplyHash{}}, nil
case types.EventStoreRollback:
return &queue.Message{Data: &types.ReplyHash{}}, nil
case types.EventStoreCommit:
return &queue.Message{Data: &types.ReplyHash{}}, nil
case types.EventCheckBlock:
return &queue.Message{Data: &types.Reply{IsOk: true}}, nil
}
return &queue.Message{}, nil
}
func TestExecBlock(t *testing.T) {
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
var txs []*types.Transaction
addr, priv := Genaddress()
tx := CreateCoinsTx(priv, addr, types.Coin)
tx.Sign(types.SECP256K1, priv)
txs = append(txs, tx)
_, _, err := ExecBlock(client, nil, &types.Block{Txs: txs}, false, true, false)
assert.NoError(t, err)
}
func TestExecAndCheckBlock(t *testing.T) {
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
_, err := ExecAndCheckBlock(client, &types.Block{}, nil, 0)
assert.NoError(t, err)
_, err = ExecAndCheckBlock2(client, &types.Block{}, nil, nil)
assert.NoError(t, err)
}
func TestCheckBlock(t *testing.T) {
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
err := CheckBlock(client, nil)
assert.NoError(t, err)
}
func TestExecKVSetRollback(t *testing.T) {
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
err := ExecKVSetRollback(client, nil)
assert.NoError(t, err)
}
func TestCheckDupTx(t *testing.T) {
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
var txs []*types.Transaction
addr, priv := Genaddress()
tx := CreateCoinsTx(priv, addr, types.Coin)
tx.Sign(types.SECP256K1, priv)
txs = append(txs, tx)
_, err := CheckDupTx(client, txs, 1)
assert.NoError(t, err)
}
func TestReportErrEventToFront(t *testing.T) {
logger := log.New("test")
client := &testClient{}
client.On("Send", mock.Anything, mock.Anything).Return(nil)
ReportErrEventToFront(logger, client, "from", "to", errors.New("test"))
}
......@@ -6,6 +6,13 @@
package basen_test
import (
"testing"
"github.com/33cn/chain33/wallet/bipwallet/basen"
"github.com/stretchr/testify/assert"
)
/*
func Test(t *testing.T) { gc.TestingT(t) }
......@@ -69,3 +76,18 @@ func (s *Suite) TestNoMultiByte(c *gc.C) {
"multi-byte characters not supported")
}
*/
func TestBase58(t *testing.T) {
s := basen.Base58.MustRandom(10)
assert.False(t, len(s) == 0)
b, err := basen.Base58.DecodeString(s)
assert.NoError(t, err)
assert.True(t, len(b) == 10)
b, err = basen.Base58.DecodeStringN(s, 12)
assert.NoError(t, err)
assert.True(t, len(b) == 12)
assert.True(t, basen.Base58.Base() == 58)
}
......@@ -124,4 +124,8 @@ func testVectorKeyPairs(t *testing.T, vector testMasterKey) {
assert.Equal(t, testChildKey.privKey, privKey.String())
assert.Equal(t, testChildKey.pubKey, pubKey.String())
}
childPubkey, err := pubKey.NewChildKey(0)
assert.NoError(t, err)
assert.NotNil(t, childPubkey)
}
......@@ -11,6 +11,7 @@ import (
bip32 "github.com/33cn/chain33/wallet/bipwallet/go-bip32"
bip39 "github.com/33cn/chain33/wallet/bipwallet/go-bip39"
. "github.com/33cn/chain33/wallet/bipwallet/go-bip44"
"github.com/stretchr/testify/assert"
)
func TestNewKeyFromMnemonic(t *testing.T) {
......@@ -30,6 +31,10 @@ func TestNewKeyFromMnemonic(t *testing.T) {
if ecKey.String() != "xprvA2ziNegvZRfAAUtDsjeS9LvCP1TFXfR3hUzMcJw7oYAhdPqZyiJTMf1ByyLRxvQmGvgbPcG6Q569m26ixWsmgTR3d3PwicrG7hGD7C7seJA" {
t.Errorf("Invalid EC key - %v", ecKey.String())
}
mnemonic = "aaaaaa"
_, err = NewKeyFromMnemonic(mnemonic, bipwallet.TypeFactomFactoids, bip32.FirstHardenedChild, 0, 0)
assert.NotNil(t, err)
}
func TestNewKeyFromMasterKey(t *testing.T) {
......@@ -60,6 +65,9 @@ func TestNewKeyFromMasterKey(t *testing.T) {
if ecKey.String() != "xprvA2ziNegvZRfAAUtDsjeS9LvCP1TFXfR3hUzMcJw7oYAhdPqZyiJTMf1ByyLRxvQmGvgbPcG6Q569m26ixWsmgTR3d3PwicrG7hGD7C7seJA" {
t.Errorf("Invalid EC key - %v", ecKey.String())
}
_, err = NewKeyFromMasterKey(&bip32.Key{}, bipwallet.TypeFactomFactoids, bip32.FirstHardenedChild, 0, 0)
assert.NotNil(t, err)
}
/*
......
......@@ -14,12 +14,12 @@ import (
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/store"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
wcom "github.com/33cn/chain33/wallet/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
_ "github.com/33cn/chain33/system"
)
func init() {
......@@ -47,6 +47,8 @@ var (
ToAddr1 string
ToAddr2 string
AddrPrivKey string
addr string
priv crypto.PrivKey
)
func blockchainModProc(q queue.Queue) {
......@@ -93,12 +95,14 @@ func blockchainModProc(q queue.Queue) {
msg.Reply(client.NewMessage("", types.EventReplyBlockHeight, &types.ReplyBlockHeight{Height: 1}))
} else if msg.Ty == types.EventIsSync {
msg.Reply(client.NewMessage("", types.EventReplyIsSync, &types.IsCaughtUp{Iscaughtup: true}))
} else if msg.Ty == types.EventQueryTx {
msg.Reply(client.NewMessage("", types.EventTransactionDetail, &types.TransactionDetail{Receipt: &types.ReceiptData{Ty: types.ExecOk}}))
}
}
}()
go func() {
client := q.Client()
client.Sub("execs")
client.Sub("exec")
for msg := range client.Recv() {
walletlog.Error("execs", "msg.Ty", msg.Ty)
if msg.Ty == types.EventBlockChainQuery {
......@@ -181,6 +185,9 @@ func TestWallet(t *testing.T) {
testSignRawTx(t, wallet)
testsetFatalFailure(t, wallet)
testgetFatalFailure(t, wallet)
testWallet(t, wallet)
testSendTx(t, wallet)
}
//ProcWalletLock
......@@ -737,3 +744,75 @@ func testgetFatalFailure(t *testing.T, wallet *Wallet) {
println("testgetFatalFailure end")
println("--------------------------")
}
func testWallet(t *testing.T, wallet *Wallet) {
println("test wallet begin")
addr, priv = util.Genaddress()
bpriv := wcom.CBCEncrypterPrivkey([]byte(wallet.Password), priv.Bytes())
was := &types.WalletAccountStore{Privkey: common.ToHex(bpriv), Label: "test", Addr: addr, TimeStamp: time.Now().String()}
err := wallet.SetWalletAccount(false, addr, was)
assert.NoError(t, err)
was1, err := wallet.GetAccountByAddr(addr)
assert.NoError(t, err)
assert.Equal(t, was.Privkey, was1.Privkey)
was2, err := wallet.GetAccountByLabel("test")
assert.NoError(t, err)
assert.Equal(t, was.Privkey, was2.Privkey)
priv2, err := wallet.GetPrivKeyByAddr(addr)
assert.NoError(t, err)
assert.Equal(t, priv, priv2)
_, err = wallet.GetWalletAccounts()
assert.NoError(t, err)
t.Log("password:", wallet.Password)
wallet.walletStore.SetWalletPassword("Newpass2")
assert.Equal(t, "Newpass2", wallet.walletStore.GetWalletPassword())
err = wallet.walletStore.SetFeeAmount(1e5)
assert.NoError(t, err)
fee := wallet.walletStore.GetFeeAmount(1e4)
assert.Equal(t, int64(1e5), fee)
println("test wallet end")
wallet.GetConfig()
wallet.GetMutex()
wallet.GetDBStore()
wallet.GetSignType()
wallet.GetPassword()
wallet.Nonce()
wallet.GetRandom()
wallet.GetBlockHeight()
wallet.GetWalletDone()
wallet.GetLastHeader()
wallet.IsClose()
wallet.AddWaitGroup(1)
wallet.WaitGroupDone()
wallet.RegisterMineStatusReporter(nil)
}
func testSendTx(t *testing.T, wallet *Wallet) {
ok := wallet.IsCaughtUp()
assert.True(t, ok)
_, err := wallet.GetBalance(addr, "coins")
assert.NoError(t, err)
_, err = wallet.GetAllPrivKeys()
assert.NoError(t, err)
hash, err := wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("coins"), priv, ToAddr1)
assert.NoError(t, err)
//wallet.WaitTx(hash)
wallet.WaitTxs([][]byte{hash})
hash, err = wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1)
assert.NoError(t, err)
t.Log(string(hash))
err = wallet.sendTransactionWait(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1)
assert.NoError(t, err)
_, err = wallet.getMinerColdAddr(addr)
assert.Equal(t, types.ErrActionNotSupport, err)
}
......@@ -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