Skip to content

Fix 7 opcode interpreter bugs to match BSV node v1.2.0 exactly#141

Open
sirdeggen wants to merge 1 commit intomasterfrom
claude/verify-opcode-implementation-HFWiZ
Open

Fix 7 opcode interpreter bugs to match BSV node v1.2.0 exactly#141
sirdeggen wants to merge 1 commit intomasterfrom
claude/verify-opcode-implementation-HFWiZ

Conversation

@sirdeggen
Copy link
Contributor

Identified and fixed the following discrepancies between the py-sdk
interpreter (bsv/script/spend.py) and the reference BSV node interpreter
(bitcoin-sv/bitcoin-sv src/script/interpreter.cpp @ v1.2.0):

  1. OP_LSHIFT / OP_RSHIFT

    • Was doing byte-level shifts; now performs bit-level shifts matching
      the node's LShift()/RShift() helpers using mask tables.
    • Was not popping n from the stack (left a stale value).
    • Added proper handling: n >= data_bits → zero-fill entire result.
  2. OP_INVERT

    • ~b in Python yields -(b+1) for unsigned bytes, causing TypeError or
      wrong results. Fixed to ~b & 0xFF.
  3. OP_DIV

    • Python // is floor division (toward -inf); C / truncates toward zero.
      Fixed with sign * (abs(a) // abs(b)).
  4. OP_MOD

    • Python % sign follows divisor; C % sign follows dividend.
      Fixed with a - b * trunc_div(a, b).
  5. OP_NUM2BIN

    • msb was initialised as b'\x00' (bytes) instead of 0 (int), causing
      TypeError when OR-ing into the bytearray for a zero input.
  6. OP_CHECKMULTISIG

    • Unconditional sigs_count -= 1 should be keys_count -= 1, matching
      the node's nKeysCount-- after each key iteration.
  7. is_chunk_minimal

    • OpCode.OP_1 + n.to_bytes(…) was bytes concatenation (2 bytes),
      so values 1–16 pushed via direct-push were never flagged as
      non-minimal. Fixed with integer arithmetic.

Also adds tests/test_opcodes.py with 49 tests covering all fixed opcodes
including bit-shift helpers, arithmetic edge cases with negative numbers,
and NUM2BIN/BIN2NUM round-trips.

https://claude.ai/code/session_01AnvbrLbXwdionxzd9askb3

Identified and fixed the following discrepancies between the py-sdk
interpreter (bsv/script/spend.py) and the reference BSV node interpreter
(bitcoin-sv/bitcoin-sv src/script/interpreter.cpp @ v1.2.0):

1. OP_LSHIFT / OP_RSHIFT
   - Was doing byte-level shifts; now performs bit-level shifts matching
     the node's LShift()/RShift() helpers using mask tables.
   - Was not popping n from the stack (left a stale value).
   - Added proper handling: n >= data_bits → zero-fill entire result.

2. OP_INVERT
   - ~b in Python yields -(b+1) for unsigned bytes, causing TypeError or
     wrong results. Fixed to ~b & 0xFF.

3. OP_DIV
   - Python // is floor division (toward -inf); C / truncates toward zero.
     Fixed with sign * (abs(a) // abs(b)).

4. OP_MOD
   - Python % sign follows divisor; C % sign follows dividend.
     Fixed with a - b * trunc_div(a, b).

5. OP_NUM2BIN
   - msb was initialised as b'\x00' (bytes) instead of 0 (int), causing
     TypeError when OR-ing into the bytearray for a zero input.

6. OP_CHECKMULTISIG
   - Unconditional sigs_count -= 1 should be keys_count -= 1, matching
     the node's nKeysCount-- after each key iteration.

7. is_chunk_minimal
   - OpCode.OP_1 + n.to_bytes(…) was bytes concatenation (2 bytes),
     so values 1–16 pushed via direct-push were never flagged as
     non-minimal. Fixed with integer arithmetic.

Also adds tests/test_opcodes.py with 49 tests covering all fixed opcodes
including bit-shift helpers, arithmetic edge cases with negative numbers,
and NUM2BIN/BIN2NUM round-trips.

https://claude.ai/code/session_01AnvbrLbXwdionxzd9askb3
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants