Unverified Commit d6bea70f authored by 33cn's avatar 33cn Committed by GitHub

Merge pull request #363 from vipwzw/fixbug_token_check_owner

token check owner address
parents 187ee1d3 142efe64
......@@ -37,7 +37,7 @@ singleMode=false
batchsync=false
isRecordBlockSequence=true
isParaChain=false
enableTxQuickIndex=false
enableTxQuickIndex=true
[p2p]
seeds=[]
......@@ -66,6 +66,7 @@ name="timeline"
poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=100
maxTxFee=1000000000
[mempool.sub.timeline]
poolCacheSize=10240
......@@ -140,6 +141,10 @@ enableMavlPrefix=false
enableMVCC=false
enableMavlPrune=false
pruneHeight=10000
# 是否使能mavl数据载入内存
enableMemTree=true
# 是否使能mavl叶子节点数据载入内存
enableMemVal=true
[wallet]
minFee=100000
......@@ -158,6 +163,7 @@ rescanMultisigAddr=false
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
alias=["token1:token","token2:token","token3:token"]
......
......@@ -166,7 +166,6 @@ func (client *client) SetQueueClient(c queue.Client) {
client.InitBlock()
})
go client.EventLoop()
client.wg.Add(1)
go client.commitMsgClient.handler()
go client.CreateBlock()
......
......@@ -219,7 +219,7 @@ func createTxsGroup(txs []*types.Transaction) ([]*types.Transaction, error) {
if err != nil {
return nil, err
}
err = group.Check(0, types.GInt("MinFee"))
err = group.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
return nil, err
}
......
......@@ -225,7 +225,7 @@ func (client *commitMsgClient) getTxsGroup(txsArr *types.Transactions) (*types.T
plog.Error("para CreateTxGroup", "err", err.Error())
return nil, err
}
err = group.Check(0, types.GInt("MinFee"))
err = group.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
plog.Error("para CheckTxGroup", "err", err.Error())
return nil, err
......
......@@ -5,27 +5,23 @@
package executor
import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
//"github.com/stretchr/testify/mock"
"testing"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
dbmock "github.com/33cn/chain33/common/db/mocks"
"github.com/33cn/chain33/types"
"bytes"
"math/rand"
"testing"
"time"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
dbmock "github.com/33cn/chain33/common/db/mocks"
"github.com/33cn/chain33/common/log"
mty "github.com/33cn/chain33/system/dapp/manage/types"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
// 构造一个4个节点的平行链数据, 进行测试
......@@ -523,12 +519,11 @@ func createCrossParaTx(s suite.Suite, to []byte) (*types.Transaction, error) {
}
func createTxsGroup(s suite.Suite, txs []*types.Transaction) ([]*types.Transaction, error) {
group, err := types.CreateTxGroup(txs)
if err != nil {
return nil, err
}
err = group.Check(0, types.GInt("MinFee"))
err = group.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
return nil, err
}
......@@ -536,7 +531,6 @@ func createTxsGroup(s suite.Suite, txs []*types.Transaction) ([]*types.Transacti
for i := range group.Txs {
group.SignN(i, int32(types.SECP256K1), privKey)
}
return group.Txs, nil
}
......
......@@ -68,7 +68,7 @@ func TestToken(t *testing.T) {
env := execEnv{
10,
types.GetDappFork(pty.TokenX, pty.ForkTokenSymbolWithNumberX),
types.GetDappFork(pty.TokenX, "ForkTokenCheckAddress"),
1539918074,
}
......@@ -98,7 +98,7 @@ func TestToken(t *testing.T) {
Introduction: Symbol,
Total: tokenTotal,
Price: 0,
Owner: string(Nodes[0]),
Owner: string(Nodes[0][1:]),
Category: pty.CategoryMintBurnSupport,
}
//v, _ := types.PBToJSON(p1)
......@@ -115,6 +115,32 @@ func TestToken(t *testing.T) {
exec.SetLocalDB(kvdb)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err := exec.Exec(createTx, int(1))
assert.NotNil(t, err)
assert.Nil(t, receipt)
p1 = &pty.TokenPreCreate{
Name: Symbol,
Symbol: Symbol,
Introduction: Symbol,
Total: tokenTotal,
Price: 0,
Owner: string(Nodes[0]),
Category: pty.CategoryMintBurnSupport,
}
//v, _ := types.PBToJSON(p1)
createTx, err = types.CallCreateTransaction(pty.TokenX, "TokenPreCreate", p1)
if err != nil {
t.Error("RPC_Default_Process", "err", err)
}
createTx, err = signTx(createTx, PrivKeyA)
if err != nil {
t.Error("RPC_Default_Process sign", "err", err)
}
exec = newToken()
exec.SetStateDB(stateDB)
exec.SetLocalDB(kvdb)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
receipt, err = exec.Exec(createTx, int(1))
assert.Nil(t, err)
assert.NotNil(t, receipt)
t.Log(receipt)
......
......@@ -10,6 +10,7 @@ import (
"strings"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/address"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
......@@ -156,6 +157,11 @@ func (action *tokenAction) preCreate(token *pty.TokenPreCreate) (*types.Receipt,
} else if token.GetTotal() > types.MaxTokenBalance || token.GetTotal() <= 0 {
return nil, pty.ErrTokenTotalOverflow
}
if types.IsDappFork(action.height, pty.TokenX, "ForkTokenCheckAddress") {
if err := address.CheckAddress(token.Owner); err != nil {
return nil, err
}
}
if !types.IsDappFork(action.height, pty.TokenX, pty.ForkTokenSymbolWithNumberX) {
if token.Category != 0 {
return nil, types.ErrNotSupport
......
......@@ -23,6 +23,7 @@ func init() {
types.RegisterDappFork(TokenX, ForkBadTokenSymbolX, 184000)
types.RegisterDappFork(TokenX, ForkTokenPriceX, 560000)
types.RegisterDappFork(TokenX, ForkTokenSymbolWithNumberX, 1298600)
types.RegisterDappFork(TokenX, "ForkTokenCheckAddress", 1600000)
}
// TokenType 执行器基类结构体
......
......@@ -102,6 +102,7 @@ poolCacheSize=10240
minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=100
maxTxFee=1000000000
[mempool.sub.timeline]
# mempool缓存容量大小,默认10240
......
......@@ -138,7 +138,7 @@ func (e *executor) checkTx(tx *types.Transaction, index int) error {
//如果已经过期
return types.ErrTxExpire
}
if err := tx.Check(e.height, types.GInt("MinFee")); err != nil {
if err := tx.Check(e.height, types.GInt("MinFee"), types.GInt("MaxFee")); err != nil {
return err
}
//允许重写的情况
......@@ -166,7 +166,7 @@ func (e *executor) checkTxGroup(txgroup *types.Transactions, index int) error {
//如果已经过期
return types.ErrTxExpire
}
if err := txgroup.Check(e.height, types.GInt("MinFee")); err != nil {
if err := txgroup.Check(e.height, types.GInt("MinFee"), types.GInt("MaxFee")); err != nil {
return err
}
return nil
......
......@@ -129,7 +129,7 @@ func (c *channelClient) CreateNoBalanceTransaction(in *types.NoBalanceTx) (*type
if err != nil {
return nil, err
}
err = group.Check(0, types.GInt("MinFee"))
err = group.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
return nil, err
}
......
......@@ -456,7 +456,7 @@ func TestChain33_CreateTxGroup(t *testing.T) {
t.Error("Test createtxgroup failed")
return
}
err = tx.Check(0, types.GInt("MinFee"))
err = tx.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
assert.Nil(t, err)
}
......
......@@ -279,6 +279,15 @@ func (bc *BaseClient) CheckBlock(block *types.BlockDetail) error {
if string(block.Block.GetParentHash()) != string(parent.Hash()) {
return types.ErrParentHash
}
//check block size and tx count
if types.IsFork(block.Block.Height, "ForkBlockCheck") {
if block.Block.Size() > types.MaxBlockSize {
return types.ErrBlockSize
}
if int64(len(block.Block.Txs)) > types.GetP(block.Block.Height).MaxTxNumber {
return types.ErrManyTx
}
}
//check by drivers
err = bc.child.CheckBlock(parent, block)
return err
......@@ -468,16 +477,17 @@ func (bc *BaseClient) ConsensusTicketMiner(iscaughtup *types.IsCaughtUp) {
func (bc *BaseClient) AddTxsToBlock(block *types.Block, txs []*types.Transaction) []*types.Transaction {
size := block.Size()
max := types.MaxBlockSize - 100000 //留下100K空间,添加其他的交易
currentcount := int64(len(block.Txs))
currentCount := int64(len(block.Txs))
maxTx := types.GetP(block.Height).MaxTxNumber
addedTx := make([]*types.Transaction, 0, len(txs))
for i := 0; i < len(txs); i++ {
txgroup, err := txs[i].GetTxGroup()
txGroup, err := txs[i].GetTxGroup()
if err != nil {
continue
}
if txgroup == nil {
if currentcount+1 > maxTx {
if txGroup == nil {
currentCount++
if currentCount > maxTx {
return addedTx
}
size += txs[i].Size()
......@@ -487,17 +497,18 @@ func (bc *BaseClient) AddTxsToBlock(block *types.Block, txs []*types.Transaction
addedTx = append(addedTx, txs[i])
block.Txs = append(block.Txs, txs[i])
} else {
if currentcount+int64(len(txgroup.Txs)) > maxTx {
currentCount += int64(len(txGroup.Txs))
if currentCount > maxTx {
return addedTx
}
for i := 0; i < len(txgroup.Txs); i++ {
size += txgroup.Txs[i].Size()
for i := 0; i < len(txGroup.Txs); i++ {
size += txGroup.Txs[i].Size()
}
if size > max {
return addedTx
}
addedTx = append(addedTx, txgroup.Txs...)
block.Txs = append(block.Txs, txgroup.Txs...)
addedTx = append(addedTx, txGroup.Txs...)
block.Txs = append(block.Txs, txGroup.Txs...)
}
}
return addedTx
......
......@@ -300,7 +300,7 @@ func createTxGroup(cmd *cobra.Command, args []string) {
fmt.Fprintln(os.Stderr, err)
return
}
err = group.Check(0, types.GInt("MinFee"))
err = group.Check(0, types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
......
......@@ -373,7 +373,7 @@ func (d *DriverBase) GetTxGroup(index int) ([]*types.Transaction, error) {
for i := index; i >= 0 && i >= index-c; i-- {
if bytes.Equal(d.txs[i].Header, d.txs[i].Hash()) { //find header
txgroup := types.Transactions{Txs: d.txs[i : i+c]}
err := txgroup.Check(d.GetHeight(), types.GInt("MinFee"))
err := txgroup.Check(d.GetHeight(), types.GInt("MinFee"), types.GInt("MaxFee"))
if err != nil {
return nil, err
}
......
......@@ -300,7 +300,7 @@ func (mem *Mempool) delBlock(block *types.Block) {
tx = group.Tx()
i = i + groupCount - 1
}
err := tx.Check(header.GetHeight(), mem.cfg.MinTxFee)
err := tx.Check(header.GetHeight(), mem.cfg.MinTxFee, mem.cfg.MaxTxFee)
if err != nil {
continue
}
......
......@@ -87,7 +87,7 @@ func (mem *Mempool) checkTxs(msg *queue.Message) *queue.Message {
txmsg := msg.GetData().(*types.Transaction)
//普通的交易
tx := types.NewTransactionCache(txmsg)
err := tx.Check(header.GetHeight(), mem.cfg.MinTxFee)
err := tx.Check(header.GetHeight(), mem.cfg.MinTxFee, mem.cfg.MaxTxFee)
if err != nil {
msg.Data = err
return msg
......
......@@ -61,6 +61,7 @@ type Mempool struct {
PoolCacheSize int64 `protobuf:"varint,2,opt,name=poolCacheSize" json:"poolCacheSize,omitempty"`
// 最小得交易手续费用,这个没有默认值,必填,一般是100000
MinTxFee int64 `protobuf:"varint,3,opt,name=minTxFee" json:"minTxFee,omitempty"`
MaxTxFee int64 `protobuf:"varint,3,opt,name=maxTxFee" json:"maxTxFee,omitempty"`
ForceAccept bool `protobuf:"varint,4,opt,name=forceAccept" json:"forceAccept,omitempty"`
// 每个账户在mempool中得最大交易数量,默认100
MaxTxNumPerAccount int64 `protobuf:"varint,5,opt,name=maxTxNumPerAccount" json:"maxTxNumPerAccount,omitempty"`
......@@ -199,6 +200,8 @@ type RPC struct {
type Exec struct {
// 执行器执行所需最小费用,低于Mempool和Wallet设置的MinFee,在minExecFee = 0 的情况下,isFree = true才会生效
MinExecFee int64 `protobuf:"varint,1,opt,name=minExecFee" json:"minExecFee,omitempty"`
// 执行器执行所需最大费用,这个值必须大于mempool 和 wallet 的值
MaxExecFee int64 `protobuf:"varint,1,opt,name=maxExecFee" json:"maxExecFee,omitempty"`
// 执行器执行是否免费
IsFree bool `protobuf:"varint,2,opt,name=isFree" json:"isFree,omitempty"`
// 是否开启stat插件
......
......@@ -256,8 +256,14 @@ func Init(t string, cfg *Config) {
if cfg.Exec.MinExecFee > cfg.Mempool.MinTxFee || cfg.Mempool.MinTxFee > cfg.Wallet.MinFee {
panic("config must meet: wallet.minFee >= mempool.minTxFee >= exec.minExecFee")
}
if cfg.Exec.MaxExecFee < cfg.Mempool.MaxTxFee {
panic("config must meet: mempool.maxTxFee <= exec.maxExecFee")
}
setMinFee(cfg.Exec.MinExecFee)
setChainConfig("FixTime", cfg.FixTime)
if cfg.Exec.MaxExecFee > 0 {
setChainConfig("MaxFee", cfg.Exec.MaxExecFee)
}
}
//local 只用于单元测试
if isLocal() {
......@@ -355,6 +361,7 @@ func setMinFee(fee int64) {
panic("fee less than zero")
}
setChainConfig("MinFee", fee)
setChainConfig("MaxFee", fee*10000)
setChainConfig("MinBalanceTransfer", fee*10)
}
......
......@@ -218,6 +218,7 @@ ForkMultiSignAddress=1298600
ForkTxHeight= -1
ForkTxGroupPara= -1
ForkChainParamV2= -1
ForkBlockCheck=1725000
[fork.sub.coins]
Enable=0
......
......@@ -75,6 +75,7 @@ var (
ErrFeeTooLow = errors.New("ErrFeeTooLow")
ErrEmptyTx = errors.New("ErrEmptyTx")
ErrTxFeeTooLow = errors.New("ErrTxFeeTooLow")
ErrTxFeeTooHigh = errors.New("ErrTxFeeTooHigh")
ErrTxMsgSizeTooBig = errors.New("ErrTxMsgSizeTooBig")
ErrFutureBlock = errors.New("ErrFutureBlock")
ErrHashNotFound = errors.New("ErrHashNotFound")
......
......@@ -211,6 +211,7 @@ func SetTestNetFork() {
systemFork.SetFork("chain33", "ForkCheckBlockTime", 1200000)
systemFork.SetFork("chain33", "ForkMultiSignAddress", 1298600)
systemFork.SetFork("chain33", "ForkStateDBSet", MaxHeight)
systemFork.SetFork("chain33", "ForkBlockCheck", 1560000)
}
func setLocalFork() {
......
......@@ -66,6 +66,7 @@ keyFile="key.pem"
poolCacheSize=102400
minTxFee=100000
maxTxNumPerAccount=100
maxTxFee=1000000000
[consensus]
name="ticket"
......@@ -145,6 +146,7 @@ minerwhitelist=["*"]
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
......@@ -170,6 +172,7 @@ ForkTxHeight= -1
ForkTxGroupPara= -1
ForkCheckBlockTime=1200000
ForkMultiSignAddress=1298600
ForkBlockCheck=1725000
[fork.sub.coins]
Enable=0
......
......@@ -65,6 +65,7 @@ grpcFuncWhitelist=["*"]
poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=10000
maxTxFee=1000000000
[consensus]
name="ticket"
......@@ -119,6 +120,7 @@ minerwhitelist=["*"]
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
alias=["token1:token","token2:token","token3:token"]
......
......@@ -188,6 +188,7 @@ ForkTxHeight= -1
ForkTxGroupPara= -1
ForkCheckBlockTime=1200000
ForkMultiSignAddress=1298600
ForkBlockCheck=1
[fork.sub.coins]
Enable=0
......
......@@ -149,7 +149,7 @@ func (txgroup *Transactions) IsExpire(height, blocktime int64) bool {
}
//Check height == 0 的时候,不做检查
func (txgroup *Transactions) Check(height int64, minfee int64) error {
func (txgroup *Transactions) Check(height, minfee, maxFee int64) error {
txs := txgroup.Txs
if len(txs) < 2 {
return ErrTxGroupCountLessThanTwo
......@@ -159,7 +159,7 @@ func (txgroup *Transactions) Check(height int64, minfee int64) error {
if txs[i] == nil {
return ErrTxGroupEmpty
}
err := txs[i].check(0)
err := txs[i].check(height, 0, maxFee)
if err != nil {
return err
}
......@@ -192,6 +192,9 @@ func (txgroup *Transactions) Check(height int64, minfee int64) error {
if txs[0].Fee < totalfee {
return ErrTxFeeTooLow
}
if txs[0].Fee > maxFee && maxFee > 0 && IsFork(height, "ForkBlockCheck") {
return ErrTxFeeTooHigh
}
//检查hash是否符合要求
for i := 0; i < len(txs); i++ {
//检查头部是否等于头部hash
......@@ -288,7 +291,7 @@ func (tx *TransactionCache) Tx() *Transaction {
}
//Check 交易缓存中交易组合费用的检测
func (tx *TransactionCache) Check(height, minfee int64) error {
func (tx *TransactionCache) Check(height, minfee, maxFee int64) error {
if !tx.checked {
tx.checked = true
txs, err := tx.GetTxGroup()
......@@ -297,9 +300,9 @@ func (tx *TransactionCache) Check(height, minfee int64) error {
return err
}
if txs == nil {
tx.checkok = tx.check(minfee)
tx.checkok = tx.check(height, minfee, maxFee)
} else {
tx.checkok = txs.Check(height, minfee)
tx.checkok = txs.Check(height, minfee, maxFee)
}
}
return tx.checkok
......@@ -449,18 +452,18 @@ func (tx *Transaction) checkSign() bool {
}
//Check 交易检测
func (tx *Transaction) Check(height, minfee int64) error {
func (tx *Transaction) Check(height, minfee, maxFee int64) error {
group, err := tx.GetTxGroup()
if err != nil {
return err
}
if group == nil {
return tx.check(minfee)
return tx.check(height, minfee, maxFee)
}
return group.Check(height, minfee)
return group.Check(height, minfee, maxFee)
}
func (tx *Transaction) check(minfee int64) error {
func (tx *Transaction) check(height, minfee, maxFee int64) error {
txSize := Size(tx)
if txSize > int(MaxTxSize) {
return ErrTxMsgSizeTooBig
......@@ -473,6 +476,9 @@ func (tx *Transaction) check(minfee int64) error {
if tx.Fee < realFee {
return ErrTxFeeTooLow
}
if tx.Fee > maxFee && maxFee > 0 && IsFork(height, "ForkBlockCheck") {
return ErrTxFeeTooHigh
}
return nil
}
......
......@@ -34,7 +34,7 @@ func TestCreateGroupTx(t *testing.T) {
t.Error(err)
return
}
err = group.Check(0, GInt("MinFee"))
err = group.Check(0, GInt("MinFee"), GInt("MaxFee"))
if err != nil {
for i := 0; i < len(group.Txs); i++ {
t.Log(group.Txs[i].JSON())
......@@ -80,7 +80,7 @@ func TestCreateGroupTxWithSize(t *testing.T) {
return
}
err = group.Check(0, GInt("MinFee"))
err = group.Check(0, GInt("MinFee"), GInt("MaxFee"))
if err != nil {
for i := 0; i < len(group.Txs); i++ {
t.Log(group.Txs[i].JSON())
......@@ -163,7 +163,7 @@ func TestSignGroupTx(t *testing.T) {
return
}
}
err = group.Check(0, GInt("MinFee"))
err = group.Check(0, GInt("MinFee"), GInt("MaxFee"))
if err != nil {
t.Error(err)
return
......
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