-
Notifications
You must be signed in to change notification settings - Fork 0
Misc. improvements and cleanups #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* Move the (much simplified) type check function to types.ts * Use `Tapleaf` type a bit more (this might be a bad idea) * Be more consistent in the capitalization of `Taptree`
Because the taggedHash API is typed, these are compile-time checked and it's more clear w/o the constants.
* More clearly show the continuation and base cases in findScriptPath * Return undefined not empty path when no path is found * This would lead to generating an invalid witness * Tighten the type for HashTree to not allow 1-sided branch nodes
* Also added caching of `hashTree`, per todo. * Added a test for this functionality
The spec uses this notation because in a spec there's no such thing as reassigning a value. In real code it is appropriate to us accumulators or such.
@@ -85,6 +88,12 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment { | |||
return a.witness.slice(); | |||
}); | |||
|
|||
const _hashTree = lazy.value(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -77,7 +77,22 @@ export interface Tapleaf { | |||
version?: number; | |||
} | |||
|
|||
export type Taptree = Array<[Tapleaf, Tapleaf] | Tapleaf>; | |||
export const TAPLEAF_VERSION_MASK = 0xfe; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if the place for this constant is in types
.
Maybe it will be extracted to a BIP341 module (see bitcoinjs#1780) together with isTapleaf
, isTaptree
in the future. OK to be here for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I really didn't have a good place for it.
Thank you for the PR! |
Thank you for the feedback, pushed fixes. |
I pushed a large commit over here: BitGo@db3bb8e that minimizes the need to thread Hopefully it goes without saying that you are welcome to cherry-pick, squash, etc. any of my commits as you see fit into your branch. Edit to add: I suspect that we're going to want to rethink having each p2tr created verify the |
NACK on removing eccLib from p2tr. Perhaps it is because there is a lack of support from libraries and lots of people are "rolling their own" for now... but I have seen examples of people sending to v1 segwit programs where the 32 bytes following is not a valid point (even though it is less than P). Bitcoin Core does not reject these, and they are essentially a black hole. (Perhaps a standardness rule could be added to Bitcoin Core to prevent their broadcasting/propagation) At the very least, we should require it for the address module, and anyone trying to get the address from p2tr. But the requirement of being a valid point is especially concerning in this case since a v0 p2wsh is also 32 bytes, but it's a hash. |
If Bitcoin Core included a standardness rule, I might consider it. |
I made an issue for discussion here |
I would be comfortable removing eccLib once an official release with that standardness rule is over 60%-ish of the observable network... |
hmm... looks like consensus is opposite (standardness rule should come after every client/library under the sun has protected against it) |
OK, I see your point. I think more and more that we should drop the Given all of this, it might make sense to apply the Factory pattern to PSBT, make an ECC library required to use PSBT in general, and avoid the conditional/optional threading. That would then open up later refactors to replace |
That is true. It's pretty expensive. Perhaps we can cache eccLib...? When comparing two objects, it returns true for equals when the object is the same reference. We could use that and have some sort of eccLib cache that is rooted in the main library, and will use the cached library if none is passed in, and even if the same library is passed multiple times, skip the check if the reference to the library object is the same? ie. // eccCache.ts (do not export this in the index.ts, it should not be exposed to the public API)
export const _ECCLIB_CACHE: { eccLib?: TinySecp256k1Lib } = {};
// p2tr.ts
import { _ECCLIB_CACHE } from '../eccCache';
if (_ECCLIB_CACHE.eccLib !== eccLib) {
check(eccLib);
_ECCLIB_CACHE.eccLib = eccLib;
} |
|
The caching approach would also solve the the "threading" of But we can have the scenario where :
Same goes for Or... are we planning to use the cache only for removing multiple verify calls for |
We could do both. Maybe even provide a public setter that will verify and set the cache so people don't have to use the weird options to begin with. "Only insert this option once, any subsequent usage isn't needed" is a weird API. |
Yes. I would prefer something explicit as in the code snippet below for several reasons:
// client code
import { payments, address, initEccLib } from 'bitcoinjs-lib'
initEccLib(clientEccLib) |
I'm in full support of an explicit @motorina0 would you like me to whip that up, or you? |
I would rather keep this PR smaller and focused on the review of the actual functionality. |
My concern with How about we wrap methods that require an
This way we can constrain the allowed ecc libs via the type system. (Disclaimer: like @brandonblack I work at BitGo) |
That boat has already sort of sailed with bip32/ecpair tbh. The answer would be to have a single file that imports bitcoinjs, bip32/ecpair, and tiny-secp256k1, mashes them together, and re-exports the eccLib-included objects. Other files would then import from that one file. |
True, but unless I am missing something those deps do not have an If the recommendation is to wrap |
They kind of have (its a factory pattern): import BIP32Factory from 'bip32';
import ECPairFactory from 'ecpair';
import { payments, address, initEccLib } from 'bitcoinjs-lib'
import * as ecc from 'tiny-secp256k1';
const bip32 = BIP32Factory(ecc);
const ECPair = ECPairFactory(ecc);
// suggested change:
initEccLib(ecc)
...
|
@brandonblack I would like to get these changes in the |
Fine with merging this as is. Still getting my head around PSBT, but hopefully others can continue reviewing in the meantime. |
Yeah merge this into the p2tr-v1 branch for now. We can continue discussion there. |
PR merged! Thanks again @brandonblack |
No description provided.