TxList 解读
本文旨在分析清楚 tx_list.go 中这个工具包里面的重要代码
堆排序
以下为tx_list.go中的heap.Interface的全部实现代码,非常标准,和默认的一样;
1 | //heap的整个实现过程 |
以下展示heap.Interface的结构:
1 | type Interface interface { |
其中sort.Interface这个接口里包含Len() Less() Swap()这三个方法,也就是对应上面的前三个方法;
加上后面的Push() Pop()两个方法,也就是我们实现了heap.Interface这个接口;
然后我们就可以使用heap包里面的相关功能性函数(因为他们的参数要求基本上都包含heap.Interface这个接口),heap包代码量非常少,算上注释才一百多行,很容易也推荐看完;
在这里附上一段试验的源码以供参考:
1 | package main |
函数功能解析
txSortedMap
具体的结构如下:
1 | type txSortedMap struct { |
以下为其对应的所有方法:
-
newTxSortedMap()进行初始化并返回初始化后的*txSortedMap -
Get(nonce uint64)获取指定nonce的交易并返回该笔交易 -
Put(tx *types.transaction)将该笔交易该笔交易添加到txSortedMap中,无论之前是否存在 -
Foward(threshold uint64)将低于这个门槛的nonce的交易全部剔除 -
reheap()根据当前的map重新进行nonceheap的排序 -
filter(filter func(*types.Transaction) bool)其中的参数filter func(*types.Transaction) bool)它的源码是
func(tx *types.Transaction) bool { return tx.Nonce() > lowest }我们可以发现该函数的作用其实为了过滤
nonce小于最低要求的交易,而Filter(filter func(*types.Transaction) bool)调用了以上的函数,所以功能差不多 -
Cap(threshold int)如果该map中的交易数量超过了限制,就删除最高nonce的交易直至数量达到要求,并返回删除掉的drops -
Remove(nonce uint64)删除成功则返回true,没有找到就返回false -
Ready(start uint64)准备好nonce高于start并且连续的交易 -
Len()返回map的大小 -
Flatten()获取全部的交易,flatten()将全部按照nonce排序好的交易进行缓存 -
LastElement()返回cashe中nonce值最高的交易
txList
具体结构如下:
1 | type txList struct { |
重要函数如下:
Overlaps(tx *types.Transaction)若是已有这笔交易就返回true,否则返回falseAdd(tx *types.Transaction,priceBump uint64)若是已有这笔交易就尝试加入,不存在就直接加入,返回交易true oldFilter(costLimit *big.Int,gasLimit uint64)过滤掉拥有过高的cost或者gas的交易,同时过滤掉后面nonce不连续的交易Remove(tx *types.Transaction)尝试移除掉指定的交易并移除后面nonce值不连续的交易
priceHeap
具体结构如下:
1 | type priceHeap struct { |
实现了heap.Interface这个接口,排序方式是先比较gasFee,再之tipFee
txPricedList
具体结构如下:
1 | type txPricedList struct { |
首先提一下,本部分源码中大量使用了原子操作,Go语言中提供的原子操作都是非侵入式的,在标准库代码包sync/atomic中提供了相关的原子函数,具体功能如下:
原子操作即是进行过程中不能被中断的操作,针对某个值的原子操作在被进行的过程中,CPU 绝不会再去进行其他的针对该值的操作。为了实现这样的严谨性,原子操作仅会由一个独立的 CPU 指令代表和完成。原子操作是无锁的,常常直接通过 CPU 指令直接实现。 事实上,其它同步技术的实现常常依赖于原子操作。
现在理解不来为何 priceHeap里要有urgent 和 floating这两个 ,(注意:应该是新增的,网上找不到资料;)





