-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Description
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):
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = NULL);
bool VerifyTx(const CTransaction& tx, CValidationState &state, const Consensus::Params&, int nBlockHeight, int64_t nBlockTime, const CCoinsViewCache& inputs, int nSpendHeight, bool cacheStore, unsigned int flags);
bool CheckTx(const CTransaction&, CValidationState&, const Consensus::Params&);
/**
* Check whether all inputs of this transaction are valid (no double spends and amounts)
* This does not modify the UTXO set. This does not check scripts and sigs.
* Preconditions: tx.IsCoinBase() is false.
*/
bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight);
/**
* Preconditions: tx.IsCoinBase() is false.
* Check whether all inputs of this transaction are valid (scripts and sigs)
* This does not modify the UTXO set. This does not check double spends and amounts.
* This is the more expensive consensus check for a transaction, do it last.
*/
bool CheckTxInputsScripts(const CTransaction& tx, CValidationState& state, const CCoinsViewCache& inputs, bool cacheStore, unsigned int flags);
/** Block header validation functions */
bool VerifyBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, int64_t nTime, CBlockIndexBase*, PrevIndexGetter);
bool CheckBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, int64_t nTime, bool fCheckPOW = true);
bool ContextualCheckBlockHeader(const CBlockHeader&, CValidationState&, const Consensus::Params&, const CBlockIndexBase*, PrevIndexGetter);
/** Block validation functions */
bool VerifyBlock(const CBlock&, CValidationState&, const Consensus::Params&, int64_t nTime, const CBlockIndexBase*, PrevIndexGetter);
bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& params, int64_t nTime, bool fCheckPOW = true, bool fCheckMerkleRoot = true);
bool ContextualCheckBlock(const CBlock&, CValidationState&, const Consensus::Params&, const CBlockIndexBase*, PrevIndexGetter);