go ethereum源码分析 PartIV Transaction相关
核心数据结构:
core.types.transaction.go
type Transaction struct { data txdata // caches hash atomic.Value size atomic.Value from atomic.Value }
Transaction.data
type txdata struct { AccountNonce uint64 `json:"nonce" gencodec:"required"` Price *big.Int `json:"gasPrice" gencodec:"required"` GasLimit uint64 `json:"gas" gencodec:"required"` Recipient *common.Address `json:"to" rlp:"nil"` // nil means contract creation Amount *big.Int `json:"value" gencodec:"required"` Payload []byte `json:"input" gencodec:"required"` // Signature values V *big.Int `json:"v" gencodec:"required"` R *big.Int `json:"r" gencodec:"required"` S *big.Int `json:"s" gencodec:"required"` // This is only used when marshaling to JSON. Hash *common.Hash `json:"hash" rlp:"-"` }
辅助数据结构
core/tx_list.go
txList
type txList struct {
//nonces是否严格递增 strict bool // Whether nonces are strictly continuous or not
txs *txSortedMap // Heap indexed sorted hash map of the transactions //costing最高的会话的价格(只有当超过balance时才重置) costcap *big.Int // Price of the highest costing transaction (reset only if exceeds balance) //spending最高的会话的gas limit
gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) }
txList.txs txSortedMap
// txSortedMap is a nonce->transaction hash map with a heap based index to allow // iterating over the contents in a nonce-incrementing way. type txSortedMap struct { items map[uint64]*types.Transaction // Hash map storing the transaction data index *nonceHeap // Heap of nonces of all the stored transactions (non-strict mode) cache types.Transactions // Cache of the transactions already sorted }
txSortedMap.index nonceHeap
type nonceHeap []uint64
类似的结构,txPricedList
// txPricedList is a price-sorted heap to allow operating on transactions pool // contents in a price-incrementing way. type txPricedList struct { all *txLookup // Pointer to the map of all transactions items *priceHeap // Heap of prices of all the stored transactions stales int // Number of stale price points to (re-heap trigger) }
tx.PricedList.items priceHeap,令人有点吃惊,不够对称
type priceHeap []*types.Transaction
在tx_list.go中需要分析两个数据结构,1. txList, 2. txPricedList
调用到tx_list.go的主要是tx_pool.go
tx_pool.go的主要数据结构是txPool,
txPool中包含目前已知的所有会话。会话上传到blockchain上的时候就会离开会话池。
// TxPool contains all currently known transactions. Transactions // enter the pool when they are received from the network or submitted // locally. They exit the pool when they are included in the blockchain. // // The pool separates processable transactions (which can be applied to the // current state) and future transactions. Transactions move between those // two states over time as they are received and processed.
//TxPool包含目前所有已知的会话,会话直接从本地提交,或者从网络传送过来之后,紧接着就进入池中
//会话被上传到blockchain的时候就会离开会话池
//会话池将processable的会话(可处理的会话)与future会话(未来的会话)分开。
//会话收发的过程中就不断在这两种状态之见切换 type TxPool struct { config TxPoolConfig chainconfig *params.ChainConfig//有专用的ChainConfig chain blockChain gasPrice *big.Int txFeed event.Feed scope event.SubscriptionScope chainHeadCh chan ChainHeadEvent chainHeadSub event.Subscription signer types.Signer mu sync.RWMutex //blockchain头节点的状态-currentState currentState *state.StateDB // Current state in the blockchain head pendingState *state.ManagedState // Pending state tracking virtual nonces //目前会话的gasLimit,有待具体确认
currentMaxGas uint64 // Current gas limit for transaction caps
locals *accountSet // Set of local transaction to exempt from eviction rules journal *txJournal // Journal of local transaction to back up to disk //可处理的 pending map[common.Address]*txList // All currently processable transactions //排着队的但是还没处理的
queue map[common.Address]*txList // Queued but non-processable transactions //最后的波纹,啊不,临近节点的心跳
beats map[common.Address]time.Time // Last heartbeat from each known account // all,有可能与txPricedList的all是同一个实例
all *txLookup // All transactions to allow lookups priced *txPricedList // All transactions sorted by price //for shutdown wg sync.WaitGroup // for shutdown sync homestead bool }
PoolConfig可以设定的内容以及默认参数
// TxPoolConfig are the configuration parameters of the transaction pool. type TxPoolConfig struct { Locals []common.Address // Addresses that should be treated by default as local NoLocals bool // Whether local transaction handling should be disabled Journal string // Journal of local transactions to survive node restarts Rejournal time.Duration // Time interval to regenerate the local transaction journal PriceLimit uint64 // Minimum gas price to enforce for acceptance into the pool PriceBump uint64 // Minimum price bump percentage to replace an already existing transaction (nonce) AccountSlots uint64 // Number of executable transaction slots guaranteed per account GlobalSlots uint64 // Maximum number of executable transaction slots for all accounts AccountQueue uint64 // Maximum number of non-executable transaction slots permitted per account GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts Lifetime time.Duration // Maximum amount of time non-executable transaction are queued } // DefaultTxPoolConfig contains the default configurations for the transaction // pool. var DefaultTxPoolConfig = TxPoolConfig{ Journal: "transactions.rlp", Rejournal: time.Hour, PriceLimit: 1, PriceBump: 10, AccountSlots: 16, GlobalSlots: 4096, AccountQueue: 64, GlobalQueue: 1024, Lifetime: 3 * time.Hour, }
ChainConfig-区块链的核心设置
// ChainConfig is the core config which determines the blockchain settings. // // ChainConfig is stored in the database on a per block basis. This means // that any network, identified by its genesis block, can have its own // set of configuration options. type ChainConfig struct { ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` }
// EthashConfig is the consensus engine configs for proof-of-work based sealing. type EthashConfig struct{}
// CliqueConfig is the consensus engine configs for proof-of-authority based sealing. type CliqueConfig struct { Period uint64 `json:"period"` // Number of seconds between blocks to enforce Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint }
BlockChain的定义,主要是起索引
type blockChain interface { CurrentBlock() *types.Block GetBlock(hash common.Hash, number uint64) *types.Block StateAt(root common.Hash) (*state.StateDB, error) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription }
状态DB的定义
// StateDBs within the ethereum protocol are used to store anything // within the merkle trie. StateDBs take care of caching and storing // nested states. It's the general query interface to retrieve: // * Contracts // * Accounts type StateDB struct { db Database trie Trie // This map holds 'live' objects, which will get modified while processing a state transition. stateObjects map[common.Address]*stateObject stateObjectsDirty map[common.Address]struct{} // DB error. // State objects are used by the consensus core and VM which are // unable to deal with database-level errors. Any error that occurs // during a database read is memoized here and will eventually be returned // by StateDB.Commit. dbErr error // The refund counter, also used by state transitioning. refund uint64 thash, bhash common.Hash txIndex int logs map[common.Hash][]*types.Log logSize uint preimages map[common.Hash][]byte // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. journal *journal validRevisions []revision nextRevisionId int }
ManagedState定义,比普通的StateDB多了accounts的管理
type ManagedState struct { *StateDB mu sync.RWMutex accounts map[common.Address]*account }
type account struct {
stateObject *stateObject
nstart uint64
nonces []bool
}
tx_pool.go中的主要逻辑