[WIP] OP_WITHDRAWPROOFVERIFY implementation#5
[WIP] OP_WITHDRAWPROOFVERIFY implementation#5Christewart wants to merge 32 commits intoSuredbits:masterfrom
Conversation
Modifying generators to be more flexible
Fixing bug in generator for merkle blocks with specific txs
Adding more flexibility to block header generators
Add merkle block
…hink it is all correct
… coins in the OP_WPV output when a user is not withdrawing all of them
Fixing bug in calculating pushops for ScriptNumberOperations
…iptNumberOperations -- for instance pushing an 83 byte transaction (whose op code is OP_3) -- whose script looks like OP_PUSHDATA1 OP_3 <83 byte tx> would fail before this
Fixing bug in pushing constants onto the stack whose op codes are Scr…
…ck to make sure withdrawl txs are valid
…pt_num_op Fixing bug in calculating pushops for ScriptNumberOperations
| (sidechainCreditingTx,outputIndex) = TransactionGenerators.buildSidechainCreditingTx(genesisBlockHash, reserveAmount) | ||
| sidechainCreditingOutput = sidechainCreditingTx.outputs(outputIndex.toInt) | ||
|
|
||
| contract = BitcoinSUtil.decodeHex("5032504800000000000000000000000000000000") ++ userSidechainAddr.bytes |
|
|
||
|
|
||
| /** Generator for a contract used within a [[WithdrawScriptSignature]] */ | ||
| def contract: Gen[Seq[Byte]] = for { |
There was a problem hiding this comment.
probably need to create a type for 'contract' and create a generator that takes in a Sha256Hash160Digest
| */ | ||
| def opWithdrawProofVerify(program : ScriptProgram) : ScriptProgram = { | ||
| // comment from bitcoin core | ||
| require(program.script.headOption == Some(OP_WITHDRAWPROOFVERIFY), "Script operation is required to be OP_WITHDRAWPROOFVERIFY") |
There was a problem hiding this comment.
Need to implement the flag 'ScriptVerifyMinimalData`, this is implemented in elements but I haven't implemented yet in bitcoin-s-sidechains
| /** Checks the given [[MerkleBlock]] to see if we have enough proof of work | ||
| * [[https://github.com/ElementsProject/elements/blob/edaaa8b0f92653d9f770e671c7493f4bab4b48c7/src/pow.cpp#L40]] | ||
| * */ | ||
| private def checkBitcoinProofOfWork(merkleBlock: MerkleBlock): Boolean = { |
|
|
||
| case object OP_WITHDRAWPROOFVERIFY extends CryptoOperation { | ||
| override def opCode = 179 | ||
| override def toString = "OP_NOP4" |
There was a problem hiding this comment.
Add comment to why this is is set to OP_NOP4 and not OP_WPV, same with OP_NOP5
| val txSigComponent = program.txSignatureComponent | ||
| logger.debug("TxSigComponent: " + txSigComponent) | ||
| /** Helper function to check if the witness was used */ | ||
| def witnessUsed(w: WitnessV0TransactionSignatureComponent) : Boolean = { |
There was a problem hiding this comment.
Consider moving this refactor upstream into bitcoin-s-core
| (scriptSig,scriptPubKey,fedPegScript,reserveAmount) <- ScriptGenerators.withdrawlScript | ||
| (sidechainCreditingTx,outputIndex) = buildSidechainCreditingTx(genesisBlockHash, reserveAmount) | ||
| sidechainCreditingOutput = sidechainCreditingTx.outputs(outputIndex.toInt) | ||
| sidechainUserOutput = TransactionOutput(scriptSig.withdrawlAmount,P2PKHScriptPubKey(scriptSig.userHash)) |
There was a problem hiding this comment.
This is not always a P2PKHScriptPubKey, can be P2SHScriptPubKey depending on what the contract specifies.
| //TODO: Investigate this further, can we technically have negative output indexes as script numbers can be negative? | ||
| UInt32(num.toLong) | ||
| case constant: ScriptConstant => | ||
| logger.error("Asm: " + asm) |
| require(program.txSignatureComponent.isInstanceOf[FedPegTransactionSignatureComponent]) | ||
| val fPegTxSigComponent = program.txSignatureComponent.asInstanceOf[FedPegTransactionSignatureComponent] | ||
|
|
||
| val relockScript: ScriptPubKey = ScriptPubKey(Seq(BytesToPushOntoStack(32),genesisHashToken, OP_WITHDRAWPROOFVERIFY)) |
There was a problem hiding this comment.
Call WithdrawScriptPubKey constracut here instead of constructing the asm ourselves.
| val partialMerkleTree = merkleBlock.partialMerkleTree | ||
| val matchedTxs: Seq[DoubleSha256Digest] = partialMerkleTree.extractMatches | ||
|
|
||
| if (partialMerkleTree.tree.value != Some(merkleBlock.blockHeader.merkleRootHash) || matchedTxs.length != 1) { |
There was a problem hiding this comment.
Instead of != I think scala recommends using .contains()
| return ScriptProgram(program, ScriptErrorWithdrawVerifyOutputScriptDest) | ||
| } | ||
|
|
||
| val contractWithoutNonce = contract.take(4) ++ contract.slice(20,contract.length) |
There was a problem hiding this comment.
After creating a type for 'contract` create a method to access the user's hash
| val (sidechainCreditingTx,outputIndex) = buildSidechainCreditingTx(genesisBlockHash) | ||
| val sidechainCreditingOutput = sidechainCreditingTx.outputs(outputIndex) | ||
| val sidechainUserOutput = TransactionOutput(amount,P2PKHScriptPubKey(usersHash)) | ||
| val relockScriptPubKey = ScriptPubKey.fromAsm(Seq(BytesToPushOntoStack(32), |
There was a problem hiding this comment.
Call WithdrawScriptPubKey.fromAsm
…nature, fixing first round of nits on OP_WPV pull request
Adding contract type to represent the contract in a WithdrawScriptSig…
Secp256k1 api enhancement
P2pkh script sig bug rd2
This pull request implements the op code OP_WITHDRAWPROOFVERIFY found in the elements project.
The purpose of OP_WITHDRAWPROOFVERIFY is to support sidechains.
To see a detailed description of OP_WPV functionality please read this blog post:
https://medium.com/@Chris_Stewart_5/op-withdrawproofverify-the-op-code-that-powers-spv-sidechains-cefce996a324#.y2dcegslq
This pull request has a generator inside of it to test all cases that should be successful for OP_WPV. We test that generator produces only valid OP_WPV withdrawls here.
TODO: