- ethash 합의 알고리즘에서 Miner가 Gas 보상을 받을 때 트랜잭션 Pool과 어떤 영향이 있는지를 파악한다
Mining에 대한 보상처리
- worker에서 block 생성에 대한 최종 처리를 위한 단계에서 보상을 받게 됨
- consensus.go의 accumulateRewards func에서 처리
- 블록을 확정하는 Finalize에서만 호출, 그 외 로직에선 호출되지 않음
var (
FrontierBlockReward *big.Int = big.NewInt(5e+18)
ByzantiumBlockReward *big.Int = big.NewInt(3e+18)
...
blockReward := FrontierBlockReward
if config.IsByzantium(header.Number) {
blockReward = ByzantiumBlockReward
}
// Accumulate the rewards for the miner and any included uncles
reward := new(big.Int).Set(blockReward)
r := new(big.Int)
for _, uncle := range uncles {
r.Add(uncle.Number, big8)
r.Sub(r, header.Number)
r.Mul(r, blockReward)
r.Div(r, big8)
state.AddBalance(uncle.Coinbase, r)
r.Div(blockReward, big32)
reward.Add(reward, r)
}
state.AddBalance(header.Coinbase, reward)
- default로 세팅된 blockReward값에 uncle이 있다면 uncle에 대한 보상까지 포함
- blockReward는 비잔틴 하드포크이냐에 따라 다름
- Uncle 보상 = (Uncle Number + 8 - Block Number) * blockReward / 8
- 로직에선 엉클을 별개로 체크하지 않고 for문으로 모든 엉클에 대한 보상 처리
- Finalize 전에 badUncle을 필터링해주고 있기 때문
- 여기까지만 봤을땐 Pool과는 연관이 없음
트랜잭션 실행에 대한 보상처리
- worker에서 TxPool에 있는 pending 트랜잭션들을 가져와 실행 후 보상을 받게 됨
- state_transition.go의 TransitionDb func에서 evm.Create 또는 evm.Call 실행 후 refundGas 및 AddBalance 에서 보상 처리
- 트랜잭션 실행할때 StateTransition을 만들어 실행하는데 여기서 가스 데이터들을 세팅하고 충전, 차감을 진행함
- StateTransition struct
- gp \*GasPool
- commitTransactions에서 현 chain의 header의 GasLimit으로 init
- 트랜잭션 실행 전 buyGas Func에서 Message의 Gas만큼 차감
- 트랜잭션 실행 후 refundGas에서 사용한 만큼의 절반을 다시 충전 (st.initialGas - st.gas) / 2
- gas uint64
- 트랜잭션 실행 전 buyGas Func에서 Message의 Gas만큼 누적
- 트랜잭션 실행 전 useGas Func에서 컨트랙트의 Data만큼의 Gas를 측정하여 그 값을 차감
- 해당 값은 IntrinsicGas에서 Data의 byte length와 default 데이터 Gas 값을 토대로 측정
- 트랜잭션이 실행되는 동안 Interpreter에서 코드를 Run하는 동안 컨트랙트의 Gas를 차감하여 사용한만큼 차감되고 남은 가스를 다시 추가해주는 방식
- 트랜잭션 실행 후 refundGas에서 사용한 만큼의 절반을 다시 충전 (st.initialGas - st.gas) / 2
- gasPrice \*big.Int
- StateTransition을 생성할때 Message의 GasPrice로 init
- initialGas uint64
- 트랜잭션 실행 전 buyGas Func에서 Message의 Gas로 init
- 결국 GasPool과 StateTransition의 Gas 데이터는 트랜잭션을 일일이 실행할때 GasLimit을 체크하여 실행할수 있게 설정된 값들인걸 알수 있음
그외 Gas, Pool과 관련된 Struct
SendTxArgs struct
- Gas
- 처음 세팅되는 Gas 한도값
- nil인 경우 setDefaults에서 90000으로 세팅됨
- GasPrice
- 처음 세팅되는 Gas의 가격값
- nil인 경우 setDefaults에서 세팅, 최신 블록에서의 가장 낮은 단가의 트랜잭션으로 계산
Transaction struct
- data = txdata struct
- Price
- NewTransaction OR NewContractCreation에서 SendTxArgs의 GasPrice 값으로 세팅
- GasLimit
- NewTransaction OR NewContractCreation에서 SendTxArgs의 Gas 값으로 세팅