Commit 6df24193 authored by hxzqlh's avatar hxzqlh

merge harrylee2015/exchange_fix_bug

parents 7a717b8d a4aa4397
...@@ -13,14 +13,7 @@ if [ "$(uname)" == "Darwin" ]; then ...@@ -13,14 +13,7 @@ if [ "$(uname)" == "Darwin" ]; then
fi fi
## get chain33 path ## get chain33 path
CHAIN33_PATH=$(grep -m1 github.com/33cn/chain33 ../../go.mod | grep -o '[^ ]\+$') CHAIN33_PATH=$(go list -f "{{.Dir}}" github.com/33cn/chain33)
CHAIN33_PATH="${CHAIN33_PATH%/}"
if [[ -d ../../${CHAIN33_PATH} ]]; then
CHAIN33_PATH=../../"$CHAIN33_PATH"
elif [[ ! -d ${CHAIN33_PATH} ]]; then
CHAIN33_PATH="${GOPATH}"/pkg/mod/github.com/33cn/chain33@"$CHAIN33_PATH"
fi
function build_auto_test() { function build_auto_test() {
......
...@@ -70,7 +70,7 @@ grpcFuncWhitelist=["*"] ...@@ -70,7 +70,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="para" name="para"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -162,8 +162,6 @@ signType="secp256k1" ...@@ -162,8 +162,6 @@ signType="secp256k1"
minerdisable=true minerdisable=true
[exec] [exec]
isFree=true
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
...@@ -66,8 +66,12 @@ grpcFuncWhitelist=["*"] ...@@ -66,8 +66,12 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="price" name="price"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
# 最小得交易手续费率,这个没有默认值,必填,一般是0.001 coins
minTxFeeRate=100000
# 最大的交易手续费率, 0.1 coins
maxTxFeeRate=10000000
# 单笔交易最大的手续费, 10 coins
maxTxFee=1000000000 maxTxFee=1000000000
isLevelFee=true isLevelFee=true
[mempool.sub.timeline] [mempool.sub.timeline]
...@@ -198,9 +202,6 @@ minerwhitelist=["*"] ...@@ -198,9 +202,6 @@ minerwhitelist=["*"]
rescanMultisigAddr=false rescanMultisigAddr=false
[exec] [exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
...@@ -229,8 +230,8 @@ genesis="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ...@@ -229,8 +230,8 @@ genesis="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
[exec.sub.manage] [exec.sub.manage]
superManager=[ superManager=[
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S", "1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv", "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK" "1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
] ]
[exec.sub.paracross] [exec.sub.paracross]
......
...@@ -3,7 +3,7 @@ module github.com/33cn/plugin ...@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12 go 1.12
require ( require (
github.com/33cn/chain33 v0.0.0-20191225114001-0e761fbcd8ce github.com/33cn/chain33 v0.0.0-20191230031247-b56730d527a0
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7 github.com/NebulousLabs/Sia v1.3.7
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac
......
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/33cn/chain33 v0.0.0-20191225114001-0e761fbcd8ce h1:8w3fHBpsupag2ue5iwyIv8cp6va2LtvZuJ/OhvNEEpk= github.com/33cn/chain33 v0.0.0-20191230031247-b56730d527a0 h1:U8qOKXeidZsyGGy/KN5fNQV1B9l28DvG52Ezqiv+4nc=
github.com/33cn/chain33 v0.0.0-20191225114001-0e761fbcd8ce/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ= github.com/33cn/chain33 v0.0.0-20191230031247-b56730d527a0/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
......
...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"] ...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[consensus] [consensus]
name="tendermint" name="tendermint"
...@@ -135,8 +135,6 @@ minerdisable=false ...@@ -135,8 +135,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -103,7 +103,7 @@ grpcFuncWhitelist=["*"] ...@@ -103,7 +103,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[consensus] [consensus]
name="dpos" name="dpos"
...@@ -176,8 +176,6 @@ minerdisable=false ...@@ -176,8 +176,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
...@@ -256,7 +254,7 @@ grpcFuncWhitelist=["*"] ...@@ -256,7 +254,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[consensus] [consensus]
name="dpos" name="dpos"
...@@ -350,8 +348,6 @@ minerdisable=false ...@@ -350,8 +348,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -74,11 +74,11 @@ func createCrossParaTempTx(cfg *types.Chain33Config, to string, amount int64) (* ...@@ -74,11 +74,11 @@ func createCrossParaTempTx(cfg *types.Chain33Config, to string, amount int64) (*
func createTxsGroup(cfg *types.Chain33Config, txs []*types.Transaction) ([]*types.Transaction, error) { func createTxsGroup(cfg *types.Chain33Config, txs []*types.Transaction) ([]*types.Transaction, error) {
group, err := types.CreateTxGroup(txs, cfg.GInt("MinFee")) group, err := types.CreateTxGroup(txs, cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = group.Check(cfg, 0, cfg.GInt("MinFee"), cfg.GInt("MaxFee")) err = group.Check(cfg, 0, cfg.GetMinTxFeeRate(), cfg.GetMaxTxFee())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -397,12 +397,12 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T ...@@ -397,12 +397,12 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T
return tx, nil return tx, nil
} }
cfg := client.paraClient.GetAPI().GetConfig() cfg := client.paraClient.GetAPI().GetConfig()
group, err := types.CreateTxGroup(txsArr.Txs, cfg.GInt("MinFee")) group, err := types.CreateTxGroup(txsArr.Txs, cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
plog.Error("para CreateTxGroup", "err", err.Error()) plog.Error("para CreateTxGroup", "err", err.Error())
return nil, err return nil, err
} }
err = group.Check(cfg, 0, cfg.GInt("MinFee"), cfg.GInt("MaxFee")) err = group.Check(cfg, 0, cfg.GetMinTxFeeRate(), cfg.GetMaxTxFee())
if err != nil { if err != nil {
plog.Error("para CheckTxGroup", "err", err.Error()) plog.Error("para CheckTxGroup", "err", err.Error())
return nil, err return nil, err
......
...@@ -53,7 +53,7 @@ verMax=119 ...@@ -53,7 +53,7 @@ verMax=119
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[rpc] [rpc]
jrpcBindAddr="localhost:8801" jrpcBindAddr="localhost:8801"
...@@ -104,8 +104,6 @@ minerdisable=false ...@@ -104,8 +104,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -61,7 +61,7 @@ grpcFuncWhitelist=["*"] ...@@ -61,7 +61,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
[mempool.sub.timeline] [mempool.sub.timeline]
...@@ -140,8 +140,6 @@ minerWaitTime="1s" ...@@ -140,8 +140,6 @@ minerWaitTime="1s"
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
...@@ -167,4 +165,4 @@ superManager=[ ...@@ -167,4 +165,4 @@ superManager=[
[exec.sub.autonomy] [exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp" total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false useBalance=false
\ No newline at end of file
...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"] ...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[consensus] [consensus]
name="tendermint" name="tendermint"
...@@ -117,8 +117,6 @@ minerdisable=false ...@@ -117,8 +117,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -63,7 +63,7 @@ grpcFuncWhitelist=["*"] ...@@ -63,7 +63,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -149,8 +149,6 @@ minerwhitelist=["*"] ...@@ -149,8 +149,6 @@ minerwhitelist=["*"]
minerWaitTime="1s" minerWaitTime="1s"
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
...@@ -179,8 +177,8 @@ signType="auth_ecdsa" ...@@ -179,8 +177,8 @@ signType="auth_ecdsa"
[exec.sub.manage] [exec.sub.manage]
superManager=[ superManager=[
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S", "1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv", "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK" "1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
] ]
......
...@@ -325,7 +325,7 @@ func TestValidateCerts(t *testing.T) { ...@@ -325,7 +325,7 @@ func TestValidateCerts(t *testing.T) {
t.Errorf("init env failed, error:%s", err) t.Errorf("init env failed, error:%s", err)
} }
prev := types.GInt("MinFee") prev := types.GetMinTxFeeRate()
types.SetMinFee(0) types.SetMinFee(0)
defer types.SetMinFee(prev) defer types.SetMinFee(prev)
......
...@@ -57,7 +57,7 @@ grpcFuncWhitelist=["*"] ...@@ -57,7 +57,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
poolCacheSize=10240 poolCacheSize=10240
minTxFee=1000000 minTxFeeRate=0
[consensus] [consensus]
name="solo" name="solo"
...@@ -81,8 +81,6 @@ signType="secp256k1" ...@@ -81,8 +81,6 @@ signType="secp256k1"
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=true
minExecFee=0
enableStat=false enableStat=false
[exec.sub.cert] [exec.sub.cert]
......
...@@ -116,7 +116,7 @@ grpcFuncWhitelist=["*"] ...@@ -116,7 +116,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
[consensus] [consensus]
name="tendermint" name="tendermint"
...@@ -189,8 +189,6 @@ minerdisable=false ...@@ -189,8 +189,6 @@ minerdisable=false
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -289,7 +289,7 @@ func createContract(cmd *cobra.Command, args []string) { ...@@ -289,7 +289,7 @@ func createContract(cmd *cobra.Command, args []string) {
func createEvmTx(cfg *types.Chain33Config, action proto.Message, execer, caller, addr, expire, rpcLaddr string, fee uint64) (string, error) { func createEvmTx(cfg *types.Chain33Config, action proto.Message, execer, caller, addr, expire, rpcLaddr string, fee uint64) (string, error) {
tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(action), Fee: 0, To: addr} tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(action), Fee: 0, To: addr}
tx.Fee, _ = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
if tx.Fee < int64(fee) { if tx.Fee < int64(fee) {
tx.Fee += int64(fee) tx.Fee += int64(fee)
} }
...@@ -341,7 +341,7 @@ func createEvmTransferTx(cfg *types.Chain33Config, cmd *cobra.Command, caller, e ...@@ -341,7 +341,7 @@ func createEvmTransferTx(cfg *types.Chain33Config, cmd *cobra.Command, caller, e
} }
var err error var err error
tx.Fee, err = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
return "", err return "", err
} }
......
...@@ -33,7 +33,7 @@ func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreat ...@@ -33,7 +33,7 @@ func (c *channelClient) Create(ctx context.Context, in evmtypes.EvmContractCreat
addr := address.ExecAddress(cfg.ExecName(in.ParaName + "evm")) addr := address.ExecAddress(cfg.ExecName(in.ParaName + "evm"))
tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(&action), Fee: 0, To: addr} tx := &types.Transaction{Execer: []byte(execer), Payload: types.Encode(&action), Fee: 0, To: addr}
tx.Fee, _ = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
if tx.Fee < in.Fee { if tx.Fee < in.Fee {
tx.Fee += in.Fee tx.Fee += in.Fee
} }
...@@ -62,7 +62,7 @@ func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq ...@@ -62,7 +62,7 @@ func (c *channelClient) Call(ctx context.Context, in evmtypes.EvmContractCallReq
tx := &types.Transaction{Execer: []byte(in.Exec), Payload: types.Encode(&action), Fee: 0, To: toAddr} tx := &types.Transaction{Execer: []byte(in.Exec), Payload: types.Encode(&action), Fee: 0, To: toAddr}
cfg := c.GetConfig() cfg := c.GetConfig()
tx.Fee, _ = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, _ = tx.GetRealFee(cfg.GetMinTxFeeRate())
if tx.Fee < feeInt64 { if tx.Fee < feeInt64 {
tx.Fee += feeInt64 tx.Fee += feeInt64
} }
...@@ -96,7 +96,7 @@ func (c *channelClient) Transfer(ctx context.Context, in evmtypes.EvmContractTra ...@@ -96,7 +96,7 @@ func (c *channelClient) Transfer(ctx context.Context, in evmtypes.EvmContractTra
} }
var err error var err error
tx.Fee, err = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -437,81 +437,294 @@ func TestExchange(t *testing.T) { ...@@ -437,81 +437,294 @@ func TestExchange(t *testing.T) {
assert.NotEqual(t, nil, err) assert.NotEqual(t, nil, err)
err = Exec_RevokeOrder(t, orderID, PrivKeyB, stateDB, kvdb, env) err = Exec_RevokeOrder(t, orderID, PrivKeyB, stateDB, kvdb, env)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
//清理环境,重建数据库
util.CloseTestDB(dir, stateDB)
total = 1000 * types.Coin
accountA = types.Account{
Balance: total,
Frozen: 0,
Addr: Nodes[0],
}
accountB = types.Account{
Balance: total,
Frozen: 0,
Addr: Nodes[1],
}
dir, stateDB, kvdb = util.CreateTestDB()
defer util.CloseTestDB(dir, stateDB)
//execAddr := address.ExecAddress(et.ExchangeX)
accA, _ = account.NewAccountDB(cfg, "coins", "bty", stateDB)
accA.SaveExecAccount(execAddr, &accountA)
accB, _ = account.NewAccountDB(cfg, "coins", "bty", stateDB)
accB.SaveExecAccount(execAddr, &accountB)
accA1, _ = account.NewAccountDB(cfg, "token", "CCNY", stateDB)
accA1.SaveExecAccount(execAddr, &accountA)
accB1, _ = account.NewAccountDB(cfg, "token", "CCNY", stateDB)
accB1.SaveExecAccount(execAddr, &accountB)
env = &execEnv{
10,
1,
1539918074,
}
/*
//批量测试,同一个区块内出现多笔可以撮合的买卖交易
用例说明:
1.在同一个区块内,出现如下:
10笔买单
20笔卖单
50笔买单
20笔卖单
50笔买单
100笔卖单
*/
acc = accB1.LoadExecAccount(Nodes[1], execAddr)
assert.Equal(t, 1000*types.Coin, acc.Balance)
acc = accA.LoadExecAccount(Nodes[0], execAddr)
assert.Equal(t, 1000*types.Coin, acc.Balance)
var txs []*types.Transaction
for i := 0; i < 10; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpBuy}, PrivKeyB)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 20; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpSell}, PrivKeyA)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 50; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpBuy}, PrivKeyB)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 20; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpSell}, PrivKeyA)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 50; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpBuy}, PrivKeyB)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 100; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpSell}, PrivKeyA)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
err = Exec_Block(t, stateDB, kvdb, env, txs...)
assert.Equal(t, nil, err)
acc = accB1.LoadExecAccount(Nodes[1], execAddr)
assert.Equal(t, 890*types.Coin, acc.Balance)
acc = accA.LoadExecAccount(Nodes[0], execAddr)
assert.Equal(t, 860*types.Coin, acc.Balance)
assert.Equal(t, 30*types.Coin, acc.Frozen)
//根据op查询市场深度
marketDepthList, err = Exec_QueryMarketDepth(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Op: et.OpBuy}, stateDB, kvdb)
assert.NotEqual(t, nil, err)
//assert.Equal(t, (200-et.MaxMatchCount)*types.Coin, marketDepthList.List[0].GetAmount())
marketDepthList, err = Exec_QueryMarketDepth(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Op: et.OpSell}, stateDB, kvdb)
assert.Equal(t, nil, err)
assert.Equal(t, 30*types.Coin, marketDepthList.List[0].GetAmount())
//清理环境,重建数据库
util.CloseTestDB(dir, stateDB)
total = 1000 * types.Coin
accountA = types.Account{
Balance: total,
Frozen: 0,
Addr: Nodes[0],
}
accountB = types.Account{
Balance: total,
Frozen: 0,
Addr: Nodes[1],
}
dir, stateDB, kvdb = util.CreateTestDB()
defer util.CloseTestDB(dir, stateDB)
//execAddr := address.ExecAddress(et.ExchangeX)
accA, _ = account.NewAccountDB(cfg, "coins", "bty", stateDB)
accA.SaveExecAccount(execAddr, &accountA)
accB, _ = account.NewAccountDB(cfg, "coins", "bty", stateDB)
accB.SaveExecAccount(execAddr, &accountB)
accA1, _ = account.NewAccountDB(cfg, "token", "CCNY", stateDB)
accA1.SaveExecAccount(execAddr, &accountA)
accB1, _ = account.NewAccountDB(cfg, "token", "CCNY", stateDB)
accB1.SaveExecAccount(execAddr, &accountB)
env = &execEnv{
10,
1,
1539918074,
}
/*
//批量测试,同个区块内出现多笔可以撮合的买卖交易
用例说明:
1.在同一区块内,出现如下:
100笔卖单
50笔买单
20笔卖单
100笔买单
*/
acc = accB1.LoadExecAccount(Nodes[1], execAddr)
assert.Equal(t, 1000*types.Coin, acc.Balance)
acc = accA.LoadExecAccount(Nodes[0], execAddr)
assert.Equal(t, 1000*types.Coin, acc.Balance)
txs = nil
for i := 0; i < 100; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpSell}, PrivKeyA)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 50; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpBuy}, PrivKeyB)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 20; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpSell}, PrivKeyA)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
for i := 0; i < 100; i++ {
tx, err := CreateLimitOrder(&et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: types.Coin, Amount: types.Coin, Op: et.OpBuy}, PrivKeyB)
assert.Equal(t, nil, err)
txs = append(txs, tx)
}
err = Exec_Block(t, stateDB, kvdb, env, txs...)
assert.Equal(t, nil, err)
acc = accB1.LoadExecAccount(Nodes[1], execAddr)
assert.Equal(t, 850*types.Coin, acc.Balance)
assert.Equal(t, 30*types.Coin, acc.Frozen)
acc = accA.LoadExecAccount(Nodes[0], execAddr)
assert.Equal(t, 880*types.Coin, acc.Balance)
//根据op查询市场深度
marketDepthList, err = Exec_QueryMarketDepth(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Op: et.OpSell}, stateDB, kvdb)
assert.NotEqual(t, nil, err)
marketDepthList, err = Exec_QueryMarketDepth(&et.QueryMarketDepth{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Op: et.OpBuy}, stateDB, kvdb)
assert.Equal(t, nil, err)
assert.Equal(t, 30*types.Coin, marketDepthList.List[0].GetAmount())
//根据状态地址查询订单信息
//分页查询
count = 0
primaryKey = ""
for {
orderList, err := Exec_QueryOrderList(et.Completed, Nodes[1], primaryKey, stateDB, kvdb)
if err != nil {
break
}
count = count + len(orderList.List)
if orderList.PrimaryKey == "" {
break
}
primaryKey = orderList.PrimaryKey
}
assert.Equal(t, 120, count)
count = 0
primaryKey = ""
for {
orderList, err := Exec_QueryOrderList(et.Ordered, Nodes[1], primaryKey, stateDB, kvdb)
if err != nil {
break
}
count = count + len(orderList.List)
if orderList.PrimaryKey == "" {
break
}
primaryKey = orderList.PrimaryKey
}
assert.Equal(t, 30, count)
} }
func Exec_LimitOrder(t *testing.T, limitOrder *et.LimitOrder, privKey string, stateDB db.DB, kvdb db.KVDB, env *execEnv) error { func CreateLimitOrder(limitOrder *et.LimitOrder, privKey string) (tx *types.Transaction, err error) {
ety := types.LoadExecutorType(et.ExchangeX) ety := types.LoadExecutorType(et.ExchangeX)
tx, err := ety.Create("LimitOrder", limitOrder) tx, err = ety.Create("LimitOrder", limitOrder)
if err != nil { if err != nil {
return err return nil, err
} }
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx) tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil { if err != nil {
return err return nil, err
} }
tx, err = signTx(tx, privKey) tx, err = signTx(tx, privKey)
if err != nil { if err != nil {
return err return nil, err
}
exec := NewExchange()
e := exec.(*exchange)
err = e.CheckTx(tx, 1)
if err != nil {
return err
}
q := queue.New("channel")
q.SetConfig(cfg)
api, _ := client.New(q.Client(), nil)
exec.SetAPI(api)
exec.SetStateDB(stateDB)
exec.SetLocalDB(kvdb)
env.blockHeight = env.blockHeight + 1
env.blockTime = env.blockTime + 20
env.difficulty = env.difficulty + 1
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(tx, int(1))
if err != nil {
return err
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(tx, receiptData, int(1))
if err != nil {
return err
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
} }
//save to database return tx, nil
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
return nil
} }
func CreateRevokeOrder(orderID int64, privKey string) (tx *types.Transaction, err error) {
func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB, kvdb db.KVDB, env *execEnv) error {
ety := types.LoadExecutorType(et.ExchangeX) ety := types.LoadExecutorType(et.ExchangeX)
tx, err := ety.Create("RevokeOrder", &et.RevokeOrder{OrderID: orderID}) tx, err = ety.Create("RevokeOrder", &et.RevokeOrder{OrderID: orderID})
if err != nil { if err != nil {
return err return nil, err
} }
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx) tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil { if err != nil {
return err return nil, err
} }
tx, err = signTx(tx, privKey) tx, err = signTx(tx, privKey)
if err != nil { if err != nil {
return err return nil, err
} }
return tx, nil
}
//模拟区块中交易得执行过程
func Exec_Block(t *testing.T, stateDB db.DB, kvdb db.KVDB, env *execEnv, txs ...*types.Transaction) error {
cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
e := exec.(*exchange) e := exec.(*exchange)
err = e.CheckTx(tx, 1) for index, tx := range txs {
assert.Nil(t, err) err := e.CheckTx(tx, index)
if err != nil {
t.Log(err.Error())
return err
}
}
q := queue.New("channel") q := queue.New("channel")
q.SetConfig(cfg) q.SetConfig(cfg)
api, _ := client.New(q.Client(), nil) api, _ := client.New(q.Client(), nil)
...@@ -522,25 +735,44 @@ func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB ...@@ -522,25 +735,44 @@ func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB
env.blockTime = env.blockTime + 20 env.blockTime = env.blockTime + 20
env.difficulty = env.difficulty + 1 env.difficulty = env.difficulty + 1
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty) exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(tx, int(1)) for index, tx := range txs {
receipt, err := exec.Exec(tx, index)
if err != nil {
t.Log(err.Error())
return err
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(tx, receiptData, index)
if err != nil {
t.Log(err.Error())
return err
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
//save to database
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
}
return nil
}
func Exec_LimitOrder(t *testing.T, limitOrder *et.LimitOrder, privKey string, stateDB db.DB, kvdb db.KVDB, env *execEnv) error {
tx, err := CreateLimitOrder(limitOrder, privKey)
if err != nil { if err != nil {
return err return err
} }
for _, kv := range receipt.KV { return Exec_Block(t, stateDB, kvdb, env, tx)
stateDB.Set(kv.Key, kv.Value) }
}
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs} func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB, kvdb db.KVDB, env *execEnv) error {
set, err := exec.ExecLocal(tx, receiptData, int(1)) tx, err := CreateRevokeOrder(orderID, privKey)
if err != nil { if err != nil {
return err return err
} }
for _, kv := range set.KV { return Exec_Block(t, stateDB, kvdb, env, tx)
kvdb.Set(kv.Key, kv.Value)
}
//save to database
util.SaveKVList(stateDB, set.KV)
assert.Equal(t, types.ExecOk, int(receipt.Ty))
return nil
} }
func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) { func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) {
......
...@@ -45,11 +45,6 @@ func (a *Action) GetKVSet(order *et.Order) (kvset []*types.KeyValue) { ...@@ -45,11 +45,6 @@ func (a *Action) GetKVSet(order *et.Order) (kvset []*types.KeyValue) {
return kvset return kvset
} }
//缓存
func (a *Action) updateStateDBCache(order *et.Order) {
a.statedb.Set(calcOrderKey(order.OrderID), types.Encode(order))
}
//反转 //反转
func (a *Action) OpSwap(op int32) int32 { func (a *Action) OpSwap(op int32) int32 {
if op == et.OpBuy { if op == et.OpBuy {
...@@ -59,7 +54,7 @@ func (a *Action) OpSwap(op int32) int32 { ...@@ -59,7 +54,7 @@ func (a *Action) OpSwap(op int32) int32 {
} }
//计算实际花费 //计算实际花费
func (a *Action) calcActualCost(op int32, amount int64, price int64) int64 { func CalcActualCost(op int32, amount int64, price int64) int64 {
if op == et.OpBuy { if op == et.OpBuy {
return SafeMul(amount, price) return SafeMul(amount, price)
} }
...@@ -193,7 +188,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { ...@@ -193,7 +188,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
amount := a.calcActualCost(et.OpBuy, balance, price) amount := CalcActualCost(et.OpBuy, balance, price)
rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr) rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr)
if rightAccount.Frozen < amount { if rightAccount.Frozen < amount {
elog.Error("revoke check right frozen", "addr", a.fromaddr, "avail", rightAccount.Frozen, "amount", amount) elog.Error("revoke check right frozen", "addr", a.fromaddr, "avail", rightAccount.Frozen, "amount", amount)
...@@ -212,7 +207,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) { ...@@ -212,7 +207,7 @@ func (a *Action) RevokeOrder(payload *et.RevokeOrder) (*types.Receipt, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
amount := a.calcActualCost(et.OpSell, balance, price) amount := CalcActualCost(et.OpSell, balance, price)
leftAccount := leftAssetDB.LoadExecAccount(a.fromaddr, a.execaddr) leftAccount := leftAssetDB.LoadExecAccount(a.fromaddr, a.execaddr)
if leftAccount.Frozen < amount { if leftAccount.Frozen < amount {
elog.Error("revoke check left frozen", "addr", a.fromaddr, "avail", leftAccount.Frozen, "amount", amount) elog.Error("revoke check left frozen", "addr", a.fromaddr, "avail", leftAccount.Frozen, "amount", amount)
...@@ -351,7 +346,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -351,7 +346,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
//未完成的订单需要冻结剩余未成交的资金 //未完成的订单需要冻结剩余未成交的资金
if payload.Op == et.OpBuy { if payload.Op == et.OpBuy {
amount := a.calcActualCost(et.OpBuy, or.Balance, payload.Price) amount := CalcActualCost(et.OpBuy, or.Balance, payload.Price)
receipt, err := rightAccountDB.ExecFrozen(a.fromaddr, a.execaddr, amount) receipt, err := rightAccountDB.ExecFrozen(a.fromaddr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("LimitOrder.ExecFrozen", "addr", a.fromaddr, "amount", amount, "err", err.Error()) elog.Error("LimitOrder.ExecFrozen", "addr", a.fromaddr, "amount", amount, "err", err.Error())
...@@ -361,7 +356,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -361,7 +356,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
} }
if payload.Op == et.OpSell { if payload.Op == et.OpSell {
amount := a.calcActualCost(et.OpSell, or.Balance, payload.Price) amount := CalcActualCost(et.OpSell, or.Balance, payload.Price)
receipt, err := leftAccountDB.ExecFrozen(a.fromaddr, a.execaddr, amount) receipt, err := leftAccountDB.ExecFrozen(a.fromaddr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("LimitOrder.ExecFrozen", "addr", a.fromaddr, "amount", amount, "err", err.Error()) elog.Error("LimitOrder.ExecFrozen", "addr", a.fromaddr, "amount", amount, "err", err.Error())
...@@ -372,6 +367,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc ...@@ -372,6 +367,7 @@ func (a *Action) matchLimitOrder(payload *et.LimitOrder, leftAccountDB, rightAcc
} }
//更新order状态 //更新order状态
kvs = append(kvs, a.GetKVSet(or)...) kvs = append(kvs, a.GetKVSet(or)...)
re.Order = or
receiptlog := &types.ReceiptLog{Ty: et.TyLimitOrderLog, Log: types.Encode(re)} receiptlog := &types.ReceiptLog{Ty: et.TyLimitOrderLog, Log: types.Encode(re)}
logs = append(logs, receiptlog) logs = append(logs, receiptlog)
receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs} receipts := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}
...@@ -390,10 +386,9 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -390,10 +386,9 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
matched = matchorder.GetBalance() matched = matchorder.GetBalance()
} }
// 挂卖吃 matchorder:买单
if payload.Op == et.OpSell { if payload.Op == et.OpSell {
//转移冻结资产 //转移冻结资产
amount := a.calcActualCost(matchorder.GetLimitOrder().Op, matched, payload.Price) amount := CalcActualCost(matchorder.GetLimitOrder().Op, matched, payload.Price)
receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, amount) receipt, err := rightAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "amount", amount, "err", err) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "amount", amount, "err", err)
...@@ -401,10 +396,9 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -401,10 +396,9 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
//解冻多余资金 //解冻多余资金
if payload.Price < matchorder.GetLimitOrder().Price { if payload.Price < matchorder.GetLimitOrder().Price {
amount := a.calcActualCost(matchorder.GetLimitOrder().Op, matched, matchorder.GetLimitOrder().Price-payload.Price) amount := CalcActualCost(matchorder.GetLimitOrder().Op, matched, matchorder.GetLimitOrder().Price-payload.Price)
receipt, err := rightAccountDB.ExecActive(matchorder.Addr, a.execaddr, amount) receipt, err := rightAccountDB.ExecActive(matchorder.Addr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecActive", "addr", matchorder.Addr, "amount", amount, "err", err.Error()) elog.Error("matchLimitOrder.ExecActive", "addr", matchorder.Addr, "amount", amount, "err", err.Error())
...@@ -414,7 +408,7 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -414,7 +408,7 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
} }
//将达成交易的相应资产结算 //将达成交易的相应资产结算
amount = a.calcActualCost(payload.Op, matched, payload.Price) amount = CalcActualCost(payload.Op, matched, payload.Price)
receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, amount) receipt, err = leftAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "amount", amount, "err", err.Error()) elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "amount", amount, "err", err.Error())
...@@ -426,12 +420,11 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -426,12 +420,11 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
//卖单成交得平均价格始终与自身挂单价格相同 //卖单成交得平均价格始终与自身挂单价格相同
or.AVGPrice = payload.Price or.AVGPrice = payload.Price
//计算matchOrder平均成交价格 //计算matchOrder平均成交价格
matchorder.AVGPrice = caclAVGPrice(matchorder, payload.Price, payload.Amount) matchorder.AVGPrice = caclAVGPrice(matchorder, payload.Price, matched) //TODO
} }
// 挂买吃 matchorder:卖单
if payload.Op == et.OpBuy { if payload.Op == et.OpBuy {
//转移冻结资产 //转移冻结资产
amount := a.calcActualCost(matchorder.GetLimitOrder().Op, matched, matchorder.GetLimitOrder().Price) amount := CalcActualCost(matchorder.GetLimitOrder().Op, matched, matchorder.GetLimitOrder().Price)
receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, amount) receipt, err := leftAccountDB.ExecTransferFrozen(matchorder.Addr, a.fromaddr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "amount", amount, "err", err.Error()) elog.Error("matchLimitOrder.ExecTransferFrozen", "addr", matchorder.Addr, "amount", amount, "err", err.Error())
...@@ -440,7 +433,7 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -440,7 +433,7 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
//将达成交易的相应资产结算 //将达成交易的相应资产结算
amount = a.calcActualCost(payload.Op, matched, matchorder.GetLimitOrder().Price) amount = CalcActualCost(payload.Op, matched, matchorder.GetLimitOrder().Price)
receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, amount) receipt, err = rightAccountDB.ExecTransfer(a.fromaddr, matchorder.Addr, a.execaddr, amount)
if err != nil { if err != nil {
elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "amount", amount, "err", err.Error()) elog.Error("matchLimitOrder.ExecTransfer", "addr", a.fromaddr, "amount", amount, "err", err.Error())
...@@ -448,10 +441,11 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -448,10 +441,11 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...) kvs = append(kvs, receipt.KV...)
//买单得话,价格选取卖单的价格 //买单得话,价格选取卖单的价格
or.AVGPrice = matchorder.GetLimitOrder().Price or.AVGPrice = matchorder.GetLimitOrder().Price
//计算matchOrder平均成交价格 //计算matchOrder平均成交价格
matchorder.AVGPrice = caclAVGPrice(matchorder, matchorder.GetLimitOrder().Price, payload.Amount) matchorder.AVGPrice = caclAVGPrice(matchorder, matchorder.GetLimitOrder().Price, matched) //TODO
} }
if matched == matchorder.GetBalance() { if matched == matchorder.GetBalance() {
...@@ -466,21 +460,25 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload * ...@@ -466,21 +460,25 @@ func (a *Action) matchModel(leftAccountDB, rightAccountDB *account.DB, payload *
or.Status = et.Ordered or.Status = et.Ordered
} }
matchorder.Balance -= matched if matched == or.GetBalance() {
matchorder.Executed += matched matchorder.Balance -= matched
matchorder.Executed = matched
kvs = append(kvs, a.GetKVSet(matchorder)...)
or.Balance -= matched or.Executed += matched // TODO why not += ?
or.Executed += matched or.Balance = 0
kvs = append(kvs, a.GetKVSet(or)...) //or complete
} else {
or.Balance -= matched
or.Executed += matched
a.updateStateDBCache(matchorder) matchorder.Executed = matched
a.updateStateDBCache(or) matchorder.Balance = 0
kvs = append(kvs, a.GetKVSet(matchorder)...) //matchorder complete
}
re.Order = or re.Order = or
re.MatchOrders = append(re.MatchOrders, matchorder) re.MatchOrders = append(re.MatchOrders, matchorder)
kvs = append(kvs, a.GetKVSet(matchorder)...)
kvs = append(kvs, a.GetKVSet(or)...)
return logs, kvs, nil return logs, kvs, nil
} }
......
# Title为local,表示此配置文件为本地单节点的配置。此时本地节点所在的链上只有这一个节点,共识模块一般采用solo模式。
Title="local"
TestNet=true
FixTime=false
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
loglevel = "info"
logConsoleLevel = "info"
# 日志文件名,可带目录,所有生成的日志文件都放到此目录下
logFile = "logs/chain33.log"
# 单个日志文件的最大值(单位:兆)
maxFileSize = 300
# 最多保存的历史日志文件个数
maxBackups = 100
# 最多保存的历史日志消息(单位:天)
maxAge = 28
# 日志文件名是否使用本地时间(否则使用UTC时间)
localTime = true
# 历史日志文件是否压缩(压缩格式为gz)
compress = true
# 是否打印调用源文件和行号
callerFile = false
# 是否打印调用方法
callerFunction = false
[blockchain]
# 缓存区块的个数
defCacheSize=128
# 同步区块时一次最多申请获取的区块个数
maxFetchBlockNum=128
# 向对端节点请求同步区块的时间间隔
timeoutSeconds=5
# 使用的数据库类型
driver="leveldb"
# 数据库文件目录
dbPath="datadir"
# 数据库缓存大小
dbCache=64
# 是否为单节点
singleMode=true
# 同步区块批量写数据库时,是否需要立即写磁盘,非固态硬盘的电脑可以设置为false,以提高性能
batchsync=false
# 是否记录添加或者删除区块的序列,若节点作为主链节点,为平行链节点提供服务,需要设置为true
isRecordBlockSequence=true
# 是否为平行链节点
isParaChain=false
# 是否开启交易快速查询索引
enableTxQuickIndex=false
[p2p]
# P2P服务监听端口号
port=13802
# 种子节点,格式为ip:port,多个节点以逗号分隔,如seeds=["10.0.0.1:13802","10.0.0.2:13802","10.0.0.3:13802"]
seeds=[]
# 是否启动P2P服务
enable=true
# 是否为种子节点
isSeed=false
# 是否作为服务端,对外提供服务
serverStart=true
# 是否使用内置的种子节点
innerSeedEnable=false
# 是否使用Github获取种子节点
useGithub=false
# 最多的接入节点个数
innerBounds=300
# 使用的数据库类型
driver="leveldb"
# 数据库文件目录
dbPath="datadir/addrbook"
# 数据库缓存大小
dbCache=4
# GRPC请求日志文件
grpcLogFile="grpc33.log"
# p2p版本号,不同的测试网络选用不同的version
version=200
verMix=200
verMax=200
[rpc]
# jrpc绑定地址
jrpcBindAddr="localhost:8801"
# grpc绑定地址
grpcBindAddr="localhost:8802"
# 白名单列表,允许访问的IP地址,默认是“*”,允许所有IP访问
whitelist=["127.0.0.1"]
# jrpc方法请求白名单,默认是“*”,允许访问所有RPC方法
jrpcFuncWhitelist=["*"]
# jrpc方法请求黑名单,禁止调用黑名单里配置的rpc方法,一般和白名单配合使用,默认是空
# jrpcFuncBlacklist=["xxxx"]
# grpc方法请求白名单,默认是“*”,允许访问所有RPC方法
grpcFuncWhitelist=["*"]
# grpc方法请求黑名单,禁止调用黑名单里配置的rpc方法,一般和白名单配合使用,默认是空
# grpcFuncBlacklist=["xxx"]
# 是否开启https
enableTLS=false
# 证书文件,证书和私钥文件可以用cli工具生成
certFile="cert.pem"
# 私钥文件
keyFile="key.pem"
[mempool]
# mempool队列名称,可配,timeline,score,price
name="timeline"
# mempool缓存容量大小,默认10240
poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000
# timeline 是默认的先来先进的按时间排序
[mempool.sub.timeline]
# mempool缓存容量大小,默认10240
poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000
# score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序
[mempool.sub.score]
# mempool缓存容量大小,默认10240
poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000
# 时间占价格比例
timeParam=1
# 手续费相对于时间的一个合适的常量,取当前unix时间戳前四位数,排队时手续费高1e-5的分数~=快1s的分数
priceConstant=1544
# 常量比例
pricePower=1
# price是价格队列模式(价格=手续费/交易字节数,价格高者优先,同价则时间早优先)
[mempool.sub.price]
# mempool缓存容量大小,默认10240
poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000
[consensus]
#共识名,可选项有solo,ticket,raft,tendermint,para
name="solo"
#是否开启挖矿,开启挖矿才能创建区块
minerstart=true
#创世区块时间(UTC时间)
genesisBlockTime=1514533394
#创世交易地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
[mver.consensus]
#基金账户地址
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
#用户回报
coinReward = 18
#发展基金回报
coinDevFund = 12
#ticket价格
ticketPrice = 10000
#挖矿难度
powLimitBits = "0x1f00ffff"
#每次调整难度的最大的范围,如果设置成 4 的话,范围是 (1/4 - 4),一次不能增加 4倍以上的难度,或者难度减少为 原来的 1/4 ,这个参数,是为了难度不会突然爆增加或者减少
retargetAdjustmentFactor = 4
#表示如果区块时间大于当前时间 16s ,那么区块就会判定为无效区块。
futureBlockTime = 16
#ticket冻结时长
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
#区块包含最多交易数
maxTxNumber = 1600 #160
#调整挖矿难度的间隔,(ps:难度不是每个区块都调整的,而是每隔 targetTimespan / targetTimePerBlock 块调整一次)
targetTimespan = 2304
#每个区块打包的目标时间
targetTimePerBlock = 16
# 仅保留这一项,其他consensus相关的配置全部删除
[consensus.sub.solo]
#创世交易地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
#创世区块时间(UTC时间)
genesisBlockTime=1514533394
#获取交易间隔时长,单位纳秒
waitTxMs=10
[store]
# 数据存储格式名称,目前支持mavl,kvdb,kvmvcc,mpt
name="mavl"
# 数据存储驱动类别,目前支持leveldb,goleveldb,memdb,gobadgerdb,ssdb,pegasus
driver="leveldb"
# 数据文件存储路径
dbPath="datadir/mavltree"
# Cache大小
dbCache=128
# 数据库版本
localdbVersion="1.0.0"
[store.sub.mavl]
# 是否使能mavl加前缀
enableMavlPrefix=false
# 是否使能MVCC,如果mavl中enableMVCC为true此处必须为true
enableMVCC=false
# 是否使能mavl数据裁剪
enableMavlPrune=false
# 裁剪高度间隔
pruneHeight=10000
[wallet]
# 交易发送最低手续费,单位0.00000001BTY(1e-8),默认100000,即0.001BTY
minFee=100000
# walletdb驱动名,支持leveldb/memdb/gobadgerdb/ssdb/pegasus
driver="leveldb"
# walletdb路径
dbPath="wallet"
# walletdb缓存大小
dbCache=16
# 钱包发送交易签名方式
signType="secp256k1"
[wallet.sub.ticket]
# 是否关闭ticket自动挖矿,默认false
minerdisable=false
# 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买
minerwhitelist=["*"]
[exec]
#执行器执行是否免费
isFree=false
#执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效
minExecFee=100000
#是否开启stat插件
enableStat=false
#是否开启MVCC插件
enableMVCC=false
alias=["token1:token","token2:token","token3:token"]
[exec.sub.token]
#是否保存token交易信息
saveTokenTxList=true
#token审批人地址
tokenApprs = [
"1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",
"1LY8GFia5EiyoTodMLfkB5PHNNpXRqxhyB",
"1GCzJDS6HbgTQ2emade7mEJGGWFfA15pS9",
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
]
[exec.sub.cert]
# 是否启用证书验证和签名
enable=false
# 加密文件路径
cryptoPath="authdir/crypto"
# 带证书签名类型,支持"auth_ecdsa", "auth_sm2"
signType="auth_ecdsa"
[exec.sub.relay]
#relay执行器保存BTC头执行权限地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
[exec.sub.manage]
#manage执行器超级管理员地址
superManager=[
"1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
]
...@@ -8,4 +8,5 @@ import ( ...@@ -8,4 +8,5 @@ import (
type Cli interface { type Cli interface {
Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error)
Query(fn string, msg proto.Message) ([]byte, error) Query(fn string, msg proto.Message) ([]byte, error)
GetExecAccount(addr string, exec string, symbol string) (*types.Account, error) // 获取 addr 在本合约中 exec 执行器下面的 symbol 子账户
} }
package test package test
import ( import (
"context"
"testing" "testing"
"github.com/33cn/plugin/plugin/dapp/exchange/executor" "github.com/33cn/plugin/plugin/dapp/exchange/executor"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
et "github.com/33cn/plugin/plugin/dapp/exchange/types" et "github.com/33cn/plugin/plugin/dapp/exchange/types"
tt "github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
var ( var (
PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
cli Cli coin = "bty"
orderId int64 token = "CCNY"
orderId2 int64 leftAsset = &et.Asset{Symbol: coin, Execer: "coins"}
coin = "bty" rightAsset = &et.Asset{Symbol: token, Execer: "token"}
token = "CCNY"
cli Cli
orderId int64
) )
func init() { func init() {
//cli = NewExecCli() cli = NewExecCli()
cli = NewGRPCCli(":8802") //cli = NewGRPCCli(":8802")
}
func TestLimitOrder2(t *testing.T) {
req := &et.LimitOrder{
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Price: 4,
Amount: 10 * types.Coin,
Op: et.OpBuy,
}
testLimitOrder(t, req, Nodes[0], PrivKeyA)
} }
func TestLimitOrder(t *testing.T) { func TestLimitOrder(t *testing.T) {
//A 挂买 4x10 //A 挂买 4x10
req := &et.LimitOrder{ req := &et.LimitOrder{LeftAsset: leftAsset, RightAsset: rightAsset, Price: 4, Amount: 10 * types.Coin, Op: et.OpBuy}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, testPlaceLimitOrder(t, req, Nodes[0], PrivKeyA)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Price: 4,
Amount: 10 * types.Coin,
Op: et.OpBuy,
}
_, err := doLimitOrder(req, PrivKeyA)
assert.Nil(t, err)
} }
func TestOrderList(t *testing.T) { func TestOrderList(t *testing.T) {
...@@ -63,105 +45,127 @@ func TestOrderList(t *testing.T) { ...@@ -63,105 +45,127 @@ func TestOrderList(t *testing.T) {
func TestGetOrder(t *testing.T) { func TestGetOrder(t *testing.T) {
order, err := getOrder(orderId) order, err := getOrder(orderId)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, int32(et.Ordered), order.Status) t.Log(order)
assert.Equal(t, 10*types.Coin, order.Balance)
} }
func TestMarketDepth(t *testing.T) { func TestMarketDepth(t *testing.T) {
depth, err := getMarketDepth(&et.QueryMarketDepth{ depth, err := getMarketDepth(&et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy})
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, t.Log(depth, err)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Op: et.OpBuy,
})
assert.Nil(t, err)
t.Log(depth)
assert.Equal(t, 10*types.Coin, depth.List[0].Amount)
} }
func TestMatch(t *testing.T) { func TestMatch(t *testing.T) {
//B 挂卖 4x5 //B 挂卖 4x5
req2 := &et.LimitOrder{ req := &et.LimitOrder{LeftAsset: leftAsset, RightAsset: rightAsset, Price: 4, Amount: 5 * types.Coin, Op: et.OpSell}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, doLimitOrder(req, PrivKeyB)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, }
Price: 4,
Amount: 5 * types.Coin, func TestHistoryOrderList(t *testing.T) {
Op: et.OpSell, historyq := &et.QueryHistoryOrderList{
LeftAsset: leftAsset,
RightAsset: rightAsset,
} }
_, err := doLimitOrder(req2, PrivKeyB) historyOrderList, err := getHistoryOrderList(historyq)
assert.Nil(t, err)
t.Log(historyOrderList)
}
func TestRevokeOrder(t *testing.T) {
//A 撤回未完成订单
testRevokeLimitOrder(t, orderId, Nodes[0], PrivKeyA)
}
func TestSample0(t *testing.T) {
depth, _ := getMarketDepth(&et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy})
assert.Nil(t, depth)
depth, _ = getMarketDepth(&et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy})
assert.Nil(t, depth)
}
//买卖单价格相同,测试正常撮合流程,查询功能是否可用
//1.先挂数量是10的买单。
//2.然后再挂数量是5的吃单
//3.最后撤销未成交部分的买单
func TestCase1(t *testing.T) {
//先挂数量是10的买单
req := &et.LimitOrder{LeftAsset: leftAsset, RightAsset: rightAsset, Price: 4, Amount: 10 * types.Coin, Op: et.OpBuy}
_, err := doLimitOrder(req, PrivKeyA)
assert.Nil(t, err) assert.Nil(t, err)
orderList, err := getOrderList(et.Completed, Nodes[1], "") orderList, err := getOrderList(et.Ordered, Nodes[0], "")
assert.Nil(t, err) assert.Nil(t, err)
t.Log(orderList)
orderId2 = orderList.List[0].OrderID
//订单1的状态应该还是ordered //根据订单号,查询订单详情
order, err := getOrder(orderId) orderID1 := orderList.List[0].OrderID
order, err := getOrder(orderID1)
assert.Nil(t, err)
assert.Equal(t, int32(et.Ordered), order.Status)
assert.Equal(t, 10*types.Coin, order.GetBalance())
//根据op查询市场深度
q := &et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy}
marketDepthList, err := getMarketDepth(q)
assert.Nil(t, err)
assert.Equal(t, 10*types.Coin, marketDepthList.List[0].GetAmount())
//然后再挂数量是5的吃单
req = &et.LimitOrder{LeftAsset: leftAsset, RightAsset: rightAsset, Price: 4, Amount: 5 * types.Coin, Op: et.OpSell}
_, err = doLimitOrder(req, PrivKeyB)
assert.Nil(t, err)
orderList, err = getOrderList(et.Completed, Nodes[1], "")
assert.Nil(t, err) assert.Nil(t, err)
orderID2 := orderList.List[0].OrderID
//查询订单1详情
order, err = getOrder(orderID1)
assert.Nil(t, err)
//订单1的状态应该还是ordered
assert.Equal(t, int32(et.Ordered), order.Status) assert.Equal(t, int32(et.Ordered), order.Status)
assert.Equal(t, 5*types.Coin, order.Balance) assert.Equal(t, 5*types.Coin, order.Balance)
//order2状态是completed //order2状态是completed
order, err = getOrder(orderId2) order, err = getOrder(orderID2)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, int32(et.Completed), order.Status) assert.Equal(t, int32(et.Completed), order.Status)
//买盘还有 5 //根据op查询市场深度
depth, err := getMarketDepth(&et.QueryMarketDepth{ q = &et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, marketDepthList, err = getMarketDepth(q)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Op: et.OpBuy,
})
assert.Nil(t, err) assert.Nil(t, err)
t.Log(depth) //市场深度应该改变
assert.Equal(t, 5*types.Coin, depth.List[0].Amount) assert.Equal(t, 5*types.Coin, marketDepthList.List[0].GetAmount())
}
func TestHistoryOrderList(t *testing.T) { //查询历史成交
historyq := &et.QueryHistoryOrderList{ q2 := &et.QueryHistoryOrderList{LeftAsset: leftAsset, RightAsset: rightAsset}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, orderList, err = getHistoryOrderList(q2)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
}
historyOrderList, err := getHistoryOrderList(historyq)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(historyOrderList) assert.Equal(t, orderID2, orderList.List[0].OrderID)
assert.Equal(t, orderId2, historyOrderList.List[0].OrderID)
}
func TestRevokeOrder(t *testing.T) { //撤回未完成的订单
//A 撤回未完成订单 _, err = doRevokeOrder(orderID1, PrivKeyA)
_, err := doRevokeOrder(orderId, PrivKeyA)
assert.Nil(t, err) assert.Nil(t, err)
//根据订单号,查询订单详情 //查询订单1详情
order, err := getOrder(orderId) order, err = getOrder(orderID1)
assert.Nil(t, err) assert.Nil(t, err)
//订单1的状态应该Revoked
assert.Equal(t, int32(et.Revoked), order.Status) assert.Equal(t, int32(et.Revoked), order.Status)
assert.Equal(t, 5*types.Coin, order.Balance) assert.Equal(t, 5*types.Coin, order.Balance)
//查询市场深度,买盘应该为空 //根据op查询市场深度
depth, err := getMarketDepth(&et.QueryMarketDepth{ q = &et.QueryMarketDepth{LeftAsset: leftAsset, RightAsset: rightAsset, Op: et.OpBuy}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, _, err = getMarketDepth(q)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, assert.NotNil(t, err)
Op: et.OpBuy,
}) //根据原有状态去查看买单是否被改变
assert.Nil(t, depth) //原有ordered状态的数据应该被删除
depth, err = getMarketDepth(&et.QueryMarketDepth{ _, err = getOrderList(et.Ordered, Nodes[0], "")
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, assert.NotNil(t, err)
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Op: et.OpSell,
})
assert.Nil(t, depth)
} }
func BenchmarkOrder(b *testing.B) { func BenchmarkOrder(b *testing.B) {
req := &et.LimitOrder{ req := &et.LimitOrder{LeftAsset: leftAsset, RightAsset: rightAsset, Price: 1, Amount: 10 * types.Coin, Op: et.OpSell}
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Price: 1,
Amount: 10 * types.Coin,
Op: et.OpSell,
}
ety := types.LoadExecutorType(et.ExchangeX) ety := types.LoadExecutorType(et.ExchangeX)
tx, _ := ety.Create("LimitOrder", req) tx, _ := ety.Create("LimitOrder", req)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
...@@ -243,83 +247,87 @@ func getHistoryOrderList(query *et.QueryHistoryOrderList) (*et.OrderList, error) ...@@ -243,83 +247,87 @@ func getHistoryOrderList(query *et.QueryHistoryOrderList) (*et.OrderList, error)
return &resp, nil return &resp, nil
} }
func getExcerBalance(addr string) (*types.Account, error) { func testPlaceLimitOrder(t *testing.T, req *et.LimitOrder, addr string, privkey string) {
var addrs []string accPrev, err := cli.GetExecAccount(addr, "coins", coin)
addrs = append(addrs, addr) assert.Nil(t, err)
params := &types.ReqBalance{ t.Log(accPrev)
Addresses: addrs,
Execer: et.ExchangeX,
}
accs, err := cli.(*GRPCCli).client.GetBalance(context.Background(), params) tokenPrev, err := cli.GetExecAccount(addr, "token", token)
if err != nil { assert.Nil(t, err)
return nil, err t.Log(tokenPrev)
}
return accs.Acc[0], nil
}
func getExcerTokenBalance(addr string, symbol string) (map[string]*types.Account, error) { _, err = doLimitOrder(req, privkey)
var addrs []string assert.Nil(t, err)
addrs = append(addrs, addr)
param := &tt.ReqTokenBalance{
Addresses: addrs,
TokenSymbol: symbol,
Execer: et.ExchangeX,
}
msg, err := cli.Query("token.GetAccountTokenBalance", param)
if err != nil {
return nil, err
}
var resp tt.ReplyAccountTokenAssets accAfter, err := cli.GetExecAccount(addr, "coins", coin)
err = types.Decode(msg, &resp) assert.Nil(t, err)
if err != nil { t.Log(accAfter)
return nil, err
}
assets := make(map[string]*types.Account) tokenAfter, err := cli.GetExecAccount(addr, "token", token)
for _, v := range resp.TokenAssets { assert.Nil(t, err)
assets[v.Symbol] = v.Account t.Log(tokenAfter)
cost := executor.CalcActualCost(req.Op, req.Amount, req.Price)
t.Log(req.Amount, req.Price, cost)
// bty/ccny
if req.Op == et.OpBuy {
// bty
assert.Equal(t, accAfter.Balance, accPrev.Balance)
assert.Equal(t, accAfter.Frozen, accPrev.Frozen)
// ccny
assert.Equal(t, tokenAfter.Balance, tokenPrev.Balance-cost)
assert.Equal(t, tokenAfter.Frozen, tokenPrev.Frozen+cost)
} else {
// bty
assert.Equal(t, accAfter.Balance, accPrev.Balance-cost)
assert.Equal(t, accAfter.Frozen, accPrev.Frozen+cost)
// ccny
assert.Equal(t, tokenAfter.Balance, tokenPrev.Balance)
assert.Equal(t, tokenAfter.Frozen, tokenPrev.Frozen)
} }
return assets, nil
} }
func testLimitOrder(t *testing.T, req *et.LimitOrder, addr string, privkey string) { func testRevokeLimitOrder(t *testing.T, orderID int64, addr string, privkey string) {
accPrev, err := getExcerBalance(addr) order, err := getOrder(orderID)
assert.Nil(t, err)
assert.NotNil(t, order)
lo := order.Value.(*et.Order_LimitOrder).LimitOrder
assert.NotNil(t, lo)
accPrev, err := cli.GetExecAccount(addr, "coins", coin)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(accPrev) t.Log(accPrev)
tokenPrev, err := getExcerTokenBalance(addr, token) tokenPrev, err := cli.GetExecAccount(addr, "token", token)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(tokenPrev) t.Log(tokenPrev)
_, err = doLimitOrder(req, privkey) _, err = doRevokeOrder(orderID, privkey)
assert.Nil(t, err) assert.Nil(t, err)
accAfter, err := getExcerBalance(addr) accAfter, err := cli.GetExecAccount(addr, "coins", coin)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(accAfter) t.Log(accAfter)
tokenAfter, err := getExcerTokenBalance(addr, token) tokenAfter, err := cli.GetExecAccount(addr, "token", token)
assert.Nil(t, err) assert.Nil(t, err)
t.Log(tokenAfter) t.Log(tokenAfter)
cost := executor.SafeMul(req.Amount, req.Price) cost := executor.CalcActualCost(lo.Op, order.Balance, lo.Price)
t.Log(req.Amount, req.Price, cost)
// bty/ccny // bty/ccny
if req.Op == et.OpBuy { if lo.Op == et.OpBuy {
// bty // bty
assert.Equal(t, accAfter.Balance, accPrev.Balance) assert.Equal(t, accAfter.Balance, accPrev.Balance)
assert.Equal(t, accAfter.Frozen, accPrev.Frozen) assert.Equal(t, accAfter.Frozen, accPrev.Frozen)
// ccny // ccny
assert.Equal(t, tokenAfter[token].Balance, tokenPrev[token].Balance-cost) assert.Equal(t, tokenAfter.Balance, tokenPrev.Balance+cost)
assert.Equal(t, tokenAfter[token].Frozen, tokenPrev[token].Frozen+cost) assert.Equal(t, tokenAfter.Frozen, tokenPrev.Frozen-cost)
} else { } else {
// bty // bty
assert.Equal(t, accAfter.Balance, accPrev.Balance-req.Amount) assert.Equal(t, accAfter.Balance, accPrev.Balance+cost)
assert.Equal(t, accAfter.Frozen, accPrev.Frozen+req.Amount) assert.Equal(t, accAfter.Frozen, accPrev.Frozen-cost)
// ccny // ccny
assert.Equal(t, tokenAfter[token].Balance, tokenPrev[token].Balance) assert.Equal(t, tokenAfter.Balance, tokenPrev.Balance)
assert.Equal(t, tokenAfter[token].Frozen, tokenPrev[token].Frozen) assert.Equal(t, tokenAfter.Frozen, tokenPrev.Frozen)
} }
} }
package test package test
import ( import (
"fmt"
"log" "log"
"time" "time"
...@@ -26,6 +27,18 @@ type ExecCli struct { ...@@ -26,6 +27,18 @@ type ExecCli struct {
height int64 height int64
blockTime int64 blockTime int64
difficulty uint64 difficulty uint64
q queue.Queue
cfg *types.Chain33Config
execAddr string
accA *account.DB //exec account
accA1 *account.DB //exec token account
accB *account.DB
accB1 *account.DB
accC *account.DB
accC1 *account.DB
accD *account.DB
accD1 *account.DB
} }
var ( var (
...@@ -43,25 +56,26 @@ func NewExecCli() *ExecCli { ...@@ -43,25 +56,26 @@ func NewExecCli() *ExecCli {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
executor.Init(et.ExchangeX, cfg, nil) executor.Init(et.ExchangeX, cfg, nil)
total := 100 * types.Coin total := 100000000 * types.Coin
accountA := types.Account{ accountA := &types.Account{
Balance: total, Balance: total,
Frozen: 0, Frozen: 0,
Addr: Nodes[0], Addr: Nodes[0],
} }
accountB := types.Account{ accountB := &types.Account{
Balance: total, Balance: total,
Frozen: 0, Frozen: 0,
Addr: Nodes[1], Addr: Nodes[1],
} }
accountC := types.Account{ accountC := &types.Account{
Balance: total, Balance: total,
Frozen: 0, Frozen: 0,
Addr: Nodes[2], Addr: Nodes[2],
} }
accountD := types.Account{ accountD := &types.Account{
Balance: total, Balance: total,
Frozen: 0, Frozen: 0,
Addr: Nodes[3], Addr: Nodes[3],
...@@ -70,28 +84,31 @@ func NewExecCli() *ExecCli { ...@@ -70,28 +84,31 @@ func NewExecCli() *ExecCli {
execAddr := address.ExecAddress(et.ExchangeX) execAddr := address.ExecAddress(et.ExchangeX)
accA, _ := account.NewAccountDB(cfg, "coins", "bty", sdb) accA, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accA.SaveExecAccount(execAddr, &accountA) accA.SaveExecAccount(execAddr, accountA)
accB, _ := account.NewAccountDB(cfg, "coins", "bty", sdb) accB, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accB.SaveExecAccount(execAddr, &accountB) accB.SaveExecAccount(execAddr, accountB)
accC, _ := account.NewAccountDB(cfg, "coins", "bty", sdb) accC, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accC.SaveExecAccount(execAddr, &accountC) accC.SaveExecAccount(execAddr, accountC)
accD, _ := account.NewAccountDB(cfg, "coins", "bty", sdb) accD, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accD.SaveExecAccount(execAddr, &accountD) accD.SaveExecAccount(execAddr, accountD)
accA1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb) accA1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accA1.SaveExecAccount(execAddr, &accountA) accA1.SaveExecAccount(execAddr, accountA)
accB1, _ := account.NewAccountDB(cfg, "paracross", "coins.bty", sdb) accB1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accB1.SaveExecAccount(execAddr, &accountB) accB1.SaveExecAccount(execAddr, accountB)
accC1, _ := account.NewAccountDB(cfg, "paracross", "token.CCNY", sdb) accC1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accC1.SaveExecAccount(execAddr, &accountC) accC1.SaveExecAccount(execAddr, accountC)
accD1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb) accD1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accD1.SaveExecAccount(execAddr, &accountD) accD1.SaveExecAccount(execAddr, accountD)
q := queue.New("channel")
q.SetConfig(cfg)
return &ExecCli{ return &ExecCli{
ldb: ldb, ldb: ldb,
...@@ -99,14 +116,24 @@ func NewExecCli() *ExecCli { ...@@ -99,14 +116,24 @@ func NewExecCli() *ExecCli {
height: 1, height: 1,
blockTime: time.Now().Unix(), blockTime: time.Now().Unix(),
difficulty: 1539918074, difficulty: 1539918074,
q: q,
cfg: cfg,
execAddr: execAddr,
accA: accA,
accA1: accA1,
accB: accB,
accB1: accB1,
accC: accC,
accC1: accC1,
accD: accD,
accD1: accD1,
} }
} }
func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error) { func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error) {
var err error var err error
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) tx, err = types.FormatTx(c.cfg, et.ExchangeX, tx)
cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -124,9 +151,7 @@ func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLo ...@@ -124,9 +151,7 @@ func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLo
c.height++ c.height++
c.blockTime += 10 c.blockTime += 10
c.difficulty++ c.difficulty++
q := queue.New("channel") api, _ := client.New(c.q.Client(), nil)
q.SetConfig(cfg)
api, _ := client.New(q.Client(), nil)
exec.SetAPI(api) exec.SetAPI(api)
exec.SetStateDB(c.sdb) exec.SetStateDB(c.sdb)
exec.SetLocalDB(c.ldb) exec.SetLocalDB(c.ldb)
...@@ -156,11 +181,7 @@ func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLo ...@@ -156,11 +181,7 @@ func (c *ExecCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLo
} }
func (c *ExecCli) Query(fn string, msg proto.Message) ([]byte, error) { func (c *ExecCli) Query(fn string, msg proto.Message) ([]byte, error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) api, _ := client.New(c.q.Client(), nil)
cfg.SetTitleOnlyForTest("chain33")
q := queue.New("channel")
q.SetConfig(cfg)
api, _ := client.New(q.Client(), nil)
exec := executor.NewExchange() exec := executor.NewExchange()
exec.SetAPI(api) exec.SetAPI(api)
exec.SetStateDB(c.sdb) exec.SetStateDB(c.sdb)
...@@ -193,3 +214,21 @@ func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error ...@@ -193,3 +214,21 @@ func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error
tx.Sign(int32(signType), privKey) tx.Sign(int32(signType), privKey)
return tx, nil return tx, nil
} }
func (c *ExecCli) GetExecAccount(addr string, exec string, symbol string) (*types.Account, error) {
//mavl-{coins}-{bty}-exec-{26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp}:{1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP}
//mavl-{token}-{ccny}-exec-{26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp}:{1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP}
key := []byte(fmt.Sprintf("mavl-%s-%s-exec-%s:%s", exec, symbol, c.execAddr, addr))
bytes, err := c.sdb.Get(key)
if err != nil {
return nil, err
}
var acc types.Account
err = types.Decode(bytes, &acc)
if err != nil {
return nil, err
}
return &acc, nil
}
...@@ -11,6 +11,7 @@ import ( ...@@ -11,6 +11,7 @@ import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/exchange/executor" "github.com/33cn/plugin/plugin/dapp/exchange/executor"
et "github.com/33cn/plugin/plugin/dapp/exchange/types" et "github.com/33cn/plugin/plugin/dapp/exchange/types"
tt "github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
...@@ -71,6 +72,45 @@ func (c *GRPCCli) Query(fn string, msg proto.Message) ([]byte, error) { ...@@ -71,6 +72,45 @@ func (c *GRPCCli) Query(fn string, msg proto.Message) ([]byte, error) {
return r.Msg, nil return r.Msg, nil
} }
func (c *GRPCCli) GetExecAccount(addr string, exec string, symbol string) (*types.Account, error) {
if exec == "coins" {
// bty
var addrs []string
addrs = append(addrs, addr)
params := &types.ReqBalance{
Addresses: addrs,
Execer: et.ExchangeX,
}
accs, err := c.client.GetBalance(context.Background(), params)
if err != nil {
return nil, err
}
return accs.Acc[0], nil
}
// token: ccny
var addrs []string
addrs = append(addrs, addr)
param := &tt.ReqTokenBalance{
Addresses: addrs,
TokenSymbol: symbol,
Execer: et.ExchangeX,
}
msg, err := c.Query("token.GetAccountTokenBalance", param)
if err != nil {
return nil, err
}
var resp tt.ReplyAccountTokenAssets
err = types.Decode(msg, &resp)
if err != nil {
return nil, err
}
return resp.TokenAssets[0].Account, nil
}
// 发送交易并等待执行结果 // 发送交易并等待执行结果
// 如果交易非法,返回错误信息 // 如果交易非法,返回错误信息
// 如果交易执行成功,返回 交易哈希、回报 // 如果交易执行成功,返回 交易哈希、回报
......
...@@ -43,12 +43,11 @@ sleep 1 ...@@ -43,12 +43,11 @@ sleep 1
## 10亿 ## 10亿
./chain33-cli send token precreate -f 0.001 -i "test ccny" -n "ccny" -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -p 0 -s CCNY -t 1000000000 -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs ./chain33-cli send token precreate -f 0.001 -i "test ccny" -n "ccny" -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -p 0 -s CCNY -t 1000000000 -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs
sleep 1 sleep 1
./chain33-cli token get_precreated ./chain33-cli token precreated
./chain33-cli send token finish -s CCNY -f 0.001 -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs ./chain33-cli send token finish -s CCNY -f 0.001 -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs
sleep 1 sleep 1
./chain33-cli token get_finish_created ./chain33-cli token created
./chain33-cli token token_balance -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -s CCNY -e token ./chain33-cli token balance -a 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs -s CCNY -e token
## transfer bty ## transfer bty
./chain33-cli send coins transfer -a 10000 -t 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs ./chain33-cli send coins transfer -a 10000 -t 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -k 1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs
...@@ -80,5 +79,5 @@ echo "account balance in execer" ...@@ -80,5 +79,5 @@ echo "account balance in execer"
./chain33-cli send token send_exec -a 200000000 -e exchange -s CCNY -k 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k ./chain33-cli send token send_exec -a 200000000 -e exchange -s CCNY -k 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
./chain33-cli send token send_exec -a 200000000 -e exchange -s CCNY -k 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs ./chain33-cli send token send_exec -a 200000000 -e exchange -s CCNY -k 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
echo "token balance in execer" echo "token balance in execer"
./chain33-cli token token_balance -e exchange -s CCNY -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs" ./chain33-cli token balance -e exchange -s CCNY -a "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
...@@ -144,7 +144,7 @@ name="timeline" ...@@ -144,7 +144,7 @@ name="timeline"
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# timeline 是默认的先来先进的按时间排序 # timeline 是默认的先来先进的按时间排序
...@@ -152,7 +152,7 @@ maxTxNumPerAccount=10000 ...@@ -152,7 +152,7 @@ maxTxNumPerAccount=10000
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序 # score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序
...@@ -160,7 +160,7 @@ maxTxNumPerAccount=10000 ...@@ -160,7 +160,7 @@ maxTxNumPerAccount=10000
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# 时间占价格比例 # 时间占价格比例
...@@ -174,7 +174,7 @@ pricePower=1 ...@@ -174,7 +174,7 @@ pricePower=1
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -256,10 +256,6 @@ minerdisable=false ...@@ -256,10 +256,6 @@ minerdisable=false
# 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买 # 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
#执行器执行是否免费
isFree=false
#执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效
minExecFee=100000
#是否开启stat插件 #是否开启stat插件
enableStat=false enableStat=false
#是否开启MVCC插件 #是否开启MVCC插件
......
...@@ -147,7 +147,7 @@ name="timeline" ...@@ -147,7 +147,7 @@ name="timeline"
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# timeline 是默认的先来先进的按时间排序 # timeline 是默认的先来先进的按时间排序
...@@ -155,7 +155,7 @@ maxTxNumPerAccount=10000 ...@@ -155,7 +155,7 @@ maxTxNumPerAccount=10000
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序 # score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序
...@@ -163,7 +163,7 @@ maxTxNumPerAccount=10000 ...@@ -163,7 +163,7 @@ maxTxNumPerAccount=10000
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# 时间占价格比例 # 时间占价格比例
...@@ -177,7 +177,7 @@ pricePower=1 ...@@ -177,7 +177,7 @@ pricePower=1
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
# 最小得交易手续费用,这个没有默认值,必填,一般是100000 # 最小得交易手续费用,这个没有默认值,必填,一般是100000
minTxFee=100000 minTxFeeRate=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -259,10 +259,6 @@ minerdisable=false ...@@ -259,10 +259,6 @@ minerdisable=false
# 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买 # 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
#执行器执行是否免费
isFree=false
#执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效
minExecFee=100000
#是否开启stat插件 #是否开启stat插件
enableStat=false enableStat=false
#是否开启MVCC插件 #是否开启MVCC插件
......
...@@ -69,7 +69,7 @@ func hashlockLockCmd(cmd *cobra.Command, args []string) { ...@@ -69,7 +69,7 @@ func hashlockLockCmd(cmd *cobra.Command, args []string) {
delay, _ := cmd.Flags().GetInt64("delay") delay, _ := cmd.Flags().GetInt64("delay")
amount, _ := cmd.Flags().GetFloat64("amount") amount, _ := cmd.Flags().GetFloat64("amount")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
...@@ -129,7 +129,7 @@ func hashlockUnlockCmd(cmd *cobra.Command, args []string) { ...@@ -129,7 +129,7 @@ func hashlockUnlockCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
secret, _ := cmd.Flags().GetString("secret") secret, _ := cmd.Flags().GetString("secret")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
...@@ -172,7 +172,7 @@ func hashlockSendCmd(cmd *cobra.Command, args []string) { ...@@ -172,7 +172,7 @@ func hashlockSendCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr") rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
secret, _ := cmd.Flags().GetString("secret") secret, _ := cmd.Flags().GetString("secret")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
......
...@@ -65,7 +65,7 @@ mainnetJrpcAddr= "http://localhost:8801" ...@@ -65,7 +65,7 @@ mainnetJrpcAddr= "http://localhost:8801"
[mempool] [mempool]
name="para" name="para"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -131,8 +131,6 @@ signType="secp256k1" ...@@ -131,8 +131,6 @@ signType="secp256k1"
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
...@@ -252,13 +252,13 @@ function token_create() { ...@@ -252,13 +252,13 @@ function token_create() {
echo "${hash}" echo "${hash}"
query_tx "${1}" "${hash}" query_tx "${1}" "${hash}"
${1} token get_precreated ${1} token precreated
owner=$(${1} token get_precreated | jq -r ".owner") owner=$(${1} token precreated | jq -r ".owner")
if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then
echo "wrong pre create owner" echo "wrong pre create owner"
exit 1 exit 1
fi fi
total=$(${1} token get_precreated | jq -r ".total") total=$(${1} token precreated | jq -r ".total")
if [ "${total}" != 10000 ]; then if [ "${total}" != 10000 ]; then
echo "wrong pre create total" echo "wrong pre create total"
exit 1 exit 1
...@@ -269,19 +269,19 @@ function token_create() { ...@@ -269,19 +269,19 @@ function token_create() {
echo "${hash}" echo "${hash}"
query_tx "${1}" "${hash}" query_tx "${1}" "${hash}"
${1} token get_finish_created ${1} token created
owner=$(${1} token get_finish_created | jq -r ".owner") owner=$(${1} token created | jq -r ".owner")
if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then if [ "${owner}" != "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" ]; then
echo "wrong finish created owner" echo "wrong finish created owner"
exit 1 exit 1
fi fi
total=$(${1} token get_finish_created | jq -r ".total") total=$(${1} token created | jq -r ".total")
if [ "${total}" != 10000 ]; then if [ "${total}" != 10000 ]; then
echo "wrong finish created total" echo "wrong finish created total"
exit 1 exit 1
fi fi
${1} token token_balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e token -s GD ${1} token balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e token -s GD
balance=$(${1} token token_balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token balance -a 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4 -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "10000.0000" ]; then if [ "${balance}" != "10000.0000" ]; then
echo "wrong para token genesis create, should be 10000.0000" echo "wrong para token genesis create, should be 10000.0000"
exit 1 exit 1
...@@ -294,8 +294,8 @@ function token_transfer() { ...@@ -294,8 +294,8 @@ function token_transfer() {
echo "${hash}" echo "${hash}"
query_tx "${1}" "${hash}" query_tx "${1}" "${hash}"
${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD ${1} token balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD
balance=$(${1} token token_balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token balance -a 1GGF8toZd96wCnfJngTwXZnWCBdWHYYvjw -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "11.0000" ]; then if [ "${balance}" != "11.0000" ]; then
echo "wrong para token transfer, should be 11.0000" echo "wrong para token transfer, should be 11.0000"
exit 1 exit 1
...@@ -308,8 +308,8 @@ function token_transfer() { ...@@ -308,8 +308,8 @@ function token_transfer() {
# $ ./build/chain33-cli exec addr -e user.p.para.paracross # $ ./build/chain33-cli exec addr -e user.p.para.paracross
# 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii # 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii
${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD ${1} token balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD
balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "11.0000" ]; then if [ "${balance}" != "11.0000" ]; then
echo "wrong para token send exec, should be 11.0000" echo "wrong para token send exec, should be 11.0000"
exit 1 exit 1
...@@ -320,8 +320,8 @@ function token_transfer() { ...@@ -320,8 +320,8 @@ function token_transfer() {
echo "${hash}" echo "${hash}"
query_tx "${1}" "${hash}" query_tx "${1}" "${hash}"
${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD ${1} token balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD
balance=$(${1} token token_balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance') balance=$(${1} token balance -a 19WJJv96nKAU4sHFWqGmsqfjxd37jazqii -e token -s GD | jq -r '.[]|.balance')
if [ "${balance}" != "0.0000" ]; then if [ "${balance}" != "0.0000" ]; then
echo "wrong para token withdraw, should be 0.0000" echo "wrong para token withdraw, should be 0.0000"
exit 1 exit 1
...@@ -398,13 +398,13 @@ function token_create_on_mainChain() { ...@@ -398,13 +398,13 @@ function token_create_on_mainChain() {
echo "MAIN_CLI is:" "${MAIN_CLI}" echo "MAIN_CLI is:" "${MAIN_CLI}"
query_tx "${MAIN_CLI}" "${hash}" query_tx "${MAIN_CLI}" "${hash}"
${CLI} token get_precreated ${CLI} token precreated
owner=$(${CLI} token get_precreated | jq -r ".owner") owner=$(${CLI} token precreated | jq -r ".owner")
if [ "${owner}" != "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ]; then if [ "${owner}" != "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ]; then
echo "wrong pre create owner" echo "wrong pre create owner"
exit 1 exit 1
fi fi
total=$(${CLI} token get_precreated | jq -r ".total") total=$(${CLI} token precreated | jq -r ".total")
if [ "${total}" != 10000 ]; then if [ "${total}" != 10000 ]; then
echo "wrong pre create total" echo "wrong pre create total"
exit 1 exit 1
...@@ -415,19 +415,19 @@ function token_create_on_mainChain() { ...@@ -415,19 +415,19 @@ function token_create_on_mainChain() {
echo "${hash}" echo "${hash}"
query_tx "${MAIN_CLI}" "${hash}" query_tx "${MAIN_CLI}" "${hash}"
${CLI} token get_finish_created ${CLI} token created
owner=$(${CLI} token get_finish_created | jq -r ".owner") owner=$(${CLI} token created | jq -r ".owner")
if [ "${owner}" != "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ]; then if [ "${owner}" != "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ]; then
echo "wrong finish created owner" echo "wrong finish created owner"
exit 1 exit 1
fi fi
total=$(${CLI} token get_finish_created | jq -r ".total") total=$(${CLI} token created | jq -r ".total")
if [ "${total}" != 10000 ]; then if [ "${total}" != 10000 ]; then
echo "wrong finish created total" echo "wrong finish created total"
exit 1 exit 1
fi fi
${CLI} token token_balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e token -s FZM ${CLI} token balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e token -s FZM
balance=$(${CLI} token token_balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e token -s FZM | jq -r '.[]|.balance') balance=$(${CLI} token balance -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -e token -s FZM | jq -r '.[]|.balance')
if [ "${balance}" != "10000.0000" ]; then if [ "${balance}" != "10000.0000" ]; then
echo "wrong para token genesis create, should be 10000.0000" echo "wrong para token genesis create, should be 10000.0000"
exit 1 exit 1
......
...@@ -735,11 +735,11 @@ func createCrossCommitTx(s suite.Suite) (*types.Transaction, error) { ...@@ -735,11 +735,11 @@ func createCrossCommitTx(s suite.Suite) (*types.Transaction, error) {
} }
func createTxsGroup(s suite.Suite, txs []*types.Transaction) ([]*types.Transaction, error) { func createTxsGroup(s suite.Suite, txs []*types.Transaction) ([]*types.Transaction, error) {
group, err := types.CreateTxGroup(txs, chain33TestCfg.GInt("MinFee")) group, err := types.CreateTxGroup(txs, chain33TestCfg.GetMinTxFeeRate())
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = group.Check(chain33TestCfg, 0, chain33TestCfg.GInt("MinFee"), chain33TestCfg.GInt("MaxFee")) err = group.Check(chain33TestCfg, 0, chain33TestCfg.GetMinTxFeeRate(), chain33TestCfg.GetMaxTxFee())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -70,7 +70,7 @@ grpcFuncWhitelist=["*"] ...@@ -70,7 +70,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[mempool.sub.para] [mempool.sub.para]
...@@ -148,8 +148,6 @@ signType="secp256k1" ...@@ -148,8 +148,6 @@ signType="secp256k1"
minerdisable=true minerdisable=true
[exec] [exec]
isFree=true
minExecFee=100000
enableStat=false enableStat=false
[exec.sub.relay] [exec.sub.relay]
......
...@@ -307,7 +307,7 @@ func CreateRawMinerTx(cfg *types.Chain33Config, value *ParacrossMinerAction) (*t ...@@ -307,7 +307,7 @@ func CreateRawMinerTx(cfg *types.Chain33Config, value *ParacrossMinerAction) (*t
Nonce: 0, //for consensus purpose, block hash need same, different auth node need keep totally same vote tx Nonce: 0, //for consensus purpose, block hash need same, different auth node need keep totally same vote tx
To: address.ExecAddress(cfg.ExecName(ParaX)), To: address.ExecAddress(cfg.ExecName(ParaX)),
} }
err := tx.SetRealFee(cfg.GInt("MinFee")) err := tx.SetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -543,7 +543,7 @@ func (policy *privacyPolicy) createPublic2PrivacyTx(req *privacytypes.ReqCreateP ...@@ -543,7 +543,7 @@ func (policy *privacyPolicy) createPublic2PrivacyTx(req *privacytypes.ReqCreateP
ActionType: action.Ty, ActionType: action.Ty,
}), }),
} }
tx.Fee, err = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
bizlog.Error("createPublic2PrivacyTx", "calc fee failed", err) bizlog.Error("createPublic2PrivacyTx", "calc fee failed", err)
return nil, err return nil, err
...@@ -622,7 +622,7 @@ func (policy *privacyPolicy) createPrivacy2PrivacyTx(req *privacytypes.ReqCreate ...@@ -622,7 +622,7 @@ func (policy *privacyPolicy) createPrivacy2PrivacyTx(req *privacytypes.ReqCreate
} }
tx.SetExpire(cfg, time.Duration(req.Expire)) tx.SetExpire(cfg, time.Duration(req.Expire))
if !isMainetCoins { if !isMainetCoins {
tx.Fee, err = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
bizlog.Error("createPrivacy2PrivacyTx", "calc fee failed", err) bizlog.Error("createPrivacy2PrivacyTx", "calc fee failed", err)
return nil, err return nil, err
...@@ -711,7 +711,7 @@ func (policy *privacyPolicy) createPrivacy2PublicTx(req *privacytypes.ReqCreateP ...@@ -711,7 +711,7 @@ func (policy *privacyPolicy) createPrivacy2PublicTx(req *privacytypes.ReqCreateP
} }
tx.SetExpire(cfg, time.Duration(req.Expire)) tx.SetExpire(cfg, time.Duration(req.Expire))
if !isMainetCoins { if !isMainetCoins {
tx.Fee, err = tx.GetRealFee(cfg.GInt("MinFee")) tx.Fee, err = tx.GetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
bizlog.Error("createPrivacy2PublicTx", "calc fee failed", err) bizlog.Error("createPrivacy2PublicTx", "calc fee failed", err)
return nil, err return nil, err
......
...@@ -220,7 +220,7 @@ func (mock *PrivacyMock) createPublic2PrivacyTx(req *ty.ReqCreatePrivacyTx) *typ ...@@ -220,7 +220,7 @@ func (mock *PrivacyMock) createPublic2PrivacyTx(req *ty.ReqCreatePrivacyTx) *typ
} }
cfg := mock.walletOp.GetAPI().GetConfig() cfg := mock.walletOp.GetAPI().GetConfig()
txSize := types.Size(tx) + types.SignatureSize txSize := types.Size(tx) + types.SignatureSize
realFee := int64((txSize+1023)>>types.Size1Kshiftlen) * cfg.GInt("MinFee") realFee := int64((txSize+1023)>>types.Size1Kshiftlen) * cfg.GetMinTxFeeRate()
tx.Fee = realFee tx.Fee = realFee
tx.SetExpire(cfg, time.Hour) tx.SetExpire(cfg, time.Hour)
return tx return tx
......
...@@ -327,7 +327,7 @@ func (r *Relayd) transaction(payload []byte) *types.Transaction { ...@@ -327,7 +327,7 @@ func (r *Relayd) transaction(payload []byte) *types.Transaction {
minFee := types.DefaultMinFee minFee := types.DefaultMinFee
if r.config.Chain33Cfg != nil { if r.config.Chain33Cfg != nil {
minFee = r.config.Chain33Cfg.GInt("MinFee") minFee = r.config.Chain33Cfg.GetMinTxFeeRate()
} }
fee, _ := tx.GetRealFee(minFee) fee, _ := tx.GetRealFee(minFee)
tx.Fee = fee tx.Fee = fee
......
...@@ -72,7 +72,7 @@ func backupCmd(cmd *cobra.Command, args []string) { ...@@ -72,7 +72,7 @@ func backupCmd(cmd *cobra.Command, args []string) {
defaultAddr, _ := cmd.Flags().GetString("default") defaultAddr, _ := cmd.Flags().GetString("default")
delay, _ := cmd.Flags().GetInt64("delay") delay, _ := cmd.Flags().GetInt64("delay")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
...@@ -133,7 +133,7 @@ func prepareCmd(cmd *cobra.Command, args []string) { ...@@ -133,7 +133,7 @@ func prepareCmd(cmd *cobra.Command, args []string) {
backup, _ := cmd.Flags().GetString("backup") backup, _ := cmd.Flags().GetString("backup")
defaultAddr, _ := cmd.Flags().GetString("default") defaultAddr, _ := cmd.Flags().GetString("default")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
...@@ -168,7 +168,7 @@ func performCmd(cmd *cobra.Command, args []string) { ...@@ -168,7 +168,7 @@ func performCmd(cmd *cobra.Command, args []string) {
backup, _ := cmd.Flags().GetString("backup") backup, _ := cmd.Flags().GetString("backup")
defaultAddr, _ := cmd.Flags().GetString("default") defaultAddr, _ := cmd.Flags().GetString("default")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
...@@ -215,7 +215,7 @@ func cancelCmd(cmd *cobra.Command, args []string) { ...@@ -215,7 +215,7 @@ func cancelCmd(cmd *cobra.Command, args []string) {
backup, _ := cmd.Flags().GetString("backup") backup, _ := cmd.Flags().GetString("backup")
defaultAddr, _ := cmd.Flags().GetString("default") defaultAddr, _ := cmd.Flags().GetString("default")
defaultFee := float64(cfg.GInt("MinFee")) / float64(types.Coin) defaultFee := float64(cfg.GetMinTxFeeRate()) / float64(types.Coin)
fee, _ := cmd.Flags().GetFloat64("fee") fee, _ := cmd.Flags().GetFloat64("fee")
if fee < defaultFee { if fee < defaultFee {
fee = defaultFee fee = defaultFee
......
...@@ -38,7 +38,7 @@ func TicketCmd() *cobra.Command { ...@@ -38,7 +38,7 @@ func TicketCmd() *cobra.Command {
// BindMinerCmd bind miner // BindMinerCmd bind miner
func BindMinerCmd() *cobra.Command { func BindMinerCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "bind_miner", Use: "bind",
Short: "Bind private key to miner address", Short: "Bind private key to miner address",
Run: bindMiner, Run: bindMiner,
} }
......
...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"] ...@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"]
[mempool] [mempool]
name="timeline" name="timeline"
poolCacheSize=10240 poolCacheSize=10240
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
...@@ -158,8 +158,6 @@ minerwhitelist=["*"] ...@@ -158,8 +158,6 @@ minerwhitelist=["*"]
minerWaitTime="1s" minerWaitTime="1s"
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
......
...@@ -208,12 +208,10 @@ Title="test" ...@@ -208,12 +208,10 @@ Title="test"
[mempool] [mempool]
poolCacheSize=102400 poolCacheSize=102400
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
...@@ -35,7 +35,7 @@ func TokenCmd() *cobra.Command { ...@@ -35,7 +35,7 @@ func TokenCmd() *cobra.Command {
CreateTokenTransferCmd(), CreateTokenTransferCmd(),
CreateTokenWithdrawCmd(), CreateTokenWithdrawCmd(),
GetTokensPreCreatedCmd(), GetTokensPreCreatedCmd(),
GetTokensFinishCreatedCmd(), GetTokensCreatedCmd(),
GetTokenAssetsCmd(), GetTokenAssetsCmd(),
GetTokenBalanceCmd(), GetTokenBalanceCmd(),
CreateRawTokenPreCreateTxCmd(), CreateRawTokenPreCreateTxCmd(),
...@@ -136,7 +136,7 @@ func createTokenWithdraw(cmd *cobra.Command, args []string) { ...@@ -136,7 +136,7 @@ func createTokenWithdraw(cmd *cobra.Command, args []string) {
// GetTokensPreCreatedCmd get precreated tokens // GetTokensPreCreatedCmd get precreated tokens
func GetTokensPreCreatedCmd() *cobra.Command { func GetTokensPreCreatedCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get_precreated", Use: "precreated",
Short: "Get precreated tokens", Short: "Get precreated tokens",
Run: getPreCreatedTokens, Run: getPreCreatedTokens,
} }
...@@ -179,10 +179,10 @@ func getPreCreatedTokens(cmd *cobra.Command, args []string) { ...@@ -179,10 +179,10 @@ func getPreCreatedTokens(cmd *cobra.Command, args []string) {
} }
} }
// GetTokensFinishCreatedCmd get finish created tokens // GetTokensCreatedCmd get finish created tokens
func GetTokensFinishCreatedCmd() *cobra.Command { func GetTokensCreatedCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get_finish_created", Use: "created",
Short: "Get finish created tokens", Short: "Get finish created tokens",
Run: getFinishCreatedTokens, Run: getFinishCreatedTokens,
} }
...@@ -229,7 +229,7 @@ func getFinishCreatedTokens(cmd *cobra.Command, args []string) { ...@@ -229,7 +229,7 @@ func getFinishCreatedTokens(cmd *cobra.Command, args []string) {
// GetTokenAssetsCmd get token assets // GetTokenAssetsCmd get token assets
func GetTokenAssetsCmd() *cobra.Command { func GetTokenAssetsCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "token_assets", Use: "assets",
Short: "Get token assets", Short: "Get token assets",
Run: tokenAssets, Run: tokenAssets,
} }
...@@ -287,7 +287,7 @@ func parseTokenAssetsRes(arg interface{}) (interface{}, error) { ...@@ -287,7 +287,7 @@ func parseTokenAssetsRes(arg interface{}) (interface{}, error) {
// GetTokenBalanceCmd get token balance // GetTokenBalanceCmd get token balance
func GetTokenBalanceCmd() *cobra.Command { func GetTokenBalanceCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "token_balance", Use: "balance",
Short: "Get token balance of one or more addresses", Short: "Get token balance of one or more addresses",
Run: tokenBalance, Run: tokenBalance,
} }
...@@ -544,7 +544,7 @@ func tokenBurn(cmd *cobra.Command, args []string) { ...@@ -544,7 +544,7 @@ func tokenBurn(cmd *cobra.Command, args []string) {
// GetTokenLogsCmd get logs of token // GetTokenLogsCmd get logs of token
func GetTokenLogsCmd() *cobra.Command { func GetTokenLogsCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get_token_logs", Use: "logs",
Short: "Get logs of token", Short: "Get logs of token",
Run: getTokenLogs, Run: getTokenLogs,
} }
...@@ -589,7 +589,7 @@ func getTokenLogsFlags(cmd *cobra.Command) { ...@@ -589,7 +589,7 @@ func getTokenLogsFlags(cmd *cobra.Command) {
// GetTokenCmd get token // GetTokenCmd get token
func GetTokenCmd() *cobra.Command { func GetTokenCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "get_token", Use: "info",
Short: "Get token info", Short: "Get token info",
Run: getToken, Run: getToken,
} }
......
...@@ -146,7 +146,7 @@ func CreateUnfreezeCreateTx(cfg *types.Chain33Config, title string, parm *Unfree ...@@ -146,7 +146,7 @@ func CreateUnfreezeCreateTx(cfg *types.Chain33Config, title string, parm *Unfree
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(), Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())), To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
} }
tx.SetRealFee(cfg.GInt("MinFee")) tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil return tx, nil
} }
...@@ -175,7 +175,7 @@ func CreateUnfreezeWithdrawTx(cfg *types.Chain33Config, title string, parm *Unfr ...@@ -175,7 +175,7 @@ func CreateUnfreezeWithdrawTx(cfg *types.Chain33Config, title string, parm *Unfr
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(), Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())), To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
} }
tx.SetRealFee(cfg.GInt("MinFee")) tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil return tx, nil
} }
...@@ -204,7 +204,7 @@ func CreateUnfreezeTerminateTx(cfg *types.Chain33Config, title string, parm *Unf ...@@ -204,7 +204,7 @@ func CreateUnfreezeTerminateTx(cfg *types.Chain33Config, title string, parm *Unf
Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(), Nonce: rand.New(rand.NewSource(time.Now().UnixNano())).Int63(),
To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())), To: address.ExecAddress(getRealExecName(cfg, cfg.GetParaName())),
} }
tx.SetRealFee(cfg.GInt("MinFee")) tx.SetRealFee(cfg.GetMinTxFeeRate())
return tx, nil return tx, nil
} }
......
...@@ -167,7 +167,7 @@ func addNode(cmd *cobra.Command, args []string) { ...@@ -167,7 +167,7 @@ func addNode(cmd *cobra.Command, args []string) {
value := &vt.ValNodeAction_Node{Node: &vt.ValNode{PubKey: pubkeybyte, Power: power}} value := &vt.ValNodeAction_Node{Node: &vt.ValNode{PubKey: pubkeybyte, Power: power}}
action := &vt.ValNodeAction{Value: value, Ty: vt.ValNodeActionUpdate} action := &vt.ValNodeAction{Value: value, Ty: vt.ValNodeActionUpdate}
tx := &types.Transaction{Execer: []byte(vt.ValNodeX), Payload: types.Encode(action), Fee: 0} tx := &types.Transaction{Execer: []byte(vt.ValNodeX), Payload: types.Encode(action), Fee: 0}
err = tx.SetRealFee(cfg.GInt("MinFee")) err = tx.SetRealFee(cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
return return
......
...@@ -212,7 +212,7 @@ func TestRealNodeMempool(t *testing.T) { ...@@ -212,7 +212,7 @@ func TestRealNodeMempool(t *testing.T) {
//发送交易组 //发送交易组
tx1 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000) tx1 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000)
tx2 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000) tx2 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000)
txgroup, err := types.CreateTxGroup([]*types.Transaction{tx1, tx2}, cfg.GInt("MinFee")) txgroup, err := types.CreateTxGroup([]*types.Transaction{tx1, tx2}, cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
log.Println(err) log.Println(err)
continue continue
......
...@@ -66,7 +66,7 @@ keyFile="key.pem" ...@@ -66,7 +66,7 @@ keyFile="key.pem"
[mempool] [mempool]
name="price" name="price"
poolCacheSize=200 poolCacheSize=200
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
[mempool.sub.timeline] [mempool.sub.timeline]
...@@ -161,8 +161,6 @@ signType="secp256k1" ...@@ -161,8 +161,6 @@ signType="secp256k1"
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
...@@ -27,7 +27,7 @@ func New(cfg *types.Mempool, sub []byte) queue.Module { ...@@ -27,7 +27,7 @@ func New(cfg *types.Mempool, sub []byte) queue.Module {
subcfg.PoolCacheSize = cfg.PoolCacheSize subcfg.PoolCacheSize = cfg.PoolCacheSize
} }
if subcfg.ProperFee == 0 { if subcfg.ProperFee == 0 {
subcfg.ProperFee = cfg.MinTxFee subcfg.ProperFee = cfg.MinTxFeeRate
} }
c.SetQueueCache(NewQueue(subcfg)) c.SetQueueCache(NewQueue(subcfg))
return c return c
......
...@@ -188,7 +188,7 @@ func TestRealNodeMempool(t *testing.T) { ...@@ -188,7 +188,7 @@ func TestRealNodeMempool(t *testing.T) {
//发送交易组 //发送交易组
tx1 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000) tx1 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000)
tx2 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000) tx2 := util.CreateCoinsTx(cfg, priv, mock33.GetGenesisAddress(), types.Coin/1000)
txgroup, err := types.CreateTxGroup([]*types.Transaction{tx1, tx2}, cfg.GInt("MinFee")) txgroup, err := types.CreateTxGroup([]*types.Transaction{tx1, tx2}, cfg.GetMinTxFeeRate())
if err != nil { if err != nil {
log.Println(err) log.Println(err)
continue continue
......
...@@ -66,7 +66,7 @@ keyFile="key.pem" ...@@ -66,7 +66,7 @@ keyFile="key.pem"
[mempool] [mempool]
name="score" name="score"
poolCacheSize=200 poolCacheSize=200
minTxFee=100000 minTxFeeRate=100000
maxTxNumPerAccount=100 maxTxNumPerAccount=100
[mempool.sub.timeline] [mempool.sub.timeline]
...@@ -160,8 +160,6 @@ signType="secp256k1" ...@@ -160,8 +160,6 @@ signType="secp256k1"
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
isFree=false
minExecFee=100000
enableStat=false enableStat=false
enableMVCC=false enableMVCC=false
......
...@@ -30,7 +30,7 @@ func New(cfg *types.Mempool, sub []byte) queue.Module { ...@@ -30,7 +30,7 @@ func New(cfg *types.Mempool, sub []byte) queue.Module {
subcfg.PoolCacheSize = cfg.PoolCacheSize subcfg.PoolCacheSize = cfg.PoolCacheSize
} }
if subcfg.ProperFee == 0 { if subcfg.ProperFee == 0 {
subcfg.ProperFee = cfg.MinTxFee subcfg.ProperFee = cfg.MinTxFeeRate
} }
c.SetQueueCache(NewQueue(subcfg)) c.SetQueueCache(NewQueue(subcfg))
return c return c
......
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