diff --git a/lib/glueby/fee_provider.rb b/lib/glueby/fee_provider.rb index e74cacf4..35b7b841 100644 --- a/lib/glueby/fee_provider.rb +++ b/lib/glueby/fee_provider.rb @@ -36,11 +36,19 @@ def initialize @utxo_pool_size = (FeeProvider.config && FeeProvidr.config[:utxo_pool_size]) || DEFAULT_UTXO_POOL_SIZE end - # Provide an input for fee to the tx. # @param [Tapyrus::Tx] tx - The tx that is provided fee as a input. It should be signed with ANYONECANPAY flag. # @return [Tapyrus::Tx] + # @raise [ArgumentError] If the signatures that the tx inputs has don't have ANYONECANPAY flag. def provide(tx) + tx.inputs.each do |txin| + get_signatures(txin.script_sig).each do |sig| + unless sig[-1].unpack1('C') & Tapyrus::SIGHASH_TYPE[:anyonecanpay] == Tapyrus::SIGHASH_TYPE[:anyonecanpay] + raise ArgumentError, 'All the signatures that the tx inputs has should have ANYONECANPAY flag.' + end + end + end + utxo = utxo_for_fee out_point = Tapyrus::OutPoint.new(utxo[:txid].rhex, utxo[:vout]) tx.inputs << Tapyrus::TxIn.new(out_point: out_point) @@ -55,5 +63,18 @@ def utxo_for_fee raise NoUtxosInUtxoPool, 'No UTXOs in Fee Provider UTXO pool. UTXOs should be created with "glueby:fee_provider:manage_utxo_pool" rake task' unless utxo utxo end + + def get_signatures(script_sig) + sighashtypes = [Tapyrus::SIGHASH_TYPE[:all], Tapyrus::SIGHASH_TYPE[:none], Tapyrus::SIGHASH_TYPE[:single]].map do |i| + [i, i | Tapyrus::SIGHASH_TYPE[:anyonecanpay]] + end.flatten + + script_sig.chunks.select do |c| + # 71, 72 and 73 are for ECDSA signature. 65 is for Schnorr signature + c.pushdata? && + [71, 72, 73, 65].include?(c.pushed_data.bytesize) && + sighashtypes.include?(c.pushed_data[-1].unpack1('C')) + end.map(&:pushed_data) + end end end \ No newline at end of file diff --git a/spec/glueby/fee_provider_spec.rb b/spec/glueby/fee_provider_spec.rb index 1c079aaf..5952ba9f 100644 --- a/spec/glueby/fee_provider_spec.rb +++ b/spec/glueby/fee_provider_spec.rb @@ -40,5 +40,13 @@ ) subject end + + context 'Signatures in tx don\'t have ANYONECNAPAY flag' do + let(:tx) { Tapyrus::Tx.parse_from_payload("01000000018939a2974964f144941ed79c60a0046ee9f842f3b60453ea7d4533601c7ca030000000006a473044022004e5c255e7f397d3ea67e104b00bebfc31cff8d8f57b4c4972473936dda35d8e0220562676a1d1dfd85c89d596e7e96eaa178f8ef4b30c109c561612435137a8860401210280b5f253e612294a2c15a912bbb39b1d5ea48163c14bff56fd1a7079fed23258ffffffff02e8030000000000001976a91402b5fb1195e4c7b069ac33751d03d73a216babe588ac28230000000000001976a9148981ef639f525dc87b0c92ea9fb9af5148cf229688ac00000000".htb) } + + it 'raise ArgumentError' do + expect { subject }.to raise_error(ArgumentError, 'All the signatures that the tx inputs has should have ANYONECANPAY flag.') + end + end end end \ No newline at end of file