require_relative '../spec_helper' RSpec.describe TxCatcher::Transaction do class TxCatcher::Transaction def assign_tx_hash(h) @tx_hash = h end end before(:each) do @hextx = File.read(File.dirname(__FILE__) + "/../fixtures/transaction.txt").strip @transaction = TxCatcher::Transaction.create(hex: @hextx) end it "parses rawtx using bitcoind" do expect(@transaction.txid).to eq("faf8368fec418a971e8fa94943e951490759498e0b2d3c4d5b9b12212c4f2e5a") end it "creates addresses and deposits" do expect(TxCatcher::Address.where(address: "323LGzCm43NgbtoYJhT6oKSwmKFTQ7AHzH").first.received).to eq(466700000) expect(TxCatcher::Address.where(address: "36u6xv2TvZqPPYdogzfLZpMAXrYdW4Vwjp").first.received).to eq(1332776478) end it "doesn't create duplicate deposits if valid? called manually before save" do TxCatcher::Transaction.select_all.delete transaction = TxCatcher::Transaction.new(hex: @hextx) transaction.valid? transaction.save expect(transaction.deposits.size).to eq(2) transaction.update(block_height: 1) expect(TxCatcher::Transaction.where(txid: transaction.txid).count).to eq(1) end it "updates block height by making manual requests to RPC and searching if tx is included in one of the previous blocks" do expect(TxCatcher.rpc_node).to receive(:getblockhash).exactly(10).times.and_return("blockhash123") expect(TxCatcher.rpc_node).to receive(:getblock).exactly(10).times.and_return({ "height" => "123", "tx" => [@transaction.txid], "hash" => "blockhash123"}) @transaction.check_block_height! expect(@transaction.block_height).to eq(123) end it "updates multiple records at once" do transaction1 = TxCatcher::Transaction.create(hex: @hextx, txid: "123") transaction2 = TxCatcher::Transaction.create(hex: @hextx, txid: "1234") transaction3 = TxCatcher::Transaction.create(hex: @hextx, txid: "1235") transaction2.block_height = 2 transaction3.block_height = 3 expect( TxCatcher::Transaction.update_all([transaction1, transaction2, transaction3]) ).to eq([transaction2.id, transaction3.id]) end it "handles an RBF transaction" do deposit_ids = @transaction.deposits.map(&:id) rbf_tx = TxCatcher::Transaction.new(hex: @hextx) rbf_tx_hash = @transaction.tx_hash rbf_tx_hash["txid"] = "rbftxid1" rbf_tx_hash["locktime"] = "1" rbf_tx.assign_tx_hash(rbf_tx_hash) rbf_tx.save expect(@transaction.reload.rbf_next_transaction_id).to eq(rbf_tx.id) expect(rbf_tx.rbf_previous_transaction_id).to eq(@transaction.id) expect(@transaction.deposits).to be_empty expect(rbf_tx.reload.deposits.map(&:id)).to eq(deposit_ids) rbf_tx.deposits.each do |d| expect(d.rbf_transaction_ids).to eq([@transaction.id]) end rbf_tx2 = TxCatcher::Transaction.new(hex: @hextx) rbf_tx_hash["txid"] = "rbftxid2" rbf_tx_hash["locktime"] = "2" rbf_tx2.assign_tx_hash(rbf_tx_hash) rbf_tx2.save expect(rbf_tx.reload.rbf_next_transaction_id).to eq(rbf_tx2.id) expect(rbf_tx2.rbf_previous_transaction_id).to eq(rbf_tx.id) expect(rbf_tx.deposits).to be_empty expect(rbf_tx2.reload.deposits.map(&:id)).to eq(deposit_ids) rbf_tx2.deposits.each do |d| expect(d.rbf_transaction_ids).to eq([@transaction.id, rbf_tx.id]) end end it "forces deposit association with itself when confirmed, but another RBF transaction is associated with the deposit" do deposit_ids = @transaction.deposits.map(&:id) rbf_tx = TxCatcher::Transaction.new(hex: @hextx) rbf_tx_hash = @transaction.tx_hash rbf_tx_hash["txid"] = "rbftxid1" rbf_tx_hash["locktime"] = "1" rbf_tx.assign_tx_hash(rbf_tx_hash) rbf_tx.save @transaction.reload.force_deposit_association_on_rbf! expect(rbf_tx.reload.deposits).to be_empty expect(@transaction.reload.deposits.map(&:id)).to eq(deposit_ids) @transaction.deposits.each do |d| expect(d.rbf_transaction_ids).to eq([@transaction.id]) end end end