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

Introduce Swarm<T>.Reorged event #945

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ To be released.
- Added `StateCompleterSet<T>` struct.
- Added `StateCompleters<T>` static class.
- Added `FungibleAssetStateCompleters<T>` static class.
- Added `Reorged` event on `BlockChain<T>`. [[#945]]
riemannulus marked this conversation as resolved.
Show resolved Hide resolved
- Added `ReorgedEventArgs` class. [[#945]]

### Behavioral changes

Expand Down Expand Up @@ -192,6 +194,7 @@ To be released.
[#936]: https://github.com/planetarium/libplanet/pull/936
[#940]: https://github.com/planetarium/libplanet/pull/940
[#941]: https://github.com/planetarium/libplanet/pull/941
[#945]: https://github.com/planetarium/libplanet/pull/945
[sleep mode]: https://en.wikipedia.org/wiki/Sleep_mode


Expand Down
37 changes: 37 additions & 0 deletions Libplanet.Tests/Blockchain/BlockChainTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2173,6 +2173,43 @@ void TipChangedHandler(object target, BlockChain<DumbAction>.TipChangedEventArgs
// TODO: Add test cases for swap
}

[Fact]
private async void Reorged()
{
Block<DumbAction> actualOldTip = null;
Block<DumbAction> actualNewTip = null;
Block<DumbAction> actualBranchpoint = null;
int callCount = 0;

_blockChain.Reorged += (target, args) =>
{
actualOldTip = args.OldTip;
actualNewTip = args.NewTip;
actualBranchpoint = args.Branchpoint;
dahlia marked this conversation as resolved.
Show resolved Hide resolved
callCount += 1;
};
var branchpoint = _blockChain.Tip;
var fork = _blockChain.Fork(_blockChain.Tip.Hash);
await fork.MineBlock(_fx.Address1);
await fork.MineBlock(_fx.Address2);
await _blockChain.MineBlock(_fx.Address3);

var oldTip = _blockChain.Tip;
var newTip = fork.Tip;

dahlia marked this conversation as resolved.
Show resolved Hide resolved
Assert.Null(actualOldTip);
Assert.Null(actualNewTip);
Assert.Null(actualBranchpoint);
Assert.Equal(0, callCount);

_blockChain.Swap(fork, false);

Assert.Equal(oldTip.Hash, actualOldTip.Hash);
Assert.Equal(newTip.Hash, actualNewTip.Hash);
Assert.Equal(branchpoint.Hash, actualBranchpoint.Hash);
Assert.Equal(1, callCount);
}

[Fact]
private async void AbortMining()
{
Expand Down
35 changes: 35 additions & 0 deletions Libplanet/Blockchain/BlockChain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ bool render
/// </summary>
public event EventHandler<TipChangedEventArgs> TipChanged;

/// <summary>
/// An event which is invoked when the chain is reorged.
/// </summary>
public event EventHandler<ReorgedEventArgs> Reorged;

public IBlockPolicy<T> Policy { get; }

/// <summary>
Expand Down Expand Up @@ -1344,11 +1349,20 @@ IEnumerable<TxId> GetTxIdsWithRange(BlockChain<T> chain, Block<T> start, Block<T
Hash = other.Tip.Hash,
Index = other.Tip.Index,
};

var reorgedEventArgs = new ReorgedEventArgs
{
OldTip = Tip,
NewTip = other.Tip,
Branchpoint = topmostCommon,
};

Guid obsoleteId = Id;
Id = other.Id;
Store.SetCanonicalChainId(Id);
_blocks = new BlockSet<T>(Store);
TipChanged?.Invoke(this, tipChangedEventArgs);
Reorged?.Invoke(this, reorgedEventArgs);
_transactions = new TransactionSet<T>(Store);
Store.DeleteChainId(obsoleteId);
}
Expand Down Expand Up @@ -1624,5 +1638,26 @@ public class TipChangedEventArgs : EventArgs
/// </summary>
public HashDigest<SHA256> Hash { get; set; }
}

/// <summary>
/// Provides data for the <see cref="BlockChain{T}.Reorged"/> event.
/// </summary>
public class ReorgedEventArgs : EventArgs
{
/// <summary>
/// The <see cref="BlockChain{T}.Tip"/> before the chain is reorged.
/// </summary>
public Block<T> OldTip { get; set; }

/// <summary>
/// The <see cref="BlockChain{T}.Tip"/> after the chain is reorged.
/// </summary>
public Block<T> NewTip { get; set; }

/// <summary>
/// The <see cref="Block{T}"/> point of the chain branches off.
/// </summary>
public Block<T> Branchpoint { get; set; }
}
}
}