diff --git a/cmd/chain33/bityuan.toml b/cmd/chain33/bityuan.toml index f6858ad42d..fc48dbf659 100644 --- a/cmd/chain33/bityuan.toml +++ b/cmd/chain33/bityuan.toml @@ -83,6 +83,10 @@ maxTxFee=1000000000 # 单笔交易最大的手续费, 50 coins maxTxFee=5000000000 +[mver.mempool.ForkMaxTxFeeV2] +# 单笔交易最大的手续费, 10 coins +maxTxFee=1000000000 + [store] # 数据文件存储路径 dbPath="datadir/mavltree" diff --git a/cmd/chain33/chain33.fork.toml b/cmd/chain33/chain33.fork.toml index f73c0a932f..cf6db35f13 100644 --- a/cmd/chain33/chain33.fork.toml +++ b/cmd/chain33/chain33.fork.toml @@ -26,7 +26,11 @@ ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 ForkProxyExec=0 +ForkMaxBlockFee=0 ForkMaxTxFeeV1=0 +ForkMaxTxFeeV2=0 + + [fork.sub.none] ForkUseTimeDelay=0 diff --git a/cmd/chain33/chain33.system.fork.toml b/cmd/chain33/chain33.system.fork.toml index e926a3f028..a47dcd8210 100644 --- a/cmd/chain33/chain33.system.fork.toml +++ b/cmd/chain33/chain33.system.fork.toml @@ -26,4 +26,6 @@ ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 ForkProxyExec=0 -ForkMaxTxFeeV1=0 \ No newline at end of file +ForkMaxTxFeeV1=0 +ForkMaxTxFeeV2=0 +ForkMaxBlockFee=0 \ No newline at end of file diff --git a/cmd/chain33/chain33.test.toml b/cmd/chain33/chain33.test.toml index 02cf92cd8c..4f29535345 100644 --- a/cmd/chain33/chain33.test.toml +++ b/cmd/chain33/chain33.test.toml @@ -107,6 +107,10 @@ isLevelFee=false # 单笔交易最大的手续费, 50 coins maxTxFee=5000000000 +[mver.mempool.ForkMaxTxFeeV2] +# 单笔交易最大的手续费, 10 coins +maxTxFee=1000000000 + [mempool.sub.timeline] poolCacheSize=10240 diff --git a/cmd/chain33/chain33.toml b/cmd/chain33/chain33.toml index a43e2283b4..8f5aa37d0a 100644 --- a/cmd/chain33/chain33.toml +++ b/cmd/chain33/chain33.toml @@ -155,7 +155,9 @@ isLevelFee=false [mver.mempool.ForkMaxTxFeeV1] # 单笔交易最大的手续费, 50 coins maxTxFee=5000000000 - +[mver.mempool.ForkMaxTxFeeV2] +# 单笔交易最大的手续费, 10 coins +maxTxFee=1000000000 [mempool.sub.timeline] # mempool缓存容量大小,默认10240 diff --git a/system/consensus/base.go b/system/consensus/base.go index 92c1c43a58..2176020190 100644 --- a/system/consensus/base.go +++ b/system/consensus/base.go @@ -36,7 +36,7 @@ func init() { QueryData.Register("base", &BaseClient{}) } -//Miner 矿工 +// Miner 矿工 type Miner interface { CreateGenesisTx() []*types.Transaction GetGenesisBlockTime() int64 @@ -48,7 +48,7 @@ type Miner interface { GetBaseClient() *BaseClient } -//BaseClient ... +// BaseClient ... type BaseClient struct { client queue.Client api client.QueueProtocolAPI @@ -66,7 +66,7 @@ type BaseClient struct { Cancel context.CancelFunc } -//NewBaseClient ... +// NewBaseClient ... func NewBaseClient(cfg *types.Consensus) *BaseClient { var flag int32 if cfg.Minerstart { @@ -79,12 +79,12 @@ func NewBaseClient(cfg *types.Consensus) *BaseClient { return client } -//GetGenesisBlockTime 获取创世区块时间 +// GetGenesisBlockTime 获取创世区块时间 func (bc *BaseClient) GetGenesisBlockTime() int64 { return bc.Cfg.GenesisBlockTime } -//SetChild ... +// SetChild ... func (bc *BaseClient) SetChild(c Miner) { bc.child = c } @@ -99,22 +99,22 @@ func (bc *BaseClient) GetBaseClient() *BaseClient { return bc } -//GetAPI 获取api +// GetAPI 获取api func (bc *BaseClient) GetAPI() client.QueueProtocolAPI { return bc.api } -//SetAPI ... +// SetAPI ... func (bc *BaseClient) SetAPI(api client.QueueProtocolAPI) { bc.api = api } -//AddBlock 添加区块的时候,通知系统做处理 +// AddBlock 添加区块的时候,通知系统做处理 func (bc *BaseClient) AddBlock(b *types.Block) error { return nil } -//InitClient 初始化 +// InitClient 初始化 func (bc *BaseClient) InitClient(c queue.Client, minerstartCB func()) { log.Info("Enter SetQueueClient method of consensus") bc.client = c @@ -128,17 +128,17 @@ func (bc *BaseClient) InitClient(c queue.Client, minerstartCB func()) { bc.InitMiner() } -//GetQueueClient 获取客户端队列 +// GetQueueClient 获取客户端队列 func (bc *BaseClient) GetQueueClient() queue.Client { return bc.client } -//RandInt64 随机数 +// RandInt64 随机数 func (bc *BaseClient) RandInt64() int64 { return randgen.Int63() } -//InitMiner 初始化矿工 +// InitMiner 初始化矿工 func (bc *BaseClient) InitMiner() { bc.once.Do(bc.minerstartCB) } @@ -156,10 +156,10 @@ func (bc *BaseClient) InitStateCommitter() { } } -//Wait wait for ready +// Wait wait for ready func (bc *BaseClient) Wait() {} -//SetQueueClient 设置客户端队列 +// SetQueueClient 设置客户端队列 func (bc *BaseClient) SetQueueClient(c queue.Client) { bc.InitClient(c, func() { //call init block @@ -169,7 +169,7 @@ func (bc *BaseClient) SetQueueClient(c queue.Client) { go bc.child.CreateBlock() } -//InitBlock change init block +// InitBlock change init block func (bc *BaseClient) InitBlock() { cfg := bc.client.GetConfig() block, err := bc.RequestLastBlock() @@ -199,7 +199,7 @@ func (bc *BaseClient) InitBlock() { } } -//Close 关闭 +// Close 关闭 func (bc *BaseClient) Close() { atomic.StoreInt32(&bc.minerStart, 0) atomic.StoreInt32(&bc.isclosed, 1) @@ -208,12 +208,12 @@ func (bc *BaseClient) Close() { log.Info("consensus base closed") } -//IsClosed 是否已经关闭 +// IsClosed 是否已经关闭 func (bc *BaseClient) IsClosed() bool { return atomic.LoadInt32(&bc.isclosed) == 1 } -//CheckTxDup 为了不引起交易检查时候产生的无序 +// CheckTxDup 为了不引起交易检查时候产生的无序 func (bc *BaseClient) CheckTxDup(txs []*types.Transaction) (transactions []*types.Transaction) { cacheTxs := types.TxsToCache(txs) var err error @@ -224,12 +224,12 @@ func (bc *BaseClient) CheckTxDup(txs []*types.Transaction) (transactions []*type return types.CacheToTxs(cacheTxs) } -//IsMining 是否在挖矿 +// IsMining 是否在挖矿 func (bc *BaseClient) IsMining() bool { return atomic.LoadInt32(&bc.minerStart) == 1 } -//IsCaughtUp 是否追上最新高度 +// IsCaughtUp 是否追上最新高度 func (bc *BaseClient) IsCaughtUp() bool { if bc.client == nil { panic("bc not bind message queue.") @@ -246,7 +246,7 @@ func (bc *BaseClient) IsCaughtUp() bool { return resp.GetData().(*types.IsCaughtUp).GetIscaughtup() } -//ExecConsensus 执行共识 +// ExecConsensus 执行共识 func (bc *BaseClient) ExecConsensus(data *types.ChainExecutor) (types.Message, error) { param, err := QueryData.Decode(data.Driver, data.FuncName, data.Param) if err != nil { @@ -262,7 +262,7 @@ func (bc *BaseClient) pubToSubModule(msg *queue.Message) { } } -//EventLoop 准备新区块 +// EventLoop 准备新区块 func (bc *BaseClient) EventLoop() { // 监听blockchain模块,获取当前最高区块 bc.client.Sub("consensus") @@ -318,7 +318,7 @@ func (bc *BaseClient) EventLoop() { }() } -//CheckBlock 检查区块 +// CheckBlock 检查区块 func (bc *BaseClient) CheckBlock(block *types.BlockDetail) error { //check parent if block.Block.Height <= 0 { //genesis block not check @@ -341,7 +341,8 @@ func (bc *BaseClient) CheckBlock(block *types.BlockDetail) error { if string(block.Block.GetParentHash()) != string(parent.Hash(cfg)) { return types.ErrParentHash } - //check block size and tx count + //check block size and tx count and blockfee + if cfg.IsFork(block.Block.Height, "ForkBlockCheck") { if block.Block.Size() > types.MaxBlockSize { return types.ErrBlockSize @@ -350,12 +351,20 @@ func (bc *BaseClient) CheckBlock(block *types.BlockDetail) error { return types.ErrManyTx } } + + if cfg.IsFork(block.Block.Height, "ForkMaxBlockFee") { + if block.Block.Fee() > types.MaxBlockFee { + return types.ErrBlockFee + } + + } + //check by drivers err = bc.child.CheckBlock(parent, block) return err } -//RequestTx Mempool中取交易列表 +// RequestTx Mempool中取交易列表 func (bc *BaseClient) RequestTx(listSize int, txHashList [][]byte) []*types.Transaction { if bc.client == nil { panic("bc not bind message queue.") @@ -372,7 +381,7 @@ func (bc *BaseClient) RequestTx(listSize int, txHashList [][]byte) []*types.Tran return resp.GetData().(*types.ReplyTxList).GetTxs() } -//RequestBlock 请求区块 +// RequestBlock 请求区块 func (bc *BaseClient) RequestBlock(start int64) (*types.Block, error) { if bc.client == nil { panic("bc not bind message queue.") @@ -391,7 +400,7 @@ func (bc *BaseClient) RequestBlock(start int64) (*types.Block, error) { return blocks.Items[0].Block, nil } -//RequestLastBlock 获取最新的block从blockchain模块 +// RequestLastBlock 获取最新的block从blockchain模块 func (bc *BaseClient) RequestLastBlock() (*types.Block, error) { if bc.client == nil { panic("client not bind message queue.") @@ -409,7 +418,7 @@ func (bc *BaseClient) RequestLastBlock() (*types.Block, error) { return block, nil } -//del mempool +// del mempool func (bc *BaseClient) delMempoolTx(deltx []*types.Transaction) error { hashList := buildHashList(deltx) msg := bc.client.NewMessage("mempool", types.EventDelTxList, hashList) @@ -435,7 +444,7 @@ func buildHashList(deltx []*types.Transaction) *types.TxHashList { return list } -//WriteBlock 向blockchain写区块 +// WriteBlock 向blockchain写区块 func (bc *BaseClient) WriteBlock(prev []byte, block *types.Block) error { //保存block的原始信息用于删除mempool中的错误交易 rawtxs := make([]*types.Transaction, len(block.Txs)) @@ -510,14 +519,14 @@ func diffTx(tx1, tx2 []*types.Transaction) (deltx []*types.Transaction) { return deltx } -//SetCurrentBlock 设置当前区块 +// SetCurrentBlock 设置当前区块 func (bc *BaseClient) SetCurrentBlock(b *types.Block) { bc.mulock.Lock() bc.currentBlock = b bc.mulock.Unlock() } -//UpdateCurrentBlock 更新当前区块 +// UpdateCurrentBlock 更新当前区块 func (bc *BaseClient) UpdateCurrentBlock(b *types.Block) { bc.mulock.Lock() defer bc.mulock.Unlock() @@ -529,14 +538,14 @@ func (bc *BaseClient) UpdateCurrentBlock(b *types.Block) { bc.currentBlock = block } -//GetCurrentBlock 获取当前区块 +// GetCurrentBlock 获取当前区块 func (bc *BaseClient) GetCurrentBlock() (b *types.Block) { bc.mulock.Lock() defer bc.mulock.Unlock() return bc.currentBlock } -//GetCurrentHeight 获取当前高度 +// GetCurrentHeight 获取当前高度 func (bc *BaseClient) GetCurrentHeight() int64 { bc.mulock.Lock() start := bc.currentBlock.Height @@ -544,17 +553,17 @@ func (bc *BaseClient) GetCurrentHeight() int64 { return start } -//Lock 上锁 +// Lock 上锁 func (bc *BaseClient) Lock() { bc.mulock.Lock() } -//Unlock 解锁 +// Unlock 解锁 func (bc *BaseClient) Unlock() { bc.mulock.Unlock() } -//ConsensusTicketMiner ... +// ConsensusTicketMiner ... func (bc *BaseClient) ConsensusTicketMiner(iscaughtup *types.IsCaughtUp) { if !atomic.CompareAndSwapInt32(&bc.isCaughtUp, 0, 1) { log.Info("ConsensusTicketMiner", "isCaughtUp", bc.isCaughtUp) @@ -563,21 +572,30 @@ func (bc *BaseClient) ConsensusTicketMiner(iscaughtup *types.IsCaughtUp) { } } -//AddTxsToBlock 添加交易到区块中 +// AddTxsToBlock 添加交易到区块中 func (bc *BaseClient) AddTxsToBlock(block *types.Block, txs []*types.Transaction) []*types.Transaction { size := block.Size() - max := types.MaxBlockSize - 100000 //留下100K空间,添加其他的交易 + max := types.MaxBlockSize - 100000 //留下100K空间,添加其他的交易 + maxFee := types.MaxBlockFee - 100000 //留下挖矿交易的手续费 1e5 currentCount := int64(len(block.Txs)) types.AssertConfig(bc.client) cfg := bc.client.GetConfig() maxTx := cfg.GetP(block.Height).MaxTxNumber addedTx := make([]*types.Transaction, 0, len(txs)) + var toalBlockFee int64 = 0 for i := 0; i < len(txs); i++ { + if cfg.IsFork(block.Height, "ForkMaxBlockFee") { + toalBlockFee += txs[i].GetTxFee() + if toalBlockFee > maxFee { + return addedTx + } + } txGroup, err := txs[i].GetTxGroup() if err != nil { continue } if txGroup == nil { + currentCount++ if currentCount > maxTx { return addedTx @@ -606,7 +624,7 @@ func (bc *BaseClient) AddTxsToBlock(block *types.Block, txs []*types.Transaction return addedTx } -//CheckTxExpire 此时的tx交易组都是展开的,过滤掉已经过期的tx交易,目前只有ticket共识需要在updateBlock时调用 +// CheckTxExpire 此时的tx交易组都是展开的,过滤掉已经过期的tx交易,目前只有ticket共识需要在updateBlock时调用 func (bc *BaseClient) CheckTxExpire(txs []*types.Transaction, height int64, blocktime int64) (transactions []*types.Transaction) { var txlist types.Transactions var hasTxExpire bool @@ -653,7 +671,7 @@ func (bc *BaseClient) CheckTxExpire(txs []*types.Transaction, height int64, bloc return txs } -//检测交易数组是否过期,只要有一个过期就认为整个交易组过期 +// 检测交易数组是否过期,只要有一个过期就认为整个交易组过期 func isExpire(cfg *types.Chain33Config, txs []*types.Transaction, height int64, blocktime int64) bool { for _, tx := range txs { if height > 0 && blocktime > 0 && tx.IsExpire(cfg, height, blocktime) { @@ -664,9 +682,9 @@ func isExpire(cfg *types.Chain33Config, txs []*types.Transaction, height int64, return false } -//CmpBestBlock 最优区块的比较 -//height,BlockTime,ParentHash必须一致才可以继续比较 -//通过比较newBlock是最优区块就返回true,否则返回false +// CmpBestBlock 最优区块的比较 +// height,BlockTime,ParentHash必须一致才可以继续比较 +// 通过比较newBlock是最优区块就返回true,否则返回false func (bc *BaseClient) CmpBestBlock(newBlock *types.Block, cmpHash []byte) bool { cfg := bc.client.GetConfig() @@ -692,7 +710,7 @@ func (bc *BaseClient) CmpBestBlock(newBlock *types.Block, cmpHash []byte) bool { return false } -//ReqBlockByHash 通过区块hash获取区块信息 +// ReqBlockByHash 通过区块hash获取区块信息 func (bc *BaseClient) ReqBlockByHash(hash []byte) (*types.Block, error) { if bc.client == nil { panic("bc not bind message queue.") diff --git a/system/consensus/solo/solo_test.go b/system/consensus/solo/solo_test.go index ede07c9763..d532770347 100644 --- a/system/consensus/solo/solo_test.go +++ b/system/consensus/solo/solo_test.go @@ -60,13 +60,32 @@ func TestSolo(t *testing.T) { mock33.GetAPI().SendTx(txs[i]) } mock33.WaitHeight(2) + //test feelimit txs ,blockfeelimit + + privkey := mock33.GetGenesisKey() + txs = util.GenCoinsTxs(cfg, nil, 30) + for i := 0; i < 30; i++ { + //每笔交易手续费10个比特元 + txs[i].Fee = 10 * 1e8 + txs[i].Sign(types.SECP256K1, privkey) + } + for i := 0; i < len(txs); i++ { + mock33.GetAPI().SendTx(txs[i]) + } + time.Sleep(time.Second * 10) + t.Log("current height:", mock33.GetBlockChain().GetBlockHeight()) + for h := 3; h <= int(mock33.GetBlockChain().GetBlockHeight()); h++ { + t.Log("blockfee:", mock33.GetBlock(int64(h)).Fee(), "blockheight:", h, "txnum:", len(mock33.GetBlock(int64(h)).Txs)) + assert.True(t, mock33.GetBlock(int64(h)).Fee() < types.MaxBlockFee) + } + } var ( tlog = log15.New("module", "test solo") ) -//mempool发送交易 10000tx/s +// mempool发送交易 10000tx/s func BenchmarkSendTx(b *testing.B) { if testing.Short() { b.Skip("skipping in short mode.") @@ -244,7 +263,7 @@ func createCoinsTx(cfg *types.Chain33Config, to string, txHeight int64) *types.T return tx } -//测试solo并发 +// 测试solo并发 func BenchmarkSolo(b *testing.B) { if testing.Short() { @@ -392,7 +411,7 @@ func BenchmarkCheckSign(b *testing.B) { } } -//消息队列发送性能, 80w /s +// 消息队列发送性能, 80w /s func BenchmarkMsgQueue(b *testing.B) { if testing.Short() { b.Skip("skipping in short mode.") diff --git a/types/block.go b/types/block.go index cbd4f46128..438c2ec64e 100644 --- a/types/block.go +++ b/types/block.go @@ -21,7 +21,7 @@ func (block *Block) Hash(cfg *Chain33Config) []byte { return block.HashOld() } -//HashByForkHeight hash 通过自己设置的fork 高度计算 hash +// HashByForkHeight hash 通过自己设置的fork 高度计算 hash func (block *Block) HashByForkHeight(forkheight int64) []byte { if block.Height >= forkheight { return block.HashNew() @@ -29,13 +29,13 @@ func (block *Block) HashByForkHeight(forkheight int64) []byte { return block.HashOld() } -//HashNew 新版本的Hash +// HashNew 新版本的Hash func (block *Block) HashNew() []byte { data := Encode(block.getHeaderHashNew()) return common.Sha256(data) } -//HashOld 老版本的hash +// HashOld 老版本的hash func (block *Block) HashOld() []byte { data := Encode(block.getHeaderHashOld()) return common.Sha256(data) @@ -46,6 +46,15 @@ func (block *Block) Size() int { return Size(block) } +func (block *Block) Fee() int64 { + txs := block.Txs + var totalFee int64 + for i := 0; i < len(txs); i++ { + totalFee += txs[i].GetTxFee() + } + return totalFee +} + // GetHeader 获取block的Header信息 func (block *Block) GetHeader(cfg *Chain33Config) *Header { head := &Header{} @@ -197,11 +206,11 @@ func CheckSign(data []byte, execer string, sign *Signature, blockHeight int64) b return c.Validate(data, sign.Pubkey, sign.Signature) == nil } -//FilterParaTxsByTitle 过滤指定title的平行链交易 -//1,单笔平行连交易 -//2,交易组中的平行连交易,需要将整个交易组都过滤出来 -//目前暂时不返回单个交易的proof证明路径, -//后面会将平行链的交易组装到一起,构成一个子roothash。会返回子roothash的proof证明路径 +// FilterParaTxsByTitle 过滤指定title的平行链交易 +// 1,单笔平行连交易 +// 2,交易组中的平行连交易,需要将整个交易组都过滤出来 +// 目前暂时不返回单个交易的proof证明路径, +// 后面会将平行链的交易组装到一起,构成一个子roothash。会返回子roothash的proof证明路径 func (blockDetail *BlockDetail) FilterParaTxsByTitle(cfg *Chain33Config, title string) *ParaTxDetail { var paraTx ParaTxDetail paraTx.Header = blockDetail.Block.GetHeader(cfg) @@ -230,7 +239,7 @@ func (blockDetail *BlockDetail) FilterParaTxsByTitle(cfg *Chain33Config, title s return ¶Tx } -//filterParaTxGroup 获取para交易所在交易组信息 +// filterParaTxGroup 获取para交易所在交易组信息 func (blockDetail *BlockDetail) filterParaTxGroup(tx *Transaction, index int) ([]*TxDetail, int) { var headIdx int var txDetails []*TxDetail diff --git a/types/config.go b/types/config.go index 360bb74a93..d7eb15e402 100644 --- a/types/config.go +++ b/types/config.go @@ -40,7 +40,8 @@ const ( MaxFloatCharNum int = 15 //float64最大可精确表示15个字符的浮点数,小数点占一位,小数点位置不确定,不好确定最大值 MaxTxSize = 100000 //100K MaxTxGroupSize int32 = 20 - MaxBlockSize = 20000000 //20M + MaxBlockSize = 20000000 //20M + MaxBlockFee = DefaultCoinPrecision * 50 //区块手续费最大 50 coins MaxTxsPerBlock = 100000 MaxTokenBalance int64 = 900 * 1e8 * DefaultCoinPrecision //缺省900亿,小数位精度为1e8, 900*1e16 大约为int64最大可表示范围 DefaultMinFee int64 = 1e5 @@ -541,13 +542,11 @@ func (c *Chain33Config) GetMaxTxFeeRate() int64 { // GetMaxTxFee get max transaction fee by blockheight func (c *Chain33Config) GetMaxTxFee(height int64) int64 { - if c.IsFork(height, "ForkMaxTxFeeV1") { conf := Conf(c, "mver.mempool") if conf.MGInt("maxTxFee", height) != 0 { return conf.MGInt("maxTxFee", height) } - } return c.GInt("MaxTxFee") } diff --git a/types/config_test.go b/types/config_test.go index 840e54628e..e8119a6793 100644 --- a/types/config_test.go +++ b/types/config_test.go @@ -26,7 +26,7 @@ func TestChainConfig(t *testing.T) { assert.Equal(t, adata.(bool), true) // tx fee config - assert.Equal(t, cfg.GetMaxTxFee(0), int64(1e9)) + assert.Equal(t, int64(1e9), cfg.GetMaxTxFee(0)) assert.Equal(t, cfg.GetMaxTxFeeRate(), int64(1e7)) assert.Equal(t, cfg.GetMinTxFeeRate(), int64(1e5)) height, ok := cfg.GetModuleConfig().Crypto.EnableHeight[secp256k1.Name] diff --git a/types/defaultcfg.go b/types/defaultcfg.go index 5e15cf57ee..9cad28dd17 100644 --- a/types/defaultcfg.go +++ b/types/defaultcfg.go @@ -107,6 +107,12 @@ poolCacheSize=102400 minTxFeeRate=100000 maxTxNumPerAccount=100000 +[mver.mempool.ForkMaxTxFeeV1] +maxTxFee=5000000000 +[mver.mempool.ForkMaxTxFeeV2] +maxTxFee=1000000000 + + [consensus] name="solo" minerstart=true @@ -250,7 +256,7 @@ useBalance=false jdkPath="../../../../build/j2sdk-image" ` -//GetDefaultCfgstring ... +// GetDefaultCfgstring ... func GetDefaultCfgstring() string { return cfgstring } diff --git a/types/error.go b/types/error.go index 382f764c23..4ebbf41735 100644 --- a/types/error.go +++ b/types/error.go @@ -172,7 +172,7 @@ var ( ErrIndex = errors.New("ErrIndex") ErrTxGroupParaCount = errors.New("ErrTxGroupParaCount") ErrTxGroupParaMainMixed = errors.New("ErrTxGroupParaMainMixed") - + ErrBlockFee = errors.New("ErrBlockFee") //ErrInvalidMainnetRPCAddr rpc模块的错误类型 ErrInvalidMainnetRPCAddr = errors.New("ErrInvalidMainnetRPCAddr") diff --git a/types/fork.go b/types/fork.go index b01b6c78eb..849003f63e 100644 --- a/types/fork.go +++ b/types/fork.go @@ -145,7 +145,8 @@ func (f *Forks) SetTestNetFork() { f.setFork("ForkCheckEthTxSort", 0) f.setFork("ForkProxyExec", 0) f.setFork("ForkMaxTxFeeV1", 0) - + f.setFork("ForkMaxTxFeeV2", 0) + f.SetFork("ForkMaxBlockFee", 0) } func (f *Forks) setLocalFork() { diff --git a/types/testdata/chain33.toml b/types/testdata/chain33.toml index 7e814ca32e..e7e938bf78 100644 --- a/types/testdata/chain33.toml +++ b/types/testdata/chain33.toml @@ -156,6 +156,8 @@ ForkV24TxGroupPara= 806578 ForkStateDBSet=-1 ForkMaxTxFeeV1=30839600 ForkMaxTxFeeV2=30939600 +ForkMaxBlockFee=30949600 + [fork.sub.manage] Enable=120000 ForkV11ManageExec= 400000 diff --git a/types/tx.go b/types/tx.go index 757ea6eec5..dbe5c2ab82 100644 --- a/types/tx.go +++ b/types/tx.go @@ -40,7 +40,7 @@ func init() { } } -//TxCacheGet 某些交易的cache 加入缓存中,防止重复进行解析或者计算 +// TxCacheGet 某些交易的cache 加入缓存中,防止重复进行解析或者计算 func TxCacheGet(tx *Transaction) (*TransactionCache, bool) { txc, ok := txCache.Get(tx) if !ok { @@ -49,7 +49,7 @@ func TxCacheGet(tx *Transaction) (*TransactionCache, bool) { return txc.(*TransactionCache), ok } -//TxCacheSet 设置 cache +// TxCacheSet 设置 cache func TxCacheSet(tx *Transaction, txc *TransactionCache) { if txc == nil { txCache.Remove(tx) @@ -102,8 +102,8 @@ func CreateTxGroup(txs []*Transaction, feeRate int64) (*Transactions, error) { return txgroup, nil } -//Tx 这比用于检查的交易,包含了所有的交易。 -//主要是为了兼容原来的设计 +// Tx 这比用于检查的交易,包含了所有的交易。 +// 主要是为了兼容原来的设计 func (txgroup *Transactions) Tx() *Transaction { if len(txgroup.GetTxs()) < 2 { return nil @@ -117,12 +117,12 @@ func (txgroup *Transactions) Tx() *Transaction { return copytx } -//GetTxGroup 获取交易组 +// GetTxGroup 获取交易组 func (txgroup *Transactions) GetTxGroup() *Transactions { return txgroup } -//SignN 对交易组的第n笔交易签名 +// SignN 对交易组的第n笔交易签名 func (txgroup *Transactions) SignN(n int, ty int32, priv crypto.PrivKey) error { if n >= len(txgroup.GetTxs()) { return ErrIndex @@ -131,7 +131,7 @@ func (txgroup *Transactions) SignN(n int, ty int32, priv crypto.PrivKey) error { return nil } -//CheckSign 检测交易组的签名 +// CheckSign 检测交易组的签名 func (txgroup *Transactions) CheckSign(blockHeight int64) bool { txs := txgroup.Txs for i := 0; i < len(txs); i++ { @@ -142,7 +142,7 @@ func (txgroup *Transactions) CheckSign(blockHeight int64) bool { return true } -//RebuiltGroup 交易内容有变化时需要重新构建交易组 +// RebuiltGroup 交易内容有变化时需要重新构建交易组 func (txgroup *Transactions) RebuiltGroup() { header := txgroup.Txs[0].Hash() for i := len(txgroup.Txs) - 1; i >= 0; i-- { @@ -158,7 +158,7 @@ func (txgroup *Transactions) RebuiltGroup() { } } -//SetExpire 设置交易组中交易的过期时间 +// SetExpire 设置交易组中交易的过期时间 func (txgroup *Transactions) SetExpire(cfg *Chain33Config, n int, expire time.Duration) { if n >= len(txgroup.GetTxs()) { return @@ -166,7 +166,7 @@ func (txgroup *Transactions) SetExpire(cfg *Chain33Config, n int, expire time.Du txgroup.GetTxs()[n].SetExpire(cfg, expire) } -//IsExpire 交易是否过期 +// IsExpire 交易是否过期 func (txgroup *Transactions) IsExpire(cfg *Chain33Config, height, blocktime int64) bool { txs := txgroup.Txs for i := 0; i < len(txs); i++ { @@ -177,7 +177,7 @@ func (txgroup *Transactions) IsExpire(cfg *Chain33Config, height, blocktime int6 return false } -//CheckWithFork 和fork 无关的有个检查函数 +// CheckWithFork 和fork 无关的有个检查函数 func (txgroup *Transactions) CheckWithFork(cfg *Chain33Config, checkFork, paraFork bool, height, minfee, maxFee int64) error { txs := txgroup.Txs if len(txs) < 2 { @@ -266,14 +266,14 @@ func (txgroup *Transactions) CheckWithFork(cfg *Chain33Config, checkFork, paraFo return nil } -//Check height == 0 的时候,不做检查 +// Check height == 0 的时候,不做检查 func (txgroup *Transactions) Check(cfg *Chain33Config, height, minfee, maxFee int64) error { paraFork := cfg.IsFork(height, "ForkTxGroupPara") checkFork := cfg.IsFork(height, "ForkBlockCheck") return txgroup.CheckWithFork(cfg, checkFork, paraFork, height, minfee, maxFee) } -//TransactionCache 交易缓存结构 +// TransactionCache 交易缓存结构 type TransactionCache struct { *Transaction txGroup *Transactions @@ -287,12 +287,12 @@ type TransactionCache struct { plerr error } -//NewTransactionCache new交易缓存 +// NewTransactionCache new交易缓存 func NewTransactionCache(tx *Transaction) *TransactionCache { return &TransactionCache{Transaction: tx} } -//Hash 交易hash +// Hash 交易hash func (tx *TransactionCache) Hash() []byte { if tx.hash == nil { tx.hash = tx.Transaction.Hash() @@ -300,14 +300,14 @@ func (tx *TransactionCache) Hash() []byte { return tx.hash } -//SetPayloadValue 设置payload 的cache +// SetPayloadValue 设置payload 的cache func (tx *TransactionCache) SetPayloadValue(plname string, payload reflect.Value, plerr error) { tx.payload = payload tx.plerr = plerr tx.plname = plname } -//GetPayloadValue 设置payload 的cache +// GetPayloadValue 设置payload 的cache func (tx *TransactionCache) GetPayloadValue() (plname string, payload reflect.Value, plerr error) { if tx.plerr != nil || tx.plname != "" { return tx.plname, tx.payload, tx.plerr @@ -322,7 +322,7 @@ func (tx *TransactionCache) GetPayloadValue() (plname string, payload reflect.Va return } -//Size 交易缓存的大小 +// Size 交易缓存的大小 func (tx *TransactionCache) Size() int { if tx.size == 0 { tx.size = Size(tx.Tx()) @@ -330,12 +330,12 @@ func (tx *TransactionCache) Size() int { return tx.size } -//Tx 交易缓存中tx信息 +// Tx 交易缓存中tx信息 func (tx *TransactionCache) Tx() *Transaction { return tx.Transaction } -//Check 交易缓存中交易组合费用的检测 +// Check 交易缓存中交易组合费用的检测 func (tx *TransactionCache) Check(cfg *Chain33Config, height, minfee, maxFee int64) error { if !tx.checked { tx.checked = true @@ -353,7 +353,7 @@ func (tx *TransactionCache) Check(cfg *Chain33Config, height, minfee, maxFee int return tx.checkok } -//GetTotalFee 获取交易真实费用 +// GetTotalFee 获取交易真实费用 func (tx *TransactionCache) GetTotalFee(minFee int64) (int64, error) { txgroup, err := tx.GetTxGroup() if err != nil { @@ -375,7 +375,7 @@ func (tx *TransactionCache) GetTotalFee(minFee int64) (int64, error) { return totalfee, nil } -//GetTxGroup 获取交易组 +// GetTxGroup 获取交易组 func (tx *TransactionCache) GetTxGroup() (*Transactions, error) { var err error if tx.txGroup == nil { @@ -387,7 +387,7 @@ func (tx *TransactionCache) GetTxGroup() (*Transactions, error) { return tx.txGroup, nil } -//CheckSign 检测签名 +// CheckSign 检测签名 func (tx *TransactionCache) CheckSign(blockHeight int64) bool { if tx.signok == 0 { tx.signok = 2 @@ -409,7 +409,7 @@ func (tx *TransactionCache) CheckSign(blockHeight int64) bool { return tx.signok == 1 } -//TxsToCache 缓存交易信息 +// TxsToCache 缓存交易信息 func TxsToCache(txs []*Transaction) (caches []*TransactionCache) { caches = make([]*TransactionCache, len(txs)) for i := 0; i < len(caches); i++ { @@ -418,7 +418,7 @@ func TxsToCache(txs []*Transaction) (caches []*TransactionCache) { return caches } -//CacheToTxs 从缓存中获取交易信息 +// CacheToTxs 从缓存中获取交易信息 func CacheToTxs(caches []*TransactionCache) (txs []*Transaction) { txs = make([]*Transaction, len(caches)) for i := 0; i < len(caches); i++ { @@ -427,12 +427,12 @@ func CacheToTxs(caches []*TransactionCache) (txs []*Transaction) { return txs } -//Tx 交易详情 +// Tx 交易详情 func (tx *Transaction) Tx() *Transaction { return tx } -//GetTxGroup 交易组装成交易组格式 +// GetTxGroup 交易组装成交易组格式 func (tx *Transaction) GetTxGroup() (*Transactions, error) { if tx.GroupCount < 0 || tx.GroupCount == 1 || tx.GroupCount > 20 { return nil, ErrTxGroupCount @@ -451,12 +451,12 @@ func (tx *Transaction) GetTxGroup() (*Transactions, error) { return nil, nil } -//Size 交易大小 +// Size 交易大小 func (tx *Transaction) Size() int { return Size(tx) } -//Sign 交易签名 +// Sign 交易签名 func (tx *Transaction) Sign(ty int32, priv crypto.PrivKey) { tx.Signature = nil data := Encode(tx) @@ -469,12 +469,12 @@ func (tx *Transaction) Sign(ty int32, priv crypto.PrivKey) { } } -//CheckSign tx 有些时候是一个交易组 +// CheckSign tx 有些时候是一个交易组 func (tx *Transaction) CheckSign(blockHeight int64) bool { return tx.checkSign(blockHeight) } -//txgroup 的情况 +// txgroup 的情况 func (tx *Transaction) checkSign(blockHeight int64) bool { copytx := CloneTx(tx) copytx.Signature = nil @@ -486,7 +486,7 @@ func (tx *Transaction) checkSign(blockHeight int64) bool { return CheckSign(data, string(tx.Execer), tx.GetSignature(), blockHeight) } -//Check 交易检测 +// Check 交易检测 func (tx *Transaction) Check(cfg *Chain33Config, height, minfee, maxFee int64) error { group, err := tx.GetTxGroup() if err != nil { @@ -521,7 +521,7 @@ func (tx *Transaction) check(cfg *Chain33Config, height, minfee, maxFee int64) e return nil } -//SetExpire 设置交易过期时间 +// SetExpire 设置交易过期时间 func (tx *Transaction) SetExpire(cfg *Chain33Config, expire time.Duration) { //Txheight处理 if cfg.IsEnable("TxHeight") && int64(expire) > TxHeightFlag { @@ -540,7 +540,7 @@ func (tx *Transaction) SetExpire(cfg *Chain33Config, expire time.Duration) { } } -//GetRealFee 获取交易真实费用 +// GetRealFee 获取交易真实费用 func (tx *Transaction) GetRealFee(minFee int64) (int64, error) { txSize := Size(tx) //如果签名为空,那么加上签名的空间 @@ -555,7 +555,7 @@ func (tx *Transaction) GetRealFee(minFee int64) (int64, error) { return realFee, nil } -//SetRealFee 设置交易真实费用 +// SetRealFee 设置交易真实费用 func (tx *Transaction) SetRealFee(minFee int64) error { if tx.Fee == 0 { fee, err := tx.GetRealFee(minFee) @@ -567,10 +567,10 @@ func (tx *Transaction) SetRealFee(minFee int64) error { return nil } -//ExpireBound 交易过期边界值 +// ExpireBound 交易过期边界值 var ExpireBound int64 = 1000000000 // 交易过期分界线,小于expireBound比较height,大于expireBound比较blockTime -//IsExpire 交易是否过期 +// IsExpire 交易是否过期 func (tx *Transaction) IsExpire(cfg *Chain33Config, height, blocktime int64) bool { group, _ := tx.GetTxGroup() if group == nil { @@ -579,7 +579,7 @@ func (tx *Transaction) IsExpire(cfg *Chain33Config, height, blocktime int64) boo return group.IsExpire(cfg, height, blocktime) } -//GetTxFee 获取交易的费用,区分单笔交易和交易组 +// GetTxFee 获取交易的费用,区分单笔交易和交易组 func (tx *Transaction) GetTxFee() int64 { group, _ := tx.GetTxGroup() if group == nil || len(group.GetTxs()) == 0 { @@ -588,13 +588,13 @@ func (tx *Transaction) GetTxFee() int64 { return group.Txs[0].Fee } -//From 交易from地址 +// From 交易from地址 func (tx *Transaction) From() string { return address.PubKeyToAddr(ExtractAddressID(tx.GetSignature().GetTy()), tx.GetSignature().GetPubkey()) } -//检查交易是否过期,过期返回true,未过期返回false +// 检查交易是否过期,过期返回true,未过期返回false func (tx *Transaction) isExpire(cfg *Chain33Config, height, blocktime int64) bool { valid := tx.Expire // Expire为0,返回false @@ -616,7 +616,7 @@ func (tx *Transaction) isExpire(cfg *Chain33Config, height, blocktime int64) boo return valid <= blocktime } -//GetTxHeight 获取交易高度 +// GetTxHeight 获取交易高度 func GetTxHeight(cfg *Chain33Config, valid int64, height int64) int64 { if cfg.IsPara() { return -1 @@ -627,7 +627,7 @@ func GetTxHeight(cfg *Chain33Config, valid int64, height int64) int64 { return -1 } -//JSON Transaction交易信息转成json结构体 +// JSON Transaction交易信息转成json结构体 func (tx *Transaction) JSON() string { type transaction struct { Hash string `json:"hash,omitempty"` @@ -667,7 +667,7 @@ func (tx *Transaction) JSON() string { return string(data) } -//Amount 解析tx的payload获取amount值 +// Amount 解析tx的payload获取amount值 func (tx *Transaction) Amount() (int64, error) { // TODO 原来有很多执行器 在这里没有代码, 用默认 0, nil 先 exec := LoadExecutorType(string(tx.Execer)) @@ -677,7 +677,7 @@ func (tx *Transaction) Amount() (int64, error) { return exec.Amount(tx) } -//Assets 获取交易中的资产 +// Assets 获取交易中的资产 func (tx *Transaction) Assets() ([]*Asset, error) { exec := LoadExecutorType(string(tx.Execer)) if exec == nil { @@ -686,7 +686,7 @@ func (tx *Transaction) Assets() ([]*Asset, error) { return exec.GetAssets(tx) } -//GetRealToAddr 解析tx的payload获取real to值 +// GetRealToAddr 解析tx的payload获取real to值 func (tx *Transaction) GetRealToAddr() string { exec := LoadExecutorType(string(tx.Execer)) if exec == nil { @@ -695,7 +695,7 @@ func (tx *Transaction) GetRealToAddr() string { return exec.GetRealToAddr(tx) } -//GetViewFromToAddr 解析tx的payload获取view from to 值 +// GetViewFromToAddr 解析tx的payload获取view from to 值 func (tx *Transaction) GetViewFromToAddr() (string, string) { exec := LoadExecutorType(string(tx.Execer)) if exec == nil { @@ -704,7 +704,7 @@ func (tx *Transaction) GetViewFromToAddr() (string, string) { return exec.GetViewFromToAddr(tx) } -//ActionName 获取tx交易的Actionname +// ActionName 获取tx交易的Actionname func (tx *Transaction) ActionName() string { execName := string(tx.Execer) exec := LoadExecutorType(execName) @@ -719,7 +719,7 @@ func (tx *Transaction) ActionName() string { return exec.ActionName(tx) } -//IsWithdraw 判断交易是withdraw交易,需要做from和to地址的swap,方便上层客户理解 +// IsWithdraw 判断交易是withdraw交易,需要做from和to地址的swap,方便上层客户理解 func (tx *Transaction) IsWithdraw(coinExec string) bool { if bytes.Equal(tx.GetExecer(), []byte(coinExec)) || bytes.Equal(tx.GetExecer(), bToken) { if tx.ActionName() == withdraw { @@ -763,7 +763,7 @@ func ParseExpire(expire string) (int64, error) { return 0, err } -//CalcTxShortHash 取txhash的前指定字节,目前默认5 +// CalcTxShortHash 取txhash的前指定字节,目前默认5 func CalcTxShortHash(hash []byte) string { if len(hash) >= 5 { return hex.EncodeToString(hash[0:5]) @@ -771,9 +771,9 @@ func CalcTxShortHash(hash []byte) string { return "" } -//TransactionSort 对主链以及平行链交易分类 -//构造一个map用于临时存储各个子链的交易, 按照title分类,主链交易的title设置成main -//并对map按照title进行排序,不然每次遍历map顺序会不一致 +// TransactionSort 对主链以及平行链交易分类 +// 构造一个map用于临时存储各个子链的交易, 按照title分类,主链交易的title设置成main +// 并对map按照title进行排序,不然每次遍历map顺序会不一致 func TransactionSort(rawtxs []*Transaction) []*Transaction { txMap := make(map[string]*Transactions) @@ -837,7 +837,7 @@ func resetTx(tx *Transaction) { *tx = Transaction{} } -//Hash 交易的hash不包含header的值,引入tx group的概念后,做了修改 +// Hash 交易的hash不包含header的值,引入tx group的概念后,做了修改 func (tx *Transaction) Hash() []byte { copytx := CloneTx(tx) copytx.Signature = nil @@ -851,7 +851,7 @@ func (tx *Transaction) Hash() []byte { return hash } -//FullHash 交易的fullhash包含交易的签名信息 +// FullHash 交易的fullhash包含交易的签名信息 func (tx *Transaction) FullHash() []byte { copytx := tx.Clone() buffer := txProtoBufferPool.Get().(*proto.Buffer) @@ -863,16 +863,16 @@ func (tx *Transaction) FullHash() []byte { return hash } -//TxGroup 交易组的接口,Transactions 和 Transaction 都符合这个接口 +// TxGroup 交易组的接口,Transactions 和 Transaction 都符合这个接口 type TxGroup interface { Tx() *Transaction GetTxGroup() (*Transactions, error) CheckSign(blockHeight int64) bool } -//CloneTx clone tx -//这里要避免用 tmp := *tx 这样就会读 可能被 proto 其他线程修改的 size 字段 -//proto buffer 字段发生更改之后,一定要修改这里,否则可能引起严重的bug +// CloneTx clone tx +// 这里要避免用 tmp := *tx 这样就会读 可能被 proto 其他线程修改的 size 字段 +// proto buffer 字段发生更改之后,一定要修改这里,否则可能引起严重的bug func CloneTx(tx *Transaction) *Transaction { copytx := NewTx() copytx.Execer = tx.Execer @@ -889,7 +889,7 @@ func CloneTx(tx *Transaction) *Transaction { return copytx } -//Clone copytx := proto.Clone(tx).(*Transaction) too slow +// Clone copytx := proto.Clone(tx).(*Transaction) too slow func (tx *Transaction) Clone() *Transaction { if tx == nil { return nil @@ -899,7 +899,7 @@ func (tx *Transaction) Clone() *Transaction { return tmp } -//GetEthTxHash 获取eth 兼容交易的交易哈希 +// GetEthTxHash 获取eth 兼容交易的交易哈希 func (tx *Transaction) GetEthTxHash() []byte { if !IsEthSignID(tx.GetSignature().GetTy()) { return nil @@ -917,7 +917,7 @@ func (tx *Transaction) GetEthTxHash() []byte { return nil } -//cloneTxs 拷贝 txs +// cloneTxs 拷贝 txs func cloneTxs(b []*Transaction) []*Transaction { if b == nil { return nil