Skip to content

Commit

Permalink
Merge pull request #934 from dahlia/block-states-completer
Browse files Browse the repository at this point in the history
More flexible state complement
  • Loading branch information
dahlia authored Aug 5, 2020
2 parents 8d81300 + fcf682e commit 8d99392
Show file tree
Hide file tree
Showing 11 changed files with 446 additions and 125 deletions.
7 changes: 7 additions & 0 deletions .idea/.idea.Libplanet/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ To be released.
- Added `Block<T>.PreEvaluationHash` property. [[#931], [#935]]
- Added `BlockHeader.PreEvaluationHash` property. [[#931], [#935]]
- Added `HashDigest(ImmutableArray<byte>)` constructor. [[#931], [#935]]
- Incomplete block states became able to be handled in more flexible way.
[[#929], [#934]]
- Replaced `BlockChain<T>.GetState(Address, HashDigest<SHA256>?, bool)`
method with `GetState(Address, HashDigest<SHA256>?, StateCompleter<T>)`
method. Specifying `completeStates: true` and `false` can be replaced
by `stateCompleter: StateCompleters<T>.Recalculate` and
`StateCompleters<T>.Reject`, respectively.
- Added `StateCompleter<T>` delegate.
- Added `FungibleAssetStateCompleter<T>` delegate.
- Added `StateCompleterSet<T>` struct.
- Added `StateCompleters<T>` static class.
- Added `FungibleAssetStateCompleters<T>` static class.

### Behavioral changes

Expand Down Expand Up @@ -168,10 +180,12 @@ To be released.
[#925]: https://github.com/planetarium/libplanet/pull/925
[#926]: https://github.com/planetarium/libplanet/pull/926
[#927]: https://github.com/planetarium/libplanet/pull/927
[#929]: https://github.com/planetarium/libplanet/issues/929
[#930]: https://github.com/planetarium/libplanet/pull/930
[#931]: https://github.com/planetarium/libplanet/issues/931
[#932]: https://github.com/planetarium/libplanet/pull/932
[#933]: https://github.com/planetarium/libplanet/pull/933
[#934]: https://github.com/planetarium/libplanet/pull/934
[#935]: https://github.com/planetarium/libplanet/pull/935
[#936]: https://github.com/planetarium/libplanet/pull/936
[#940]: https://github.com/planetarium/libplanet/pull/940
Expand Down
47 changes: 43 additions & 4 deletions Libplanet.Tests/Blockchain/BlockChainTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1467,6 +1467,31 @@ public async void GetStateReturnsValidStateAfterFork()
Assert.Equal("item0.0,item1.0", (Text)forked.GetState(_fx.Address1));
}

[Fact]
public void GetStateWithStateCompleter()
{
(Address signer, Address[] addresses, BlockChain<DumbAction> chain)
= MakeIncompleteBlockStates();
StoreTracker store = (StoreTracker)chain.Store;

IValue value = chain.GetState(
addresses[4],
chain.Tip.Hash,
(bc, bh, a) => throw new Exception("This exception should not be thrown.")
);
Assert.Equal(new Text("9"), value);

value = chain.GetState(
addresses[4],
chain.BlockHashes.Skip((int)chain.Count - 2).First(),
(bc, hash, addr) =>
new Text($"{bc.Id}/{hash}/{addr}: callback called")
);
HashDigest<SHA256> prevUpdate = chain.BlockHashes.Skip(addresses.Length).First();
var expected = new Text($"{chain.Id}/{prevUpdate}/{addresses[4]}: callback called");
Assert.Equal(expected, value);
}

[Fact]
public void GetStateWithCompletingStates()
{
Expand Down Expand Up @@ -1510,7 +1535,10 @@ HashDigest<SHA256>[] ListStateReferences(string stateKey)
long txNonce = store.GetTxNonce(chain.Id, signer);

store.ClearLogs();
chain.GetState(addresses.Last(), completeStates: true);
chain.GetState(
addresses.Last(),
stateCompleter: StateCompleters<DumbAction>.Recalculate
);

Assert.Empty(
store.Logs.Where(l => l.Method == "StoreStateReference")
Expand All @@ -1524,7 +1552,10 @@ HashDigest<SHA256>[] ListStateReferences(string stateKey)
}

store.ClearLogs();
chain.GetState(addresses[0], completeStates: true);
chain.GetState(
addresses[0],
stateCompleter: StateCompleters<DumbAction>.Recalculate
);

foreach (var blockHash in chain.BlockHashes)
{
Expand Down Expand Up @@ -1899,7 +1930,11 @@ public void EvaluateBlockAction()
);

var miner = genesis.Miner.GetValueOrDefault();
var blockActionEvaluation = _blockChain.EvaluateBlockAction(genesis, null);
var blockActionEvaluation = _blockChain.EvaluateBlockAction(
genesis,
null,
StateCompleterSet<DumbAction>.Recalculate
);
Assert.Equal(_blockChain.Policy.BlockAction, blockActionEvaluation.Action);
Assert.Equal(
(Integer)2,
Expand All @@ -1915,7 +1950,11 @@ public void EvaluateBlockAction()
var txEvaluations = block1.EvaluateActionsPerTx(a =>
_blockChain.GetState(a, block1.PreviousHash))
.Select(te => te.Item2).ToList();
blockActionEvaluation = _blockChain.EvaluateBlockAction(block1, txEvaluations);
blockActionEvaluation = _blockChain.EvaluateBlockAction(
block1,
txEvaluations,
StateCompleterSet<DumbAction>.Recalculate
);

Assert.Equal((Integer)2, (Integer)blockActionEvaluation.OutputStates.GetState(miner));
}
Expand Down
47 changes: 34 additions & 13 deletions Libplanet.Tests/Net/SwarmTest.Preload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,10 @@ public async Task PreloadWithTrustedPeers(bool trust, bool genesisWithAction)
foreach (BlockChain<DumbAction> chain in new[] { minerChain, receiverChain })
{
var chainType = ReferenceEquals(chain, minerChain) ? "M" : "R";
var state = chain.GetState(target, completeStates: false);
IValue state = chain.GetState(
target,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal(
$"({chainType}) Item0.{i},Item1.{i},Item2.{i}",
Expand All @@ -610,7 +613,7 @@ public async Task PreloadWithTrustedPeers(bool trust, bool genesisWithAction)
IValue TryToGetDeepStates() => receiverChain.GetState(
target,
deepBlockHash,
completeStates: false
StateCompleters<DumbAction>.Reject
);

if (trust)
Expand All @@ -633,15 +636,21 @@ IValue TryToGetDeepStates() => receiverChain.GetState(
{
foreach (BlockChain<DumbAction> chain in new[] { minerChain, receiverChain })
{
var state = chain.GetState(genesisTarget, completeStates: false);
IValue state = chain.GetState(
genesisTarget,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal((Text)"Genesis", state);
}
}

foreach (BlockChain<DumbAction> chain in new[] { minerChain, receiverChain })
{
var minerState = chain.GetState(minerSwarm.Address, completeStates: false);
IValue minerState = chain.GetState(
minerSwarm.Address,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(minerState);
Assert.Equal(
(Integer)((genesisWithAction ? 1 : 0) + repeat * fixturePairs.Length),
Expand Down Expand Up @@ -924,7 +933,10 @@ await receiverSwarm.PreloadAsync(
foreach (BlockChain<DumbAction> chain in new[] { minerChain, receiverChain })
{
var chainType = ReferenceEquals(chain, minerChain) ? "M" : "R";
var state = chain.GetState(target, completeStates: false);
IValue state = chain.GetState(
target,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal(
$"({chainType}) Item0.{i},Item1.{i},Item2.{i},Item3.{i},Item9.{i}",
Expand All @@ -935,7 +947,7 @@ await receiverSwarm.PreloadAsync(
IValue TryToGetDeepStates() => receiverChain.GetState(
target,
deepBlockHash,
completeStates: false
StateCompleters<DumbAction>.Reject
);

Assert.Throws<IncompleteBlockStatesException>(
Expand All @@ -947,7 +959,10 @@ IValue TryToGetDeepStates() => receiverChain.GetState(

foreach (BlockChain<DumbAction> chain in new[] { minerChain, receiverChain })
{
var state = chain.GetState(genesisTarget, completeStates: false);
IValue state = chain.GetState(
genesisTarget,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal((Text)"Genesis", state);
}
Expand Down Expand Up @@ -1014,7 +1029,10 @@ await swarm1.PreloadAsync(

foreach (BlockChain<DumbAction> chain in new[] { chain0, chain1 })
{
var blockActionState = chain.GetState(swarm0.Address, completeStates: false);
IValue blockActionState = chain.GetState(
swarm0.Address,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(blockActionState);
Assert.Equal((Integer)repeat, (Integer)blockActionState);
}
Expand All @@ -1026,7 +1044,7 @@ await swarm1.PreloadAsync(
var state = chain1.GetState(
swarm0.Address,
blockHashes[i],
completeStates: false
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal((Integer)i, (Integer)state);
Expand All @@ -1038,7 +1056,7 @@ await swarm1.PreloadAsync(
chain1.GetState(
swarm0.Address,
blockHashes[i],
completeStates: false
stateCompleter: StateCompleters<DumbAction>.Reject
);
});
}
Expand All @@ -1052,7 +1070,10 @@ await swarm2.PreloadAsync(

foreach (BlockChain<DumbAction> chain in new[] { chain1, chain2 })
{
var blockActionState = chain.GetState(swarm0.Address, completeStates: false);
IValue blockActionState = chain.GetState(
swarm0.Address,
stateCompleter: StateCompleters<DumbAction>.Reject
);
Assert.NotNull(blockActionState);
Assert.Equal((Integer)repeat, (Integer)blockActionState);
}
Expand All @@ -1064,7 +1085,7 @@ await swarm2.PreloadAsync(
var state = chain2.GetState(
swarm0.Address,
blockHashes[i],
completeStates: false
StateCompleters<DumbAction>.Reject
);
Assert.NotNull(state);
Assert.Equal((Integer)i, (Integer)state);
Expand All @@ -1076,7 +1097,7 @@ await swarm2.PreloadAsync(
chain2.GetState(
swarm0.Address,
blockHashes[i],
completeStates: false
StateCompleters<DumbAction>.Reject
);
});
}
Expand Down
1 change: 1 addition & 0 deletions Libplanet.Tools/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# npm
!bin/
bin/*/
node_modules/
package-lock.json
Loading

0 comments on commit 8d99392

Please sign in to comment.