Skip to content

Commit

Permalink
Support PSBT_IN_HASH256 of PSBT v0
Browse files Browse the repository at this point in the history
  • Loading branch information
azuchi committed May 20, 2022
1 parent 8536ab3 commit 6367d7a
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/bitcoin/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module Bitcoin
SHA256_SIZE = 32
# Byte size of the HASH160 hash
HASH160_SIZE = 20
# Byte size of the HASH256 hash
HASH256_SIZE = 32

# The maximum allowed size for a serialized block, in bytes (only for buffer size limits)
MAX_BLOCK_SERIALIZED_SIZE = 4_000_000
Expand Down
7 changes: 7 additions & 0 deletions lib/bitcoin/psbt/input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Input
attr_accessor :ripemd160_preimages
attr_accessor :sha256_preimages
attr_accessor :hash160_preimages
attr_accessor :hash256_preimages
attr_accessor :proprietaries
attr_accessor :unknowns

Expand All @@ -28,6 +29,7 @@ def initialize(non_witness_utxo: nil, witness_utxo: nil)
@ripemd160_preimages = {}
@sha256_preimages = {}
@hash160_preimages = {}
@hash256_preimages = {}
@proprietaries = []
@unknowns = {}
end
Expand Down Expand Up @@ -101,6 +103,10 @@ def self.parse_from_buf(buf)
raise ArgumentError, 'Size of key was not the expected size for the type hash160 preimage' unless key.bytesize == HASH160_SIZE
raise ArgumentError, 'Duplicate Key, input hash160 preimage already provided' if input.hash160_preimages[key.bth]
input.hash160_preimages[key.bth] = value.bth
when PSBT_IN_TYPES[:hash256]
raise ArgumentError, 'Size of key was not the expected size for the type hash256 preimage' unless key.bytesize == HASH256_SIZE
raise ArgumentError, 'Duplicate Key, input hash256 preimage already provided' if input.hash256_preimages[key.bth]
input.hash256_preimages[key.bth] = value.bth
when PSBT_IN_TYPES[:proprietary]
raise ArgumentError, 'Duplicate Key, key for proprietary value already provided.' if input.proprietaries.any?{|p| p.key == key}
input.proprietaries << Proprietary.new(key, value)
Expand Down Expand Up @@ -128,6 +134,7 @@ def to_payload
payload << ripemd160_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:ripemd160], key: k.htb, value: v.htb)}.join
payload << sha256_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:sha256], key: k.htb, value: v.htb)}.join
payload << hash160_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:hash160], key: k.htb, value: v.htb)}.join
payload << hash256_preimages.map{|k, v|PSBT.serialize_to_vector(PSBT_IN_TYPES[:hash256], key: k.htb, value: v.htb)}.join
end
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:script_sig], value: final_script_sig.to_payload) if final_script_sig
payload << PSBT.serialize_to_vector(PSBT_IN_TYPES[:script_witness], value: final_script_witness.to_payload) if final_script_witness
Expand Down
26 changes: 26 additions & 0 deletions spec/bitcoin/psbt_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -447,4 +447,30 @@
end
end
end

context 'has PSBT_IN_HASH256' do
it 'parse sha256 data' do
base64 = 'cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAIQ12pWrO2RXSUT3NhMLDeLLoqlzWMrW3HKLyrFsOOmSb2wIBAiENnBLP3ATHRYTXh6w9I3chMsGFJLx6so3sQhm4/FtCX3ABAQAAAA=='
psbt = Bitcoin::PSBT::Tx.parse_from_base64(base64)
expect(psbt.inputs.size).to eq(1)
expect(psbt.inputs[0].hash256_preimages.size).to eq(2)
expect(psbt.inputs[0].hash256_preimages['76a56aced915d2513dcd84c2c378b2e8aa5cd632b5b71ca2f2ac5b0e3a649bdb']).to eq('0102')
expect(psbt.inputs[0].hash256_preimages['9c12cfdc04c74584d787ac3d23772132c18524bc7ab28dec4219b8fc5b425f70']).to eq('01')
expect(psbt.to_base64).to eq(base64)
end

context 'duplicate PSBT_IN_HASH256 key' do
it 'raise ArgumentError' do
hex = '70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab300000000210d9c12cfdc04c74584d787ac3d23772132c18524bc7ab28dec4219b8fc5b425f70020102210d9c12cfdc04c74584d787ac3d23772132c18524bc7ab28dec4219b8fc5b425f700101000000'
expect {Bitcoin::PSBT::Tx.parse_from_payload(hex.htb)}.to raise_error(ArgumentError, 'Duplicate Key, input hash256 preimage already provided')
end
end

context 'invalid key size' do
it 'raise ArgumentError' do
hex = '70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab300000000200da56aced915d2513dcd84c2c378b2e8aa5cd632b5b71ca2f2ac5b0e3a649bdb020102210d9c12cfdc04c74584d787ac3d23772132c18524bc7ab28dec4219b8fc5b425f700101000000'
expect {Bitcoin::PSBT::Tx.parse_from_payload(hex.htb)}.to raise_error(ArgumentError, 'Size of key was not the expected size for the type hash256 preimage')
end
end
end
end

0 comments on commit 6367d7a

Please sign in to comment.