Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6254410
calculator
ak88 Nov 14, 2025
d95b2c0
Merge branch 'master' into feature/xdc-reward-handler
ak88 Nov 14, 2025
6dd5ba6
state reader
ak88 Nov 17, 2025
f7e2c2e
masternode voting contract
ak88 Nov 18, 2025
55190f7
fix
ak88 Nov 18, 2025
0f5adc3
abi json
ak88 Nov 19, 2025
6594334
working load test
ak88 Nov 19, 2025
a491b29
Merge branch 'master' into feature/xdc-state-reader
ak88 Nov 19, 2025
aab0908
test
ak88 Nov 19, 2025
e321be3
test
ak88 Nov 20, 2025
5861105
test getCandidates
ak88 Nov 21, 2025
c157ad0
cleanup
ak88 Nov 21, 2025
840b59d
format
ak88 Nov 21, 2025
7864c1b
remove var
ak88 Nov 21, 2025
1504dff
Merge branch 'master' into feature/xdc-state-reader
ak88 Nov 23, 2025
5b1fc8f
format
ak88 Nov 24, 2025
23a7c12
review comments
ak88 Nov 24, 2025
e847dfd
implement calculate rewards base flow and get signing txs
cicr99 Nov 24, 2025
fe9df29
implement rewards per signer and distribution calculations
cicr99 Nov 24, 2025
ffb5e9b
Merge branch 'feature/xdc-state-reader' into feature/xdc-reward-handler
cicr99 Nov 25, 2025
3536869
implement getCadidateOwner
cicr99 Nov 25, 2025
a350bcd
refactors and add comments to the code
cicr99 Nov 25, 2025
11347ba
add block signer contract address to the configuration spec
cicr99 Nov 26, 2025
f6ea634
implement reward module tests
cicr99 Dec 3, 2025
ba630e3
implement hook for reward calculation in hotstuff pipeline
cicr99 Dec 4, 2025
3a632bf
refactor and format
cicr99 Dec 4, 2025
30b0d61
Merge branch 'master' into feature/xdc-reward-handler
cicr99 Dec 4, 2025
a1d0ddd
format
cicr99 Dec 4, 2025
9a93a79
fix xdc test
cicr99 Dec 4, 2025
327724a
wire IRewardClaculator in ConfigureContainer in XdcTestBlockchain
cicr99 Dec 4, 2025
a99d718
address review comments and add unit test with precalculated xdc rewa…
cicr99 Dec 22, 2025
457c310
add missing dependencies in Xdc module
cicr99 Dec 23, 2025
181d69b
fix resolving contract addresses from spec
cicr99 Dec 24, 2025
69d3c7e
Merge branch 'master' into feature/xdc-reward-handler
cicr99 Dec 24, 2025
1754d3b
fix error with WorldState after merge
cicr99 Dec 24, 2025
95fa3c3
add comments for reward tests with link to original source
cicr99 Dec 29, 2025
bc1f9f3
Merge branch 'master' into feature/xdc-reward-handler
ak88 Dec 30, 2025
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
4 changes: 3 additions & 1 deletion src/Nethermind/Chains/xdc.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@
"TimeoutPeriod": 10,
"MinePeriod": 2
}
]
],
"masternodeVotingContract": "0x0000000000000000000000000000000000000088",
"blockSignerContract": "0x0000000000000000000000000000000000000089"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: 2025 Demerzel Solutions Limited
// SPDX-License-Identifier: LGPL-3.0-only

using System;
using Nethermind.Core;
using Nethermind.Core.Crypto;
using Nethermind.Core.Test.Builders;
using Nethermind.Xdc.Spec;

namespace Nethermind.Xdc.Test.Helpers;

public static class TransactionBuilderXdcExtensions
{
// function sign(uint256 _blockNumber, bytes32 _blockHash)
// selector = 0xe341eaa4
private static ReadOnlySpan<byte> SignSelector => new byte[] { 0xE3, 0x41, 0xEA, 0xA4 };

/// <summary>Sets 'To' to the XDC block-signer contract from the spec.</summary>
public static TransactionBuilder<Transaction> ToBlockSignerContract(
this TransactionBuilder<Transaction> b, IXdcReleaseSpec spec)
=> b.To(spec.BlockSignerContract);

/// <summary>
/// Appends ABI-encoded calldata for sign(uint256 _blockNumber, bytes32 _blockHash).
/// Calldata = 4-byte selector + 32-byte big-endian uint + 32-byte bytes32 (68 bytes total).
/// </summary>
public static TransactionBuilder<Transaction> WithXdcSigningData(
this TransactionBuilder<Transaction> b, long blockNumber, Hash256 blockHash)
=> b.WithData(CreateSigningCalldata(blockNumber, blockHash));

private static byte[] CreateSigningCalldata(long blockNumber, Hash256 blockHash)
{
Span<byte> data = stackalloc byte[68]; // 4 + 32 + 32

// 0..3: selector
SignSelector.CopyTo(data);

// 4..35: uint256 blockNumber (big-endian, right-aligned in 32 bytes)
var be = BitConverter.GetBytes((ulong)blockNumber);
if (BitConverter.IsLittleEndian) Array.Reverse(be);
// last 8 bytes of that 32 are the ulong
for (int i = 0; i < 8; i++) data[4 + 24 + i] = be[i];

// 36..67: bytes32 blockHash
blockHash.Bytes.CopyTo(data.Slice(36, 32));

return data.ToArray();
}
}
31 changes: 28 additions & 3 deletions src/Nethermind/Nethermind.Xdc.Test/Helpers/XdcTestBlockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Nethermind.Consensus.Comparers;
using Nethermind.Consensus.Processing;
using Nethermind.Consensus.Producers;
using Nethermind.Consensus.Rewards;
using Nethermind.Core;
using Nethermind.Core.Specs;
using Nethermind.Core.Test.Blockchain;
Expand Down Expand Up @@ -55,7 +56,7 @@ public static async Task<XdcTestBlockchain> Create(int blocksToAdd = 3, bool use

if (testConfiguration.SuggestGenesisOnStart)
{
// The block added event is not waited by genesis, but its needed to wait here so that `AddBlock` wait correctly.
// The block added event is not waited by genesis, but it's needed to wait here so that `AddBlock` waits correctly.
Task newBlockWaiter = chain.BlockTree.WaitForNewBlock(chain.CancellationToken);
chain.MainProcessingContext.GenesisLoader.Load();
await newBlockWaiter;
Expand Down Expand Up @@ -173,7 +174,16 @@ protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder,
.AddSingleton<Configuration>()
.AddSingleton<FromContainer>()
.AddSingleton<FromXdcContainer>()
.AddScoped<IGenesisBuilder, XdcTestGenesisBuilder>()
.AddScoped<IGenesisBuilder>(ctx =>
new XdcTestGenesisBuilder(
ctx.Resolve<ISpecProvider>(),
ctx.Resolve<IWorldState>(),
ctx.Resolve<ISnapshotManager>(),
ctx.Resolve<IEnumerable<IGenesisPostProcessor>>().ToArray(),
ctx.Resolve<Configuration>(),
MasterNodeCandidates
)
)
.AddSingleton<IBlockProducer, TestXdcBlockProducer>()
.AddSingleton((ctx) => new CandidateContainer(MasterNodeCandidates))
.AddSingleton<ISigner>(ctx =>
Expand All @@ -185,6 +195,7 @@ protected override ContainerBuilder ConfigureContainer(ContainerBuilder builder,
})
.AddSingleton((_) => BlockProducer)
//.AddSingleton((_) => BlockProducerRunner)
.AddSingleton<IRewardCalculator, ZeroRewardCalculator>()
.AddSingleton<IBlockProducerRunner, XdcHotStuff>()
.AddSingleton<IProcessExitSource>(new ProcessExitSource(TestContext.CurrentContext.CancellationToken))

Expand Down Expand Up @@ -218,6 +229,7 @@ private IXdcReleaseSpec WrapReleaseSpec(IReleaseSpec spec)
xdcSpec.LimitPenaltyEpoch = 2;
xdcSpec.MinimumSigningTx = 1;
xdcSpec.GasLimitBoundDivisor = 1024;
xdcSpec.BlockSignerContract = new Address("0x0000000000000000000000000000000000000089");

V2ConfigParams[] v2ConfigParams = [
new V2ConfigParams {
Expand Down Expand Up @@ -263,6 +275,8 @@ private IXdcReleaseSpec WrapReleaseSpec(IReleaseSpec spec)
];

xdcSpec.V2Configs = v2ConfigParams.ToList();
xdcSpec.ValidateChainId = false;
xdcSpec.Reward = 5000;
return xdcSpec;
}

Expand Down Expand Up @@ -302,7 +316,8 @@ private class XdcTestGenesisBuilder(
IWorldState state,
ISnapshotManager snapshotManager,
IGenesisPostProcessor[] postProcessors,
Configuration testConfiguration
Configuration testConfiguration,
List<PrivateKey> masterNodeCandidates
) : IGenesisBuilder
{
public Block Build()
Expand All @@ -311,6 +326,11 @@ public Block Build()
state.CreateAccount(TestItem.AddressB, testConfiguration.AccountInitialValue);
state.CreateAccount(TestItem.AddressC, testConfiguration.AccountInitialValue);

foreach (PrivateKey candidate in masterNodeCandidates)
{
state.CreateAccount(candidate.Address, testConfiguration.AccountInitialValue);
}

IXdcReleaseSpec? finalSpec = (IXdcReleaseSpec)specProvider.GetFinalSpec();

XdcBlockHeaderBuilder xdcBlockHeaderBuilder = new();
Expand All @@ -335,6 +355,11 @@ public Block Build()
}
}

private class ZeroRewardCalculator : IRewardCalculator
{
public BlockReward[] CalculateRewards(Block block) => Array.Empty<BlockReward>();
}

public void ChangeReleaseSpec(Action<XdcReleaseSpec> reconfigure)
{
reconfigure((XdcReleaseSpec)SpecProvider.GetXdcSpec((XdcBlockHeader)BlockTree.Head!.Header));
Expand Down
Loading