Browse Source

Merge pull request #5252

b9a36b1 Make comments in /src/script doxygen compatible (Michael Ford)
0.10
Wladimir J. van der Laan 10 years ago
parent
commit
6c5c06eff7
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 39
      src/script/interpreter.cpp
  2. 44
      src/script/script.h
  3. 10
      src/script/sigcache.cpp
  4. 12
      src/script/sign.cpp
  5. 6
      src/script/sign.h
  6. 6
      src/script/standard.cpp
  7. 31
      src/script/standard.h

39
src/script/interpreter.cpp

@ -41,10 +41,10 @@ bool CastToBool(const valtype& vch)
return false; return false;
} }
// /**
// Script is a stack machine (like Forth) that evaluates a predicate * Script is a stack machine (like Forth) that evaluates a predicate
// returning a bool indicating valid or not. There are no loops. * returning a bool indicating valid or not. There are no loops.
// */
#define stacktop(i) (stack.at(stack.size()+(i))) #define stacktop(i) (stack.at(stack.size()+(i)))
#define altstacktop(i) (altstack.at(altstack.size()+(i))) #define altstacktop(i) (altstack.at(altstack.size()+(i)))
static inline void popstack(vector<valtype>& stack) static inline void popstack(vector<valtype>& stack)
@ -69,12 +69,16 @@ bool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
return true; return true;
} }
/**
* A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
* Where R and S are not negative (their first byte has its highest bit not set), and not
* excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
* in which case a single 0 byte is necessary and even required).
*
* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
*/
bool static IsDERSignature(const valtype &vchSig) { bool static IsDERSignature(const valtype &vchSig) {
// See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
// A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>
// Where R and S are not negative (their first byte has its highest bit not set), and not
// excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
// in which case a single 0 byte is necessary and even required).
if (vchSig.size() < 9) if (vchSig.size() < 9)
return error("Non-canonical signature: too short"); return error("Non-canonical signature: too short");
if (vchSig.size() > 73) if (vchSig.size() > 73)
@ -862,17 +866,18 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
namespace { namespace {
/** Wrapper that serializes like CTransaction, but with the modifications /**
* Wrapper that serializes like CTransaction, but with the modifications
* required for the signature hash done in-place * required for the signature hash done in-place
*/ */
class CTransactionSignatureSerializer { class CTransactionSignatureSerializer {
private: private:
const CTransaction &txTo; // reference to the spending transaction (the one being serialized) const CTransaction &txTo; //! reference to the spending transaction (the one being serialized)
const CScript &scriptCode; // output script being consumed const CScript &scriptCode; //! output script being consumed
const unsigned int nIn; // input index of txTo being signed const unsigned int nIn; //! input index of txTo being signed
const bool fAnyoneCanPay; // whether the hashtype has the SIGHASH_ANYONECANPAY flag set const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set
const bool fHashSingle; // whether the hashtype is SIGHASH_SINGLE const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE
const bool fHashNone; // whether the hashtype is SIGHASH_NONE const bool fHashNone; //! whether the hashtype is SIGHASH_NONE
public: public:
CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
@ -951,7 +956,7 @@ public:
::WriteCompactSize(s, nOutputs); ::WriteCompactSize(s, nOutputs);
for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++) for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++)
SerializeOutput(s, nOutput, nType, nVersion); SerializeOutput(s, nOutput, nType, nVersion);
// Serialie nLockTime // Serialize nLockTime
::Serialize(s, txTo.nLockTime, nType, nVersion); ::Serialize(s, txTo.nLockTime, nType, nVersion);
} }
}; };

44
src/script/script.h

@ -179,12 +179,14 @@ public:
class CScriptNum class CScriptNum
{ {
// Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers. /**
// The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1], * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers.
// but results may overflow (and are valid as long as they are not used in a subsequent * The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1],
// numeric operation). CScriptNum enforces those semantics by storing results as * but results may overflow (and are valid as long as they are not used in a subsequent
// an int64 and allowing out-of-range values to be returned as a vector of bytes but * numeric operation). CScriptNum enforces those semantics by storing results as
// throwing an exception if arithmetic is done or the result is interpreted as an integer. * an int64 and allowing out-of-range values to be returned as a vector of bytes but
* throwing an exception if arithmetic is done or the result is interpreted as an integer.
*/
public: public:
explicit CScriptNum(const int64_t& n) explicit CScriptNum(const int64_t& n)
@ -516,7 +518,7 @@ public:
return true; return true;
} }
// Encode/decode small integers: /** Encode/decode small integers: */
static int DecodeOP_N(opcodetype opcode) static int DecodeOP_N(opcodetype opcode)
{ {
if (opcode == OP_0) if (opcode == OP_0)
@ -560,25 +562,31 @@ public:
return nFound; return nFound;
} }
// Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs /**
// as 20 sigops. With pay-to-script-hash, that changed: * Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs
// CHECKMULTISIGs serialized in scriptSigs are * as 20 sigops. With pay-to-script-hash, that changed:
// counted more accurately, assuming they are of the form * CHECKMULTISIGs serialized in scriptSigs are
// ... OP_N CHECKMULTISIG ... * counted more accurately, assuming they are of the form
* ... OP_N CHECKMULTISIG ...
*/
unsigned int GetSigOpCount(bool fAccurate) const; unsigned int GetSigOpCount(bool fAccurate) const;
// Accurately count sigOps, including sigOps in /**
// pay-to-script-hash transactions: * Accurately count sigOps, including sigOps in
* pay-to-script-hash transactions:
*/
unsigned int GetSigOpCount(const CScript& scriptSig) const; unsigned int GetSigOpCount(const CScript& scriptSig) const;
bool IsPayToScriptHash() const; bool IsPayToScriptHash() const;
// Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
bool IsPushOnly() const; bool IsPushOnly() const;
// Returns whether the script is guaranteed to fail at execution, /**
// regardless of the initial stack. This allows outputs to be pruned * Returns whether the script is guaranteed to fail at execution,
// instantly when entering the UTXO set. * regardless of the initial stack. This allows outputs to be pruned
* instantly when entering the UTXO set.
*/
bool IsUnspendable() const bool IsUnspendable() const
{ {
return (size() > 0 && *begin() == OP_RETURN); return (size() > 0 && *begin() == OP_RETURN);

10
src/script/sigcache.cpp

@ -15,13 +15,15 @@
namespace { namespace {
// Valid signature cache, to avoid doing expensive ECDSA signature checking /**
// twice for every transaction (once when accepted into memory pool, and * Valid signature cache, to avoid doing expensive ECDSA signature checking
// again when accepted into the block chain) * twice for every transaction (once when accepted into memory pool, and
* again when accepted into the block chain)
*/
class CSignatureCache class CSignatureCache
{ {
private: private:
// sigdata_type is (signature hash, signature, public key): //! sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type; typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
std::set< sigdata_type> setValid; std::set< sigdata_type> setValid;
boost::shared_mutex cs_sigcache; boost::shared_mutex cs_sigcache;

12
src/script/sign.cpp

@ -46,12 +46,12 @@ bool SignN(const vector<valtype>& multisigdata, const CKeyStore& keystore, uint2
return nSigned==nRequired; return nSigned==nRequired;
} }
// /**
// Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type. * Sign scriptPubKey with private keys stored in keystore, given transaction hash and hash type.
// Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
// unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script.
// Returns false if scriptPubKey could not be completely satisfied. * Returns false if scriptPubKey could not be completely satisfied.
// */
bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType, bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash, int nHashType,
CScript& scriptSigRet, txnouttype& whichTypeRet) CScript& scriptSigRet, txnouttype& whichTypeRet)
{ {

6
src/script/sign.h

@ -17,8 +17,10 @@ struct CMutableTransaction;
bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL);
// Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders, /**
// combine them intelligently and return the result. * Given two sets of signatures for scriptPubKey, possibly with OP_0 placeholders,
* combine them intelligently and return the result.
*/
CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2); CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, const CScript& scriptSig1, const CScript& scriptSig2);
#endif // BITCOIN_SCRIPT_SIGN_H #endif // BITCOIN_SCRIPT_SIGN_H

6
src/script/standard.cpp

@ -34,9 +34,9 @@ const char* GetTxnOutputType(txnouttype t)
return NULL; return NULL;
} }
// /**
// Return public keys or hashes from scriptPubKey, for 'standard' transaction types. * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
// */
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet) bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
{ {
// Templates // Templates

31
src/script/standard.h

@ -25,27 +25,31 @@ public:
CScriptID(const uint160& in) : uint160(in) {} CScriptID(const uint160& in) : uint160(in) {}
}; };
static const unsigned int MAX_OP_RETURN_RELAY = 40; // bytes static const unsigned int MAX_OP_RETURN_RELAY = 40; //! bytes
extern unsigned nMaxDatacarrierBytes; extern unsigned nMaxDatacarrierBytes;
// Mandatory script verification flags that all new blocks must comply with for /**
// them to be valid. (but old blocks may not comply with) Currently just P2SH, * Mandatory script verification flags that all new blocks must comply with for
// but in the future other flags may be added, such as a soft-fork to enforce * them to be valid. (but old blocks may not comply with) Currently just P2SH,
// strict DER encoding. * but in the future other flags may be added, such as a soft-fork to enforce
// * strict DER encoding.
// Failing one of these tests may trigger a DoS ban - see CheckInputs() for *
// details. * Failing one of these tests may trigger a DoS ban - see CheckInputs() for
* details.
*/
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
// Standard script verification flags that standard transactions will comply /**
// with. However scripts violating these flags may still be present in valid * Standard script verification flags that standard transactions will comply
// blocks and we must accept those blocks. * with. However scripts violating these flags may still be present in valid
* blocks and we must accept those blocks.
*/
static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS |
SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_STRICTENC |
SCRIPT_VERIFY_MINIMALDATA | SCRIPT_VERIFY_MINIMALDATA |
SCRIPT_VERIFY_NULLDUMMY; SCRIPT_VERIFY_NULLDUMMY;
// For convenience, standard but not mandatory verify flags. /** For convenience, standard but not mandatory verify flags. */
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
enum txnouttype enum txnouttype
@ -65,7 +69,8 @@ public:
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
}; };
/** A txout script template with a specific destination. It is either: /**
* A txout script template with a specific destination. It is either:
* * CNoDestination: no destination set * * CNoDestination: no destination set
* * CKeyID: TX_PUBKEYHASH destination * * CKeyID: TX_PUBKEYHASH destination
* * CScriptID: TX_SCRIPTHASH destination * * CScriptID: TX_SCRIPTHASH destination

Loading…
Cancel
Save