There have been multiple discussions about completing libconsensus in the mailing list but they are hard to find. Here’s a detailed plan
Goals:
-
Complete libconsensus’s C API with the following functions: VerifyScript, VerifyHeader, VerifyTx and VerifyBlock. Possibly also: CheckTransaction/Consensus::CheckTx, Consensus::CheckTxInputs, Consensus::CheckTxInputsScripts (doesn’t exist yet in master), CheckBlockHeader, ContextualCheckBlockHeader, CheckBlock and ContextualCheckBlock.
-
Maintain libconsensus as a stateless library that doesn’t have its own storage.
Regardless of the concrete final C API, here’s some things we do know now and if done in advance, would simplify the task of reviewing concrete C API’s proposals:
- Separate consensus critical code into different files. Right now, if one wants to propose a concrete C API without moving any code, he needs to include main.cpp (and its abundant dependencies) in the libconsensus build. This goes against goal 2.
- Remove depencies that use globals (like Params()/pCurrentParams, util::mapArgs or util::error/util::LogPrintStr/fPrintToConsole_and_friends).
The most complicated part of proposing a concrete C API is to somehow interface with the equivalent of CBlockIndex and CCoinsViewCache (which depend on storage) in Bitcoin Core:
- C-compatible API for CBlockIndex
- C-compatible API for CCoinsViewCache
- Discuss and accept a complete C API for libconsensus.
If you think this plan is not detailed enough, please make concrete suggestions or questions: “this is not well documented enough” is not very useful as feedback.
Proposed API (C++, not the final C API):
0bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
1
2bool VerifyTx(const CTransaction& tx, CValidationState &state, const Consensus::Params&, int nBlockHeight, int64_t nBlockTime, const CCoinsViewCache& inputs, int nSpendHeight, bool cacheStore, unsigned int flags);
3bool CheckTx(const CTransaction&, CValidationState&, const Consensus::Params&);
4/**
5 * Check whether all inputs of this transaction are valid (no double spends and amounts)
6 * This does not modify the UTXO set. This does not check scripts and sigs.
7 * Preconditions: tx.IsCoinBase() is false.
8 */
9bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight);
10/**
11 * Preconditions: tx.IsCoinBase() is false.
12 * Check whether all inputs of this transaction are valid (scripts and sigs)
13 * This does not modify the UTXO set. This does not check double spends and amounts.
14 * This is the more expensive consensus check for a transaction, do it last.
15 */
16bool CheckTxInputsScripts(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, bool cacheStore, unsigned int flags);
17
18/** Block header validation functions */
19
20bool VerifyBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, int64_t nTime, CBlockIndexBase*, PrevIndexGetter);
21bool CheckBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, int64_t nTime, bool fCheckPOW = true);
22bool ContextualCheckBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, const CBlockIndexBase*, PrevIndexGetter);
23
24/** Block validation functions */
25
26bool VerifyBlock(const CBlock&, CValidationState&, const Consensus::Params&, int64_t nTime, const CBlockIndexBase*, PrevIndexGetter);
27bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& params, int64_t nTime, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
28bool ContextualCheckBlock(const CBlock&, CValidationState&, const Consensus::Params&, const CBlockIndexBase*, PrevIndexGetter);