txpool2

package
v1.0.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2020 License: GPL-3.0, GPL-3.0 Imports: 14 Imported by: 0

README

交易池设计思路

结构

TxPool是个单例模式,在其中缓存了正常交易和孤儿交易。

支持的交易类型

支持普通的转账交易、用户合约调用后包含结果的交易,以及系统合约的请求交易。系统合约的完整交易不支持添加到交易池。 用户合约的请求交易能添加,但是不能被打包发现。

正常交易池

里面是有序的Tx,是一个队列和一个堆,所有交易要进入则必须排序。在打包时也是从链表中依次获得Tx。

孤儿交易池

是一个堆。从DAG和TxPool初OrhpanPool外的其他池查找UTXO,如果找不到,则认为是一个孤儿Tx。

用户合约请求池

对用户合约的请求,只支持Request ,不支持FullTx,如果FullTx到来,那么Request会从该池删除,并将FullTx添加到Normal池。

依赖了用户合约请求的交易池

如果一个用户合约请求ReqA添加到了交易池,然后TxB依赖于ReqA,那么在FullTxA还没有到达交易池之前,TxB就存储在这个池

Tx进入交易池的逻辑

AddLocal是添加Tx到交易池的主要函数。Tx在进入交易池后会被封装成TxPoolTx,在其中缓存了:Fee、Status等字段。

  1. 调用Validator检查Tx的状态,如果非法,抛弃;如果是孤儿,直接进入孤儿池。
  2. 对新来的TxA和现有交易池的Tx进行排序,找到TxA对应的位置,并插入。如果没有关联关系,就根据手续费大小,放到对应的优先级位置。
  3. 检查孤儿交易池,看有没有交易是依赖于TxA的,有则将孤儿交易从孤儿池移除,并重复步骤2,3.
TxList

TxList中维护的应该是一个不存在双花的Txs,在加入Tx时,判断是否形成双花,如果形成则拒绝加入。

打包时获得Txs的逻辑

只从正常交易池获得Txs,按队列方式获取,

打包完成或者收到Unit后,更新Tx状态

Unit已打包未稳定

对于普通交易池,打包只是修改状态,不影响队列的变化。将Txs找到后,将状态改为已打包。 对于孤儿交易池,查找有没有Tx是依赖于本Unit的交易的,如果有,而且满足了普通交易的条件,则将孤儿交易从孤儿池删除,并加入到普通池。

  1. 如果传入的Tx在本Pool中找不到:
  • 1.1 判断是否有Tx与这个Tx存在双花的冲突,如果存在,则删除Txpool中的Tx,并将本Tx添加到Pool
  • 1.2 如果没找到冲突交易,则不做任何操作。
Unit已稳定

将该Unit中的所有Txs在正常池和孤儿池中查找,一旦找到,将状态改为删除。并且从队列中移除。 TxPool有定时清理任务,会将状态标记为Discard的,从物理上进行删除。 删除一个Tx包括:

  1. 删除对应的NewUtxo和SpendUTXO
  2. 更新TxList中的root列表
Unit回滚

将该Unit中的所有Txs在正常池和孤儿池中查找,一旦找到,将状态改为未打包。

关于Request和FullTx

Txpool同时支持Request和FullTx的Add,对于用户合约调用,先是将Request添加到交易池,Jury根据Request产生Tx,Tx再次添加到Pool时,原来对于的Request应该被替换。 按理来说系统合约的FullTx不会进入交易池,只有Request进入交易池。

更新交易状态为已打包

如果有ABCDE连续交易,本节点只收到了BCE,现在来了一个Unit包含AB交易,那么在更新状态时, 应该把BC从孤儿池删除,ABC交易放入Normal,然后更新状态Packed,E保持不变。

###关于UTXO的查询 假如我们要发起ReqA,ReqB,ReqC3笔用户合约调用,当发起第二笔时,ReqA未完成,所以ReqB是基于ReqA的,然后再过了一会儿FullTxA来替换了ReqA,然后发起ReqC,我们必须知道ReqB已经把FullTxA的UTXO使用了。

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotFound    = errors.New("txpool: not found")
	ErrDuplicate   = errors.New("txpool: duplicate")
	ErrDoubleSpend = errors.New("txpool: double spend")
	ErrNotSupport  = errors.New("txpool: not support")
)
View Source
var Instance txspool.ITxPool

Functions

This section is empty.

Types

type TxPool

type TxPool struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewTxPool

func NewTxPool(config txspool.TxPoolConfig, cachedb palletcache.ICache, unit txspool.IDag, enableGasFee bool) *TxPool

NewTxPool creates a new transaction pool to gather, sort and filter inbound transactions from the network.

func NewTxPool4DI

func NewTxPool4DI(config txspool.TxPoolConfig, cachedb palletcache.ICache, dag txspool.IDag,
	tokenEngine tokenengine.ITokenEngine, txValidator txspool.IValidator) *TxPool

func (*TxPool) AddLocal

func (pool *TxPool) AddLocal(tx *modules.Transaction) error

支持合约Request,普通FullTx,用户合约FullTx的加入,不支持系统合约FullTx

func (*TxPool) AddRemote

func (pool *TxPool) AddRemote(tx *modules.Transaction) error

func (*TxPool) Clear

func (pool *TxPool) Clear()

func (*TxPool) Content

func (*TxPool) DeleteTx added in v1.0.9

func (pool *TxPool) DeleteTx(hash common.Hash) error

func (*TxPool) DiscardTxs

func (pool *TxPool) DiscardTxs(txs []*modules.Transaction) error

从交易池删除指定的交易

func (*TxPool) GetAddrUtxos

func (pool *TxPool) GetAddrUtxos(addr common.Address, token *modules.Asset) (
	map[modules.OutPoint]*modules.Utxo, error)

func (*TxPool) GetSortedTxs

func (pool *TxPool) GetSortedTxs() ([]*txspool.TxPoolTransaction, error)

func (*TxPool) GetStxoEntry

func (pool *TxPool) GetStxoEntry(outpoint *modules.OutPoint) (*modules.Stxo, error)

func (*TxPool) GetTx

func (pool *TxPool) GetTx(hash common.Hash) (*txspool.TxPoolTransaction, error)

func (*TxPool) GetUnpackedTxsByAddr

func (pool *TxPool) GetUnpackedTxsByAddr(addr common.Address) ([]*txspool.TxPoolTransaction, error)

func (*TxPool) GetUtxoEntry

func (pool *TxPool) GetUtxoEntry(outpoint *modules.OutPoint) (*modules.Utxo, error)

主要用于Validator,不带锁,从Normal,Request和BasedOnReq三个池获取UTXO,而且禁止双花,如果Pool找不到,就去Dag找

func (*TxPool) GetUtxoFromAll

func (pool *TxPool) GetUtxoFromAll(outpoint *modules.OutPoint) (*modules.Utxo, error)

带锁的对外暴露的查询,只查询Pool的所有新UTXO,不查询DAG

func (*TxPool) Orphan added in v1.0.9

func (pool *TxPool) Orphan() ([]*txspool.TxPoolTransaction, error)

func (*TxPool) Packed added in v1.0.9

func (pool *TxPool) Packed() (map[common.Hash][]*txspool.TxPoolTransaction, error)
func (pool *TxPool) GetUnpackedTxs() (map[common.Hash]*txspool.TxPoolTransaction, error) {
	return pool.normals.GetTxsByStatus(txspool.TxPoolTxStatus_Unpacked)
}

func (*TxPool) ResetPendingTxs

func (pool *TxPool) ResetPendingTxs(txs []*modules.Transaction) error

将交易状态改为未打包

func (*TxPool) SetPendingTxs

func (pool *TxPool) SetPendingTxs(unitHash common.Hash, num uint64, txs []*modules.Transaction) error

将交易状态改为已打包

func (*TxPool) Status

func (pool *TxPool) Status() (int, int, int)

基本状态(未打包,已打包,孤儿)

func (*TxPool) Stop

func (pool *TxPool) Stop()

func (*TxPool) SubscribeTxPreEvent

func (pool *TxPool) SubscribeTxPreEvent(ch chan<- modules.TxPreEvent) event.Subscription

SubscribeTxPreEvent registers a subscription of TxPreEvent and starts sending event to the given channel.

func (*TxPool) Unpack added in v1.0.9

func (pool *TxPool) Unpack() ([]*txspool.TxPoolTransaction, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL