Skip to content

Conversation

@stringintech
Copy link
Owner

@stringintech stringintech commented Nov 26, 2025

Addresses #5.
Pre-release v0.0.2-alpha.1 can be used to test these changes (as I have used and tested in stringintech/go-bitcoinkernel@f03919c)

@stringintech stringintech linked an issue Nov 26, 2025 that may be closed by this pull request
@janb84
Copy link
Contributor

janb84 commented Nov 26, 2025

fast feedback : please also update the documentation =>
docs/handler-spec.md

### Error Response

```json
{
  "id": "unique-request-id",
  "error": {
    "type": "error_category",
    "variant": "specific_error"
  }
}

Error response fields:

  • id (string, required): Must match the request ID
  • success (null or omitted): Must not be present on error <===
  • error (object, required): Error details
    • type (string, required): Error category/type
    • variant (string, optional): Specific error variant within the type. Whether the runner expects this field depends on the specific test case

@stringintech
Copy link
Owner Author

Oops, forgot to adapt the spec; thanks @janb84!
I will push another commit for that.

Copy link
Contributor

@janb84 janb84 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK cc128f1

lgtm and no mayor issues implementing the changes om my .NET handler.

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this alignment, I think it's definitely an improvement. I've thought a bit more about my earlier suggestion wrt the Response format, and I think it can be improved further.

A Response format could look like:

{
  "id": str,
  "result": optional[any],
  "error": optional[error]
}

For result:

  • if a function return a value, result is specified as "result": value
  • if a function returns a nullptr, result must be null
  • if a function doesn't return (it is void, or the function errored), result must be null

For error:

  • if a function doesn't "throw", error must be null
  • if a function throws, error must be defined, with "error": {} being the base, catch-all exception, that may be further specified, e.g. with a code object (that is already in the spec)
  • if error is not null, success must be null

Note: null is equivalent to the key being omitted from the object.

A couple of examples:

Scenario A: Function returns a value (e.g., btck_script_pubkey_verify -> true)

{
  "id": "req-1",
  "result": true
}

Scenario B: Function is void or returns nullptr on success, but doesn't throw

{
  "id": "req-2",
  "result": null  # can also be omitted
}

Scenario C: Specific Error (e.g., verification failed with code)

{
  "id": "req-3",
  "error": {
    "code": {
      "type": "btck_ScriptVerifyStatus",
      "member": "ERROR_INVALID_FLAGS_COMBINATION"
    }
  }
}

Scenario D: Generic/Unspecified Error

{
  "id": "req-4",
  "error": {}
}

@stringintech
Copy link
Owner Author

stringintech commented Nov 28, 2025

Thank you for the review @stickies-v!

I like the improvement you are suggesting; besides the success boolean field, adding a result field is inevitable for adding next test cases. So it makes sense to merge them and only have the result. Also, differentiating "error": {} from "error": null (or omitted) is reasonable and is a bit closer to what I initially had in mind.

Regarding your comment #7 (comment) on whether to treat invalid scripts (when the request is valid) as success cases:

I think it comes down to how to interpret the C API a bit. I understand how you are reading into this though: we are either successful in verifying (valid/invalid script) or we are not (error/throw), and it makes sense. I am OK with applying the change here, though it seems it contradicts the Rust/Go/.NET approaches (edit: also the python approach now that I am looking) of treating everything but the valid script as an error/exception. And with this change applied, these bindings have to translate back the invalid error cases to non-errors for the handler implementation.

This eliminates usage of the "VERIFY_ALL_PRE_TAPROOT" flag which is not exported from `libbitcoinkernel`
@stringintech
Copy link
Owner Author

Rebased and implemented the semantics suggested here #7 (review) - Thanks @stickies-v!
Also added a unit test for handler response validation which exercises the new semantics in different scenarios.
Pre-release v0.0.2-alpha.2 can be used to test the changes (which I used and tested in stringintech/go-bitcoinkernel@f1a1438).

Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach ACK 0f1e00d

Besides nits as commented, everything feels about as natural as I can imagine it right now. No further suggestions from me for now, not sure I'll be diving deeper into code review.

(edit: draft PR for py-bitcoinkernel implementing conformance is here)

Update btck_script_pubkey_verify test cases to match the C function signature and parameter names from bitcoinkernel.h:

- Method name: Use `btck_script_pubkey_verify` instead of `script_pubkey.verify`
- Parameters: Rename fields to match C API:
  - `script_pubkey_hex` → `script_pubkey`
  - `tx_hex` → `tx_to`
  - `value` → `amount` (in spent_outputs array)
Drop test cases for errors not exported by `bitcoinkernel.h` (`TxInputIndex`, `SpentOutputsMismatch`, `InvalidFlags`) to align with C API capabilities.
Also refactor response validation to be aligned with the improved semantics:
- Success case: result contains the return value (or null for void/nullptr), error must be null/omitted
- Error case: result must be null/omitted, error contains error details

Additional changes:
- Replace Error.type/variant with Error.code.type/member
- Split validation into separate validateResponseForSuccess/Error functions
- Update test cases to reflect new format
Adapt Makefile to also run unit tests with `make test`
@stringintech stringintech force-pushed the btck-symbol-alignment branch from 0f1e00d to dd5c930 Compare December 2, 2025 10:45
@stringintech
Copy link
Owner Author

stringintech commented Dec 2, 2025

Applied @stickies-v's #7 (comment) for further alignment with the C API naming and tested the new pre-release v0.0.2-alpha.3 in stringintech/go-bitcoinkernel@c57354b.

I think I will be merging this in a few hours (if no one sees any further issues) to be able to rebase and merge #9 too. Then hopefully all changes can be exercised with the release v0.0.2.

Copy link
Contributor

@janb84 janb84 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK dd5c930

Good update, nice to have unit tests now also !

@stickies-v
Copy link
Contributor

Updated stickies-v/py-bitcoinkernel#42 to the latest force-push, no more comments on the alignment! Didn't review the code, but everything seems to work well.

For a future improvement, I think it might be worth considering using JSON Schema (or even OpenRPC) to document the interface in a more systematic way, but that's out of scope for this PR.

@stringintech stringintech force-pushed the btck-symbol-alignment branch from dd5c930 to bda7ae4 Compare December 2, 2025 12:15
@stringintech
Copy link
Owner Author

For a future improvement, I think it might be worth considering using JSON Schema (or even OpenRPC) to document the interface in a more systematic way

That would be nice! Especially if we can have something that allows auto-generating code for encoding/decoding the JSON data on the handler side.

@stringintech stringintech force-pushed the btck-symbol-alignment branch from bda7ae4 to e8ddf75 Compare December 2, 2025 12:29
@stringintech stringintech merged commit 4df1da5 into main Dec 2, 2025
2 checks passed
@stringintech stringintech deleted the btck-symbol-alignment branch December 2, 2025 13:16
@janb84
Copy link
Contributor

janb84 commented Dec 2, 2025

Updated stickies-v/py-bitcoinkernel#42 to the latest force-push, no more comments on the alignment! Didn't review the code, but everything seems to work well.

For a future improvement, I think it might be worth considering using JSON Schema (or even OpenRPC) to document the interface in a more systematic way, but that's out of scope for this PR.

Added schema.json in #10

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.

Conformance to exported symbols

4 participants