Skip to content

Commit

Permalink
Merge pull request #3912 from planetarium/exp/dpos-sloth
Browse files Browse the repository at this point in the history
Preparation for PoS
  • Loading branch information
s2quake authored Oct 22, 2024
2 parents 68d8f42 + d65ff91 commit 2b8189d
Show file tree
Hide file tree
Showing 33 changed files with 510 additions and 482 deletions.
17 changes: 17 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ To be released.

### Backward-incompatible API changes

- (Libplanet.Action) Added `MaxGasPrice` property to `IActionContext`
interface and its implementations. [[#3912]]
- (Libplanet.Explorer) Added `self` field to `NoteStateType`. [[#3912]]
- (Libplanet.Action) Removed `IFeeCollector` interface
and its implementations. [[#3912]]
- (Libplanet.Action) Removed following methods from the
`IActionContext` interface. [[#3912]]
- Removed `IActionContext.UseGas(long)`.
- Removed `IActionContext.GasUsed()`.
- Removed `IActionContext.GasLimit()`.
- (Libplanet.Action) Added `GasTracer` static class. [[#3912]]
- (Libplanet.Action) Added `LastCommit` property to `IActionContext`
interface and its implementations. [[#3912]]


### Backward-incompatible network protocol changes

### Backward-incompatible storage format changes
Expand All @@ -24,6 +39,8 @@ To be released.

### CLI tools

[#3912]: https://github.com/planetarium/libplanet/pull/3912


Version 5.3.1
-------------
Expand Down
57 changes: 14 additions & 43 deletions src/Libplanet.Action/ActionContext.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using System.Diagnostics.Contracts;
using Libplanet.Action.State;
using Libplanet.Crypto;
using Libplanet.Types.Assets;
using Libplanet.Types.Blocks;
using Libplanet.Types.Evidence;
using Libplanet.Types.Tx;

namespace Libplanet.Action
{
internal class ActionContext : IActionContext
{
public static readonly AsyncLocal<GasMeter> GetGasMeter = new AsyncLocal<GasMeter>();

private readonly long _gasLimit;

private readonly IReadOnlyList<ITransaction> _txs;

public ActionContext(
Expand All @@ -23,10 +20,11 @@ public ActionContext(
Address miner,
long blockIndex,
int blockProtocolVersion,
BlockCommit? lastCommit,
IWorld previousState,
int randomSeed,
bool isPolicyAction,
long gasLimit,
FungibleAssetValue? maxGasPrice,
IReadOnlyList<ITransaction>? txs = null,
IReadOnlyList<EvidenceBase>? evidence = null)
{
Expand All @@ -35,14 +33,13 @@ public ActionContext(
Miner = miner;
BlockIndex = blockIndex;
BlockProtocolVersion = blockProtocolVersion;
LastCommit = lastCommit;
PreviousState = previousState;
RandomSeed = randomSeed;
IsPolicyAction = isPolicyAction;
_gasLimit = gasLimit;
MaxGasPrice = maxGasPrice;
_txs = txs ?? ImmutableList<Transaction>.Empty;
Evidence = evidence ?? ImmutableList<EvidenceBase>.Empty;

GetGasMeter.Value = new GasMeter(_gasLimit);
}

/// <inheritdoc cref="IActionContext.Signer"/>
Expand All @@ -60,6 +57,9 @@ public ActionContext(
/// <inheritdoc cref="IActionContext.BlockProtocolVersion"/>
public int BlockProtocolVersion { get; }

/// <inheritdoc cref="IActionContext.LastCommit"/>
public BlockCommit? LastCommit { get; }

/// <inheritdoc cref="IActionContext.PreviousState"/>
public IWorld PreviousState { get; }

Expand All @@ -69,6 +69,10 @@ public ActionContext(
/// <inheritdoc cref="IActionContext.IsPolicyAction"/>
public bool IsPolicyAction { get; }

/// <inheritdoc cref="IActionContext.MaxGasPrice"/>
[Pure]
public FungibleAssetValue? MaxGasPrice { get; }

/// <inheritdoc cref="IActionContext.Txs"/>
public IReadOnlyList<ITransaction> Txs => IsPolicyAction
? _txs
Expand All @@ -77,40 +81,7 @@ public ActionContext(
/// <inheritdoc cref="IActionContext.Evidence"/>
public IReadOnlyList<EvidenceBase> Evidence { get; }

/// <inheritdoc cref="IActionContext.UseGas(long)"/>
public void UseGas(long gas) => GetGasMeter.Value?.UseGas(gas);

/// <inheritdoc cref="IActionContext.GetRandom"/>
public IRandom GetRandom() => new Random(RandomSeed);

/// <summary>
/// Returns the elapsed gas of the current action.
/// </summary>
/// <returns>
/// The elapsed gas of the current action.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown when <see cref="GetGasMeter"/> is not initialized.
/// </exception>
public long GasUsed()
{
if (GetGasMeter.Value is { } gasMeter)
{
return gasMeter.GasUsed;
}

throw new InvalidOperationException($"{nameof(GetGasMeter)} is not initialized.");
}

/// <summary>
/// Returns the gas limit of the current action.
/// </summary>
/// <returns>
/// The gas limit of the current action.
/// </returns>
public long GasLimit()
{
return _gasLimit;
}
}
}
37 changes: 16 additions & 21 deletions src/Libplanet.Action/ActionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,34 +207,32 @@ internal static IEnumerable<ActionEvaluation> EvaluateActions(
{
IActionContext CreateActionContext(
IWorld prevState,
int randomSeed,
long actionGasLimit)
int randomSeed)
{
return new ActionContext(
signer: tx?.Signer ?? block.Miner,
txid: tx?.Id ?? null,
miner: block.Miner,
blockIndex: block.Index,
blockProtocolVersion: block.ProtocolVersion,
lastCommit: block.LastCommit,
txs: block.Transactions,
previousState: prevState,
isPolicyAction: isPolicyAction,
randomSeed: randomSeed,
gasLimit: actionGasLimit,
maxGasPrice: tx?.MaxGasPrice,
evidence: block.Evidence);
}

long gasLimit = tx?.GasLimit ?? long.MaxValue;

byte[] preEvaluationHashBytes = block.PreEvaluationHash.ToByteArray();
byte[] signature = tx?.Signature ?? Array.Empty<byte>();
int seed = GenerateRandomSeed(preEvaluationHashBytes, signature, 0);

IWorld state = previousState;
foreach (IAction action in actions)
{
IActionContext context = CreateActionContext(state, seed, gasLimit);
(ActionEvaluation Evaluation, long NextGasLimit) result = EvaluateAction(
IActionContext context = CreateActionContext(state, seed);
ActionEvaluation evaluation = EvaluateAction(
block,
tx,
context,
Expand All @@ -243,10 +241,9 @@ IActionContext CreateActionContext(
isPolicyAction,
logger);

yield return result.Evaluation;
yield return evaluation;

state = result.Evaluation.OutputState;
gasLimit = result.NextGasLimit;
state = evaluation.OutputState;

unchecked
{
Expand All @@ -255,7 +252,7 @@ IActionContext CreateActionContext(
}
}

internal static (ActionEvaluation Evaluation, long NextGasLimit) EvaluateAction(
internal static ActionEvaluation EvaluateAction(
IPreEvaluationBlock block,
ITransaction? tx,
IActionContext context,
Expand All @@ -274,7 +271,6 @@ internal static (ActionEvaluation Evaluation, long NextGasLimit) EvaluateAction(
IActionContext inputContext = context;
IWorld state = inputContext.PreviousState;
Exception? exc = null;
IFeeCollector feeCollector = new FeeCollector(context, tx?.MaxGasPrice);

IActionContext CreateActionContext(IWorld newPrevState)
{
Expand All @@ -284,10 +280,11 @@ IActionContext CreateActionContext(IWorld newPrevState)
miner: inputContext.Miner,
blockIndex: inputContext.BlockIndex,
blockProtocolVersion: inputContext.BlockProtocolVersion,
lastCommit: inputContext.LastCommit,
previousState: newPrevState,
randomSeed: inputContext.RandomSeed,
isPolicyAction: isPolicyAction,
gasLimit: inputContext.GasLimit(),
maxGasPrice: tx?.MaxGasPrice,
txs: inputContext.Txs,
evidence: inputContext.Evidence);
}
Expand All @@ -297,9 +294,7 @@ IActionContext CreateActionContext(IWorld newPrevState)
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
AccountMetrics.Initialize();
state = feeCollector.Mortgage(state);
context = CreateActionContext(state);
feeCollector = feeCollector.Next(context);
state = action.Execute(context);
logger?
.ForContext("Tag", "Metric")
Expand Down Expand Up @@ -361,8 +356,6 @@ IActionContext CreateActionContext(IWorld newPrevState)
e);
}

state = feeCollector.Refund(state);
state = feeCollector.Reward(state);
state = stateStore.CommitWorld(state);

if (!state.Trie.Recorded)
Expand All @@ -371,13 +364,11 @@ IActionContext CreateActionContext(IWorld newPrevState)
$"Failed to record {nameof(IAccount)}'s {nameof(ITrie)}.");
}

return (
new ActionEvaluation(
return new ActionEvaluation(
action: action,
inputContext: inputContext,
outputState: state,
exception: exc),
context.GasLimit() - context.GasUsed());
exception: exc);
}

/// <summary>
Expand Down Expand Up @@ -479,6 +470,8 @@ internal IEnumerable<ActionEvaluation> EvaluateTx(
ITransaction tx,
IWorld previousState)
{
GasTracer.Initialize(tx.GasLimit ?? long.MaxValue);
GasTracer.StartTrace();
var evaluations = ImmutableList<ActionEvaluation>.Empty;
if (_policyActionsRegistry.BeginTxActions.Length > 0)
{
Expand Down Expand Up @@ -507,6 +500,8 @@ internal IEnumerable<ActionEvaluation> EvaluateTx(
EvaluatePolicyEndTxActions(block, tx, previousState));
}

GasTracer.EndTrace();

return evaluations;
}

Expand Down
Loading

0 comments on commit 2b8189d

Please sign in to comment.