Skip to content

Commit dda45ff

Browse files
committed
Fix bug with esip1 transfers, add tests and indices
1 parent a59160b commit dda45ff

8 files changed

Lines changed: 255 additions & 17 deletions

app/models/eth_transaction.rb

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ class EthTransaction < ApplicationRecord
33
belongs_to :eth_block, foreign_key: :block_number, primary_key: :block_number, optional: true,
44
inverse_of: :eth_block
55
has_one :ethscription, foreign_key: :transaction_hash, primary_key: :transaction_hash,
6-
inverse_of: :eth_transaction, inverse_of: :eth_transaction
6+
inverse_of: :eth_transaction
77
has_many :ethscription_transfers, foreign_key: :transaction_hash,
88
primary_key: :transaction_hash, inverse_of: :eth_transaction
99
has_many :ethscription_ownership_versions, foreign_key: :transaction_hash,
@@ -157,14 +157,15 @@ def create_ethscription_transfers_from_events!
157157

158158
if event_type == Esip1EventSig
159159
begin
160-
event_to = Eth::Abi.decode(['address'], topics.third).first
160+
event_to = Eth::Abi.decode(['address'], topics.second).first
161+
tx_hash = Eth::Util.bin_to_prefixed_hex(
162+
Eth::Abi.decode(['bytes32'], topics.third).first
163+
)
161164
rescue Eth::Abi::DecodingError
162165
next
163166
end
164167

165-
next unless valid_bytes32?(topics.third)
166-
167-
target_ethscription = Ethscription.find_by(transaction_hash: topics.third)
168+
target_ethscription = Ethscription.find_by(transaction_hash: tx_hash)
168169

169170
if target_ethscription.present?
170171
ethscription_transfers.create!(
@@ -181,13 +182,14 @@ def create_ethscription_transfers_from_events!
181182
begin
182183
event_previous_owner = Eth::Abi.decode(['address'], topics.second).first
183184
event_to = Eth::Abi.decode(['address'], topics.third).first
185+
tx_hash = Eth::Util.bin_to_prefixed_hex(
186+
Eth::Abi.decode(['bytes32'], topics.fourth).first
187+
)
184188
rescue Eth::Abi::DecodingError
185189
next
186190
end
187191

188-
next unless valid_bytes32?(topics.fourth)
189-
190-
target_ethscription = Ethscription.find_by(transaction_hash: topics.fourth)
192+
target_ethscription = Ethscription.find_by(transaction_hash: tx_hash)
191193

192194
if target_ethscription.present?
193195
ethscription_transfers.create!(
@@ -289,10 +291,6 @@ def self.esip1_enabled?(block_number)
289291
block_number >= 17672762
290292
end
291293

292-
def valid_bytes32?(value)
293-
/\A0x[0-9a-f]{64}\z/i.match?(value.to_s)
294-
end
295-
296294
def self.contract_transfer_event_signatures(block_number)
297295
[].tap do |res|
298296
res << Esip1EventSig if esip1_enabled?(block_number)

db/migrate/20231216161930_create_eth_blocks.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ def change
1818
t.index :imported_at
1919
t.index [:imported_at, :block_number]
2020
t.index :parent_blockhash, unique: true
21+
t.index :state_hash, unique: true
22+
t.index :parent_state_hash, unique: true
2123
t.index :timestamp
2224

2325
t.check_constraint "blockhash ~ '^0x[a-f0-9]{64}$'"

db/migrate/20231216163233_create_eth_transactions.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ def change
1818

1919
t.index [:block_number, :transaction_index], unique: true
2020
t.index :block_number
21+
t.index :block_timestamp
2122
t.index :from_address
2223
t.index :status
2324
t.index :to_address
2425
t.index :transaction_hash, unique: true
26+
t.index :logs, using: :gin
2527

2628
t.check_constraint "block_number <= 4370000 AND status IS NULL OR block_number > 4370000 AND status = 1", name: "status_check"
2729
t.check_constraint "created_contract_address IS NULL AND to_address IS NOT NULL OR

db/migrate/20231216213103_create_ethscription_transfers.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def change
1212
t.bigint :transaction_index, null: false
1313
t.string :enforced_previous_owner
1414

15+
t.index :ethscription_transaction_hash
1516
t.index :block_number
1617
t.index :from_address
1718
t.index :to_address

db/migrate/20231216215348_create_ethscription_ownership_versions.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ def change
1111
t.string :current_owner, null: false
1212
t.string :previous_owner, null: false
1313

14+
t.index :current_owner
15+
t.index :previous_owner
16+
t.index [:current_owner, :previous_owner]
1417
t.index :ethscription_transaction_hash
1518
t.index :transaction_hash
1619
t.index :block_number

db/structure.sql

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ CREATE FUNCTION public.check_block_order() RETURNS trigger
6464
NEW.parent_blockhash <> (SELECT blockhash FROM eth_blocks WHERE block_number = NEW.block_number - 1) THEN
6565
RAISE EXCEPTION 'Parent block hash does not match the parent''s block hash';
6666
END IF;
67-
67+
6868
RETURN NEW;
6969
END;
7070
$$;
@@ -603,6 +603,13 @@ CREATE UNIQUE INDEX idx_on_block_number_transaction_index_transfer_inde_8090d24b
603603
CREATE UNIQUE INDEX idx_on_block_number_transaction_index_transfer_inde_fc9ee59957 ON public.ethscription_transfers USING btree (block_number, transaction_index, transfer_index);
604604

605605

606+
--
607+
-- Name: idx_on_current_owner_previous_owner_7bb4bbf3cf; Type: INDEX; Schema: public; Owner: -
608+
--
609+
610+
CREATE INDEX idx_on_current_owner_previous_owner_7bb4bbf3cf ON public.ethscription_ownership_versions USING btree (current_owner, previous_owner);
611+
612+
606613
--
607614
-- Name: idx_on_ethscription_transaction_hash_block_number_t_a807d2b571; Type: INDEX; Schema: public; Owner: -
608615
--
@@ -673,6 +680,20 @@ CREATE INDEX index_eth_blocks_on_imported_at_and_block_number ON public.eth_bloc
673680
CREATE UNIQUE INDEX index_eth_blocks_on_parent_blockhash ON public.eth_blocks USING btree (parent_blockhash);
674681

675682

683+
--
684+
-- Name: index_eth_blocks_on_parent_state_hash; Type: INDEX; Schema: public; Owner: -
685+
--
686+
687+
CREATE UNIQUE INDEX index_eth_blocks_on_parent_state_hash ON public.eth_blocks USING btree (parent_state_hash);
688+
689+
690+
--
691+
-- Name: index_eth_blocks_on_state_hash; Type: INDEX; Schema: public; Owner: -
692+
--
693+
694+
CREATE UNIQUE INDEX index_eth_blocks_on_state_hash ON public.eth_blocks USING btree (state_hash);
695+
696+
676697
--
677698
-- Name: index_eth_blocks_on_timestamp; Type: INDEX; Schema: public; Owner: -
678699
--
@@ -694,13 +715,27 @@ CREATE INDEX index_eth_transactions_on_block_number ON public.eth_transactions U
694715
CREATE UNIQUE INDEX index_eth_transactions_on_block_number_and_transaction_index ON public.eth_transactions USING btree (block_number, transaction_index);
695716

696717

718+
--
719+
-- Name: index_eth_transactions_on_block_timestamp; Type: INDEX; Schema: public; Owner: -
720+
--
721+
722+
CREATE INDEX index_eth_transactions_on_block_timestamp ON public.eth_transactions USING btree (block_timestamp);
723+
724+
697725
--
698726
-- Name: index_eth_transactions_on_from_address; Type: INDEX; Schema: public; Owner: -
699727
--
700728

701729
CREATE INDEX index_eth_transactions_on_from_address ON public.eth_transactions USING btree (from_address);
702730

703731

732+
--
733+
-- Name: index_eth_transactions_on_logs; Type: INDEX; Schema: public; Owner: -
734+
--
735+
736+
CREATE INDEX index_eth_transactions_on_logs ON public.eth_transactions USING gin (logs);
737+
738+
704739
--
705740
-- Name: index_eth_transactions_on_status; Type: INDEX; Schema: public; Owner: -
706741
--
@@ -729,6 +764,20 @@ CREATE UNIQUE INDEX index_eth_transactions_on_transaction_hash ON public.eth_tra
729764
CREATE INDEX index_ethscription_ownership_versions_on_block_number ON public.ethscription_ownership_versions USING btree (block_number);
730765

731766

767+
--
768+
-- Name: index_ethscription_ownership_versions_on_current_owner; Type: INDEX; Schema: public; Owner: -
769+
--
770+
771+
CREATE INDEX index_ethscription_ownership_versions_on_current_owner ON public.ethscription_ownership_versions USING btree (current_owner);
772+
773+
774+
--
775+
-- Name: index_ethscription_ownership_versions_on_previous_owner; Type: INDEX; Schema: public; Owner: -
776+
--
777+
778+
CREATE INDEX index_ethscription_ownership_versions_on_previous_owner ON public.ethscription_ownership_versions USING btree (previous_owner);
779+
780+
732781
--
733782
-- Name: index_ethscription_ownership_versions_on_transaction_hash; Type: INDEX; Schema: public; Owner: -
734783
--
@@ -743,6 +792,13 @@ CREATE INDEX index_ethscription_ownership_versions_on_transaction_hash ON public
743792
CREATE INDEX index_ethscription_transfers_on_block_number ON public.ethscription_transfers USING btree (block_number);
744793

745794

795+
--
796+
-- Name: index_ethscription_transfers_on_ethscription_transaction_hash; Type: INDEX; Schema: public; Owner: -
797+
--
798+
799+
CREATE INDEX index_ethscription_transfers_on_ethscription_transaction_hash ON public.ethscription_transfers USING btree (ethscription_transaction_hash);
800+
801+
746802
--
747803
-- Name: index_ethscription_transfers_on_from_address; Type: INDEX; Schema: public; Owner: -
748804
--

lib/ethscription_test_helper.rb

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,29 @@
11
module EthscriptionTestHelper
2+
def self.create_from_hash(hash)
3+
resp = AlchemyClient.query_api(
4+
method: 'eth_getTransactionByHash',
5+
params: [hash]
6+
)['result']
7+
8+
resp2 = AlchemyClient.query_api(
9+
method: 'eth_getTransactionReceipt',
10+
params: [hash]
11+
)['result']
12+
13+
create_eth_transaction(
14+
input: resp['input'],
15+
to: resp['to'],
16+
from: resp['from'],
17+
logs: resp2['logs']
18+
)
19+
end
20+
221
def self.create_eth_transaction(
322
input:,
423
from:,
524
to:,
6-
logs:
25+
logs: [],
26+
tx_hash: nil
727
)
828
existing = Ethscription.newest_first.first
929

@@ -12,8 +32,11 @@ def self.create_eth_transaction(
1232
transaction_index = existing&.transaction_index.to_i + 1
1333
overall_order_number = block_number * 1e8 + transaction_index
1434

15-
hex_input = input.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
16-
hex_input = "0x" + hex_input
35+
hex_input = if input.match?(/\A0x([a-f0-9]{2})+\z/i)
36+
input.downcase
37+
else
38+
"0x" + input.bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
39+
end
1740

1841
if EthBlock.exists?
1942
parent_block = EthBlock.order(block_number: :desc).first
@@ -33,7 +56,7 @@ def self.create_eth_transaction(
3356
tx = EthTransaction.create!(
3457
block_number: block_number,
3558
block_timestamp: eth_block.timestamp,
36-
transaction_hash: "0x" + SecureRandom.hex(32),
59+
transaction_hash: tx_hash || "0x" + SecureRandom.hex(32),
3760
from_address: from.downcase,
3861
to_address: to.downcase,
3962
transaction_index: transaction_index,
@@ -49,6 +72,7 @@ def self.create_eth_transaction(
4972
tx.process!
5073

5174
eth_block.update!(imported_at: Time.current)
75+
tx
5276
end
5377

5478
def self.t

0 commit comments

Comments
 (0)