Skip to content

Commit 3cb46c1

Browse files
committed
Commentary
1 parent f79f2ea commit 3cb46c1

File tree

7 files changed

+58
-0
lines changed

7 files changed

+58
-0
lines changed

src/chainparams.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ static CTestNetParams testNetParams;
241241
/**
242242
* Segnet
243243
*/
244+
// NOTE: segnet is not intended to be merged into Core. It was intended to allow testing before migrating to testnet.
244245
class CSegNetParams : public CChainParams {
245246
public:
246247
CSegNetParams() {

src/core_read.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ CScript ParseScript(const std::string& s)
9090
return result;
9191
}
9292

93+
/* NOTE: For every serialization corresponds to at most one valid transaction,
94+
with or without witness. Thus, in every situation where we deal with
95+
valid transactions, we can simply try to decode with witness flag
96+
enabled, and there will be no ambiguity.
97+
98+
However, when dealing with potentially invalid transactions, things are
99+
different. The decoderawtransaction and fundrawtransaction RPCs accept
100+
serialized transaction that potentially don't have any inputs. Such a
101+
serialization may be ambiguous. In those cases, and only those, we
102+
first try to decode without, and then with, checking that the entire
103+
serialization is consumed.
104+
*/
93105
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx, bool fTryNoWitness)
94106
{
95107
if (!IsHex(strHexTx))

src/main.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,10 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
940940
return nSigOps;
941941
}
942942

943+
// NOTE: this is a tricky refactor. All call sites to GetLegacySigOpCount, GetP2SHSigOpCount, and
944+
// the new CountWitnessSigOps are moved to this function, in both AcceptToMemoryPoolWorker
945+
// and ConnectBlock. In ConnectBlock however, the existing calls are spread over a parent
946+
// code block and a !tx.IsCoinBase() conditional (which is mimicked in this function),
943947
int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
944948
{
945949
int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR;
@@ -2412,6 +2416,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
24122416
return state.DoS(100, error("ConnectBlock(): too many sigops"),
24132417
REJECT_INVALID, "bad-blk-sigops");
24142418

2419+
// NOTE: the existing (!tx.IsCoinBase()) conditional is split in two, as the above
2420+
// GetTransactionSigOpCost requires being called for non-coinbase transactions as
2421+
// well, but the HaveInputs() call above needs to be called before, and the
2422+
// script evaluation below needs to go after.
24152423
if (!tx.IsCoinBase())
24162424
{
24172425
nFees += view.GetValueIn(tx)-tx.GetValueOut();
@@ -2675,6 +2683,11 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) {
26752683
}
26762684

26772685
/** Disconnect chainActive's tip. You probably want to call mempool.removeForReorg and manually re-limit mempool size after this, with cs_main held. */
2686+
/* NOTE: Disconnecting many blocks is very slow if we want to retain mempool consistency.
2687+
During RewindBlock (called at startup, to go back to the state of the last block before the
2688+
fork), no entries exist in the mempool anyway, so we're able to skip all mempool-related
2689+
logic. The fBare parameter indicates that just chainstate but no mempool operations
2690+
need to be performed. */
26782691
bool static DisconnectTip(CValidationState& state, const CChainParams& chainparams, bool fBare = false)
26792692
{
26802693
CBlockIndex *pindexDelete = chainActive.Tip();

src/policy/policy.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
151151
return true;
152152
}
153153

154+
/* NOTE: For transactions we define a 'virtual transaction size' (equal to
155+
transaction_cost / 4), which has no consensus meaning, but is used
156+
for fee calculations, so there is a smooth transition from feerate
157+
defined by size (for non-segwit transactions, size == vsize) */
154158
int64_t GetVirtualTransactionSize(const CTransaction& tx)
155159
{
156160
return (GetTransactionCost(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;

src/primitives/block.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ class CBlockHeader
3838
template <typename Stream, typename Operation>
3939
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
4040
READWRITE(this->nVersion);
41+
// NOTE: the assignment to the local variable nVersion is removed as it is unused. It was
42+
// intended to let serialization depend on block version number. That strategy would
43+
// lead to inconsistent behaviour, and you really need coordinated serialization changes
44+
// across the network instead. See the extended serialization format for transactions
45+
// instead, which is designed to be (1) backward compatible and (2) is purely a p2p
46+
// layer change that doesn't leak into consensus structures (so a new node can
47+
// downgrade when relaying to an old node, without breaking PoW).
4148
READWRITE(hashPrevBlock);
4249
READWRITE(hashMerkleRoot);
4350
READWRITE(nTime);

src/script/interpreter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ class MutableTransactionSignatureChecker : public TransactionSignatureChecker
156156
bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = NULL);
157157
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror = NULL);
158158

159+
/* NOTE: previously, sigop counting was done inside main, and implemented separately for P2SH and normal inputs.
160+
This is not a very scalable approach if we expect more script improvements in the future that may
161+
introduce new signature types. Thus, we move sigop counting to script, passing along the evaluation flags. */
159162
size_t CountWitnessSigOps(const CScript& scriptSig, const CScript& scriptPubKey, const CScriptWitness* witness, unsigned int flags);
160163

161164
#endif // BITCOIN_SCRIPT_INTERPRETER_H

src/script/sign.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,24 @@ static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSi
286286

287287
namespace
288288
{
289+
/* NOTE: a large amount of the code changes related to signing are due switching
290+
* internal functions to operate on byte arrays directly rather than
291+
* CScript encoded lists of pushes.
292+
*
293+
* However, that is (1) inconvenient in a segwit setting,
294+
* where we may need to convert the result of a normal signing operation
295+
* to a scriptwitness (which is not a script, but a vector of byte arrays,
296+
* see SignatureData) and (2) annoying even in the existing cases (for example,
297+
* you can't do manipulation like popping off a stack element without first
298+
* calling EvalScript).
299+
*
300+
* So all internal signing code is changed to work on byte array vectors or the
301+
* Stacks type below, which is converted to a SignatureData type by all externally
302+
* callable functions. A side effect is that ProduceSignature can't write
303+
* directly into a CMutableTransaction anymore, but a separate UpdateTransaction
304+
* is used to convert the results in SignatureData to the scriptSig and scriptWitness
305+
* fields.
306+
*/
289307
struct Stacks
290308
{
291309
std::vector<valtype> script;

0 commit comments

Comments
 (0)