Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add dpos related actions #2466

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 2 additions & 0 deletions .Lib9c.Tests/Action/ActionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public class ActionContext : IActionContext

public int BlockProtocolVersion { get; set; }

public BlockCommit LastCommit { get; set; }

public IWorld PreviousState { get; set; }

public int RandomSeed { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion .Libplanet
Submodule .Libplanet updated 131 files
60 changes: 60 additions & 0 deletions Lib9c.DPoS.Tests/ActionContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#nullable disable

using System.Security.Cryptography;
using Libplanet.Action;
using Libplanet.Action.State;
using Libplanet.Common;
using Libplanet.Crypto;
using Libplanet.Types.Blocks;
using Libplanet.Types.Tx;

namespace Lib9c.DPoS.Tests
{
public class ActionContext : IActionContext
{
private long _gasUsed;

private IRandom _random = null;

public BlockHash? GenesisHash { get; set; }

public Address Signer { get; set; }

public TxId? TxId { get; set; }

public Address Miner { get; set; }

public BlockHash BlockHash { get; set; }

public long BlockIndex { get; set; }

public int BlockProtocolVersion { get; set; }

public BlockCommit LastCommit { get; set; }

public IWorld PreviousState { get; set; }

public int RandomSeed { get; set; }

public HashDigest<SHA256>? PreviousStateRootHash { get; set; }

public bool BlockAction { get; }

public void UseGas(long gas)
{
_gasUsed += gas;
}

public IRandom GetRandom() => _random ?? new TestRandom(RandomSeed);

public long GasUsed() => _gasUsed;

public long GasLimit() => 0;

// FIXME: Temporary measure to allow inheriting already mutated IRandom.
public void SetRandom(IRandom random)
{
_random = random;
}
}
}
193 changes: 193 additions & 0 deletions Lib9c.DPoS.Tests/Control/DelegateCtrlTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
using System.Collections.Immutable;
using Lib9c.DPoS.Control;
using Lib9c.DPoS.Exception;
using Lib9c.DPoS.Misc;
using Lib9c.DPoS.Model;
using Libplanet.Action.State;
using Libplanet.Crypto;
using Libplanet.Types.Assets;
using Nekoyume.Module;
using Xunit;

namespace Lib9c.DPoS.Tests.Control
{
public class DelegateCtrlTest : PoSTest
{
private readonly PublicKey _operatorPublicKey;
private readonly Address _operatorAddress;
private readonly Address _delegatorAddress;
private readonly Address _validatorAddress;
private ImmutableHashSet<Currency> _nativeTokens;
private IWorld _states;

public DelegateCtrlTest()
{
_operatorPublicKey = new PrivateKey().PublicKey;
_operatorAddress = _operatorPublicKey.Address;
_delegatorAddress = CreateAddress();
_validatorAddress = Validator.DeriveAddress(_operatorAddress);
_nativeTokens = ImmutableHashSet.Create(
Asset.GovernanceToken, Asset.ConsensusToken, Asset.Share);
_states = InitializeStates();
}

[Fact]
public void InvalidCurrencyTest()
{
Initialize(500, 500, 100);
_states = _states.MintAsset(
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
Asset.ConsensusToken * 50);
Assert.Throws<InvalidCurrencyException>(
() => _states = DelegateCtrl.Execute(
_states,
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
_validatorAddress,
Asset.ConsensusToken * 30,
_nativeTokens));
}

[Fact]
public void InvalidValidatorTest()
{
Initialize(500, 500, 100);
Assert.Throws<NullValidatorException>(
() => _states = DelegateCtrl.Execute(
_states,
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
CreateAddress(),
Asset.GovernanceToken * 10,
_nativeTokens));
}

[Fact]
public void InvalidShareTest()
{
Initialize(500, 500, 100);
_states = _states.BurnAsset(
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_validatorAddress,
Asset.ConsensusToken * 100);
Assert.Throws<InvalidExchangeRateException>(
() => _states = DelegateCtrl.Execute(
_states,
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
_validatorAddress,
Asset.GovernanceToken * 10,
_nativeTokens));
}

[Theory]
[InlineData(500, 500, 100, 10)]
[InlineData(500, 500, 100, 20)]
public void BalanceTest(
int operatorMintAmount,
int delegatorMintAmount,
int selfDelegateAmount,
int delegateAmount)
{
Initialize(operatorMintAmount, delegatorMintAmount, selfDelegateAmount);
_states = DelegateCtrl.Execute(
_states,
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
_validatorAddress,
Asset.GovernanceToken * delegateAmount,
_nativeTokens);
Assert.Equal(
Asset.GovernanceToken * 0,
_states.GetBalance(_validatorAddress, Asset.GovernanceToken));
Assert.Equal(
Asset.ConsensusToken * 0,
_states.GetBalance(_operatorAddress, Asset.ConsensusToken));
Assert.Equal(
Asset.ConsensusToken * 0,
_states.GetBalance(_delegatorAddress, Asset.ConsensusToken));
Assert.Equal(
Asset.Share * 0,
_states.GetBalance(_operatorAddress, Asset.Share));
Assert.Equal(
Asset.Share * 0,
_states.GetBalance(_delegatorAddress, Asset.Share));
Assert.Equal(
Asset.ConsensusToken * (selfDelegateAmount + delegateAmount),
_states.GetBalance(_validatorAddress, Asset.ConsensusToken));
Assert.Equal(
Asset.GovernanceToken * (operatorMintAmount - selfDelegateAmount),
_states.GetBalance(_operatorAddress, Asset.GovernanceToken));
Assert.Equal(
Asset.GovernanceToken * (delegatorMintAmount - delegateAmount),
_states.GetBalance(_delegatorAddress, Asset.GovernanceToken));
Assert.Equal(
Asset.GovernanceToken * (selfDelegateAmount + delegateAmount),
_states.GetBalance(ReservedAddress.UnbondedPool, Asset.GovernanceToken));
Assert.Equal(
ValidatorCtrl.GetValidator(_states, _validatorAddress)!.DelegatorShares,
_states.GetBalance(
Delegation.DeriveAddress(_operatorAddress, _validatorAddress), Asset.Share)
+ _states.GetBalance(
Delegation.DeriveAddress(_delegatorAddress, _validatorAddress), Asset.Share));
}

private void Initialize(
int operatorMintAmount, int delegatorMintAmount, int selfDelegateAmount)
{
_states = InitializeStates();
_states = _states.MintAsset(
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_operatorAddress,
Asset.GovernanceToken * operatorMintAmount);
_states = _states.MintAsset(
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_delegatorAddress,
Asset.GovernanceToken * delegatorMintAmount);
_states = ValidatorCtrl.Create(
_states,
new ActionContext
{
PreviousState = _states,
BlockIndex = 1,
},
_operatorAddress,
_operatorPublicKey,
Asset.GovernanceToken * selfDelegateAmount,
_nativeTokens);
}
}
}
Loading
Loading