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

Prepare initial states for testing #2506

Draft
wants to merge 44 commits into
base: feature/dpos
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5354eb0
bump: libplanet
limebell Mar 20, 2024
083ee2e
feat: add dpos related actions
limebell Mar 15, 2024
11ec77e
test: add unit tests
limebell Mar 20, 2024
a18acd3
Merge pull request #2473 from limebell/feature/dpos
limebell Mar 26, 2024
7adb80b
refactor: Add the `type_id` value to pos-related actions.
s2quake Mar 26, 2024
21b7ce3
Merge pull request #2488 from s2quake/feature/dpos
s2quake Mar 26, 2024
8d6d406
feat: change get methods to iworldstate
limebell Mar 26, 2024
520bba6
chore: prevent typo error
limebell Mar 26, 2024
6da9f8a
Merge pull request #2487 from limebell/dpos/get-worldstate
limebell Mar 26, 2024
90cc46c
refactor: move DPoS feaures under Lib9c project
limebell Mar 29, 2024
051c5c2
Merge pull request #2498 from limebell/refactor/move-dpos
limebell Mar 29, 2024
69f72d1
fix: Fix an issue with deletaion not being listed when bond is execut…
s2quake Apr 2, 2024
3bcb166
test: Add test code for ValidatorDelegationSetCtrl.
s2quake Apr 2, 2024
38f8d2f
Merge pull request #2505 from s2quake/fix/delegations-not-listed
s2quake Apr 2, 2024
ce02e8b
refactor: separate PoSAction and implement ActionBase
limebell Apr 3, 2024
d457a6a
Merge pull request #2507 from limebell/dpos/actionbase
limebell Apr 3, 2024
119b691
refator: refactor dpos actions
limebell Apr 4, 2024
519c3cf
Merge pull request #2510 from limebell/dpos/refactor-systemaction
limebell Apr 4, 2024
4005c46
fix: Fix test fails due to missing `UseGas`.
s2quake Apr 9, 2024
443a5d4
Merge pull request #2520 from s2quake/fix/test-fails-missing-usegas
s2quake Apr 9, 2024
d0ba581
refactor: Change decimal places for NCG, ConsensusToken, Share.
s2quake Apr 9, 2024
928513f
test: Fixes test failures caused by changing decimal places.
s2quake Apr 9, 2024
06b38a2
Merge pull request #2521 from s2quake/refactor/currency-for-dpos
s2quake Apr 9, 2024
e6a4af6
refactor: rename AllocateRewardCtrl
limebell Apr 5, 2024
98ffc27
bump: libplanet
limebell Apr 5, 2024
181d40f
feat: adjust changes from the libplanet API changes
limebell Apr 9, 2024
24bca50
test: add regression test
limebell Apr 5, 2024
939328c
bugfix: fix logic error in dpos methods
limebell Apr 5, 2024
4f2e2b9
Merge pull request #2515 from limebell/bugfix/zero-asset
limebell Apr 9, 2024
a37c1d7
feat: Add slashing-related code.
s2quake Apr 9, 2024
5b3d0c7
test: Add test code for slashing.
s2quake Apr 9, 2024
6921c25
Merge pull request #2517 from s2quake/feature/dpos-slashing
s2quake Apr 16, 2024
5bd2644
bump: libplanet
limebell Apr 18, 2024
6f3d8ad
adjust api changes from libplanet
limebell Apr 18, 2024
d76f626
Merge pull request #2538 from limebell/bump/libplanet-dpos-begintx
limebell Apr 18, 2024
0e5609e
feat: introduce RecordProposer action
limebell Apr 19, 2024
13801c7
bump: libplanet
limebell Apr 22, 2024
909f918
chore: apply API changes from libplanet
limebell Apr 24, 2024
5d425ee
feat: implement gold distribution replacing fee collector
limebell Apr 22, 2024
4dafb05
test: fix DistributeTest
limebell Apr 24, 2024
c35ec5c
bump: libplanet
limebell Apr 25, 2024
5e56b64
temp: test
limebell Apr 25, 2024
0750a86
1
limebell Apr 25, 2024
b093458
feat: prepare initial states
limebell Apr 25, 2024
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
Prev Previous commit
Next Next commit
test: add unit tests
limebell committed Mar 22, 2024
commit 11ec77efc92c545790d8767ea078f4854bd30c77
2 changes: 2 additions & 0 deletions .Lib9c.Tests/Action/ActionContext.cs
Original file line number Diff line number Diff line change
@@ -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; }
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

Unchanged files with check annotations Beta

// May be it would be better to be serialized
public static FungibleAssetValue MinSelfDelegation => Asset.ConsensusToken * 1;
public static BigInteger CommissionNumer => 1;

Check warning on line 46 in Lib9c.DPoS/Model/Validator.cs

GitHub Actions / typos

"Numer" should be "Number".
public static BigInteger CommissionDenom => 10;
{
public static class AllocateReward
{
public static BigInteger BaseProposerRewardNumer => 1;

Check warning on line 20 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
public static BigInteger BaseProposerRewardDenom => 100;
public static BigInteger BonusProposerRewardNumer => 4;

Check warning on line 24 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
public static BigInteger BonusProposerRewardDenom => 100;
= bondedValidatorSet.Set.ToImmutableDictionary(
bondedValidator => bondedValidator.OperatorPublicKey);
FungibleAssetValue votePowerNumer

Check warning on line 96 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
= votes.Aggregate(
Asset.ConsensusToken * 0, (total, next)
=> total + bondedValidatorDict[next.ValidatorPublicKey].ConsensusToken);
= bondedValidatorSet.TotalConsensusToken;
var (baseProposerReward, _)
= (blockReward * BaseProposerRewardNumer).DivRem(BaseProposerRewardDenom);

Check warning on line 105 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
var (bonusProposerReward, _)
= (blockReward * votePowerNumer.RawValue * BonusProposerRewardNumer)

Check warning on line 107 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".

Check warning on line 107 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
.DivRem(votePowerDenom.RawValue * BonusProposerRewardDenom);
FungibleAssetValue proposerReward = baseProposerReward + bonusProposerReward;
ValidatorPower bondedValidator = bondedValidatorDict[vote.ValidatorPublicKey];
FungibleAssetValue powerNumer

Check warning on line 146 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
= bondedValidator.ConsensusToken;
FungibleAssetValue powerDenom
= bondedValidatorSet.TotalConsensusToken;
var (validatorReward, _)
= (validatorRewardSum * powerNumer.RawValue)

Check warning on line 153 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
.DivRem(powerDenom.RawValue);
var (commission, _)
= (validatorReward * Validator.CommissionNumer)

Check warning on line 156 in Lib9c.DPoS/Control/AllocateReward.cs

GitHub Actions / typos

"Numer" should be "Number".
.DivRem(Validator.CommissionDenom);
FungibleAssetValue delegationRewardSum = validatorReward - commission;
public class GetWorldStateResponseType
{
public StateQueryWithWorldStateType StateQuery { get; set; }

Check warning on line 82 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteWorldState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'StateQuery' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}
public class StateQueryWithWorldStateType
{
public WorldStateType WorldState { get; set; }

Check warning on line 87 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteWorldState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'WorldState' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}
public class WorldStateType
{
public string StateRootHash { get; set; }

Check warning on line 92 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteWorldState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'StateRootHash' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public bool Legacy { get; set; }
}
decimalPlaces = currency.DecimalPlaces,
minters = currency.Minters?.Select(addr => addr.ToString()).ToArray(),
totalSupplyTrackable = currency.TotalSupplyTrackable,
maximumSupplyMajorUnit = currency.MaximumSupply.Value.MajorUnit,

Check warning on line 132 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Nullable value type may be null.
maximumSupplyMinorUnit = currency.MaximumSupply.Value.MinorUnit,
} : new
{
{
ticker = currency.Ticker,
decimalPlaces = currency.DecimalPlaces,
minters = currency.Minters.Select(addr => addr.ToString()).ToArray(),

Check warning on line 178 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Possible null reference argument for parameter 'source' in 'IEnumerable<string> Enumerable.Select<Address, string>(IEnumerable<Address> source, Func<Address, string> selector)'.
totalSupplyTrackable = currency.TotalSupplyTrackable,
maximumSupplyMajorUnit = currency.MaximumSupply.Value.MajorUnit,

Check warning on line 180 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Nullable value type may be null.
maximumSupplyMinorUnit = currency.MaximumSupply.Value.MinorUnit,
} : new
{
ticker = currency.Ticker,
decimalPlaces = currency.DecimalPlaces,
minters = currency.Minters.Select(addr => addr.ToString()).ToArray(),

Check warning on line 186 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Possible null reference argument for parameter 'source' in 'IEnumerable<string> Enumerable.Select<Address, string>(IEnumerable<Address> source, Func<Address, string> selector)'.
totalSupplyTrackable = currency.TotalSupplyTrackable,
};
var response = _graphQlHttpClient.SendQueryAsync<GetTotalSupplyResponseType>(
private class GetAccountStateResponseType
{
public StateQueryWithAccountStateType StateQuery { get; set; }

Check warning on line 251 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'StateQuery' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}
private class StateQueryWithAccountStateType
{
public AccountStateType AccountState { get; set; }

Check warning on line 256 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'AccountState' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}
public class AccountStateType
private class ValidatorType
{
public string PublicKey { get; set; }

Check warning on line 311 in .Libplanet.Extensions.RemoteBlockChainStates/RemoteAccountState.cs

GitHub Actions / build-and-test (Release)

Non-nullable property 'PublicKey' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public long Power { get; set; }
}