Skip to content

Commit

Permalink
Fix/arg out of range SnapProvider.AddAccountRange (#7060)
Browse files Browse the repository at this point in the history
Co-authored-by: Lukasz Rozmej <lukasz.rozmej@gmail.com>
  • Loading branch information
ak88 and LukaszRozmej authored May 29, 2024
1 parent 4020ade commit a61df04
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using FluentAssertions;
using Nethermind.Blockchain;
using Nethermind.Core.Crypto;
using Nethermind.Core.Extensions;
using Nethermind.Db;
using Nethermind.Logging;
using Nethermind.State.Snap;
using Nethermind.Synchronization.SnapSync;
using Nethermind.Trie;
using NSubstitute;
using NUnit.Framework;
using System;
using System.Collections.Generic;

namespace Nethermind.Synchronization.Test.SnapSync;

[TestFixture]
public class SnapProviderTests
{

[Test]
public void AddAccountRange_AccountListIsEmpty_ThrowArgumentException()
{
MemDb db = new();
IDbProvider dbProvider = new DbProvider();
dbProvider.RegisterDb(DbNames.State, db);
using ProgressTracker progressTracker = new(Substitute.For<IBlockTree>(), dbProvider.GetDb<IDb>(DbNames.State), LimboLogs.Instance);
dbProvider.RegisterDb(DbNames.Code, new MemDb());
SnapProvider sut = new(progressTracker, dbProvider.CodeDb, new NodeStorage(dbProvider.StateDb), LimboLogs.Instance);

Assert.That(
() => sut.AddAccountRange(
0,
Keccak.Zero,
Keccak.Zero,
Array.Empty<PathWithAccount>(),
Array.Empty<byte[]>().AsReadOnly()), Throws.ArgumentException);
}


[Test]
public void AddAccountRange_ResponseHasEmptyListOfAccountsAndOneProof_ReturnsExpiredRootHash()
{
MemDb db = new();
IDbProvider dbProvider = new DbProvider();
dbProvider.RegisterDb(DbNames.State, db);
using ProgressTracker progressTracker = new(Substitute.For<IBlockTree>(), dbProvider.GetDb<IDb>(DbNames.State), LimboLogs.Instance);
dbProvider.RegisterDb(DbNames.Code, new MemDb());
AccountRange accountRange = new(Keccak.Zero, Keccak.Zero, Keccak.MaxValue);
using AccountsAndProofs accountsAndProofs = new();
accountsAndProofs.PathAndAccounts = new List<PathWithAccount>().ToPooledList();
accountsAndProofs.Proofs = new List<byte[]> { new byte[] { 0x0 } }.ToPooledList();

SnapProvider sut = new(progressTracker, dbProvider.CodeDb, new NodeStorage(dbProvider.StateDb), LimboLogs.Instance);

sut.AddAccountRange(accountRange, accountsAndProofs).Should().Be(AddRangeResult.ExpiredRootHash);
}

}
20 changes: 17 additions & 3 deletions src/Nethermind/Nethermind.Synchronization/SnapSync/SnapProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,21 @@ public AddRangeResult AddAccountRange(AccountRange request, AccountsAndProofs re
{
AddRangeResult result;

if (response.PathAndAccounts.Count == 0 && response.Proofs.Count == 0)
if (response.PathAndAccounts.Count == 0)
{
_logger.Trace($"SNAP - GetAccountRange - requested expired RootHash:{request.RootHash}");

result = AddRangeResult.ExpiredRootHash;
}
else
{
result = AddAccountRange(request.BlockNumber.Value, request.RootHash, request.StartingHash, response.PathAndAccounts, response.Proofs, hashLimit: request.LimitHash);
result = AddAccountRange(
request.BlockNumber.Value,
request.RootHash,
request.StartingHash,
response.PathAndAccounts,
response.Proofs,
hashLimit: request.LimitHash);

if (result == AddRangeResult.OK)
{
Expand All @@ -73,8 +79,16 @@ public AddRangeResult AddAccountRange(AccountRange request, AccountsAndProofs re
return result;
}

public AddRangeResult AddAccountRange(long blockNumber, in ValueHash256 expectedRootHash, in ValueHash256 startingHash, IReadOnlyList<PathWithAccount> accounts, IReadOnlyList<byte[]> proofs = null, in ValueHash256? hashLimit = null!)
public AddRangeResult AddAccountRange(
long blockNumber,
in ValueHash256 expectedRootHash,
in ValueHash256 startingHash,
IReadOnlyList<PathWithAccount> accounts,
IReadOnlyList<byte[]> proofs = null,
in ValueHash256? hashLimit = null!)
{
if (accounts.Count == 0)
throw new ArgumentException("Cannot be empty.", nameof(accounts));
ITrieStore store = _trieStorePool.Get();
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
Expand Down Expand Up @@ -31,7 +32,8 @@ public static (AddRangeResult result, bool moreChildrenToRight, List<PathWithAcc
)
{
// TODO: Check the accounts boundaries and sorting

if (accounts.Count == 0)
throw new ArgumentException("Cannot be empty.", nameof(accounts));
ValueHash256 lastHash = accounts[^1].Path;

(AddRangeResult result, List<(TrieNode, TreePath)> sortedBoundaryList, bool moreChildrenToRight) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public async Task Dispatch(PeerInfo peerInfo, SnapSyncBatch batch, CancellationT
Logger.Error($"DEBUG/ERROR Error after dispatching the snap sync request. Request: {batch}", e);
}
}

await Task.CompletedTask;
}
}
}

0 comments on commit a61df04

Please sign in to comment.