script: Add CScript::DummyScriptBytes

This commit is contained in:
Luke Dashjr 2023-08-24 21:59:07 +00:00 committed by Léo Haf
parent f409444d02
commit a3068674ff
Signed by: Retropex
GPG Key ID: F5073C4F4882FFFC
2 changed files with 49 additions and 0 deletions

View File

@ -303,6 +303,53 @@ bool CScript::HasValidOps() const
return true; return true;
} }
size_t CScript::DummyScriptBytes() const
{
size_t counted{0};
opcodetype opcode, last_opcode{OP_INVALIDOPCODE};
std::vector<unsigned char> push_data;
unsigned int inside_noop{0}, inside_conditional{0};
CScript::const_iterator opcode_it = begin(), data_began = begin();
for (CScript::const_iterator it = begin(); it < end(); last_opcode = opcode) {
opcode_it = it;
if (!GetOp(it, opcode, push_data)) {
// Invalid scripts are necessarily all data
return size();
}
if (opcode == OP_IF || opcode == OP_NOTIF) {
++inside_conditional;
} else if (opcode == OP_ENDIF) {
if (!inside_conditional) return size(); // invalid
--inside_conditional;
}
// Match OP_FALSE OP_IF
if (inside_noop) {
switch (opcode) {
case OP_IF: case OP_NOTIF:
++inside_noop;
break;
case OP_ENDIF:
if (0 == --inside_noop) {
counted += it - data_began + 1;
}
break;
default: /* do nothing */;
}
} else if (opcode == OP_IF && last_opcode == OP_FALSE) {
inside_noop = 1;
data_began = opcode_it;
// Match <data> OP_DROP
} else if (opcode <= OP_PUSHDATA4) {
data_began = opcode_it;
} else if (opcode == OP_DROP && last_opcode <= OP_PUSHDATA4) {
counted += it - data_began;
}
}
return counted;
}
bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet) bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet)
{ {
opcodeRet = OP_INVALIDOPCODE; opcodeRet = OP_INVALIDOPCODE;

View File

@ -573,6 +573,8 @@ public:
return (size() > 0 && *begin() == OP_RETURN) || (size() > MAX_SCRIPT_SIZE); return (size() > 0 && *begin() == OP_RETURN) || (size() > MAX_SCRIPT_SIZE);
} }
size_t DummyScriptBytes() const;
void clear() void clear()
{ {
// The default prevector::clear() does not release memory // The default prevector::clear() does not release memory