Skip to content
This repository was archived by the owner on Feb 7, 2025. It is now read-only.

[SVR-303] 무역상점 가격 수정 기능 추가 #161

Merged
merged 2 commits into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions backend/app/Savor22b.Tests/Action/UpdateTradeGoodActionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
namespace Savor22b.Tests.Action;

using System;
using System.Collections.Immutable;
using Libplanet;
using Libplanet.Assets;
using Libplanet.State;
using Savor22b.Action;
using Savor22b.States;
using Savor22b.States.Trade;
using Xunit;

public class UpdateTradeGoodActionTests : ActionTests
{

public UpdateTradeGoodActionTests() { }

[Fact]
public void RegisterTradeGoodActionExecute_Success()
{

var (beforeState, foodProductId) = CreatePresetStateDelta();
var action = new UpdateTradeGoodAction(
foodProductId,
FungibleAssetValue.Parse(
Currencies.KeyCurrency,
"10000"
)
);

var afterState = action.Execute(
new DummyActionContext
{
PreviousStates = beforeState,
Signer = SignerAddress(),
Random = random,
Rehearsal = false,
BlockIndex = 1,
}
);

var afterTradeInventoryState = DeriveTradeInventoryStateDelta(afterState);
var tradeGood = afterTradeInventoryState.TradeGoods.First(g => g.Value.SellerAddress == SignerAddress()).Value;

if (tradeGood is FoodGoodState foodGoodState)
{
Assert.Equal(foodGoodState.Price, FungibleAssetValue.Parse(Currencies.KeyCurrency, "10000"));
}
else
{
throw new Exception();
}
}

private (IAccountStateDelta, Guid) CreatePresetStateDelta()
{
IAccountStateDelta state = new DummyState();
Address signerAddress = SignerAddress();

TradeInventoryState tradeInventoryState = state.GetState(TradeInventoryState.StateAddress) is Bencodex.Types.Dictionary tradeInventoryStateEncoded
? new TradeInventoryState(tradeInventoryStateEncoded)
: new TradeInventoryState();

var foodProductId = Guid.NewGuid();

var food = RefrigeratorState.CreateFood(
Guid.NewGuid(),
1,
"D",
1,
1,
1,
1,
1,
ImmutableList<Guid>.Empty
);

tradeInventoryState = tradeInventoryState.RegisterGood(
new FoodGoodState(
signerAddress,
foodProductId,
FungibleAssetValue.Parse(Currencies.KeyCurrency, "10"),
food)
);

return (state.SetState(TradeInventoryState.StateAddress, tradeInventoryState.Serialize()), foodProductId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Savor22b.Action.Exceptions;


[Serializable]
public class PermissionDeniedException : ActionException
{
public PermissionDeniedException(string message, int? errorCode = null)
: base(message, "PermissionDeniedException", errorCode)
{
}
}
69 changes: 69 additions & 0 deletions backend/app/Savor22b/Action/UpdateTradeGoodAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
namespace Savor22b.Action;

using System;
using System.Collections.Immutable;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Assets;
using Libplanet.Headless.Extensions;
using Libplanet.State;
using Savor22b.States;
using Savor22b.States.Trade;
using Savor22b.Action.Exceptions;

[ActionType(nameof(UpdateTradeGoodAction))]
public class UpdateTradeGoodAction : SVRAction
{
public UpdateTradeGoodAction() { }

public UpdateTradeGoodAction(Guid productId, FungibleAssetValue price)
{
ProductId = productId;
Price = price;
}

public FungibleAssetValue Price;

public Guid ProductId;

protected override IImmutableDictionary<string, IValue> PlainValueInternal =>
new Dictionary<string, IValue>()
{
[nameof(ProductId)] = ProductId.Serialize(),
[nameof(Price)] = Price.ToBencodex(),
}.ToImmutableDictionary();

protected override void LoadPlainValueInternal(IImmutableDictionary<string, IValue> plainValue)
{
ProductId = plainValue[nameof(ProductId)].ToGuid();
Price = plainValue[nameof(Price)].ToFungibleAssetValue();
}

public override IAccountStateDelta Execute(IActionContext ctx)
{
if (ctx.Rehearsal)
{
return ctx.PreviousStates;
}

IAccountStateDelta states = ctx.PreviousStates;

TradeInventoryState tradeInventoryState = states.GetState(TradeInventoryState.StateAddress) is Dictionary tradeInventoryStateEncoded
? new TradeInventoryState(tradeInventoryStateEncoded)
: new TradeInventoryState();

var good = tradeInventoryState.TradeGoods.First(g => g.Key == ProductId);

if (good.Value.SellerAddress != ctx.Signer)
{
throw new PermissionDeniedException("You not have permission");
}

good.Value.UpdatePrice(Price);

tradeInventoryState.TradeGoods.Remove(good.Key);
tradeInventoryState.TradeGoods.Add(good.Key, good.Value);

return states.SetState(TradeInventoryState.StateAddress, tradeInventoryState.Serialize());
}
}
40 changes: 40 additions & 0 deletions backend/app/Savor22b/GraphTypes/Query/Query.cs
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,46 @@ swarm is null
}
);

Field<NonNullGraphType<StringGraphType>>(
"createAction_UpdateTradeGoodAction",
description: "무역상점 상품 가격 수정",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<StringGraphType>>
{
Name = "publicKey",
Description = "The base64-encoded public key for Transaction.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이거 너무 티나요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쉿 지금 아무도 몰라요

},
new QueryArgument<NonNullGraphType<GuidGraphType>>
{
Name = "productId",
Description = "상품 고유 Id",
},
new QueryArgument<NonNullGraphType<IntGraphType>>
{
Name = "price",
Description = "가격",
}
),
resolve: context =>
{
var publicKey = new PublicKey(
ByteUtil.ParseHex(context.GetArgument<string>("publicKey"))
);
var price = FungibleAssetValue.Parse(Currencies.KeyCurrency, context.GetArgument<int>("price").ToString());

var action = new UpdateTradeGoodAction(
context.GetArgument<Guid>("productId"),
price);

return new GetUnsignedTransactionHex(
action,
publicKey,
_blockChain,
_swarm
).UnsignedTransactionHex;
}
);

Field<NonNullGraphType<StringGraphType>>(
"createAction_BuyTradeGoodAction",
description: "무역상점 구매",
Expand Down
5 changes: 5 additions & 0 deletions backend/app/Savor22b/States/Trade/TradeGood.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ public virtual IValue Serialize()
};
return new Dictionary(pairs);
}

public void UpdatePrice(FungibleAssetValue price)
{
Price = price;
}
}
Loading