Unverified Commit 518217d8 authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #625 from mdj33/issue462_decouple_mver_consens_ticket

mver consens 解耦ticket 参数
parents dc137f11 30696f6c
......@@ -80,18 +80,14 @@ minerExecs=["paracross"] #配置挖矿合约
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600
[mver.consensus.paracross]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[consensus.sub.para]
#主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“101.37.227.226:8802,39.97.20.242:8802,47.107.15.126:8802,jiedian2.bityuan.com,cloud.bityuan.com”
......
......@@ -90,37 +90,43 @@ minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits="0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ForkChainParamV1]
maxTxNumber = 1500
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits="0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock=16
[mver.consensus.ForkChainParamV1]
[mver.consensus.ticket.ForkChainParamV1]
futureBlockTime = 15
ticketFrozenTime = 43200
ticketWithdrawTime = 172800
ticketMinerWaitTime = 7200
maxTxNumber = 1500
targetTimespan = 2160
targetTimePerBlock = 15
[mver.consensus.ForkChainParamV2]
[mver.consensus.ticket.ForkChainParamV2]
coinReward = 5
coinDevFund = 3
targetTimespan = 720
targetTimePerBlock = 5
ticketPrice = 3000
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[consensus.sub.ticket]
genesisBlockTime=1514533394
......
......@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6
github.com/33cn/chain33 v0.0.0-20190910084507-3738525edd10
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac
......
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6 h1:zj6rCGS9sowochmjveOoxhunvhqpkx1S6abhhhfS7KU=
github.com/33cn/chain33 v0.0.0-20190906093700-93b043f5fce6/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/33cn/chain33 v0.0.0-20190910084507-3738525edd10 h1:tz0yj8OE2RDCpHt3hGC+rNZ1cNF4t4JVFCJ1+iRtqf8=
github.com/33cn/chain33 v0.0.0-20190910084507-3738525edd10/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/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
......
......@@ -66,23 +66,11 @@ minerstart=false
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
......
......@@ -83,23 +83,11 @@ minerstart=false
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
......
......@@ -70,23 +70,11 @@ minerstart=false
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
......
......@@ -74,30 +74,35 @@ minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5
ticketWithdrawTime = 10
ticketMinerWaitTime = 2
maxTxNumber = 1600
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ticket.ForkChainParamV1]
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
......
......@@ -125,7 +125,7 @@ func createTicket(minerAddr, returnAddr string, count int32, height int64) (ret
tx1.To = minerAddr
//gen payload
g := &cty.CoinsAction_Genesis{}
g.Genesis = &types.AssetsGenesis{Amount: types.GetP(height).TicketPrice}
g.Genesis = &types.AssetsGenesis{Amount: ty.GetTicketMinerParam(height).TicketPrice}
tx1.Payload = types.Encode(&cty.CoinsAction{Value: g, Ty: cty.CoinsActionGenesis})
ret = append(ret, &tx1)
......@@ -135,7 +135,7 @@ func createTicket(minerAddr, returnAddr string, count int32, height int64) (ret
tx2.To = driver.ExecAddress("ticket")
//gen payload
g = &cty.CoinsAction_Genesis{}
g.Genesis = &types.AssetsGenesis{Amount: int64(count) * types.GetP(height).TicketPrice, ReturnAddress: returnAddr}
g.Genesis = &types.AssetsGenesis{Amount: int64(count) * ty.GetTicketMinerParam(height).TicketPrice, ReturnAddress: returnAddr}
tx2.Payload = types.Encode(&cty.CoinsAction{Value: g, Ty: cty.CoinsActionGenesis})
ret = append(ret, &tx2)
......@@ -307,7 +307,7 @@ func (client *Client) getModify(beg, end int64) ([]byte, error) {
// CheckBlock ticket implete checkblock func
func (client *Client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
cfg := types.GetP(current.Block.Height)
cfg := ty.GetTicketMinerParam(current.Block.Height)
if current.Block.BlockTime-types.Now().Unix() > cfg.FutureBlockTime {
return types.ErrFutureBlock
}
......@@ -444,7 +444,8 @@ func (client *Client) getNextRequiredDifficulty(block *types.Block, bits uint32)
if block == nil {
return types.GetP(0).PowLimitBits, defaultModify, nil
}
cfg := types.GetP(block.Height)
powLimitBits := types.GetP(block.Height).PowLimitBits
cfg := ty.GetTicketMinerParam(block.Height)
blocksPerRetarget := int64(cfg.TargetTimespan / cfg.TargetTimePerBlock)
// Return the previous block's difficulty requirements if this block
// is not at a difficulty retarget interval.
......@@ -462,15 +463,15 @@ func (client *Client) getNextRequiredDifficulty(block *types.Block, bits uint32)
// worth of blocks).
firstBlock, err := client.RequestBlock(block.Height + 1 - blocksPerRetarget)
if err != nil {
return cfg.PowLimitBits, defaultModify, err
return powLimitBits, defaultModify, err
}
if firstBlock == nil {
return cfg.PowLimitBits, defaultModify, types.ErrBlockNotFound
return powLimitBits, defaultModify, types.ErrBlockNotFound
}
modify, err := client.getModify(block.Height+1-blocksPerRetarget, block.Height)
if err != nil {
return cfg.PowLimitBits, defaultModify, err
return powLimitBits, defaultModify, err
}
// Limit the amount of adjustment that can occur to the previous
// difficulty.
......@@ -496,7 +497,7 @@ func (client *Client) getNextRequiredDifficulty(block *types.Block, bits uint32)
newTarget.Div(newTarget, big.NewInt(targetTimespan))
// Limit new value to the proof of work limit.
powLimit := difficulty.CompactToBig(cfg.PowLimitBits)
powLimit := difficulty.CompactToBig(powLimitBits)
if newTarget.Cmp(powLimit) > 0 {
newTarget.Set(powLimit)
}
......@@ -542,7 +543,7 @@ func (client *Client) searchTargetTicket(parent, block *types.Block) (*ty.Ticket
continue
}
//已经到成熟期
if !ticket.GetIsGenesis() && (block.BlockTime-ticket.GetCreateTime() <= types.GetP(block.Height).TicketFrozenTime) {
if !ticket.GetIsGenesis() && (block.BlockTime-ticket.GetCreateTime() <= ty.GetTicketMinerParam(block.Height).TicketFrozenTime) {
continue
}
// 查找私钥
......@@ -638,7 +639,7 @@ func (client *Client) addMinerTx(parent, block *types.Block, diff *big.Int, priv
miner.TicketId = tid
miner.Bits = difficulty.BigToCompact(diff)
miner.Modify = modify
miner.Reward = types.GetP(block.Height).CoinReward + fee
miner.Reward = ty.GetTicketMinerParam(block.Height).CoinReward + fee
privHash, err := genPrivHash(priv, tid)
if err != nil {
return err
......
......@@ -76,18 +76,14 @@ minerExecs=["paracross"] #配置挖矿合约
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.paracross]
coinReward = 18
coinDevFund = 12
[consensus.sub.para]
ParaRemoteGrpcClient = "localhost:8802"
......
......@@ -941,8 +941,8 @@ func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
if miner.IsSelfConsensus {
//增发coins到paracross合约中,只处理发放,不做分配
totalReward := int64(0)
coinReward := types.MGInt("mver.consensus.coinReward", a.height)
fundReward := types.MGInt("mver.consensus.coinDevFund", a.height)
coinReward := types.MGInt("mver.consensus.paracross.coinReward", a.height)
fundReward := types.MGInt("mver.consensus.paracross.coinDevFund", a.height)
if coinReward > 0 {
totalReward += coinReward
......
......@@ -11,8 +11,8 @@ import (
func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus) (*types.Receipt, error) {
//获取挖矿相关配置,这里需注意是共识的高度,而不是交易的高度
coinReward := types.MGInt("mver.consensus.coinReward", nodeStatus.Height) * types.Coin
fundReward := types.MGInt("mver.consensus.coinDevFund", nodeStatus.Height) * types.Coin
coinReward := types.MGInt("mver.consensus.paracross.coinReward", nodeStatus.Height) * types.Coin
fundReward := types.MGInt("mver.consensus.paracross.coinDevFund", nodeStatus.Height) * types.Coin
fundAddr := types.MGStr("mver.consensus.fundKeyAddr", nodeStatus.Height)
minerAddrs := getMiners(stat.Details, nodeStatus.BlockHash)
......
......@@ -84,19 +84,27 @@ minerExecs=["paracross"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.paracross]
coinReward = 18
coinDevFund = 12
[consensus.sub.para]
#主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“101.37.227.226:8802,39.97.20.242:8802,47.107.15.126:8802,jiedian2.33.cn”
ParaRemoteGrpcClient=""
......
......@@ -74,32 +74,41 @@ minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ForkChainParamV2]
maxTxNumber = 1500
powLimitBits = "0x1f2fffff"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5
ticketWithdrawTime = 10
ticketMinerWaitTime = 2
maxTxNumber = 1600
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ticket.ForkChainParamV1]
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
[mver.consensus.ticket.ForkChainParamV2]
coinReward = 5
coinDevFund = 3
ticketPrice = 3000
maxTxNumber = 1500
targetTimespan = 720
targetTimePerBlock = 1
powLimitBits = "0x1f2fffff"
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
......
......@@ -42,13 +42,13 @@ func TestTicketPrice(t *testing.T) {
func TestCheckFork(t *testing.T) {
assert.Equal(t, int64(1), types.GetFork("ForkChainParamV2"))
p1 := types.GetP(0)
p1 := ty.GetTicketMinerParam(0)
assert.Equal(t, 10000*types.Coin, p1.TicketPrice)
p1 = types.GetP(1)
p1 = ty.GetTicketMinerParam(1)
assert.Equal(t, 3000*types.Coin, p1.TicketPrice)
p1 = types.GetP(2)
p1 = ty.GetTicketMinerParam(2)
assert.Equal(t, 3000*types.Coin, p1.TicketPrice)
p1 = types.GetP(3)
p1 = ty.GetTicketMinerParam(3)
assert.Equal(t, 3000*types.Coin, p1.TicketPrice)
}
......
......@@ -37,7 +37,7 @@ type DB struct {
//GetRealPrice 获取真实的价格
func (t *DB) GetRealPrice() int64 {
if t.GetPrice() == 0 {
cfg := types.GetP(types.GetFork("ForkChainParamV1"))
cfg := ty.GetTicketMinerParam(types.GetFork("ForkChainParamV1"))
return cfg.TicketPrice
}
return t.GetPrice()
......@@ -142,7 +142,7 @@ func (action *Action) GenesisInit(genesis *ty.TicketGenesis) (*types.Receipt, er
prefix = genesis.MinerAddress + ":" + prefix + ":"
var logs []*types.ReceiptLog
var kv []*types.KeyValue
cfg := types.GetP(action.height)
cfg := ty.GetTicketMinerParam(action.height)
for i := 0; i < int(genesis.Count); i++ {
id := prefix + fmt.Sprintf("%010d", i)
t := NewDB(id, genesis.MinerAddress, genesis.ReturnAddress, action.blocktime, action.height, cfg.TicketPrice, true)
......@@ -240,7 +240,7 @@ func (action *Action) TicketOpen(topen *ty.TicketOpen) (*types.Receipt, error) {
}
}
//action.fromaddr == topen.ReturnAddress or mineraddr == action.fromaddr
cfg := types.GetP(action.height)
cfg := ty.GetTicketMinerParam(action.height)
for i := 0; i < int(topen.Count); i++ {
id := prefix + fmt.Sprintf("%010d", i)
//add pubHash
......@@ -303,7 +303,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
if ticket.Status != 1 {
return nil, types.ErrCoinBaseTicketStatus
}
cfg := types.GetP(action.height)
cfg := ty.GetTicketMinerParam(action.height)
if !ticket.IsGenesis {
if action.blocktime-ticket.GetCreateTime() < cfg.TicketFrozenTime {
return nil, ty.ErrTime
......@@ -370,7 +370,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
// TicketClose close tick
func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error) {
tickets := make([]*DB, len(tclose.TicketId))
cfg := types.GetP(action.height)
cfg := ty.GetTicketMinerParam(action.height)
for i := 0; i < len(tclose.TicketId); i++ {
ticket, err := readTicket(action.db, tclose.TicketId[i])
if err != nil {
......
......@@ -32,7 +32,7 @@ func (g *channelClient) CreateBindMiner(ctx context.Context, in *ty.ReqBindMiner
if err != nil {
return nil, err
}
if in.Amount%types.GetP(header.Height).TicketPrice != 0 || in.Amount < 0 {
if in.Amount%ty.GetTicketMinerParam(header.Height).TicketPrice != 0 || in.Amount < 0 {
return nil, types.ErrAmount
}
err = address.CheckAddress(in.BindAddr)
......
......@@ -28,16 +28,19 @@ Title="test"
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 10000
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5
ticketWithdrawTime = 10
ticketMinerWaitTime = 2
maxTxNumber = 10000
targetTimespan = 2304
targetTimePerBlock = 16
`
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package testnode
import (
"testing"
"github.com/33cn/chain33/util/testnode"
ty "github.com/33cn/plugin/plugin/dapp/ticket/types"
ticketwallet "github.com/33cn/plugin/plugin/dapp/ticket/wallet"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
_ "github.com/33cn/plugin/plugin"
)
func TestWalletTicket(t *testing.T) {
minerAddr := "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
t.Log("Begin wallet ticket test")
cfg, sub := testnode.GetDefaultConfig()
cfg.Consensus.Name = "ticket"
mock33 := testnode.NewWithConfig(cfg, sub, nil)
defer mock33.Close()
err := mock33.WaitHeight(0)
assert.Nil(t, err)
msg, err := mock33.GetAPI().Query(ty.TicketX, "TicketList", &ty.TicketList{Addr: minerAddr, Status: 1})
assert.Nil(t, err)
ticketList := msg.(*ty.ReplyTicketList)
assert.NotNil(t, ticketList)
//return
ticketwallet.FlushTicket(mock33.GetAPI())
err = mock33.WaitHeight(2)
assert.Nil(t, err)
header, err := mock33.GetAPI().GetLastHeader()
require.Equal(t, err, nil)
require.Equal(t, header.Height >= 2, true)
in := &ty.TicketClose{MinerAddress: minerAddr}
msg, err = mock33.GetAPI().ExecWalletFunc(ty.TicketX, "CloseTickets", in)
assert.Nil(t, err)
hashes := msg.(*types.ReplyHashes)
assert.NotNil(t, hashes)
in = &ty.TicketClose{}
msg, err = mock33.GetAPI().ExecWalletFunc(ty.TicketX, "CloseTickets", in)
assert.Nil(t, err)
hashes = msg.(*types.ReplyHashes)
assert.NotNil(t, hashes)
t.Log("End wallet ticket test")
}
......@@ -7,6 +7,7 @@ package types
import (
"errors"
"reflect"
"time"
//log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
......@@ -119,3 +120,34 @@ func (ticket *TicketType) GetTypeMap() map[string]int32 {
"Miner": TicketActionMiner,
}
}
// TicketMinerParam
type TicketMinerParam struct {
CoinDevFund int64
CoinReward int64
FutureBlockTime int64
TicketPrice int64
TicketFrozenTime int64
TicketWithdrawTime int64
TicketMinerWaitTime int64
TargetTimespan time.Duration
TargetTimePerBlock time.Duration
RetargetAdjustmentFactor int64
}
// GetTicketMinerParam 获取ticket miner config params
func GetTicketMinerParam(height int64) *TicketMinerParam {
conf := types.Conf("mver.consensus.ticket")
c := &TicketMinerParam{}
c.CoinDevFund = conf.MGInt("coinDevFund", height) * types.Coin
c.CoinReward = conf.MGInt("coinReward", height) * types.Coin
c.FutureBlockTime = conf.MGInt("futureBlockTime", height)
c.TicketPrice = conf.MGInt("ticketPrice", height) * types.Coin
c.TicketFrozenTime = conf.MGInt("ticketFrozenTime", height)
c.TicketWithdrawTime = conf.MGInt("ticketWithdrawTime", height)
c.TicketMinerWaitTime = conf.MGInt("ticketMinerWaitTime", height)
c.TargetTimespan = time.Duration(conf.MGInt("targetTimespan", height)) * time.Second
c.TargetTimePerBlock = time.Duration(conf.MGInt("targetTimePerBlock", height)) * time.Second
c.RetargetAdjustmentFactor = conf.MGInt("retargetAdjustmentFactor", height)
return c
}
......@@ -402,15 +402,16 @@ func (policy *ticketPolicy) forceCloseTicketList(height int64, priv crypto.PrivK
var ids []string
var tl []*ty.Ticket
now := types.Now().Unix()
cfg := ty.GetTicketMinerParam(height)
for _, t := range tlist {
if !t.IsGenesis {
if t.Status == 1 && now-t.GetCreateTime() < types.GetP(height).TicketWithdrawTime {
if t.Status == 1 && now-t.GetCreateTime() < cfg.TicketWithdrawTime {
continue
}
if t.Status == 2 && now-t.GetCreateTime() < types.GetP(height).TicketWithdrawTime {
if t.Status == 2 && now-t.GetCreateTime() < cfg.TicketWithdrawTime {
continue
}
if t.Status == 2 && now-t.GetMinerTime() < types.GetP(height).TicketMinerWaitTime {
if t.Status == 2 && now-t.GetMinerTime() < cfg.TicketMinerWaitTime {
continue
}
}
......@@ -495,12 +496,13 @@ func (policy *ticketPolicy) closeTicketsByAddr(height int64, priv crypto.PrivKey
var ids []string
var tl []*ty.Ticket
now := types.Now().Unix()
cfg := ty.GetTicketMinerParam(height)
for _, t := range tlist {
if !t.IsGenesis {
if now-t.GetCreateTime() < types.GetP(height).TicketWithdrawTime {
if now-t.GetCreateTime() < cfg.TicketWithdrawTime {
continue
}
if now-t.GetMinerTime() < types.GetP(height).TicketMinerWaitTime {
if now-t.GetMinerTime() < cfg.TicketMinerWaitTime {
continue
}
}
......@@ -633,10 +635,11 @@ func (policy *ticketPolicy) buyTicketOne(height int64, priv crypto.PrivKey) ([]b
}
//留一个币作为手续费,如果手续费不够了,不能挖矿
//判断手续费是否足够,如果不足要及时补充。
cfg := ty.GetTicketMinerParam(height)
fee := types.Coin
if acc1.Balance+acc2.Balance-2*fee >= types.GetP(height).TicketPrice {
if acc1.Balance+acc2.Balance-2*fee >= cfg.TicketPrice {
// 如果可用余额+冻结余额,可以凑成新票,则转币到冻结余额
if (acc1.Balance+acc2.Balance-2*fee)/types.GetP(height).TicketPrice > acc2.Balance/types.GetP(height).TicketPrice {
if (acc1.Balance+acc2.Balance-2*fee)/cfg.TicketPrice > acc2.Balance/cfg.TicketPrice {
//第一步。转移币到 ticket
toaddr := address.ExecAddress(ty.TicketX)
amount := acc1.Balance - 2*fee
......@@ -657,7 +660,7 @@ func (policy *ticketPolicy) buyTicketOne(height int64, priv crypto.PrivKey) ([]b
if err != nil {
return nil, 0, err
}
count := acc.Balance / types.GetP(height).TicketPrice
count := acc.Balance / cfg.TicketPrice
if count > 0 {
txhash, err := policy.openticket(addr, addr, priv, int32(count))
return txhash, int(count), err
......@@ -737,6 +740,7 @@ func (policy *ticketPolicy) buyMinerAddrTicketOne(height int64, priv crypto.Priv
}
total := 0
var hashes [][]byte
cfg := ty.GetTicketMinerParam(height)
for i := 0; i < len(addrs); i++ {
bizlog.Info("sourceaddr", "addr", addrs[i])
ok := checkMinerWhiteList(addrs[i])
......@@ -748,7 +752,7 @@ func (policy *ticketPolicy) buyMinerAddrTicketOne(height int64, priv crypto.Priv
if err != nil {
return nil, 0, err
}
count := acc.Balance / types.GetP(height).TicketPrice
count := acc.Balance / cfg.TicketPrice
if count > 0 {
txhash, err := policy.openticket(addr, addrs[i], priv, int32(count))
if err != nil {
......
......@@ -2,54 +2,260 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package wallet_test
package wallet
import (
"encoding/hex"
"math/rand"
"sync"
"testing"
"github.com/stretchr/testify/mock"
"github.com/33cn/chain33/util/testnode"
wcom "github.com/33cn/chain33/wallet/common"
ty "github.com/33cn/plugin/plugin/dapp/ticket/types"
ticketwallet "github.com/33cn/plugin/plugin/dapp/ticket/wallet"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
_ "github.com/33cn/plugin/plugin"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/db"
)
func Test_WalletTicket(t *testing.T) {
minerAddr := "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
t.Log("Begin wallet ticket test")
const (
sendhash = "sendhash"
)
cfg, sub := testnode.GetDefaultConfig()
func TestMain(m *testing.M) {
cfg, _ := testnode.GetDefaultConfig()
cfg.Consensus.Name = "ticket"
mock33 := testnode.NewWithConfig(cfg, sub, nil)
defer mock33.Close()
err := mock33.WaitHeight(0)
types.Init(cfg.Title, cfg)
m.Run()
}
func TestForceCloseTicketList(t *testing.T) {
ticket := &ticketPolicy{mtx: &sync.Mutex{}}
ticket.walletOperate = new(walletOperateMock)
t1 := &ty.Ticket{Status: 1, IsGenesis: false}
t2 := &ty.Ticket{Status: 2, IsGenesis: false}
t3 := &ty.Ticket{Status: 3, IsGenesis: false}
tlist := []*ty.Ticket{t1, t2, t3}
r1, r2 := ticket.forceCloseTicketList(0, nil, tlist)
assert.Equal(t, []byte(sendhash), r1)
assert.Nil(t, r2)
}
func TestCloseTicketsByAddr(t *testing.T) {
pk, err := hex.DecodeString("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
assert.Nil(t, err)
msg, err := mock33.GetAPI().Query(ty.TicketX, "TicketList", &ty.TicketList{Addr: minerAddr, Status: 1})
secp, err := crypto.New(types.GetSignName("", types.SECP256K1))
assert.Nil(t, err)
ticketList := msg.(*ty.ReplyTicketList)
assert.NotNil(t, ticketList)
//return
ticketwallet.FlushTicket(mock33.GetAPI())
err = mock33.WaitHeight(2)
priKey, err := secp.PrivKeyFromBytes(pk)
assert.Nil(t, err)
header, err := mock33.GetAPI().GetLastHeader()
require.Equal(t, err, nil)
require.Equal(t, header.Height >= 2, true)
in := &ty.TicketClose{MinerAddress: minerAddr}
msg, err = mock33.GetAPI().ExecWalletFunc(ty.TicketX, "CloseTickets", in)
ticket := &ticketPolicy{mtx: &sync.Mutex{}}
wallet := new(walletOperateMock)
qapi := new(mocks.QueueProtocolAPI)
wallet.api = qapi
ticket.walletOperate = wallet
t1 := &ty.Ticket{Status: 1, IsGenesis: false}
t2 := &ty.Ticket{Status: 2, IsGenesis: false}
t3 := &ty.Ticket{Status: 3, IsGenesis: false}
tlist := &ty.ReplyTicketList{Tickets: []*ty.Ticket{t1, t2, t3}}
qapi.On("Query", ty.TicketX, "TicketList", mock.Anything).Return(tlist, nil)
r1, r2 := ticket.closeTicketsByAddr(0, priKey)
assert.Equal(t, []byte(sendhash), r1)
assert.Nil(t, r2)
}
func TestBuyTicketOne(t *testing.T) {
ticket := &ticketPolicy{mtx: &sync.Mutex{}}
ticket.walletOperate = new(walletOperateMock)
pk, err := hex.DecodeString("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
assert.Nil(t, err)
secp, err := crypto.New(types.GetSignName("", types.SECP256K1))
assert.Nil(t, err)
priKey, err := secp.PrivKeyFromBytes(pk)
assert.Nil(t, err)
hashes := msg.(*types.ReplyHashes)
assert.NotNil(t, hashes)
hash, r1, r2 := ticket.buyTicketOne(0, priKey)
assert.Equal(t, []byte(sendhash), hash)
assert.Equal(t, 10, r1)
assert.Nil(t, r2)
}
in = &ty.TicketClose{}
msg, err = mock33.GetAPI().ExecWalletFunc(ty.TicketX, "CloseTickets", in)
func TestBuyMinerAddrTicketOne(t *testing.T) {
pk, err := hex.DecodeString("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
assert.Nil(t, err)
hashes = msg.(*types.ReplyHashes)
assert.NotNil(t, hashes)
t.Log("End wallet ticket test")
secp, err := crypto.New(types.GetSignName("", types.SECP256K1))
assert.Nil(t, err)
priKey, err := secp.PrivKeyFromBytes(pk)
assert.Nil(t, err)
ticket := &ticketPolicy{mtx: &sync.Mutex{}}
ticket.cfg = &subConfig{}
ticket.initMinerWhiteList(nil)
wallet := new(walletOperateMock)
qapi := new(mocks.QueueProtocolAPI)
wallet.api = qapi
ticket.walletOperate = wallet
tlist := &types.ReplyStrings{Datas: []string{"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"}}
qapi.On("Query", ty.TicketX, "MinerSourceList", mock.Anything).Return(tlist, nil)
hashs, r2, r3 := ticket.buyMinerAddrTicketOne(0, priKey)
assert.Equal(t, [][]byte{[]byte(sendhash)}, hashs)
assert.Equal(t, 10, r2)
assert.Nil(t, r3)
}
type walletOperateMock struct {
api client.QueueProtocolAPI
}
func (_m *walletOperateMock) AddrInWallet(addr string) bool {
return false
}
// CheckWalletStatus provides a mock function with given fields:
func (_m *walletOperateMock) CheckWalletStatus() (bool, error) {
return false, nil
}
// GetAPI provides a mock function with given fields:
func (_m *walletOperateMock) GetAPI() client.QueueProtocolAPI {
return _m.api
}
// GetAllPrivKeys provides a mock function with given fields:
func (_m *walletOperateMock) GetAllPrivKeys() ([]crypto.PrivKey, error) {
return nil, nil
}
// GetBalance provides a mock function with given fields: addr, execer
func (_m *walletOperateMock) GetBalance(addr string, execer string) (*types.Account, error) {
return &types.Account{Balance: 10000000000000, Addr: "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"}, nil
}
// GetBlockHeight provides a mock function with given fields:
func (_m *walletOperateMock) GetBlockHeight() int64 {
return 0
}
// GetConfig provides a mock function with given fields:
func (_m *walletOperateMock) GetConfig() *types.Wallet {
return nil
}
// GetDBStore provides a mock function with given fields:
func (_m *walletOperateMock) GetDBStore() db.DB {
return nil
}
// GetLastHeader provides a mock function with given fields:
func (_m *walletOperateMock) GetLastHeader() *types.Header {
return nil
}
// GetMutex provides a mock function with given fields:
func (_m *walletOperateMock) GetMutex() *sync.Mutex {
return nil
}
// GetPassword provides a mock function with given fields:
func (_m *walletOperateMock) GetPassword() string {
return ""
}
// GetPrivKeyByAddr provides a mock function with given fields: addr
func (_m *walletOperateMock) GetPrivKeyByAddr(addr string) (crypto.PrivKey, error) {
return nil, nil
}
// GetRandom provides a mock function with given fields:
func (_m *walletOperateMock) GetRandom() *rand.Rand {
return nil
}
// GetSignType provides a mock function with given fields:
func (_m *walletOperateMock) GetSignType() int {
return 0
}
// GetTxDetailByHashs provides a mock function with given fields: ReqHashes
func (_m *walletOperateMock) GetTxDetailByHashs(ReqHashes *types.ReqHashes) {
}
// GetWaitGroup provides a mock function with given fields:
func (_m *walletOperateMock) GetWaitGroup() *sync.WaitGroup {
return nil
}
// GetWalletAccounts provides a mock function with given fields:
func (_m *walletOperateMock) GetWalletAccounts() ([]*types.WalletAccountStore, error) {
return nil, nil
}
// GetWalletDone provides a mock function with given fields:
func (_m *walletOperateMock) GetWalletDone() chan struct{} {
return nil
}
// IsCaughtUp provides a mock function with given fields:
func (_m *walletOperateMock) IsCaughtUp() bool {
return false
}
// IsClose provides a mock function with given fields:
func (_m *walletOperateMock) IsClose() bool {
return false
}
// IsWalletLocked provides a mock function with given fields:
func (_m *walletOperateMock) IsWalletLocked() bool {
return true
}
// Nonce provides a mock function with given fields:
func (_m *walletOperateMock) Nonce() int64 {
return 0
}
// RegisterMineStatusReporter provides a mock function with given fields: reporter
func (_m *walletOperateMock) RegisterMineStatusReporter(reporter wcom.MineStatusReport) error {
return nil
}
// SendToAddress provides a mock function with given fields: priv, addrto, amount, note, Istoken, tokenSymbol
func (_m *walletOperateMock) SendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) {
return &types.ReplyHash{Hash: []byte(sendhash)}, nil
}
// SendTransaction provides a mock function with given fields: payload, execer, priv, to
func (_m *walletOperateMock) SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) ([]byte, error) {
return []byte(sendhash), nil
}
// WaitTx provides a mock function with given fields: hash
func (_m *walletOperateMock) WaitTx(hash []byte) *types.TransactionDetail {
return nil
}
// WaitTxs provides a mock function with given fields: hashes
func (_m *walletOperateMock) WaitTxs(hashes [][]byte) []*types.TransactionDetail {
return nil
}
......@@ -89,27 +89,32 @@ genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ticket]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ticket.ForkChainParamV1]
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
......
......@@ -89,27 +89,31 @@ genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits = "0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
powLimitBits = "0x1f00ffff"
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
maxTxNumber = 1600 #160
targetTimespan = 2304
targetTimePerBlock = 16
[mver.consensus.ForkChainParamV1]
maxTxNumber = 10000
[mver.consensus.ticket.ForkChainParamV1]
targetTimespan = 288 #only for test
targetTimePerBlock = 2
[mver.consensus.ForkChainParamV2]
powLimitBits = "0x1f2fffff"
[consensus.sub.solo]
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisBlockTime=1514533394
......
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