Changeset View
Standalone View
src/script/interpreter.h
Show All 23 Lines | |||||
uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, | uint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, | ||||
unsigned int nIn, SigHashType sigHashType, | unsigned int nIn, SigHashType sigHashType, | ||||
const Amount amount, | const Amount amount, | ||||
const PrecomputedTransactionData *cache = nullptr, | const PrecomputedTransactionData *cache = nullptr, | ||||
uint32_t flags = SCRIPT_ENABLE_SIGHASH_FORKID); | uint32_t flags = SCRIPT_ENABLE_SIGHASH_FORKID); | ||||
class BaseSignatureChecker { | class BaseSignatureChecker { | ||||
public: | public: | ||||
virtual bool VerifySignature(const std::vector<uint8_t> &vchSig, | virtual bool VerifySignatureECDSA(const std::vector<uint8_t> &vchSig, | ||||
const CPubKey &vchPubKey, | const CPubKey &vchPubKey, | ||||
const uint256 &sighash) const; | const uint256 &sighash) const; | ||||
virtual bool CheckSig(const std::vector<uint8_t> &scriptSig, | virtual bool CheckSigECDSA(const std::vector<uint8_t> &scriptSig, | ||||
const std::vector<uint8_t> &vchPubKey, | const std::vector<uint8_t> &vchPubKey, | ||||
const CScript &scriptCode, uint32_t flags) const { | const CScript &scriptCode, | ||||
uint32_t flags) const { | |||||
deadalnix: I don't think it make sense to specialize this API on the type of signature. | |||||
markblundebergAuthorUnsubmitted Done Inline ActionsIt seems there are four ways to go. One choice:
Otherwise if we use 'naked' Schnorr signatures without flag byte, then we must pass along the decision of whether a 64 byte vchSig blob is supposed to be interpreted as ECDSA or Schnorr. Only EvalScript has enough information to make this classification, as the decision will depend on which opcode is being executed, how it is being executed, AND whether flag ENABLE_SCHNORR is active. I can think of three ways to do this:
Which do you prefer, or is there another way I haven't thought of? markblundeberg: It seems there are four ways to go. One choice:
* prefix a flag byte (like in current Schnorr… | |||||
deadalnixUnsubmitted Not Done Inline ActionsWhat does CheckSig do ? It checks if a signature is valid, according to a certain pubkey, a certain message and a certain set of flags. A caller can pass it down a signature, a pubkey, and tell what type of signature he/she is willing to accept or not. This seems to me to be a perfectly fine contract to present to the caller. At the end of the day, this is what an API is: a contract and this is what this diff is about: defining what the contract is in a way that allow for extension that we are interested in. Contract are about defining responsibilities. The way we check to know if a signature is schnorr signature or not has nothing to do with it. There is a piece of code right now who's responsibility is to check if a signature is valid or not. It is the responsibility of piece of code to decide if a signature is valid. It seems like a totology? It's because it. deadalnix: What does CheckSig do ? It checks if a signature is valid, according to a certain pubkey, a… | |||||
markblundebergAuthorUnsubmitted Done Inline Actions
OK, so are you saying we should extend the API with an enum parameter (EXPECT_ECDSA, ACCEPT_BOTH) to provide context on which signatures are expected / acceptable for that opcode executing in that mode? CheckSig needs additional information to know whether it is supposed to interpret a 64 byte blob as ECDSA or Schnorr: I.e.,
Or, we can triplicate the API into CheckSig, CheckMultiSigLegacy, CheckMultiSigNew. (Or we can put a flag byte on the blockchain to make it so we don't have an ugly internal API.) markblundeberg: > and tell what type of signature he/she is willing to accept or not.
OK, so are you saying we… | |||||
markblundebergAuthorUnsubmitted Done Inline Actions
(or alternatively: CheckSigEither, CheckSigECDSAOnly, CheckSigSchnorrOnly) markblundeberg: > CheckSig, CheckMultiSigLegacy, CheckMultiSigNew.
(or alternatively: CheckSigEither… | |||||
return false; | return false; | ||||
} | } | ||||
virtual bool CheckLockTime(const CScriptNum &nLockTime) const { | virtual bool CheckLockTime(const CScriptNum &nLockTime) const { | ||||
return false; | return false; | ||||
} | } | ||||
virtual bool CheckSequence(const CScriptNum &nSequence) const { | virtual bool CheckSequence(const CScriptNum &nSequence) const { | ||||
Show All 15 Lines | TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn, | ||||
const Amount amountIn) | const Amount amountIn) | ||||
: txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {} | : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {} | ||||
TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn, | TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn, | ||||
const Amount amountIn, | const Amount amountIn, | ||||
const PrecomputedTransactionData &txdataIn) | const PrecomputedTransactionData &txdataIn) | ||||
: txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} | : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {} | ||||
// The overriden functions are now final. | // The overriden functions are now final. | ||||
bool CheckSig(const std::vector<uint8_t> &scriptSig, | bool CheckSigECDSA(const std::vector<uint8_t> &scriptSig, | ||||
const std::vector<uint8_t> &vchPubKey, | const std::vector<uint8_t> &vchPubKey, | ||||
const CScript &scriptCode, | const CScript &scriptCode, | ||||
uint32_t flags) const final override; | uint32_t flags) const final override; | ||||
bool CheckLockTime(const CScriptNum &nLockTime) const final override; | bool CheckLockTime(const CScriptNum &nLockTime) const final override; | ||||
bool CheckSequence(const CScriptNum &nSequence) const final override; | bool CheckSequence(const CScriptNum &nSequence) const final override; | ||||
}; | }; | ||||
class MutableTransactionSignatureChecker : public TransactionSignatureChecker { | class MutableTransactionSignatureChecker : public TransactionSignatureChecker { | ||||
private: | private: | ||||
const CTransaction txTo; | const CTransaction txTo; | ||||
Show All 15 Lines |
I don't think it make sense to specialize this API on the type of signature.