Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
s2quake committed Dec 10, 2024
1 parent 5eaa7bf commit a73925d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/Libplanet/Blockchain/Policies/BlockPolicy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public BlockPolicy(
if (block.Evidence.Any(evidence => evidence.Height < evidenceExpirationHeight))
{
return new InvalidBlockEvidencePendingDurationException(
$"Block #{block.Index} {block.Hash} includes evidence" +
$"Block #{block.Index} {block.Hash} includes evidence " +
$"that is older than expiration height {evidenceExpirationHeight}");
}

Expand Down
37 changes: 30 additions & 7 deletions test/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Libplanet.Types.Tx;
using Libplanet.Store;
using Libplanet.Store.Trie;
using Libplanet.Tests.Blockchain.Evidence;

namespace Libplanet.Explorer.Tests;

Expand All @@ -29,6 +30,8 @@ public class GeneratedBlockChainFixture

public int MaxTxCount { get; }

public int MaxEvidenceCount { get; }

public ImmutableDictionary<Address, ImmutableArray<Block>>
MinedBlocks { get; private set; }

Expand All @@ -43,7 +46,8 @@ public GeneratedBlockChainFixture(
int maxTxCount = 20,
int privateKeyCount = 10,
ImmutableArray<ImmutableArray<ImmutableArray<SimpleAction>>>?
txActionsForSuffixBlocks = null)
txActionsForSuffixBlocks = null,
int maxEvidenceCount = 2)
{
txActionsForSuffixBlocks ??=
ImmutableArray<ImmutableArray<ImmutableArray<SimpleAction>>>.Empty;
Expand All @@ -65,6 +69,7 @@ public GeneratedBlockChainFixture(
.ToImmutableDictionary(
key => key.Address,
key => ImmutableArray<Transaction>.Empty);
MaxEvidenceCount = maxEvidenceCount;

var privateKey = new PrivateKey();
var policy = new BlockPolicy(
Expand Down Expand Up @@ -105,22 +110,24 @@ public GeneratedBlockChainFixture(

while (Chain.Count < blockCount)
{
AddBlock(GetRandomTransactions());
AddBlock(GetRandomTransactions(), GetRandomEvidence(height: Chain.Count - 1));
}

if (txActionsForSuffixBlocks is { } txActionsForSuffixBlocksVal)
{
foreach (var actionsForTransactions in txActionsForSuffixBlocksVal)
{
var pk = PrivateKeys[Random.Next(PrivateKeys.Length)];
AddBlock(actionsForTransactions
var txs = actionsForTransactions
.Select(actions =>
Transaction.Create(
nonce: Chain.GetNextTxNonce(pk.Address),
privateKey: pk,
genesisHash: Chain.Genesis.Hash,
actions: actions.ToPlainValues()))
.ToImmutableArray());
.ToImmutableArray();
var evs = ImmutableArray<EvidenceBase>.Empty;
AddBlock(txs, evs);
}
}
}
Expand Down Expand Up @@ -159,6 +166,21 @@ private Transaction GetRandomTransaction(PrivateKey pk, long nonce)
gasLimit: null);
}

private ImmutableArray<EvidenceBase> GetRandomEvidence(long height)
{
return Enumerable
.Range(0, Random.Next(MaxEvidenceCount))
.Select<int, EvidenceBase>(_ =>
{
return new TestEvidence(
height: height,
validatorAddress: new PrivateKey().Address,
timestamp: DateTimeOffset.UtcNow);
})
.OrderBy(ev => ev.Id)
.ToImmutableArray();
}

private ImmutableArray<SimpleAction> GetRandomActions()
{
return Enumerable
Expand All @@ -167,7 +189,8 @@ private ImmutableArray<SimpleAction> GetRandomActions()
.ToImmutableArray();
}

private void AddBlock(ImmutableArray<Transaction> transactions)
private void AddBlock(
ImmutableArray<Transaction> transactions, ImmutableArray<EvidenceBase> evidence)
{
var proposer = PrivateKeys[Random.Next(PrivateKeys.Length)];
var block = Chain.EvaluateAndSign(
Expand All @@ -179,9 +202,9 @@ private void AddBlock(ImmutableArray<Transaction> transactions)
Chain.Tip.Hash,
BlockContent.DeriveTxHash(transactions),
Chain.Store.GetChainBlockCommit(Chain.Store.GetCanonicalChainId()!.Value),
evidenceHash: null),
evidenceHash: BlockContent.DeriveEvidenceHash(evidence)),
transactions,
evidence: Array.Empty<EvidenceBase>()).Propose(),
evidence: evidence).Propose(),
proposer);
Chain.Append(
block,
Expand Down
56 changes: 31 additions & 25 deletions test/Libplanet.Explorer.Tests/Queries/EvidenceQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,49 +22,55 @@
using static Libplanet.Explorer.Tests.GraphQLTestUtils;
using Libplanet.Action.Loader;
using Libplanet.Types.Evidence;
using Libplanet.Types.Blocks;

namespace Libplanet.Explorer.Tests.Queries;

public class EvidenceQueryTest
{
protected readonly BlockChain Chain;
protected MockBlockChainContext Source;
private readonly GeneratedBlockChainFixture _fixture;
private readonly MockBlockChainContext _source;
private readonly EvidenceQuery _queryGraph;

public EvidenceQueryTest()
{
Chain = Libplanet.Tests.TestUtils.MakeBlockChain(
new BlockPolicy(),
new MemoryStore(),
new TrieStateStore(new MemoryKeyValueStore()),
new SingleActionLoader(typeof(NullAction)),
privateKey: new PrivateKey(),
timestamp: DateTimeOffset.UtcNow
);
Source = new MockBlockChainContext(Chain);
_fixture = new GeneratedBlockChainFixture(seed: 0);
_source = new MockBlockChainContext(_fixture.Chain);
_queryGraph = new EvidenceQuery();
var _ = new ExplorerQuery(_source);
}

[Fact]
public async Task ExecuteAsync()
{
var tx = Transaction.Create(
0L,
new PrivateKey(),
Source.BlockChain.Genesis.Hash,
Enumerable.Empty<NullAction>().ToPlainValues()
);
tx.MarshalUnsignedTx();
ExecutionResult result = await ExecuteQueryAsync<EvidenceQuery>(@$"
var blocks = GetBlocks().ToArray();
var block = blocks[System.Random.Shared.Next(blocks.Length)];

ExecutionResult result = await ExecuteQueryAsync(@$"
{{
bindSignature(
unsignedTransaction: ""{ByteUtil.Hex(tx.SerializeUnsignedTx())}"",
signature: ""{ByteUtil.Hex(tx.Signature)}""
)
committedEvidence(
offset: {block.Index}
) {{
id
}}
}}
", source: Source);
", _queryGraph, source: _source);
Assert.Null(result.Errors);
ExecutionNode resultData = Assert.IsAssignableFrom<ExecutionNode>(result.Data);
IDictionary<string, object> resultDict =
Assert.IsAssignableFrom<IDictionary<string, object>>(resultData!.ToValue());
Assert.Equal(tx.Serialize(), ByteUtil.ParseHex((string)resultDict["bindSignature"]));
// Assert.Equal(tx.Serialize(), ByteUtil.ParseHex((string)resultDict["bindSignature"]));
}

private IEnumerable<Block> GetBlocks()
{
for (var i = 0; i < _fixture.Chain.Count; i++)
{
var block = _fixture.Chain[i];
if (block.Evidence.Count > 0)
{
yield return block;
}
}
}
}
45 changes: 21 additions & 24 deletions tools/Libplanet.Explorer/Queries/EvidenceQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,32 @@ public EvidenceQuery()
Field<NonNullGraphType<ListGraphType<NonNullGraphType<EvidenceType>>>>(
"committedEvidence",
arguments: new QueryArguments(
new QueryArgument<BlockHashType>
{
Name = "blockHash",
DefaultValue = null,
},
new QueryArgument<BooleanGraphType>
new QueryArgument<IdGraphType> { Name = "hash" },
new QueryArgument<IdGraphType> { Name = "index" }
),
resolve: context =>
{
string hash = context.GetArgument<string>("hash");
long? index = context.GetArgument<long?>("index", null);

if (!(hash is null ^ index is null))
{
Name = "desc",
DefaultValue = false,
},
new QueryArgument<IntGraphType>
throw new ExecutionError(
"The parameters hash and index are mutually exclusive; " +
"give only one at a time.");
}

if (hash is { } nonNullHash)
{
Name = "offset",
DefaultValue = 0,
},
new QueryArgument<IntGraphType>
return ExplorerQuery.ListCommitEvidence(BlockHash.FromString(nonNullHash));
}

if (index is { } nonNullIndex)
{
Name = "limit",
DefaultValue = MaxLimit,
return ExplorerQuery.ListCommitEvidence(nonNullIndex);
}
),
resolve: context =>
{
var blockHash = context.GetArgument<BlockHash?>("blockHash");
bool desc = context.GetArgument<bool>("desc");
int offset = context.GetArgument<int>("offset");
int? limit = context.GetArgument<int?>("limit");

return ExplorerQuery.ListCommitEvidence(blockHash, desc, offset, limit);
throw new ExecutionError("Unexpected block query");
}
);

Expand Down
18 changes: 9 additions & 9 deletions tools/Libplanet.Explorer/Queries/ExplorerQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,18 @@ internal static IEnumerable<EvidenceBase> ListPendingEvidence(
return evidence;
}

internal static IEnumerable<EvidenceBase> ListCommitEvidence(
BlockHash? blockHash, bool desc, int offset, int? limit)
internal static IEnumerable<EvidenceBase> ListCommitEvidence(BlockHash blockHash)
{
var blockChain = Chain;
var block = blockHash != null ? blockChain[blockHash.Value] : blockChain.Tip;
var comparer = desc ? EvidenceIdComparer.Descending : EvidenceIdComparer.Ascending;
var evidence = block.Evidence
.Skip(offset)
.Take(limit ?? int.MaxValue)
.OrderBy(ev => ev.Id, comparer);
var block = blockChain[blockHash];
return block.Evidence;
}

return evidence;
internal static IEnumerable<EvidenceBase> ListCommitEvidence(long index)
{
var blockChain = Chain;
var block = blockChain[index];
return block.Evidence;
}

internal static Block? GetBlockByHash(BlockHash hash) => Store.GetBlock(hash);
Expand Down

0 comments on commit a73925d

Please sign in to comment.