先看一下 tendermint 供应的接口:
tendermint 接口
这里面我们提交交易紧张有两个接口:broadcast_tx_commit, broadcast_tx_sync, broadcast_tx_async。个中 sync 的接口返回的是当前交易的 check 的结果(不是 deliver 结果),async 接口返回的是当前交易的 hash,之后我们可以利用这个 hash 值去查询这笔交易的实行结果。commit 接口返回的是交易的终极结果,也便是 deliver 的结果,但是利用 commit 接口 tendermint 默认的 deliver 的超时时间是两分钟,也便是说,如果你发送的交易须要很永劫光才可以实行完,那么我们最好利用 async 的接口,但是如果只是一笔大略的转账交易,我们利用 commit 是没有问题的,由于这个过程是很快的。

当我们把一笔交易通过 commit 接口发送给 tendermint 之后,tendermint 是如何处理的呢?下面是我自己画的一个大略的过程:
交易 check 流程
针对一笔交易,我们的 check 的流程基本上便是上图这样,至于 deliver 与共识过程往后文章再聊。
tendermint 中很多事宜都是订阅发布模式,例如一笔交易,我们可以打算出唯一的 hash 值,那么对付这笔交易的实行结果我们可以去订阅,订阅之后我们会收到一个 channel,当交易实行结束后,就可以从这个 channel 中收到结果。
mempool 初始化时,state 共识部分创建一个 goroutine: receiveRoutine,这里面会监听一个 channel,浸染便是关照当前 mempool 中有交易可以去 deliver。当我们知道有交易后,就会进行其他操作。
go 措辞中函数是一等公民,tendermint 中很多地方也利用了回调函数,在一笔交易 check 后,会调用其事先设置好的回调函数,这样就很方便的实现了可插拔的特性。
末了我们再看一下 mempool 的构造:
type Mempool struct { config cfg.MempoolConfig proxyMtx sync.Mutex proxyAppConn proxy.AppConnMempool txs clist.CList // concurrent linked-list of good txs preCheck PreCheckFunc postCheck PostCheckFunc // Track whether we're rechecking txs. // These are not protected by a mutex and are expected to be mutated // in serial (ie. by abci responses which are called in serial). recheckCursor clist.CElement // next expected response recheckEnd clist.CElement // re-checking stops here // notify listeners (ie. consensus) when txs are available notifiedTxsAvailable bool txsAvailable chan struct{} // fires once for each height, when the mempool is not empty // Map for quick access to txs to record sender in CheckTx. // txsMap: txKey -> CElement txsMap sync.Map // Atomic integers height int64 // the last block Update()'d to rechecking int32 // for re-checking filtered txs on Update() txsBytes int64 // total size of mempool, in bytes // Keep a cache of already-seen txs. // This reduces the pressure on the proxyApp. cache txCache // A log of mempool txs wal auto.AutoFile logger log.Logger metrics Metrics}
txsAvailable 便是用来关照有 check 通过的交易的 channel,tx 中便是mempool 中的交易。preCheck 和 postCheck 是两个回调用函数。proxyAppConn 是我们自己的 app 的代理,卖力把交易发送过去。
这里面我们阅读源码第一理解 tendermint 的处理流程,第二是学习其编码优点,例如这里面的 回调函数,发布订阅模式,这种 mempool 的思想等。多看看著名项目的源码可以学到很多,自己写代码时肯定有帮助。
更多内容可以关注公众年夜众号:Go措辞之美。