Skip to content

Commit ba0543d

Browse files
committed
wip
1 parent a56730f commit ba0543d

File tree

17 files changed

+390
-510
lines changed

17 files changed

+390
-510
lines changed

src/Libplanet.Action/State/IWorldExtensions.cs

+29-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Libplanet.Crypto;
2+
using Libplanet.Serialization;
23
using Libplanet.Types.Assets;
34
using Libplanet.Types.Consensus;
45

@@ -57,16 +58,20 @@ public static FungibleAssetValue GetTotalSupply(this IWorldState @this, Currency
5758
=> @this.GetCurrencyAccount(currency).GetTotalSupply(currency);
5859

5960
public static ImmutableSortedSet<Validator> GetValidatorSet(this IWorldState @this)
60-
=> @this.GetValidatorSetAccount().GetValidatorSet();
61+
{
62+
var accountState = @this.GetAccountState(ReservedAddresses.ValidatorSetAddress);
63+
var value = accountState.GetState(ReservedAddresses.ValidatorSetAddress);
64+
return ModelSerializer.Deserialize<ImmutableSortedSet<Validator>>(value);
65+
}
6166

62-
public static IWorld SetValidatorSet(this IWorld @this, ImmutableSortedSet<Validator> validatorSet)
63-
=> @this.SetValidatorSetAccount(
64-
@this.GetValidatorSetAccount().SetValidatorSet(validatorSet));
67+
// public static IWorld SetValidatorSet(this IWorld @this, ImmutableSortedSet<Validator> validatorSet)
68+
// => @this.SetValidatorSetAccount(
69+
// @this.GetValidatorSetAccount().SetValidatorSet(validatorSet));
6570

66-
internal static ValidatorSetAccount GetValidatorSetAccount(this IWorldState @this)
67-
=> new(
68-
@this.GetAccountState(ReservedAddresses.ValidatorSetAccount).Trie,
69-
@this.Version);
71+
// internal static ValidatorSetAccount GetValidatorSetAccount(this IWorldState @this)
72+
// => new(
73+
// @this.GetAccountState(ReservedAddresses.ValidatorSetAccount).Trie,
74+
// @this.Version);
7075

7176
internal static CurrencyAccount GetCurrencyAccount(
7277
this IWorldState @this, Currency currency)
@@ -92,20 +97,20 @@ internal static IWorld SetCurrencyAccount(
9297
currencyAccount.AsAccount());
9398
}
9499

95-
internal static IWorld SetValidatorSetAccount(
96-
this IWorld @this, ValidatorSetAccount validatorSetAccount)
97-
{
98-
if (@this.Version != validatorSetAccount.WorldVersion)
99-
{
100-
throw new ArgumentException(
101-
$"Given {nameof(validatorSetAccount)} must have the same version as " +
102-
$"the version of the world {@this.Version}: " +
103-
$"{validatorSetAccount.WorldVersion}",
104-
nameof(validatorSetAccount));
105-
}
106-
107-
return @this.SetAccount(
108-
ReservedAddresses.ValidatorSetAccount,
109-
validatorSetAccount.AsAccount());
110-
}
100+
// internal static IWorld SetValidatorSetAccount(
101+
// this IWorld @this, ValidatorSetAccount validatorSetAccount)
102+
// {
103+
// if (@this.Version != validatorSetAccount.WorldVersion)
104+
// {
105+
// throw new ArgumentException(
106+
// $"Given {nameof(validatorSetAccount)} must have the same version as " +
107+
// $"the version of the world {@this.Version}: " +
108+
// $"{validatorSetAccount.WorldVersion}",
109+
// nameof(validatorSetAccount));
110+
// }
111+
112+
// return @this.SetAccount(
113+
// ReservedAddresses.ValidatorSetAccount,
114+
// validatorSetAccount.AsAccount());
115+
// }
111116
}

src/Libplanet.Action/State/ReservedAddresses.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ public static class ReservedAddresses
77
public static readonly Address LegacyAccount =
88
Address.Parse("1000000000000000000000000000000000000000");
99

10-
public static readonly Address ValidatorSetAccount =
11-
Address.Parse("1000000000000000000000000000000000000001");
10+
public static readonly Address ValidatorSetAddress =
11+
Address.Parse("1000000000000000000000000000000000000000");
1212
}
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
using Libplanet.Crypto;
2-
using Libplanet.Serialization;
3-
using Libplanet.Store.Trie;
4-
using Libplanet.Types;
5-
using Libplanet.Types.Consensus;
1+
// using Libplanet.Crypto;
2+
// using Libplanet.Serialization;
3+
// using Libplanet.Store.Trie;
4+
// using Libplanet.Types;
5+
// using Libplanet.Types.Consensus;
66

7-
namespace Libplanet.Action.State;
7+
// namespace Libplanet.Action.State;
88

9-
public class ValidatorSetAccount(ITrie trie, int worldVersion)
10-
{
11-
public static readonly Address ValidatorSetAddress =
12-
Address.Parse("1000000000000000000000000000000000000000");
9+
// public class ValidatorSetAccount(ITrie trie, int worldVersion)
10+
// {
11+
// public static readonly Address ValidatorSetAddress =
12+
// Address.Parse("1000000000000000000000000000000000000000");
1313

14-
public ITrie Trie { get; } = trie;
14+
// public ITrie Trie { get; } = trie;
1515

16-
public int WorldVersion { get; } = worldVersion;
16+
// public int WorldVersion { get; } = worldVersion;
1717

18-
public ImmutableSortedSet<Validator> GetValidatorSet()
19-
{
20-
var value = Trie[KeyConverters.ToStateKey(ValidatorSetAddress)];
21-
return [.. BencodexUtility.ToObjects(value, ModelSerializer.Deserialize<Validator>)];
22-
}
18+
// public ImmutableSortedSet<Validator> GetValidatorSet()
19+
// {
20+
// var value = Trie[KeyConverters.ToStateKey(ValidatorSetAddress)];
21+
// return [.. BencodexUtility.ToObjects(value, ModelSerializer.Deserialize<Validator>)];
22+
// }
2323

24-
public ValidatorSetAccount SetValidatorSet(ImmutableSortedSet<Validator> validatorSet)
25-
{
26-
var value = BencodexUtility.ToValue([.. validatorSet], ModelSerializer.Serialize);
27-
return new ValidatorSetAccount(
28-
Trie.Set(KeyConverters.ToStateKey(ValidatorSetAddress), value),
29-
WorldVersion);
30-
}
24+
// public ValidatorSetAccount SetValidatorSet(ImmutableSortedSet<Validator> validatorSet)
25+
// {
26+
// var value = BencodexUtility.ToValue([.. validatorSet], ModelSerializer.Serialize);
27+
// return new ValidatorSetAccount(
28+
// Trie.Set(KeyConverters.ToStateKey(ValidatorSetAddress), value),
29+
// WorldVersion);
30+
// }
3131

32-
public IAccount AsAccount()
33-
{
34-
return new Account(new AccountState(Trie));
35-
}
36-
}
32+
// public IAccount AsAccount()
33+
// {
34+
// return new Account(new AccountState(Trie));
35+
// }
36+
// }

src/Libplanet.Action/Sys/Initialize.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Bencodex.Types;
2+
using Libplanet.Action.State;
23
using Libplanet.Crypto;
34
using Libplanet.Serialization;
45
using Libplanet.Types.Consensus;
@@ -58,6 +59,12 @@ public sealed record class Initialize : ActionBase, IEquatable<Initialize>
5859

5960
protected override void OnExecute(IWorldContext world, IActionContext context)
6061
{
61-
throw new NotImplementedException();
62+
if (context.BlockHeight != 0)
63+
{
64+
throw new InvalidOperationException(
65+
$"{nameof(Initialize)} action can be executed only genesis block.");
66+
}
67+
68+
world[ReservedAddresses.ValidatorSetAddress, ReservedAddresses.ValidatorSetAddress] = Validators;
6269
}
6370
}

src/Libplanet.Store/IStateStore.cs

-27
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,12 @@
11
using System.Security.Cryptography;
22
using Libplanet.Common;
33
using Libplanet.Store.Trie;
4-
using Libplanet.Store.Trie.Nodes;
54

65
namespace Libplanet.Store;
76

8-
/// <summary>
9-
/// An interface to store states.
10-
/// </summary>
117
public interface IStateStore : IDisposable
128
{
13-
/// <summary>
14-
/// Gets the state root trie of the <paramref name="stateRootHash"/> from the state store.
15-
/// </summary>
16-
/// <param name="stateRootHash">The state root hash of the state root trie to get.
17-
/// If <see langword="null"/> is passed the empty state root trie is returned.</param>
18-
/// <returns>The state root trie of the <paramref name="stateRootHash"/>.
19-
/// If <see langword="null"/> is passed the empty state root trie is returned.</returns>
209
ITrie GetStateRoot(HashDigest<SHA256> stateRootHash);
2110

22-
/// <summary>
23-
/// Commits given <paramref name="trie"/> to storage.
24-
/// Returned <see cref="ITrie"/> must be identical to the one obtained from
25-
/// <see cref="GetStateRoot"/> with resulting <see cref="ITrie"/>'s
26-
/// <see cref="ITrie.Hash"/>.
27-
/// </summary>
28-
/// <param name="trie">The <see cref="ITrie"/> to commit.</param>
29-
/// <returns>The committed <see cref="ITrie"/>. The committed <see cref="ITrie"/>'s
30-
/// <see cref="ITrie.Node"/> is guaranteed to be either <see langword="null"/>
31-
/// or a <see cref="HashNode"/>.</returns>
32-
/// <remarks>
33-
/// Given <paramref name="trie"/> must have originated from the same instance
34-
/// (or with an instance with the same reference to an <see cref="IKeyValueStore"/>).
35-
/// Otherwise, this is not guaranteed to work properly.
36-
/// </remarks>
37-
/// <seealso cref="GetStateRoot"/>
3811
ITrie Commit(ITrie trie);
3912
}

src/Libplanet.Store/Trie/NodeInserter.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ internal static class NodeInserter
1111
ValueNode valueNode => InsertToValueNode(valueNode, cursor, value),
1212
ShortNode shortNode => InsertToShortNode(shortNode, cursor, value),
1313
FullNode fullNode => InsertToFullNode(fullNode, cursor, value),
14-
NullNode _ => InsertToNullNode(cursor, value),
14+
NullNode nullNode => InsertToNullNode(nullNode, cursor, value),
1515
_ => throw new UnreachableException(
1616
$"Unsupported node value: {node.ToBencodex().Inspect()}"),
1717
};
1818

19+
private static INode InsertToNullNode(NullNode nullNode, in PathCursor cursor, ValueNode value)
20+
=> cursor.IsEnd ? value : new ShortNode(cursor.NextNibbles, value);
21+
1922
private static INode InsertToNullNode(in PathCursor cursor, ValueNode value)
2023
=> cursor.IsEnd ? value : new ShortNode(cursor.NextNibbles, value);
2124

src/Libplanet.Store/Trie/Nodes/HashNode.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.Security.Cryptography;
23
using Bencodex.Types;
34
using Libplanet.Common;
@@ -56,6 +57,8 @@ public INode Expand()
5657
}
5758

5859
return NodeDecoder.Decode(
59-
intermediateValue, NodeDecoder.HashEmbeddedNodeTypes, keyValueStore);
60+
intermediateValue, NodeDecoder.HashEmbeddedNodeTypes, keyValueStore)
61+
?? throw new UnreachableException(
62+
$"Failed to decode the hash node with hash {Hash}.");
6063
}
6164
}

src/Libplanet.Store/Trie/Nodes/NodeDecoder.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public static class NodeDecoder
2222
public const NodeTypes HashEmbeddedNodeTypes =
2323
NodeTypes.Value | NodeTypes.Short | NodeTypes.Full;
2424

25-
public static INode Decode(IValue value, NodeTypes nodeTypes, IKeyValueStore keyValueStore)
25+
public static INode? Decode(IValue value, NodeTypes nodeTypes, IKeyValueStore keyValueStore)
2626
{
2727
if (value is List list)
2828
{
@@ -62,7 +62,7 @@ public static INode Decode(IValue value, NodeTypes nodeTypes, IKeyValueStore key
6262
{
6363
if ((nodeTypes & NodeTypes.Null) == NodeTypes.Null)
6464
{
65-
return NullNode.Value;
65+
return null;
6666
}
6767
}
6868

src/Libplanet.Store/Trie/Trie.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ public sealed partial record class Trie(INode Node) : ITrie
1111
{
1212
private static readonly Codec _codec = new();
1313

14+
public Trie()
15+
: this(NullNode.Value)
16+
{
17+
}
18+
1419
public HashDigest<SHA256> Hash => Node switch
1520
{
1621
HashNode hashNode => hashNode.Hash,
22+
NullNode _ => default,
1723
_ => HashDigest<SHA256>.DeriveFrom(_codec.Encode(Node.ToBencodex())),
1824
};
1925

20-
public bool IsCommitted { get; private set; } = Node is HashNode;
26+
public bool IsCommitted { get; private set; } = Node is HashNode or NullNode;
2127

2228
public IValue this[in KeyBytes key]
2329
=> NodeResolver.ResolveToValue(Node, PathCursor.Create(key))

src/Libplanet.Store/TrieStateStore.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ var accountStateRootHash
8484
_logger.Verbose("Finished {MethodName}()", nameof(CopyStates));
8585
}
8686

87-
public ITrie GetStateRoot(HashDigest<SHA256> stateRootHash) => Trie.Trie.Create(stateRootHash, _keyValueStore);
87+
public ITrie GetStateRoot(HashDigest<SHA256> stateRootHash)
88+
=> stateRootHash == default ? new Trie.Trie() : Trie.Trie.Create(stateRootHash, _keyValueStore);
8889

8990
public void Dispose()
9091
{

src/Libplanet/Blockchain/BlockChain.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,8 @@ internal ImmutableSortedSet<Validator> GetValidatorSet(long index)
13141314
{
13151315
if (index == 0)
13161316
{
1317-
return GetNextWorldState().GetValidatorSet();
1317+
var worldContext = new WorldStateContext(GetNextWorldState());
1318+
return (ImmutableSortedSet<Validator>)worldContext[ReservedAddresses.ValidatorSetAddress][ReservedAddresses.ValidatorSetAddress];;
13181319
}
13191320

13201321
if (GetBlockCommit(index) is { } commit)

0 commit comments

Comments
 (0)