Blockcore
repository·master·Indexed 42 days ago
https://github.com/block-core/blockcoreAn open-source .NET-based platform written in C# for building Layer 1 consensus networks using the Bitcoin protocol. It serves as an alternative C# Bitcoin implementation focused on open and public blockchains.
What's inside Blockcore
- Blockcore is an open-source platform for building Layer 1 consensus networks based on the Bitcoin protocol. It is written entirely in C# and built on the .NET Core framework. It serves as an alternative C# Bitcoin implementation, drawing inspiration from the NBitcoin and Stratis projects, with a focus on open and public blockchains.
Write non-entry/exit logs
masterNon-entry and non-exit logs provide extra information about the system state or specific events.
Style Guidelines:
- Use a unique, concise, English sentence.
- Do not use
[CONTEXT]identifiers (the sentence should provide context). - Do not use
nameof()or"name:value"/"name=value"notation. - Focus on describing the event naturally.
this.logger.LogTrace("UTXO '{0}/{1}' with value {2} might be available for staking.", stakeTx.OutPoint.Hash, stakeTx.OutPoint.N, utxo.Value);Understand Cold Staking in Stratis
masterCold staking is a mechanism designed to allow miners to participate in block production without keeping their staking coins in a 'hot wallet' (an online, potentially vulnerable wallet).
How it works
Traditionally, a miner must keep coins in a hot wallet to sign coinstake transactions. With cold staking, a special transaction transfers coins to a cold storage wallet (like a hardware or paper wallet) while simultaneously delegating staking rights back to the hot wallet.
Key Benefits
- Security: Reduces the risk of theft if a running node or hot wallet is compromised.
- Participation: Enables safer staking for exchanges and the potential for pool staking.
- Network Strength: Encourages more users to stake by removing the security barrier of keeping large amounts online.
Understand the PR review policy tags
masterEvery Pull Request (PR) must be associated with a PR review policy tag. These tags determine the level of scrutiny and the specific requirements for testing and verification required before a change can be merged. The policy levels are:
pr-review-critical: Highest level of scrutiny. Requires review by at least two core devs, all tests (Unit and Integration) passing for both author and reviewers, and synchronization of all 4 chains (Bitcoin main/test, Stratis main/test) to an agreed height.pr-review-high: Requires review by at least two core devs, all tests (Unit and Integration) passing for both author and reviewers, and synchronization of all 4 chains (Bitcoin main/test, Stratis main/test) to an agreed height.pr-review-medium: Requires review by at least two core devs (author and reviewer) and all tests (Unit and Integration) passing.pr-review-low: Requires review by at least one core dev and all tests (Unit and Integration) passing.
Understand default logging behavior
masterBy default, the node uses NLog with a minimum log level of
Informationfor all classes. Logs are sent to both the console and a rotating main log file namednode.txtlocated in the$DATADIR/Logsdirectory.Log Rotation Details:
- A new log file is created daily.
- Old logs are renamed using the pattern
node-YYYY-MM-DD.N.txt(the timestamp reflects the day the log was rotated, not the day the logs were written). - The system archives logs from the last 7 days; files older than 7 days are automatically deleted.
Understand the ProvenHeaders specification
masterProvenHeaders is a security mechanism designed to prevent 'fake header' attacks on Proof-of-Stake (PoS) networks like Stratis. In PoS, attackers can easily construct long chains of fake headers with high perceived chainwork. Without ProvenHeaders, a node might switch to this fake chain and then hang indefinitely while waiting for blocks that will never arrive.
ProvenHeaders solves this by requiring headers to be accompanied by cryptographic proof of stake (coinstake) to validate the chain's work.
Record execution flow with TRACE logs
masterTRACE level logs should be used to record execution flow so that the exact path of object instances can be inspected.
Best Practices:
- Distinguishable Branches: Ensure every important execution path branch is distinguishable. You can achieve this by placing a log in one branch, or in both if necessary. If a branch is rarely executed (the 'abnormal' case), logging only in that branch is sufficient to inform the reader that the 'normal' path was taken.
- Coverage: Logs should provide enough information to reconstruct the state transitions. For example, in a loop, log the state at each iteration rather than just the final exit state to capture the number of operations performed.
while (true) { uint256 hash = await this.UTXOSet.Rewind(); ChainedBlock rewinded = this.Chain.GetBlock(hash); if (rewinded == null) { // Log the specific branch to distinguish it from the successful path this.logger.LogTrace("Rewound to '{0}', which is still not a part of the current best chain, rewinding further.", hash); continue; } // Log the successful path this.logger.LogTrace("Rewound to '{0}'.", hash); this.Tip = rewinded; this.Puller.SetLocation(rewinded); break; }Understand PoA max reorg and signature validation
masterIn a dynamic PoA federation, headers may be signed by members that a node does not yet recognize, making immediate validation impossible.
To resolve this, the network uses a
max reorgmechanism. Voting results are only executed aftermax reorgblocks have passed. This ensures the node has sufficient historical data to verify the federation state for the window ofCT + 1toCT + max reorg.This logic is implemented in
PoAHeaderSignatureRule. Headers located within themax reorgwindow from the consensus tip that contain invalid signatures are marked asinsufficientand are re-validated as the consensus tip advances.Extending contract transaction validation via DI
masterThe system uses Dependency Injection (DI) to apply validation rules to contract transactions. TheSmartContractPoARuleRegistrationautomatically injects all registered implementations ofIContractTransactionFullValidationRuleinto theContractTransactionFullValidationRule. This allows developers to add custom logic to validate the contract transaction format.Understand the security challenges of Blockcore Proof of Stake
masterThe Blockcore Proof of Stake (PoS) protocol faces several theoretical and practical security challenges that developers and operators should be aware of:
Nothing-at-Stake (NAS)
Validators may have a financial incentive to mine on every fork of the blockchain. This can disrupt consensus and make it difficult for honest nodes to identify the chain with the majority of honest staking power, potentially confusing nodes during Initial Block Download (IBD).
Stake Grinding
A validator attempts to bias randomness in their favor by modifying block headers. An attacker with a small amount of stake can scan blockchain history to find opportunities to win blocks and then manipulate subsequent headers to consecutively win blocks.
The IBD (Initial Block Download) Problem
During initial sync, a node might be presented with a 'fake chain' (a chain not accepted by the majority of stakers). If the fork is beyond the
maxreorgparameter, the local node cannot rewind and may become stuck on the wrong chain.Mitigations implemented in Blockcore:
- Checkpoints: The software includes regularly hard-coded checkpoints of the correct chain to prevent nodes from following fake chains.
- Connection Restrictions: During IBD, a node will only accept outgoing connections to mitigate the risk of being fed a fake chain by malicious peers.
General PoS Considerations
- Complexity: The protocol is more complex than Proof of Work (PoW), which may introduce unknown attack vectors.
- Decentralization: PoS is often considered less decentralized due to the reliance on checkpoints for IBD and the requirement for a majority of nodes to have synchronized global time.
- 51% Attack Recovery: In the event of a 51% attack, user intervention (such as utilizing checkpoints) may be required to recover the network.
Use AsyncWrapper for high-volume logging
masterTo improve performance when logging large volumes of data, use the
AsyncWrappertarget in yourNLog.config.Note on Reliability: Async logging may result in lost logs if the program crashes unexpectedly, as logs might not be flushed to disk. For development where crashes are expected, use a standard
Filetarget. For testing features where you expect stability, useAsyncWrapper.If you handle exceptions manually and want to ensure logs are saved before a crash, call
NLog.LogManager.Flush().<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true"> <targets> <target name="debugAllFile" xsi:type="AsyncWrapper" queueLimit="10000" overflowAction="Block" batchSize="1000"> <target xsi:type="File" fileName="debug.txt" layout="[${longdate:universalTime=true} ${threadid}${mdlc:item=id}] ${level:uppercase=true}: ${callsite} ${message}" encoding="utf-8" /> </target> <target xsi:type="null" name="null" formatMessage="false" /> </targets> <rules> <logger name="*" minlevel="Trace" writeTo="null" final="true" /> <logger name="*" minlevel="Trace" writeTo="debugAllFile" /> </rules> </nlog>How Smart Contract Whitelisting works
masterSmart Contract Whitelisting integrates with the Proof of Authority (PoA) voting feature. The process works as follows:
- Hashing: The system hashes the bytecode of any contract creation transaction.
- Validation: The resulting hash is checked against the federation's whitelist.
- Enforcement: If the hash is not in the whitelist, the contract deployment fails.
Validation Layers
- Consensus Rule: The system uses a full-validation consensus rule called
AllowedCodeHashLogic. Full validation is required because the whitelist repository itself is updated via full-validation rules. This prevents issues during chain reorgs where a hash might be removed from the whitelist. - Mempool Validation: The mempool pre-validates incoming transactions using the same consensus rule. If a transaction's code hash is not whitelisted, it will not be considered for inclusion in a block.
Note: A transaction might be accepted into the mempool but fail to be included in a block if the contract's code hash is removed from the whitelist between the time of mempool entry and the time of mining.