Skip to content

Commit

Permalink
[skip changelog] New transaction ordering optimized
Browse files Browse the repository at this point in the history
Comment added for clarity

Unnecessary parameters removed
  • Loading branch information
greymistcube authored and longfin committed Jun 5, 2021
1 parent 2cc7d16 commit ed604d2
Showing 1 changed file with 11 additions and 10 deletions.
21 changes: 11 additions & 10 deletions Libplanet/Blocks/Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,8 @@ internal static IEnumerable<Transaction<T>> OrderTxsForEvaluation(
BlockHash preEvaluationHash)
{
return protocolVersion > 1
? OrderTxsForEvaluationV2(protocolVersion, txs, preEvaluationHash)
: OrderTxsForEvaluationV0(protocolVersion, txs, preEvaluationHash);
? OrderTxsForEvaluationV2(txs, preEvaluationHash)
: OrderTxsForEvaluationV0(txs, preEvaluationHash);
}

internal void Validate(DateTimeOffset currentTime)
Expand Down Expand Up @@ -723,12 +723,9 @@ internal RawBlock ToRawBlock()
}

private static IEnumerable<Transaction<T>> OrderTxsForEvaluationV0(
int protocolVersion,
IEnumerable<Transaction<T>> txs,
BlockHash preEvaluationHash)
{
// As the order of transactions should be unpredictable until a block is mined,
// the sorter key should be derived from both a block hash and a txid.
var maskInteger = new BigInteger(preEvaluationHash.ToByteArray());

// Transactions with the same signers are grouped first and the ordering of the groups
Expand All @@ -745,16 +742,20 @@ private static IEnumerable<Transaction<T>> OrderTxsForEvaluationV0(
}

private static IEnumerable<Transaction<T>> OrderTxsForEvaluationV2(
int protocolVersion,
IEnumerable<Transaction<T>> txs,
BlockHash preEvaluationHash)
{
using SHA256 sha256 = SHA256.Create();
var mask = new BigInteger(sha256.ComputeHash(preEvaluationHash.ToByteArray()));
var numShiftBits = sizeof(long) * 8;
var maskInteger = new BigInteger(sha256.ComputeHash(preEvaluationHash.ToByteArray()));

return txs.OrderBy(tx =>
((new BigInteger(tx.Signer.ToByteArray()) ^ mask) << numShiftBits) + tx.Nonce);
// Transactions with the same signers are grouped first and the ordering of the groups
// is determined by the signer's address with XOR bitmask applied using
// the pre-evaluation hash provided. Then within each group, transactions
// are ordered by nonce.
return txs
.GroupBy(tx => tx.Signer)
.OrderBy(group => maskInteger ^ new BigInteger(group.Key.ToByteArray()))
.SelectMany(group => group.OrderBy(tx => tx.Nonce));
}

private readonly struct BlockSerializationContext
Expand Down

0 comments on commit ed604d2

Please sign in to comment.