Skip to content

Commit

Permalink
DBFTPlugin: adapt Conflicts attribute verification (#802)
Browse files Browse the repository at this point in the history
* DBFTPlugin: adapt Conflicts attribute verification

Depends on neo-project/neo#2818, see the
neo-project/neo#2818 (comment).

Signed-off-by: Anna Shaleva <[email protected]>

* Fix Conflicts attribute verification

Fetch the update from core: neo-project/neo#2818 (comment).

* Fetch on-chain conflict signer fix from core

Use new API from neo-project/neo@ee7333f.

---------

Signed-off-by: Anna Shaleva <[email protected]>
Co-authored-by: Vitor Nazário Coelho <[email protected]>
Co-authored-by: Owen Zhang <[email protected]>
Co-authored-by: Jimmy <[email protected]>
  • Loading branch information
4 people authored Sep 5, 2023
1 parent c0de35f commit 906b3f2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/DBFTPlugin/Consensus/ConsensusService.OnMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,26 @@ private void OnPrepareRequestReceived(ExtensiblePayload payload, PrepareRequest
{
if (mempoolVerified.TryGetValue(hash, out Transaction tx))
{
if (NativeContract.Ledger.ContainsConflictHash(context.Snapshot, hash, tx.Signers.Select(s => s.Account)))
{
Log($"Invalid request: transaction has on-chain conflict", LogLevel.Warning);
return;
}

if (!AddTransaction(tx, false))
return;
}
else
{
if (neoSystem.MemPool.TryGetValue(hash, out tx))
{
if (NativeContract.Ledger.ContainsConflictHash(context.Snapshot, hash, tx.Signers.Select(s => s.Account)))
{
Log($"Invalid request: transaction has on-chain conflict", LogLevel.Warning);
return;
}
unverified.Add(tx);
}
}
}
foreach (Transaction tx in unverified)
Expand Down
33 changes: 32 additions & 1 deletion src/DBFTPlugin/Consensus/ConsensusService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,38 @@ private bool AddTransaction(Transaction tx, bool verify)
{
if (verify)
{
VerifyResult result = tx.Verify(neoSystem.Settings, context.Snapshot, context.VerificationContext);
// At this step we're sure that there's no on-chain transaction that conflicts with
// the provided tx because of the previous Blockchain's OnReceive check. Thus, we only
// need to check that current context doesn't contain conflicting transactions.
VerifyResult result;

// Firstly, check whether tx has Conlicts attribute with the hash of one of the context's transactions.
foreach (var h in tx.GetAttributes<Conflicts>().Select(attr => attr.Hash))
{
if (context.TransactionHashes.Contains(h))
{
result = VerifyResult.HasConflicts;
Log($"Rejected tx: {tx.Hash}, {result}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
RequestChangeView(ChangeViewReason.TxInvalid);
return false;
}
}
// After that, check whether context's transactions have Conflicts attribute with tx's hash.
foreach (var pooledTx in context.Transactions.Values)
{
if (pooledTx.GetAttributes<Conflicts>().Select(attr => attr.Hash).Contains(tx.Hash))
{
result = VerifyResult.HasConflicts;
Log($"Rejected tx: {tx.Hash}, {result}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
RequestChangeView(ChangeViewReason.TxInvalid);
return false;
}
}

// We've ensured that there's no conlicting transactions in the context, thus, can safely provide an empty conflicting list
// for futher verification.
var conflictingTxs = new List<Transaction>();
result = tx.Verify(neoSystem.Settings, context.Snapshot, context.VerificationContext, conflictingTxs);
if (result != VerifyResult.Succeed)
{
Log($"Rejected tx: {tx.Hash}, {result}{Environment.NewLine}{tx.ToArray().ToHexString()}", LogLevel.Warning);
Expand Down

0 comments on commit 906b3f2

Please sign in to comment.