Page MenuHomePhabricator

[Cashtab] Add new validation function for parsing opreturn as a bip21 parameter
ClosedPublic

Authored by bytesofman on Dec 22 2023, 00:31.

Details

Summary

Add new function and unit tests for validating a raw hex string to be included in OP_RETURN for an eCash tx. See D15032 for proof of concept / where this is going.

Spec for ref: https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/standards/bip21-ecash-additions.md

Test Plan

npm test

Diff Detail

Repository
rABC Bitcoin ABC
Branch
fn-isvalidopreturn
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 26102
Build 51777: Build Diffcashtab-tests
Build 51776: arc lint + arc unit

Event Timeline

bytesofman edited the summary of this revision. (Show Details)
bytesofman retitled this revision from [Cashtab] Add new validation function for parsing opreturn as a pip21 parameter to [Cashtab] Add new validation function for parsing opreturn as a bip21 parameter.
Fabien added inline comments.
cashtab/src/config/opreturn.js
35 ↗(On Diff #43757)

The limit is 220 bytes of data for an op_return. The extra 3 bytes are 1 for the op_return opcode and 2 for the push opcodes.

I didn't check if the node would reject a 222 bytes op_return (I doubt it) but it might make more sense to limit to 220 in the URI and add the push opcode ourselves, as it's commonly done on the network already

cashtab/src/utils/__tests__/validation.test.js
1054 ↗(On Diff #43757)

This is also a good point for the implicit push. There is no reason you can't push some arbitrary data starting with 0x6a

PiRK added inline comments.
cashtab/src/utils/validation.js
702 ↗(On Diff #43757)

I'm not sure about this restriction. To me it makes sense to either accept any arbitrary data (including weird stuff like OP_RETURN "6a6a6a") or else be even more restrictive by forcing the data to start with a push operator (anything in range "00" -- "4c").

cashtab/src/utils/validation.js
702 ↗(On Diff #43757)

I wrote this before seeing Fabien's review. Similar concern.

PiRK requested changes to this revision.Dec 22 2023, 09:49

I checked the standardness rules. So if you want the node to accept broadcasting the tx, you need the OP_RETURN to be followed by a push opcode.

The policy.cpp::AreInputsStandard function calls standard.cpp::Solver

Screenshot from 2023-12-22 10-31-53.png (234×638 px, 24 KB)

IsPushOnly returns true for any opcode <= OP_16, so anything in range 0x00 - 0x60 is considered standard.

Screenshot from 2023-12-22 10-45-27.png (400×709 px, 42 KB)

This revision now requires changes to proceed.Dec 22 2023, 09:49
cashtab/src/config/opreturn.js
35 ↗(On Diff #43757)

Feedback here is good. I'm thinking it might be more direct though to change the spec and require the opreturn= param to be fully formed and valid opreturn, i.e. starting with 6a, and simply use the 220+3 max.

Originally I figured including the 6a was a waste, as the 6a is implied by the opreturn=. However I don't think there's really a byte limit concern with URI creation, and not including the 6a creates more complications (validation functions need to specifically ignore it, whatever code being used to generate the URI is probably also having to slice off the 6a to comply with the spec, only for all wallet software to then have to add it back on before broadcasting).

If we are going to add our own opcodes -- imo not a bad appraoch -- spec does need to be quite different and more complicated, something like opreturn=true&pushCount=3&encoding=utf8&push1=xxxx&push2=xxxx&push3=xxx ... this type of approach would make it easier(ish) for non-developers to create opreturn URIs. imo tho we could expand to add this if there is demand, but starting with a one-param, always hex, always valid opreturn is the simplest.

I'm assuming the main use for this is creating very specific OP_RETURN outputs that can be indexed or tracked somehow by their creator, so requiring the hex to be "the exact thing" is the best first step.

use library for validation

Tail of the build log:

/work/cashtab /work/abc-ci-builds/cashtab-tests
npm WARN deprecated w3c-hr-time@1.0.2: Use your platform's native performance.now() and performance.timeOrigin.
npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
npm WARN deprecated stable@0.1.8: Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility
npm WARN deprecated rollup-plugin-terser@7.0.2: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser
npm WARN deprecated text-encoding@0.6.4: no longer maintained
npm WARN deprecated ts-custom-error@2.2.2: npm package tarball contains useless codeclimate-reporter binary, please update to version 3.1.1. See https://github.com/adriengibrat/ts-custom-error/issues/32

added 1730 packages, and audited 1731 packages in 22s

236 packages are looking for funding
  run `npm fund` for details

5 moderate severity vulnerabilities

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

> cashtab@1.0.0 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

[eslint] 
src/utils/validation.js
  Line 13:10:  'opReturn' is defined but never used  no-unused-vars

Search for the keywords to learn more about each error.


Build cashtab-tests failed with exit code 1
cashtab/src/config/opreturn.js
35 ↗(On Diff #43757)

OK following discussion

  • We want to keep it so that app dev pushes 6a, so that this param can always only be an OP_RETURN
  • Keep param to one string

Validation function here is for Cashtab convenience, i.e. I don't want to be broadcasting something to the node that I know will be rejected there. So we validate for valid OP_RETURN string before broadcasting the tx.

cashtab/src/utils/__tests__/validation.test.js
1054 ↗(On Diff #43757)

In this case, it would be invalid. We can push 6a arbitrarily if we like -- but it needs its own pushdata, which will not be 6a. So, we do want this test.

cashtab/src/utils/validation.js
702 ↗(On Diff #43757)

or else be even more restrictive by forcing the data to start with a push operator (anything in range "00" -- "4c").

I think this is the right approach.

Use constant instead of hard coded '6a'

Fabien requested changes to this revision.Jan 2 2024, 19:51
Fabien added inline comments.
cashtab/src/utils/validation.js
693

You actually don't need it, it's handled by getStackArray

699–700

Does it support or does it NOT support mixed case ? I can't decide from this comment

This revision now requires changes to proceed.Jan 2 2024, 19:51
bytesofman added inline comments.
cashtab/src/utils/validation.js
693

I originally had this omitted, but it causes the unit test for just '6a' to fail since no error is thrown.

getStackArray('6a') = []

which is expected behavior.

bytesofman marked an inline comment as done.

clarify comment

Fabien added inline comments.
cashtab/src/utils/validation.js
693

OK, looking at the code I expected it to throw

This revision is now accepted and ready to land.Jan 3 2024, 08:56