Skip to content

Commit

Permalink
Merge pull request #3721 from greymistcube/refactor/dumb-action
Browse files Browse the repository at this point in the history
♻️ Add mint and burn functionality to `DumbAction`
  • Loading branch information
greymistcube authored Apr 2, 2024
2 parents a763a2b + 742e8d3 commit 1ea676d
Show file tree
Hide file tree
Showing 23 changed files with 285 additions and 227 deletions.
2 changes: 1 addition & 1 deletion Libplanet.Action.Tests/ActionEvaluationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void Constructor()
ReservedAddresses.LegacyAccount,
world.GetAccount(ReservedAddresses.LegacyAccount).SetState(address, (Text)"item"));
var evaluation = new ActionEvaluation(
new DumbAction((address, "item")),
DumbAction.Create((address, "item")),
new ActionContext(
address,
txid,
Expand Down
106 changes: 67 additions & 39 deletions Libplanet.Action.Tests/Common/DumbAction.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
using System.Collections.Immutable;
using System.Numerics;
using Bencodex.Types;
using Libplanet.Action.State;
Expand All @@ -11,6 +12,8 @@ namespace Libplanet.Action.Tests.Common
{
public sealed class DumbAction : IAction
{
public static readonly DumbAction NoOp = DumbAction.Create();

public static readonly Text TypeId = new Text(nameof(DumbAction));

public static readonly Address RandomRecordsAddress =
Expand All @@ -23,23 +26,11 @@ public DumbAction()
{
}

public DumbAction(
(Address At, string Item)? append,
(Address From, Address To, BigInteger Amount)? transfer = null,
IEnumerable<PublicKey>? validators = null,
bool recordRandom = false)
{
Append = append;
Transfer = transfer;
Validators = validators;
RecordRandom = recordRandom;
}

public (Address At, string Item)? Append { get; private set; }

public (Address From, Address To, BigInteger Amount)? Transfer { get; private set; }
public (Address? From, Address? To, BigInteger Amount)? Transfer { get; private set; }

public IEnumerable<PublicKey>? Validators { get; private set; }
public ImmutableList<Validator>? Validators { get; private set; }

public bool RecordRandom { get; private set; }

Expand All @@ -59,15 +50,15 @@ public IValue PlainValue
if (Transfer is { } transfer)
{
plainValue = plainValue
.Add("transfer_from", transfer.From.Bencoded)
.Add("transfer_to", transfer.To.Bencoded)
.Add("transfer_from", transfer.From?.Bencoded ?? Null.Value)
.Add("transfer_to", transfer.To?.Bencoded ?? Null.Value)
.Add("transfer_amount", transfer.Amount);
}

if (Validators is { } validators)
{
plainValue = plainValue
.Add("validators", new List(validators.Select(p => p.Format(false))));
.Add("validators", new List(validators.Select(v => v.Bencoded)));
}

if (RecordRandom)
Expand All @@ -81,6 +72,28 @@ public IValue PlainValue
}
}

public static DumbAction Create(
(Address At, string Item)? append = null,
(Address? From, Address? To, BigInteger Amount)? transfer = null,
IEnumerable<Validator>? validators = null,
bool recordRandom = false)
{
if (transfer is { } t && t.From is null && t.To is null)
{
throw new ArgumentException(
$"From and To of {nameof(transfer)} cannot both be null when " +
$"{nameof(transfer)} is not null: {transfer}");
}

return new DumbAction()
{
Append = append,
Transfer = transfer,
Validators = validators?.ToImmutableList(),
RecordRandom = recordRandom,
};
}

public IWorld Execute(IActionContext context)
{
IWorld world = context.PreviousState;
Expand All @@ -96,20 +109,32 @@ public IWorld Execute(IActionContext context)

if (Transfer is { } transfer)
{
world = world.TransferAsset(
context,
sender: transfer.From,
recipient: transfer.To,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount),
allowNegativeBalance: true);
world = (transfer.From, transfer.To) switch
{
(Address from, Address to) => world.TransferAsset(
context,
sender: from,
recipient: to,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount),
allowNegativeBalance: true),
(null, Address to) => world.MintAsset(
context,
recipient: to,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount)),
(Address from, null) => world.BurnAsset(
context,
owner: from,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount)),
_ => throw new ArgumentException(
$"Both From and To cannot be null for {transfer}"),
};
}

if (Validators is { } validators)
{
world = validators.Aggregate(
world,
(current, validator) =>
current.SetValidator(new Validator(validator, BigInteger.One)));
(current, validator) => current.SetValidator(validator));
}

if (RecordRandom)
Expand All @@ -136,23 +161,26 @@ public void LoadPlainValue(Dictionary plainValue)

if (plainValue.TryGetValue((Text)"target_address", out IValue at) &&
plainValue.TryGetValue((Text)"item", out IValue item) &&
item is Text t)
item is Text i)
{
Append = (new Address(at), t);
Append = (new Address(at), i);
}

if (plainValue.TryGetValue((Text)"transfer_from", out IValue from) &&
plainValue.TryGetValue((Text)"transfer_to", out IValue to) &&
if (plainValue.TryGetValue((Text)"transfer_from", out IValue f) &&
plainValue.TryGetValue((Text)"transfer_to", out IValue t) &&
plainValue.TryGetValue((Text)"transfer_amount", out IValue a) &&
a is Integer amount)
{
Transfer = (new Address(from), new Address(to), amount.Value);
Address? from = f is Null ? null : new Address(f);
Address? to = t is Null ? null : new Address(t);
Transfer = (from, to, amount.Value);
}

if (plainValue.ContainsKey((Text)"validators"))
{
Validators = ((List)plainValue["validators"])
.Select(value => new PublicKey(((Binary)value).ByteArray));
.Select(value => new Validator(value))
.ToImmutableList();
}

RecordRandom =
Expand All @@ -164,17 +192,17 @@ public void LoadPlainValue(Dictionary plainValue)
public override string ToString()
{
const string T = "true", F = "false";
const string N = "null";
const string E = "empty";
string append = Append is { } a
? $"({a.At}, {a.Item})"
: "null";
: N;
string transfer = Transfer is { } t
? $"({t.From}, {t.To}, {t.Amount})"
: "null";
string validators = Validators is { } vs
? vs
.Aggregate(string.Empty, (s, key) => s + key.Format(false) + ", ")
.TrimEnd(',', ' ')
: "none";
? $"({t.From?.ToString() ?? N}, {t.To?.ToString() ?? N}, {t.Amount})"
: N;
string validators = Validators is { } vs && vs.Any()
? string.Join(",", vs.Select(v => v.OperatorAddress))
: E;
return $"{nameof(DumbAction)} {{ " +
$"{nameof(Append)} = {append}, " +
$"{nameof(Transfer)} = {transfer}, " +
Expand Down
106 changes: 67 additions & 39 deletions Libplanet.Action.Tests/Common/DumbModernAction.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#nullable enable
using System.Collections.Immutable;
using System.Numerics;
using Bencodex.Types;
using Libplanet.Action.State;
Expand All @@ -11,6 +12,8 @@ namespace Libplanet.Action.Tests.Common
{
public sealed class DumbModernAction : IAction
{
public static readonly DumbModernAction NoOp = DumbModernAction.Create();

public static readonly Text TypeId = new Text(nameof(DumbAction));

public static readonly Address DumbModernAddress =
Expand All @@ -26,23 +29,11 @@ public DumbModernAction()
{
}

public DumbModernAction(
(Address At, string Item)? append,
(Address From, Address To, BigInteger Amount)? transfer = null,
IEnumerable<PublicKey>? validators = null,
bool recordRandom = false)
{
Append = append;
Transfer = transfer;
Validators = validators;
RecordRandom = recordRandom;
}

public (Address At, string Item)? Append { get; private set; }

public (Address From, Address To, BigInteger Amount)? Transfer { get; private set; }
public (Address? From, Address? To, BigInteger Amount)? Transfer { get; private set; }

public IEnumerable<PublicKey>? Validators { get; private set; }
public ImmutableList<Validator>? Validators { get; private set; }

public bool RecordRandom { get; private set; }

Expand All @@ -62,15 +53,15 @@ public IValue PlainValue
if (Transfer is { } transfer)
{
plainValue = plainValue
.Add("transfer_from", transfer.From.Bencoded)
.Add("transfer_to", transfer.To.Bencoded)
.Add("transfer_from", transfer.From?.Bencoded ?? Null.Value)
.Add("transfer_to", transfer.To?.Bencoded ?? Null.Value)
.Add("transfer_amount", transfer.Amount);
}

if (Validators is { } validators)
{
plainValue = plainValue
.Add("validators", new List(validators.Select(p => p.Format(false))));
.Add("validators", new List(validators.Select(v => v.Bencoded)));
}

if (RecordRandom)
Expand All @@ -84,6 +75,28 @@ public IValue PlainValue
}
}

public static DumbModernAction Create(
(Address At, string Item)? append = null,
(Address? From, Address? To, BigInteger Amount)? transfer = null,
IEnumerable<Validator>? validators = null,
bool recordRandom = false)
{
if (transfer is { } t && t.From is null && t.To is null)
{
throw new ArgumentException(
$"From and To of {nameof(transfer)} cannot both be null when " +
$"{nameof(transfer)} is not null: {transfer}");
}

return new DumbModernAction()
{
Append = append,
Transfer = transfer,
Validators = validators?.ToImmutableList(),
RecordRandom = recordRandom,
};
}

public IWorld Execute(IActionContext context)
{
IWorld world = context.PreviousState;
Expand All @@ -99,20 +112,32 @@ public IWorld Execute(IActionContext context)

if (Transfer is { } transfer)
{
world = world.TransferAsset(
context,
sender: transfer.From,
recipient: transfer.To,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount),
allowNegativeBalance: true);
world = (transfer.From, transfer.To) switch
{
(Address from, Address to) => world.TransferAsset(
context,
sender: from,
recipient: to,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount),
allowNegativeBalance: true),
(null, Address to) => world.MintAsset(
context,
recipient: to,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount)),
(Address from, null) => world.BurnAsset(
context,
owner: from,
value: FungibleAssetValue.FromRawValue(DumbCurrency, transfer.Amount)),
_ => throw new ArgumentException(
$"Both From and To cannot be null for {transfer}"),
};
}

if (Validators is { } validators)
{
world = validators.Aggregate(
world,
(current, validator) =>
current.SetValidator(new Validator(validator, BigInteger.One)));
(current, validator) => current.SetValidator(validator));
}

if (RecordRandom)
Expand All @@ -139,23 +164,26 @@ public void LoadPlainValue(Dictionary plainValue)

if (plainValue.TryGetValue((Text)"target_address", out IValue at) &&
plainValue.TryGetValue((Text)"item", out IValue item) &&
item is Text t)
item is Text i)
{
Append = (new Address(at), t);
Append = (new Address(at), i);
}

if (plainValue.TryGetValue((Text)"transfer_from", out IValue from) &&
plainValue.TryGetValue((Text)"transfer_to", out IValue to) &&
if (plainValue.TryGetValue((Text)"transfer_from", out IValue f) &&
plainValue.TryGetValue((Text)"transfer_to", out IValue t) &&
plainValue.TryGetValue((Text)"transfer_amount", out IValue a) &&
a is Integer amount)
{
Transfer = (new Address(from), new Address(to), amount.Value);
Address? from = f is Null ? null : new Address(f);
Address? to = t is Null ? null : new Address(t);
Transfer = (from, to, amount.Value);
}

if (plainValue.ContainsKey((Text)"validators"))
{
Validators = ((List)plainValue["validators"])
.Select(value => new PublicKey(((Binary)value).ByteArray));
.Select(value => new Validator(value))
.ToImmutableList();
}

RecordRandom =
Expand All @@ -167,17 +195,17 @@ public void LoadPlainValue(Dictionary plainValue)
public override string ToString()
{
const string T = "true", F = "false";
const string N = "null";
const string E = "empty";
string append = Append is { } a
? $"({a.At}, {a.Item})"
: "null";
: N;
string transfer = Transfer is { } t
? $"({t.From}, {t.To}, {t.Amount})"
: "null";
string validators = Validators is { } vs
? vs
.Aggregate(string.Empty, (s, key) => s + key.Format(false) + ", ")
.TrimEnd(',', ' ')
: "none";
? $"({t.From?.ToString() ?? N}, {t.To?.ToString() ?? N}, {t.Amount})"
: N;
string validators = Validators is { } vs && vs.Any()
? string.Join(",", vs.Select(v => v.OperatorAddress))
: E;
return $"{nameof(DumbModernAction)} {{ " +
$"{nameof(Append)} = {append}, " +
$"{nameof(Transfer)} = {transfer}, " +
Expand Down
2 changes: 1 addition & 1 deletion Libplanet.Action.Tests/Loader/IndexedActionLoaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void LoadAction()
var loader1 = new SingleActionLoader(typeof(DumbAction));
var loader2 = new SingleActionLoader(typeof(Attack));
var loader3 = new SingleActionLoader(typeof(RandomAction));
var action1 = new DumbAction((new PrivateKey().Address, "foo"));
var action1 = DumbAction.Create((new PrivateKey().Address, "foo"));
var action2 = new Attack();
action2.LoadPlainValue(Dictionary.Empty
.Add("type_id", "attack")
Expand Down
Loading

0 comments on commit 1ea676d

Please sign in to comment.