diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8aa3aebbd..19bbff1ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -226,9 +226,20 @@ jobs: - name: Build files with isMainModule run: | + executables=( + "beacon_chain/el/deposit_contract" + "beacon_chain/fork_choice/fork_choice" + "beacon_chain/fork_choice/proto_array" + "beacon_chain/networking/network_metadata_downloads" + "beacon_chain/era_db" + "beacon_chain/trusted_node_sync" + "benchmarks/rest_api_benchmark" + "tests/mocking/mock_genesis" + ) source env.sh - nim c beacon_chain/era_db - nim c beacon_chain/trusted_node_sync + for executable in "${executables[@]}"; do + nim c --passC:-fsyntax-only --noLinking:on -d:chronicles_log_level=TRACE "${executable}" + done lint: name: "Lint" diff --git a/CHANGELOG.md b/CHANGELOG.md index aad2db282..a9664ff4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +2024-06-24 v24.6.0 +================== + +Nimbus `v24.6.0` is a `low-urgency` release with performance and safety improvements. + +### Improvements + +* Improve SHA256 protocol object hashing speed by 30%: + https://github.com/status-im/nimbus-eth2/pull/6292 + +* Ensure that when a paired Nimbus beacon node and validator client improperly share validator keys, they avoid slashing: + https://github.com/status-im/nimbus-eth2/pull/6329 + +* Add block scoring to validator client to pick the best block from multiple beacon nodes: + https://github.com/status-im/nimbus-eth2/pull/6303 + +* Enable block monitoring in validator client by default to attest earlier and more reliably: + https://github.com/status-im/nimbus-eth2/pull/6331 + +### Fixes + +* Fix light client libp2p gossip topic subscriptions: + https://github.com/status-im/nimbus-eth2/pull/6351 + 2024-05-23 v24.5.1 ================== diff --git a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim index 3903246ca..89fc6ce7e 100644 --- a/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim +++ b/beacon_chain/consensus_object_pools/sync_committee_msg_pool.nim @@ -217,15 +217,16 @@ func produceContribution*( else: false -func addAggregateAux(bestVotes: var BestSyncSubcommitteeContributions, - contribution: SyncCommitteeContribution) = +func addContribution( + contributions: var BestSyncSubcommitteeContributions, + contribution: SyncCommitteeContribution) = let currentBestTotalParticipants = - bestVotes.subnets[contribution.subcommittee_index].totalParticipants + contributions.subnets[contribution.subcommittee_index].totalParticipants newBestTotalParticipants = countOnes(contribution.aggregation_bits) if newBestTotalParticipants > currentBestTotalParticipants: - bestVotes.subnets[contribution.subcommittee_index] = + contributions.subnets[contribution.subcommittee_index] = BestSyncSubcommitteeContribution( totalParticipants: newBestTotalParticipants, participationBits: contribution.aggregation_bits, @@ -241,10 +242,10 @@ func isSeen*( seenKey in pool.seenContributionByAuthor func covers( - bestVotes: BestSyncSubcommitteeContributions, + contributions: BestSyncSubcommitteeContributions, contribution: SyncCommitteeContribution): bool = contribution.aggregation_bits.isSubsetOf( - bestVotes.subnets[contribution.subcommittee_index].participationBits) + contributions.subnets[contribution.subcommittee_index].participationBits) func covers*( pool: var SyncCommitteeMsgPool, @@ -271,22 +272,12 @@ proc addContribution(pool: var SyncCommitteeMsgPool, pool.seenContributionByAuthor.incl seenKey let target = pool.cfg.toSyncMsgTarget(bid, contribution.slot) - if target notin pool.bestContributions: - let totalParticipants = countOnes(contribution.aggregation_bits) - var initialBestContributions = BestSyncSubcommitteeContributions() - - initialBestContributions.subnets[contribution.subcommittee_index] = - BestSyncSubcommitteeContribution( - totalParticipants: totalParticipants, - participationBits: contribution.aggregation_bits, - signature: signature) - - pool.bestContributions[target] = initialBestContributions - else: - try: - addAggregateAux(pool.bestContributions[target], contribution) - except KeyError: - raiseAssert "We have checked for the key upfront" + pool.bestContributions.withValue(target, contributions): + contributions[].addContribution(contribution) + do: + var contributions: BestSyncSubcommitteeContributions + contributions.addContribution(contribution) + pool.bestContributions[target] = contributions proc addContribution*(pool: var SyncCommitteeMsgPool, scproof: SignedContributionAndProof, @@ -334,11 +325,35 @@ proc produceSyncAggregateAux( aggregate proc produceSyncAggregate*( - pool: SyncCommitteeMsgPool, + pool: var SyncCommitteeMsgPool, bid: BlockId, signatureSlot: Slot): SyncAggregate = # Sync committee signs previous slot, relative to when new block is produced - let target = pool.cfg.toSyncMsgTarget(bid, max(signatureSlot, 1.Slot) - 1) + let + slot = max(signatureSlot, 1.Slot) - 1 + target = pool.cfg.toSyncMsgTarget(bid, slot) + + var contribution {.noinit.}: SyncCommitteeContribution + pool.bestContributions.withValue(target, contributions): + for subcommitteeIdx in SyncSubcommitteeIndex: + if contributions.subnets[subcommitteeIdx].totalParticipants == 0 and + pool.produceContribution(slot, bid, subcommitteeIdx, contribution): + debug "Did not receive contribution, did aggregate locally", + target, subcommitteeIdx + contributions[].addContribution(contribution) + do: + var + contributions: BestSyncSubcommitteeContributions + didAggregate = false + for subcommitteeIdx in SyncSubcommitteeIndex: + if pool.produceContribution(slot, bid, subcommitteeIdx, contribution): + debug "Did not receive contribution, did aggregate locally", + target, subcommitteeIdx + contributions.addContribution(contribution) + didAggregate = true + if didAggregate: + pool.bestContributions[target] = contributions + if target in pool.bestContributions: try: produceSyncAggregateAux(pool.bestContributions[target]) diff --git a/beacon_chain/fork_choice/fork_choice.nim b/beacon_chain/fork_choice/fork_choice.nim index 0156a2b3d..6b638ce58 100644 --- a/beacon_chain/fork_choice/fork_choice.nim +++ b/beacon_chain/fork_choice/fork_choice.nim @@ -502,8 +502,8 @@ when isMainModule: for i in 0 ..< validator_count: indices.add fakeHash(i), i votes.add default(VoteTracker) - old_balances.add 0 - new_balances.add 0 + old_balances.add 0.Gwei + new_balances.add 0.Gwei let err = deltas.compute_deltas( indices, indices_offset = 0, votes, old_balances, new_balances diff --git a/beacon_chain/version.nim b/beacon_chain/version.nim index 8cae95c1f..7d199a5e7 100644 --- a/beacon_chain/version.nim +++ b/beacon_chain/version.nim @@ -18,8 +18,8 @@ const "Copyright (c) 2019-" & compileYear & " Status Research & Development GmbH" versionMajor* = 24 - versionMinor* = 5 - versionBuild* = 1 + versionMinor* = 6 + versionBuild* = 0 versionBlob* = "stateofus" # Single word - ends up in the default graffiti diff --git a/benchmarks/rest_api_benchmark.nim b/benchmarks/rest_api_benchmark.nim index 00050e3ab..c496ef62f 100644 --- a/benchmarks/rest_api_benchmark.nim +++ b/benchmarks/rest_api_benchmark.nim @@ -1,3 +1,12 @@ +# beacon_chain +# Copyright (c) 2022-2024 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +{.push raises: [].} + import chronicles, chronicles/[topics_registry, timings], confutils, confutils/std/net, @@ -6,11 +15,11 @@ import type Config = object serverIpAddress {. - defaultValue: ValidIpAddress.init("127.0.0.1") + defaultValue: static(parseIpAddress("127.0.0.1")) defaultValueDesc: "127.0.0.1" desc: "IP address of the beacon node's REST server" abbr: "a" - name: "address" }: ValidIpAddress + name: "address" }: IpAddress serverPort {. defaultValue: 5052 @@ -29,7 +38,7 @@ type abbr: "n" name: "count" }: uint -proc main = +proc main() {.raises: [ConfigurationError, HttpError, OSError].} = let config = Config.load let serverAddress = initTAddress(config.serverIpAddress, config.serverPort) let client = RestClientRef.new(serverAddress) @@ -43,10 +52,10 @@ proc main = info.logTime(apiName): for slot in config.startSlot ..< (config.startSlot + config.requestsCount): let ident = StateIdent(kind: StateQueryKind.Slot, slot: slot.Slot) - discard waitFor client.`apiNameIdent`(ident) + discard waitFor noCancel client.`apiNameIdent`(ident) benchmark(getStateRoot) - benchmark(getStateFork) + benchmark(getStateForkPlain) benchmark(getStateFinalityCheckpoints) benchmark(getStateValidatorBalances) diff --git a/tests/mocking/mock_genesis.nim b/tests/mocking/mock_genesis.nim index 0e0b74c9f..66bb6ace2 100644 --- a/tests/mocking/mock_genesis.nim +++ b/tests/mocking/mock_genesis.nim @@ -39,4 +39,4 @@ proc initGenesisState*( when isMainModule: # Smoke test let state = initGenesisState(num_validators = SLOTS_PER_EPOCH) - doAssert state.validators.len == SLOTS_PER_EPOCH \ No newline at end of file + doAssert getStateField(state[], validators).lenu64 == SLOTS_PER_EPOCH diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index 2fa2c4425..8cb7dbb42 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit 2fa2c4425f4bb835c0517efc03009925dcd28239 +Subproject commit 8cb7dbb425df1124b17c6b3142a19a380114a693