Last active
May 4, 2023 10:21
-
-
Save riemannulus/4f213628bba047974e08586a4297e394 to your computer and use it in GitHub Desktop.
Psuedo ActionEvaluator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
IEnumerable<ActionEvaluation> EvaluateBlock(IPreEvaluationBlock block, IAccountStateDelta prevState) | |
{ | |
UInt256 remainingGasPerBlock = block.GasLimit(); | |
IEnumerable<ActionEvaluation> evaluations | |
= ExecuteActions(_beginBlockActions, prevState, remainingGasPerBlock, 0); | |
foreach(ActionEvaluation eval in evaluations) | |
{ | |
yield return eval; | |
prevState = eval.OutputState.UseGas(0); | |
} | |
foreach(ITransaction tx in block.Transactions) | |
{ | |
evaluations = ExecuteTx(tx, prevState, remainingGasPerBlock); | |
foreach(ActionEvaluation eval in evaluations) | |
{ | |
yield return eval; | |
prevState = eval.OutputState; | |
} | |
UInt256 usedGas = evaluations.Select(x => x.OutputStates.GasUsed).Sum(); | |
remainingGasPerBlock -= usedGas; | |
} | |
evaluations = ExecuteActions(_endBlockActions, prevState, remainingGasPerBlock, 0); | |
foreach(ActionEvaluation eval in evaluations) | |
{ | |
yield return eval; | |
prevState = eval.OutputState; | |
} | |
} | |
IEnumerable<ActionEvaluation> EvaluateTx(ITransaction tx, IAccountStateDelta prevState, UInt256 gasLimit, FungibleAssetValue baseGasPrice) | |
{ | |
UInt256 gasLimitPerTransaction = tx.GasLimit(); | |
if(gasLimit < gasLimitPerTransaction) throw InvalidTransaction(); | |
FungibleAssetValue commissionGasPrice = Min(tx.CommissionGasPrice(), tx.MaxGasPrice() - baseGasPrice); | |
FungibleAssetValue gasPrice = commissionGasPrice + baseGasPrice; | |
return EvaluateActions(tx.Actions, prevState, gasLimitPerTransaction, gasPrice); | |
} | |
IEnumerable<ActionEvaluation> EvaluateActions(IImmutableList<IAction> actions, IAccountStateDelta prevState, UInt256 gasLimit, FungibleAssetValue commissionGasPrice, FungibleAssetValue gasPrice) | |
{ | |
foreach(IAction action in actions) | |
{ | |
// Burn reserve fee first for prevent collect minus fee | |
FungibleAssetValue reserveFee = gasPrice * gasLimit; | |
IAccountStateDelta nextState = prevState.BurnAsset(signer, reserveFee); | |
// Execute Action | |
// If gasLimit is less then used gas in action, it throw OutOfGasException | |
ActionContext context = CreateContext(state, seed, gasLimit); | |
nextState = action.Execute(nextState); | |
// Refund unused gas | |
UInt256 unusedGas = gasLimit - nextState.GasUsed(); | |
nextState = nextState.MintAsset(signer, gasPrice * unusedGas); | |
// Calculate gas fee for collect | |
FungibleAssetValue commissionFee = commissionGasPrice * nextState.GasUsed(); | |
FungibleAssetValue totalFee = gasPrice * nextState.GasUsed(); | |
// Collect gas fee | |
// It distribute on next `BeginBlock` timing | |
nextState = nextState.MintAsset(feeCollectPool, commissionFee) | |
// Burn or transfer to community pool | |
// If burn, do nothing | |
// If transfer to community pool, mint to community pool | |
nextState = nextState.MintAsset(communityPool, totalFee - commissionFee) | |
yield return new ActionEvaluation(nextState); | |
// calculate next action gas limit | |
gasLimit = gasLimit - nextState.GasUsed(); | |
// initialize useGas state to 0 | |
prevState = nextState.UseGas(0); | |
} | |
} | |
UInt256 EstimateGas(ITransaction tx, IAccountStateDelta prevState, UInt256 gasLimit, FungibleAssetValue baseGasPrice) | |
{ | |
evaluations = ExecuteTx(tx, prevState, remainingGasPerBlock); | |
foreach(ActionEvaluation eval in evaluations) | |
{ | |
yield return eval; | |
prevState = eval.OutputState; | |
} | |
return evaluations.Select(x => x.OutputStates.GasUsed).Sum(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment