Skip to content
This repository has been archived by the owner on Apr 3, 2019. It is now read-only.

Remove Redeem Script Classification Requirement from Script.isScriptHashIn() #36

Closed
wants to merge 5 commits into from

Conversation

APTy
Copy link

@APTy APTy commented Jan 12, 2016

This change fixes an issue where the Script object would return an unknown script type when trying to classify a redeem script in Script.isScriptHashIn(). Every type of redeem script must be defined in script.js in order to be recognized. At current, only Multisig and DataOut redeem script types are supported. In other words, new script types such as those used in CLTV payment channel transactions are not recognized.

This can cause issues where Script implementations don't recognize a script, and, in the case of bitcore-node, fail to index the transaction, causing issues like bitpay/insight-api#444 where insight-api is unable to find a custom p2sh in its leveldb indexes. This is perhaps an implementation oversight on the part of bitcore-node but the fact remains that there are many possible redeem scripts, and we shouldn't have to itemize every type for the Script object to recognize them.

Due to the fact that there is little (if any) cost to incorrectly classifying a redeem script as valid after all other script types have been exhausted, and rather than define every possible redeem script type, we should remove this requirement and instead only verify basic attributes like length, ability to be serialized, etc.

Tyler J added 2 commits January 5, 2016 11:28
- The bitcore-lib Script is primarily concerned with serializing,
  deserializing, building common bitcoin scripts, and extracting
  commonly needed information
- Script.isScriptHashIn() requires the Script object to conclude
  whether a P2SH redeem script is valid, which in many cases, it
  cannot (nor should it)
- The Script object should remain unopinionated, especially in
  light of a P2SH redeemscript, where the benefits of classification
  are dwarfed by the costs of it being incorrect

- In the case of BIP 65's OP_CHECKLOCKTIMEVERIFY, this error causes
  consumers of bitcore-lib to incorrectly conclude that CLTV
  transactions are not P2SH spends
- Over-zealous classification in this case is fragile and breaks
  forward compatibility - it should be removed until a more stable
  P2SH check is implemented
- Data transactions consist of OP_RETURN followed by a push of bytes
  to the stack
- P2SH redeem scripts (generally) consist of signatures and relevant
  information followed by a push of bytes to the stack
- To differentiate the two, we check that the first OP code is not
  OP_RETURN in Script.isScriptHashIn()
@APTy APTy changed the title Remove Redeem Script Classification Requirement from ScriptHashIn Check Remove Redeem Script Classification Requirement from Script.isScriptHashIn() Jan 12, 2016
Tyler J added 2 commits January 11, 2016 17:38
- Since we've relaxed our definition of what a valid redeemscript
  comprises of, we need to update the test to check for that. In
  this case, it's a script that simply pushes bytes to the stack.
@APTy APTy force-pushed the fix-p2sh-classification branch from 730bfc2 to 2a54b18 Compare January 12, 2016 01:44
@braydonf
Copy link
Contributor

Interesting, bitcoind.isSpentis currently used for balances, however the corresponding spending txid may not show up if it's not classified (though could still be valid).

@APTy
Copy link
Author

APTy commented Jan 14, 2016

Right - so users of bitcore-node with this version of bitcore-lib will be report incorrect results when doing a lookup of transactions by address, due to transactions not being indexed. This is problematic for applications that rely on an accurate lookup of that kind.

This patch has proven effective on a bitcore node for the past few weeks. I think it would be helpful to others, but let me know if you think a fix is more suitable on the bitcore-node side, and I could certainly take a look.

Thanks!

@braydonf
Copy link
Contributor

This may be something that we need to fix on the bitcore-node side. Without looking at the classification, we would need to have a reference to the output to know if it's standard pay-to-script-hash. Example:

> var tx = bitcore.Transaction('0100000001ce5d8ced3c8c364b4f74dfd646b641b63887772f3a6b6dcf0ba8dc9b7bd12f4e010000008b483045022100d39707717cf2a172c98c932001b220c4ba9b2925e61d34574a8a9c7d8db3a03f022066bf18115b3e011d17b8879b088b90cd416fae825719a23e759dca151f016dfa01410470a47342c1d1ab469fbb3ec339b37b9da9ffea707aab41e127dcbac47fba2a3da5f1097d46a7e47788d9215a32e3d2a540cef0475e6a1901b9b037b3ffaf0bdaffffffff0292c67e09000000001976a914715832ea41ae50d5fc0c3a8e3f4dad12a2a20b7788aca6ca064b020000001976a914e780f5642809d1a0b24d6db71fcd17ff2e32343f88ac00000000');
> tx.toObject()
{ hash: '0cf9a0218b79625003b90cdacd1b6b215b1d4480d2e4ccd5ddc3cd72f20ccba5',
  version: 1,
  inputs: 
   [ { prevTxId: '4e2fd17b9bdca80bcf6d6b3a2f778738b641b646d6df744f4b368c3ced8c5dce',
       outputIndex: 1,
       sequenceNumber: 4294967295,
       script: '483045022100d39707717cf2a172c98c932001b220c4ba9b2925e61d34574a8a9c7d8db3a03f022066bf18115b3e011d17b8879b088b90cd416fae825719a23e759dca151f016dfa01410470a47342c1d1ab469fbb3ec339b37b9da9ffea707aab41e127dcbac47fba2a3da5f1097d46a7e47788d9215a32e3d2a540cef0475e6a1901b9b037b3ffaf0bda',
       scriptString: '72 0x3045022100d39707717cf2a172c98c932001b220c4ba9b2925e61d34574a8a9c7d8db3a03f022066bf18115b3e011d17b8879b088b90cd416fae825719a23e759dca151f016dfa01 65 0x0470a47342c1d1ab469fbb3ec339b37b9da9ffea707aab41e127dcbac47fba2a3da5f1097d46a7e47788d9215a32e3d2a540cef0475e6a1901b9b037b3ffaf0bda' } ],
  outputs: 
   [ { satoshis: 159303314,
       script: '76a914715832ea41ae50d5fc0c3a8e3f4dad12a2a20b7788ac' },
     { satoshis: 9848670886,
       script: '76a914e780f5642809d1a0b24d6db71fcd17ff2e32343f88ac' } ],
  nLockTime: 0 }
> var s = bitcore.Script('483045022100d39707717cf2a172c98c932001b220c4ba9b2925e61d34574a8a9c7d8db3a03f022066bf18115b3e011d17b8879b088b90cd416fae825719a23e759dca151f016dfa01410470a47342c1d1ab469fbb3ec339b37b9da9ffea707aab41e127dcbac47fba2a3da5f1097d46a7e47788d9215a32e3d2a540cef0475e6a1901b9b037b3ffaf0bda');
> s.isScriptHashIn()
true
> s.isPublicKeyHashIn()
true

@APTy
Copy link
Author

APTy commented May 22, 2016

Closing this in favor of the bitcore-node issues

@APTy APTy closed this May 22, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants