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

Integrate Block<T>.Validate() and .EvaluateActions() #243

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGES.md
Expand Up @@ -47,6 +47,7 @@ To be released.
[[#232]]
- Added `IStore.ForkStateReferences<T>(string, string, Block<T>,
IImmutableSet<Address>` method. [[#232]]
- Removed `Block<T>.Validate()` and `Block<T>.EvaluateActions()` method. [[#243]]

### Added interfaces

Expand Down Expand Up @@ -74,6 +75,7 @@ To be released.
messages when a `Swarm` instance is requested to terminate.
- Added `NamespaceNotFoundException` class. [[#232]]
- Added `SimultaneousTxsException` class. [[#242]]
- Added `Block<T>.Evaluate()` method. [[#243]]

### Behavioral changes

Expand All @@ -97,7 +99,11 @@ To be released.
to the previous state. [[#241]]
- A signer became to allowed to have only one transaction at most in
`Block<T>.Transactions`. [[#125]], [[#242]]

- `Block<T>.Validate()` and `Block<T>.EvaluateActions()` are integrated into
`Block<T>.Evaluate()`. [[#243]]
- `BlockChain<T>.Append()` became to execute `Action.Execute()` only once per
actions in the `Block<T>`. [[#243]]
longfin marked this conversation as resolved.
Show resolved Hide resolved

### Bug fixes

- Fixed a bug that TURN relay had been disconnected when being connected for
Expand Down Expand Up @@ -156,6 +162,7 @@ To be released.
[#240]: https://github.com/planetarium/libplanet/pull/240
[#241]: https://github.com/planetarium/libplanet/pull/241
[#242]: https://github.com/planetarium/libplanet/pull/242
[#243]: https://github.com/planetarium/libplanet/pull/243


Version 0.2.2
Expand Down
80 changes: 31 additions & 49 deletions Libplanet.Tests/Blocks/BlockTest.cs
Expand Up @@ -8,6 +8,7 @@
using Libplanet.Blocks;
using Libplanet.Crypto;
using Libplanet.Tests.Common.Action;
using Libplanet.Tests.Tx;
using Libplanet.Tx;
using Xunit;
using static Libplanet.Tests.TestUtils;
Expand Down Expand Up @@ -169,7 +170,7 @@ public void FromBencodex()
"SA1118",
Justification = "Long array literals should be multiline.")]
[Fact]
public void EvaluateActions()
public void EvaluateActionsPerTx()
{
ImmutableArray<Address> addresses = Enumerable.Range(0, 5)
.Select(_ => new Address(new PrivateKey().PublicKey))
Expand All @@ -179,20 +180,19 @@ public void EvaluateActions()

Block<DumbAction> genesis = MineGenesis<DumbAction>();
Assert.Empty(genesis.EvaluateActionsPerTx(address => null));
Assert.Empty(genesis.EvaluateActions(address => null));

Transaction<DumbAction>[] blockIdx1Txs =
{
Transaction<DumbAction>.Create(
_fx.TxFixture.PrivateKey,
_fx.TxFixture.PrivateKey1,
new[]
{
MakeAction(addresses[0], 'A'),
MakeAction(addresses[1], 'B'),
}
),
Transaction<DumbAction>.Create(
_fx.TxFixture.PrivateKey,
_fx.TxFixture.PrivateKey2,
new[] { MakeAction(addresses[2], 'C') }
),
};
Expand All @@ -201,11 +201,11 @@ public void EvaluateActions()
.EvaluateActionsPerTx(address => null)
.ToImmutableArray();
int randomValue = 0;
(int, int, string[])[] expectations =
(int, int, string[], Address)[] expectations =
{
(0, 0, new[] { "A", null, null, null, null }),
(0, 1, new[] { "A", "B", null, null, null }),
(1, 0, new[] { "A", "B", "C", null, null }),
(0, 0, new[] { "A", null, null, null, null }, _fx.TxFixture.PrivateKey1.PublicKey.ToAddress()),
longfin marked this conversation as resolved.
Show resolved Hide resolved
(0, 1, new[] { "A", "B", null, null, null }, _fx.TxFixture.PrivateKey1.PublicKey.ToAddress()),
longfin marked this conversation as resolved.
Show resolved Hide resolved
(1, 0, new[] { "A", "B", "C", null, null }, _fx.TxFixture.PrivateKey2.PublicKey.ToAddress()),
};
Assert.Equal(expectations.Length, pairs.Length);
foreach (
Expand All @@ -218,7 +218,7 @@ public void EvaluateActions()
blockIdx1Txs[expect.Item1].Actions[expect.Item2],
eval.Action
);
Assert.Equal(_fx.TxFixture.Address, eval.InputContext.Signer);
Assert.Equal(expect.Item4, eval.InputContext.Signer);
Assert.Equal(GenesisMinerAddress, eval.InputContext.Miner);
Assert.Equal(blockIdx1.Index, eval.InputContext.BlockIndex);
Assert.False(eval.InputContext.Rehearsal);
Expand All @@ -236,10 +236,10 @@ public void EvaluateActions()
}

IImmutableDictionary<Address, object> dirty1 = blockIdx1
.EvaluateActions(address => null)
.Evaluate(DateTimeOffset.UtcNow, address => null)
.Aggregate(
ImmutableDictionary<Address, object>.Empty,
(dirty, delta) => dirty.SetItems(delta.GetUpdatedStates())
(dirty, ev) => dirty.SetItems(ev.OutputStates.GetUpdatedStates())
);
Assert.Equal(
new Dictionary<Address, object>
Expand All @@ -255,15 +255,15 @@ public void EvaluateActions()
Transaction<DumbAction>[] blockIdx2Txs =
{
Transaction<DumbAction>.Create(
_fx.TxFixture.PrivateKey,
_fx.TxFixture.PrivateKey1,
new[] { MakeAction(addresses[0], 'D') }
),
Transaction<DumbAction>.Create(
_fx.TxFixture.PrivateKey,
_fx.TxFixture.PrivateKey2,
new[] { MakeAction(addresses[3], 'E') }
),
Transaction<DumbAction>.Create(
_fx.TxFixture.PrivateKey,
_fx.TxFixture.PrivateKey3,
new[]
{
new DumbAction(
Expand All @@ -275,15 +275,16 @@ public void EvaluateActions()
}
),
};

Block<DumbAction> blockIdx2 = MineNext(blockIdx1, blockIdx2Txs);
pairs = blockIdx2
.EvaluateActionsPerTx(dirty1.GetValueOrDefault)
.ToImmutableArray();
expectations = new[]
{
(0, 0, new[] { "A,D", "B", "C", null, null }),
(1, 0, new[] { "A,D", "B", "C", "E", null }),
(2, 0, new[] { "A,D", "B", "C", "E", "RecordRehearsal:False" }),
(0, 0, new[] { "A,D", "B", "C", null, null }, _fx.TxFixture.PrivateKey1.PublicKey.ToAddress()),
longfin marked this conversation as resolved.
Show resolved Hide resolved
(1, 0, new[] { "A,D", "B", "C", "E", null }, _fx.TxFixture.PrivateKey2.PublicKey.ToAddress()),
(2, 0, new[] { "A,D", "B", "C", "E", "RecordRehearsal:False" }, _fx.TxFixture.PrivateKey3.PublicKey.ToAddress()),
longfin marked this conversation as resolved.
Show resolved Hide resolved
};
Assert.Equal(expectations.Length, pairs.Length);
foreach (
Expand All @@ -296,7 +297,7 @@ public void EvaluateActions()
blockIdx2Txs[expect.Item1].Actions[expect.Item2],
eval.Action
);
Assert.Equal(_fx.TxFixture.Address, eval.InputContext.Signer);
Assert.Equal(expect.Item4, eval.InputContext.Signer);
Assert.Equal(GenesisMinerAddress, eval.InputContext.Miner);
Assert.Equal(blockIdx2.Index, eval.InputContext.BlockIndex);
Assert.False(eval.InputContext.Rehearsal);
Expand All @@ -314,10 +315,10 @@ public void EvaluateActions()
}

IImmutableDictionary<Address, object> dirty2 = blockIdx2
.EvaluateActions(dirty1.GetValueOrDefault)
.Evaluate(DateTimeOffset.UtcNow, dirty1.GetValueOrDefault)
.Aggregate(
ImmutableDictionary<Address, object>.Empty,
(dirty, delta) => dirty.SetItems(delta.GetUpdatedStates())
(dirty, ev) => dirty.SetItems(ev.OutputStates.GetUpdatedStates())
);
Assert.Equal(
new Dictionary<Address, object>
Expand All @@ -332,26 +333,7 @@ public void EvaluateActions()
}

[Fact]
public void Validate()
{
IAccountStateDelta state0 =
_fx.Genesis.Validate(DateTimeOffset.UtcNow, _ => null);
Assert.Empty(state0.UpdatedAddresses);

IAccountStateDelta state1 =
_fx.Next.Validate(DateTimeOffset.UtcNow, state0.GetState);
Assert.Empty(state1.UpdatedAddresses);

IAccountStateDelta state2 =
_fx.HasTx.Validate(DateTimeOffset.UtcNow, state1.GetState);
Assert.Equal(
new[] { _fx.TxFixture.Address }.ToImmutableHashSet(),
state2.UpdatedAddresses
);
}

[Fact]
public void ValidateInvalidTxSignature()
public void EvaluateInvalidTxSignature()
{
RawTransaction rawTx = new RawTransaction(
_fx.TxFixture.Address.ToByteArray(),
Expand All @@ -367,12 +349,12 @@ public void ValidateInvalidTxSignature()
new List<Transaction<DumbAction>> { invalidTx }
);
Assert.Throws<InvalidTxSignatureException>(() =>
invalidBlock.Validate(DateTimeOffset.UtcNow, _ => null)
invalidBlock.Evaluate(DateTimeOffset.UtcNow, _ => null)
);
}

[Fact]
public void ValidateInvalidTxPublicKey()
public void EvaluateInvalidTxPublicKey()
{
RawTransaction rawTxWithoutSig = new RawTransaction(
new PrivateKey().PublicKey.ToAddress().ToByteArray(),
Expand All @@ -382,7 +364,7 @@ public void ValidateInvalidTxPublicKey()
new IDictionary<string, object>[0],
new byte[0]
);
byte[] sig = _fx.TxFixture.PrivateKey.Sign(
byte[] sig = _fx.TxFixture.PrivateKey1.Sign(
new Transaction<DumbAction>(rawTxWithoutSig).ToBencodex(false)
);
var invalidTx = new Transaction<DumbAction>(
Expand All @@ -400,12 +382,12 @@ public void ValidateInvalidTxPublicKey()
new List<Transaction<DumbAction>> { invalidTx }
);
Assert.Throws<InvalidTxPublicKeyException>(() =>
invalidBlock.Validate(DateTimeOffset.UtcNow, _ => null)
invalidBlock.Evaluate(DateTimeOffset.UtcNow, _ => null)
);
}

[Fact]
public void ValidateInvalidTxUpdatedAddresses()
public void EvaluateInvalidTxUpdatedAddresses()
{
ImmutableArray<IDictionary<string, object>> rawActions =
_fx.TxFixture.TxWithActions
Expand All @@ -418,7 +400,7 @@ public void ValidateInvalidTxUpdatedAddresses()
rawActions,
new byte[0]
);
byte[] sig = _fx.TxFixture.PrivateKey.Sign(
byte[] sig = _fx.TxFixture.PrivateKey1.Sign(
new Transaction<PolymorphicAction<BaseAction>>(
rawTxWithoutSig
).ToBencodex(false)
Expand All @@ -441,12 +423,12 @@ public void ValidateInvalidTxUpdatedAddresses()
}
);
Assert.Throws<InvalidTxUpdatedAddressesException>(() =>
invalidBlock.Validate(DateTimeOffset.UtcNow, _ => null)
invalidBlock.Evaluate(DateTimeOffset.UtcNow, _ => null)
);
}

[Fact]
public void ValidateSignersHaveOnlyOneTransactions()
public void EvaluateSignersHaveOnlyOneTransactions()
{
var privateKey = new PrivateKey();

Expand All @@ -462,7 +444,7 @@ public void ValidateSignersHaveOnlyOneTransactions()
new[] { tx1, tx2 });

Assert.Throws<SimultaneousTxsException>(() =>
invalidBlock.Validate(DateTimeOffset.UtcNow, _ => null));
invalidBlock.Evaluate(DateTimeOffset.UtcNow, _ => null));
}

[Fact]
Expand Down
20 changes: 10 additions & 10 deletions Libplanet.Tests/Tx/TransactionTest.cs
Expand Up @@ -97,13 +97,13 @@ public void Create()
public void CreateWithDefaultUpdatedAddresses()
{
Transaction<DumbAction> emptyTx = Transaction<DumbAction>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
new DumbAction[0]
);
Assert.Empty(emptyTx.UpdatedAddresses);

var tx = Transaction<PolymorphicAction<BaseAction>>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
_fx.TxWithActions.Actions
);
Assert.Equal(
Expand All @@ -113,7 +113,7 @@ public void CreateWithDefaultUpdatedAddresses()

Address additionalAddr = new PrivateKey().PublicKey.ToAddress();
var txWithAddr = Transaction<PolymorphicAction<BaseAction>>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
_fx.TxWithActions.Actions,
new[] { additionalAddr }.ToImmutableHashSet()
);
Expand All @@ -128,7 +128,7 @@ public void CreateWithDefaultTimestamp()
{
DateTimeOffset rightBefore = DateTimeOffset.UtcNow;
Transaction<DumbAction> tx = Transaction<DumbAction>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
new DumbAction[0],
ImmutableHashSet<Address>.Empty
);
Expand All @@ -153,7 +153,7 @@ public void CreateWithMissingRequiredArguments()
// The actions parameter cannot be null.
Assert.Throws<ArgumentNullException>(() =>
Transaction<DumbAction>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
null,
ImmutableHashSet<Address>.Empty,
DateTimeOffset.UtcNow
Expand All @@ -167,7 +167,7 @@ public void CreateWithActionsThrowingException()
var action = new ThrowException { Throw = true };
Assert.Throws<UnexpectedlyTerminatedTxRehearsalException>(() =>
Transaction<ThrowException>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
new[] { action },
ImmutableHashSet<Address>.Empty,
DateTimeOffset.UtcNow
Expand Down Expand Up @@ -602,7 +602,7 @@ public void EvaluateActions()
new DumbAction(addresses[2], "R", true, recordRandom: true),
};
Transaction<DumbAction> tx =
Transaction<DumbAction>.Create(_fx.PrivateKey, actions);
Transaction<DumbAction>.Create(_fx.PrivateKey1, actions);
foreach (bool rehearsal in new[] { false, true })
{
DumbAction.RehearsalRecords.Value =
Expand Down Expand Up @@ -843,12 +843,12 @@ public void ActionsAreIsolatedFromOutside()
{
var actions = new List<DumbAction>();
Transaction<DumbAction> t1 = Transaction<DumbAction>.Create(
_fx.PrivateKey,
_fx.PrivateKey1,
actions
);
var t2 = new Transaction<DumbAction>(
_fx.PrivateKey.PublicKey.ToAddress(),
_fx.PrivateKey.PublicKey,
_fx.PrivateKey1.PublicKey.ToAddress(),
_fx.PrivateKey1.PublicKey,
ImmutableHashSet<Address>.Empty,
t1.Timestamp,
actions,
Expand Down