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

🧹 Remove mining #3067

Merged
merged 4 commits into from Apr 6, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Expand Up @@ -55,6 +55,9 @@ To be released.
- (Libplanet.Extensions.Cocona) Changed signature of
`ApvCommand.Verify(string?, string[]?, bool)` method to
`ApvCommand.Verify(string?, PublicKey[]?, bool)`. [[#3044]]
- Removed `PreEvaluationBlock<T>.Mine()` and `BlockMetadata.MineNonce()`
methods. [[#3067]]
- Removed `HashCash` class. [[#3067]]

### Backward-incompatible network protocol changes

Expand Down Expand Up @@ -140,6 +143,7 @@ To be released.
[#3044]: https://github.com/planetarium/libplanet/pull/3044
[#3054]: https://github.com/planetarium/libplanet/issues/3054
[#3060]: https://github.com/planetarium/libplanet/pull/3060
[#3067]: https://github.com/planetarium/libplanet/pull/3067


Version 0.53.4
Expand Down
2 changes: 1 addition & 1 deletion Libplanet.Tests/Blockchain/BlockChainTest.MineBlock.cs
Expand Up @@ -496,7 +496,7 @@ public void IgnoreDuplicatedNonceTxs()
[SkippableFact]
public void GatherTransactionsToPropose()
{
// TODO: We test more properties of GatherTransactionsToMine() method:
// TODO: We test more properties of GatherTransactionsToPropose() method:
// - if transactions are cut off if they exceed GetMaxTransactionsBytes()
// - if transactions with already consumed nonces are excluded
// - if transactions with greater nonces than unconsumed nonces are excluded
Expand Down
14 changes: 0 additions & 14 deletions Libplanet.Tests/Blocks/BlockMetadataTest.cs
Expand Up @@ -329,20 +329,6 @@ public void ValidateLastCommit()
lastCommit: validLastCommit);
}

[Fact]
public void MineNonce()
{
var codec = new Codec();
var difficulty = 5000L;

(Nonce nonce, HashDigest<SHA256> preEvalHash) =
GenesisMetadata.MineNonce(difficulty);
Assert.True(Satisfies(preEvalHash.ByteArray, difficulty));
HashDigest<SHA256> actual = HashDigest<SHA256>.DeriveFrom(
codec.Encode(GenesisMetadata.MakeCandidateData(nonce)));
AssertBytesEqual(actual.ByteArray, preEvalHash.ByteArray);
}

private static Vote GenerateVote(BlockHash? hash, long height, int round, VoteFlag flag)
{
var key = new PrivateKey();
Expand Down
88 changes: 0 additions & 88 deletions Libplanet.Tests/HashcashTest.cs

This file was deleted.

44 changes: 0 additions & 44 deletions Libplanet.Tests/TestUtils.cs
Expand Up @@ -402,30 +402,6 @@ public static byte[] GetRandomBytes(int size)
height, round, blockHash, votes);
}

public static PreEvaluationBlock<T> MineGenesis<T>(
PublicKey miner = null,
IReadOnlyList<Transaction<T>> transactions = null,
DateTimeOffset? timestamp = null,
int protocolVersion = Block<T>.CurrentProtocolVersion
)
where T : IAction, new()
{
var txs = transactions?.OrderBy(tx => tx.Id).ToList() ?? new List<Transaction<T>>();
var content = new BlockContent<T>(
new BlockMetadata(
protocolVersion: protocolVersion,
index: 0,
timestamp: timestamp ??
new DateTimeOffset(2018, 11, 29, 0, 0, 0, TimeSpan.Zero),
miner: (miner ?? GenesisProposer.PublicKey).ToAddress(),
publicKey: protocolVersion >= 2 ? miner ?? GenesisProposer.PublicKey : null,
previousHash: null,
txHash: BlockContent<T>.DeriveTxHash(txs.OrderBy(tx => tx.Id).ToList()),
lastCommit: null),
transactions: txs);
return content.Mine(0L, default);
}

public static PreEvaluationBlock<T> ProposeGenesis<T>(
PublicKey proposer = null,
IReadOnlyList<Transaction<T>> transactions = null,
Expand Down Expand Up @@ -466,26 +442,6 @@ public static byte[] GetRandomBytes(int size)
return content.Propose();
}

public static Block<T> MineGenesisBlock<T>(
PrivateKey miner,
IReadOnlyList<Transaction<T>> transactions = null,
DateTimeOffset? timestamp = null,
int protocolVersion = Block<T>.CurrentProtocolVersion,
HashDigest<SHA256> stateRootHash = default
)
where T : IAction, new()
{
PreEvaluationBlock<T> preEval = MineGenesis(
miner?.PublicKey,
transactions,
timestamp,
protocolVersion);
var hash = preEval.Header.DeriveBlockHash(stateRootHash, null);
return protocolVersion < 2
? new Block<T>(preEval, (stateRootHash, null, hash))
: preEval.Sign(miner, stateRootHash);
}

public static Block<T> ProposeGenesisBlock<T>(
PrivateKey miner,
IReadOnlyList<Transaction<T>> transactions = null,
Expand Down
21 changes: 0 additions & 21 deletions Libplanet/Blocks/BlockContent.cs
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Security.Cryptography;
using System.Threading;
using Libplanet.Action;
using Libplanet.Crypto;
using Libplanet.Tx;
Expand Down Expand Up @@ -196,26 +195,6 @@ public BlockContent(IBlockMetadata metadata, IEnumerable<Transaction<T>> transac
return new HashDigest<SHA256>(hasher.Hash);
}

/// <summary>
/// Mines the PoW (proof-of-work) nonce satisfying <paramref name="difficulty"/>
/// for <see cref="PreEvaluationBlockHeader.PreEvaluationHash"/>
/// and returns a valid <see cref="PreEvaluationBlock{T}"/> instance.
/// </summary>
/// <param name="difficulty">The difficulty to target when mining
/// <see cref="PreEvaluationBlockHeader.PreEvaluationHash"/>.</param>
/// <param name="cancellationToken">An optional cancellation token used to propagate signal
/// that this operation should be cancelled.</param>
/// <returns>A <see cref="PreEvaluationBlock{T}"/> instance with a valid proof-of-work.
/// </returns>
/// <exception cref="OperationCanceledException">Thrown when the specified
/// <paramref name="cancellationToken"/> received a cancellation request.</exception>
public PreEvaluationBlock<T> Mine(
long difficulty,
CancellationToken cancellationToken = default) =>
new PreEvaluationBlock<T>(
this,
_blockMetadata.MineNonce(difficulty, cancellationToken).PreEvaluationHash);

public PreEvaluationBlock<T> Propose()
{
return new PreEvaluationBlock<T>(
Expand Down
61 changes: 0 additions & 61 deletions Libplanet/Blocks/BlockMetadata.cs
@@ -1,11 +1,7 @@
using System;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using Bencodex;
using Bencodex.Types;
using Libplanet.Crypto;

namespace Libplanet.Blocks
Expand Down Expand Up @@ -311,62 +307,5 @@ public Bencodex.Types.Dictionary MakeCandidateData(Nonce nonce)
/// <returns>A pre-evaluation block hash.</returns>
public HashDigest<SHA256> DerivePreEvaluationHash(Nonce nonce) =>
HashDigest<SHA256>.DeriveFrom(Codec.Encode(MakeCandidateData(nonce)));

/// <summary>
/// Mines the PoW (proof-of-work) nonce satisfying <paramref name="difficulty"/>.
/// </summary>
/// <param name="difficulty">The difficulty to target when mining
/// <see cref="PreEvaluationBlockHeader.PreEvaluationHash"/>.</param>
/// <param name="cancellationToken">An optional cancellation token used to propagate signal
/// that this operation should be cancelled.</param>
/// <returns>A pair of the mined nonce and the pre-evaluation hash that satisfy the
/// block <paramref name="difficulty"/>.</returns>
/// <exception cref="OperationCanceledException">Thrown when the specified
/// <paramref name="cancellationToken"/> received a cancellation request.</exception>
public (Nonce Nonce, HashDigest<SHA256> PreEvaluationHash) MineNonce(
long difficulty,
CancellationToken cancellationToken = default)
{
Hashcash.Stamp stamp = GetStampFunction();
var random = new Random();
int seed = random.Next();
return Hashcash.Answer(
stamp, difficulty, seed, cancellationToken);
}

private Hashcash.Stamp GetStampFunction()
{
// Poor man' way to optimize stamp...
// FIXME: We need to rather reorganize the serialization layout.
byte[] emptyNonce = Codec.Encode(MakeCandidateData(default));
byte[] oneByteNonce = Codec.Encode(MakeCandidateData(new Nonce(new byte[1])));
int offset = 0;
while (offset < emptyNonce.Length && emptyNonce[offset].Equals(oneByteNonce[offset]))
{
offset++;
}

// Prepares fixed parts (stampPrefix, stampSuffix, colon) ahead of time
// so that they can be reused:
const int nonceLength = 2; // In Bencodex, empty bytes are represented as "0:".
byte[] stampPrefix = new byte[offset];
Array.Copy(emptyNonce, stampPrefix, stampPrefix.Length);
byte[] stampSuffix = new byte[emptyNonce.Length - offset - nonceLength];
Array.Copy(emptyNonce, offset + nonceLength, stampSuffix, 0, stampSuffix.Length);
byte[] colon = { 0x3a }; // ':'

byte[] Stamp(Nonce nonce)
{
int nLen = nonce.ByteArray.Length;
return stampPrefix
.Concat(Encoding.ASCII.GetBytes(nLen.ToString(CultureInfo.InvariantCulture)))
.Concat(colon)
.Concat(nonce.ToByteArray())
.Concat(stampSuffix)
.ToArray();
}

return Stamp;
}
}
}
83 changes: 0 additions & 83 deletions Libplanet/Hashcash.cs

This file was deleted.