diff --git a/app/models/cita_sync/persist.rb b/app/models/cita_sync/persist.rb index d4e7ee2..f7b73aa 100644 --- a/app/models/cita_sync/persist.rb +++ b/app/models/cita_sync/persist.rb @@ -21,12 +21,13 @@ def save_blocks? # @param hex_num_str [String] block number in hex_num_str # @return [Block, SyncError] return SyncError if rpc return an error def save_block(hex_num_str) - data = CitaSync::Api.get_block_by_number(hex_num_str, false) + rpc_params = [hex_num_str, true] + data = CitaSync::Api.get_block_by_number(*rpc_params) result = data["result"] error = data["error"] # handle error - return handle_error("getBlockByNumber", [hex_num_str, false], error) unless error.nil? + return handle_error("getBlockByNumber", rpc_params, error) unless error.nil? # handle for result.nil # raise "network error, retry later" if result.nil? @@ -35,19 +36,20 @@ def save_block(hex_num_str) block_number_hex_str = result.dig("header", "number") block_number = HexUtils.to_decimal(block_number_hex_str) - transaction_hashes = result.dig("body", "transactions") + block_hash = result["hash"] + transactions_data = result.dig("body", "transactions") block = Block.new( version: result["version"], - cita_hash: result["hash"], + cita_hash: block_hash, header: result["header"], # body: result["body"], block_number: block_number, - transaction_count: transaction_hashes.count + transaction_count: transactions_data.count ) block.save! if save_blocks? - transaction_hashes.each do |hash| - SaveTransactionWorker.perform_async(hash) + transactions_data.each.with_index do |tx_data, index| + SaveTransactionWorker.perform_async(tx_data, index, block_number_hex_str, block_hash, block.id) end block @@ -56,39 +58,30 @@ def save_block(hex_num_str) # save a transaction # block persisted first # - # @param hash [String] hash of transaction + # @param tx_data [Hash] hash and content of transaction + # @param index [Integer] transaction index # @return [Transaction, SyncError] return SyncError if rpc return an error - def save_transaction(hash) - tx_data = CitaSync::Api.get_transaction(hash) + def save_transaction(tx_data, index, block_number_hex_str, block_hash, block_id) + hash = tx_data["hash"] + content = tx_data["content"] receipt_data = CitaSync::Api.get_transaction_receipt(hash) - tx_result = tx_data["result"] - tx_error = tx_data["error"] - receipt_result = receipt_data["result"] receipt_error = receipt_data["error"] # handle error - unless tx_error.nil? && receipt_error.nil? - tx_sync_error = handle_error("getTransaction", [hash], tx_error) unless tx_error.nil? - receipt_sync_error = handle_error("getTransactionReceipt", [hash], receipt_error) unless receipt_error.nil? - return [tx_sync_error, receipt_sync_error] - end - - return if tx_result.nil? && receipt_result.nil? + return handle_error("getTransactionReceipt", [hash], receipt_error) unless receipt_error.nil? - block = nil - block = Block.find_by(block_number: HexUtils.to_decimal(tx_result["blockNumber"])) if save_blocks? + return if tx_data.nil? && receipt_result.nil? - content = tx_result["content"] message = Message.new(content) transaction = Transaction.new( - cita_hash: tx_result["hash"], + cita_hash: hash, content: content, - block_number: tx_result["blockNumber"], - block_hash: tx_result["blockHash"], - index: tx_result["index"], - block: block, + block_number: block_number_hex_str, + block_hash: block_hash, + index: HexUtils.to_hex(index), + block_id: block_id, from: message.from, to: message.to, data: message.data, @@ -103,7 +96,7 @@ def save_transaction(hash) ApplicationRecord.transaction do transaction.save! receipt_result["logs"]&.each do |log| - transaction.event_logs.build(log.transform_keys { |key| key.to_s.underscore }.merge(block: block)) + transaction.event_logs.build(log.transform_keys { |key| key.to_s.underscore }.merge(block_id: block_id)) end transaction.save! end diff --git a/app/workers/save_transaction_worker.rb b/app/workers/save_transaction_worker.rb index fecde21..5b5d5fb 100644 --- a/app/workers/save_transaction_worker.rb +++ b/app/workers/save_transaction_worker.rb @@ -3,7 +3,7 @@ class SaveTransactionWorker include Sidekiq::Worker - def perform(hash) - CitaSync::Persist.save_transaction(hash) + def perform(tx_data, index, block_number_hex_str, block_hash, block_id) + CitaSync::Persist.save_transaction(tx_data, index, block_number_hex_str, block_hash, block_id) end end diff --git a/spec/models/cita_sync/persist_spec.rb b/spec/models/cita_sync/persist_spec.rb index c8b2479..c372085 100644 --- a/spec/models/cita_sync/persist_spec.rb +++ b/spec/models/cita_sync/persist_spec.rb @@ -38,7 +38,7 @@ def set_false it "with error params" do sync_error = CitaSync::Persist.save_block("a") expect(sync_error.method).to eq "getBlockByNumber" - expect(sync_error.params).to eq ["a", false] + expect(sync_error.params).to eq ["a", true] expect(sync_error.code).to eq block_zero_params_error_code expect(sync_error.message).to eq block_zero_params_error_message expect(sync_error.data).to be nil @@ -53,9 +53,16 @@ def set_false end context "save transaction" do + let(:tx_data) do + { + "hash" => transaction_hash, + "content" => transaction_content + } + end + it "save transaction" do block = CitaSync::Persist.save_block("0x1") - transaction = CitaSync::Persist.save_transaction(transaction_hash) + transaction = CitaSync::Persist.save_transaction(tx_data, 0, HexUtils.to_hex(block.block_number), block.cita_hash, block.id) expect(transaction.cita_hash).to eq transaction_hash expect(transaction.errors.full_messages).to be_empty expect(transaction.block).to eq block @@ -63,7 +70,7 @@ def set_false it "save transaction with SAVE_BLOCKS set false" do set_false - transaction = CitaSync::Persist.save_transaction(transaction_hash) + transaction = CitaSync::Persist.save_transaction(tx_data, 0, "0x0", "0x123", nil) expect(transaction.cita_hash).to eq transaction_hash expect(transaction.errors.full_messages).to be_empty expect(transaction.block).to be nil @@ -78,20 +85,29 @@ def set_false # end it "save transaction without block will be success" do - transaction = CitaSync::Persist.save_transaction(transaction_hash) + transaction = CitaSync::Persist.save_transaction(tx_data, 0, nil, nil, nil) expect(transaction.errors.full_messages).to be_empty end it "with error params" do - params = ["0x0"] - tx_sync_error, receipt_sync_error = CitaSync::Persist.save_transaction(*params) + params = [ + { + "hash" => "0x0", + "content" => "0x123" + }, + 0, + nil, + nil, + nil + ] + + receipt_sync_error = CitaSync::Persist.save_transaction(*params) - expect(tx_sync_error.method).to eq "getTransaction" expect(receipt_sync_error.method).to eq "getTransactionReceipt" - expect(tx_sync_error.params).to eq params - expect(tx_sync_error.code).to eq transaction_params_error_code - expect(tx_sync_error.message).to eq transaction_params_error_message - expect(tx_sync_error.data).to be nil + expect(receipt_sync_error.params).to eq ["0x0"] + expect(receipt_sync_error.code).to eq transaction_params_error_code + expect(receipt_sync_error.message).to eq transaction_params_error_message + expect(receipt_sync_error.data).to be nil end end diff --git a/spec/supports/block_mock_support.rb b/spec/supports/block_mock_support.rb index 24e881b..61651f0 100644 --- a/spec/supports/block_mock_support.rb +++ b/spec/supports/block_mock_support.rb @@ -78,6 +78,7 @@ def stub_request_error_wrapper(method, params, error, status: 200, json_rpc: "2. end let(:mock_get_block_by_number_zero_params_error) do stub_request_error_wrapper("getBlockByNumber", ["a", false], block_zero_params_error) + stub_request_error_wrapper("getBlockByNumber", ["a", true], block_zero_params_error) end let(:block_one_hash) { "0xa18f9c384107d9a4fcd2fae656415928bd921047519fea5650cba394f6b6142b" } @@ -201,10 +202,11 @@ def stub_request_error_wrapper(method, params, error, status: 200, json_rpc: "2. end let(:transaction_hash) { "0x4b364ce2e607c57200995ee39ecdd98f5749107752125383c2df5058e53be2f7" } + let(:transaction_content) { "0x0a770a28636235313466303134313761626366626431663632393961306434313961326430656165613362361220323066613965333731663531343062613862656533333632313735396338343718e80720db8512322000000000000000000000000000000000000000000000000000000000000010003801124113ec0f1aba3247937c069d250faa708f53162b2a8059597f3df4d1a74ff1c2214eb6251e4bb336a2cc3b6c432fe1e0c79ba9d464fdd8ab8eb525cb2ac93c8a7500" } let(:transaction_result) do { "hash": transaction_hash, - "content": "0x0a770a28636235313466303134313761626366626431663632393961306434313961326430656165613362361220323066613965333731663531343062613862656533333632313735396338343718e80720db8512322000000000000000000000000000000000000000000000000000000000000010003801124113ec0f1aba3247937c069d250faa708f53162b2a8059597f3df4d1a74ff1c2214eb6251e4bb336a2cc3b6c432fe1e0c79ba9d464fdd8ab8eb525cb2ac93c8a7500", + "content": transaction_content, "blockNumber": "0x1", "blockHash": block_one_hash, "index": "0x0"