Skip to content

Commit 85f6c74

Browse files
authored
fix: missing InactiveNameOwner record (#598)
1 parent 83af31b commit 85f6c74

File tree

4 files changed

+177
-37
lines changed

4 files changed

+177
-37
lines changed

lib/ae_mdw/db/name.ex

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,9 @@ defmodule AeMdw.Db.Name do
119119
@spec expire_name(transaction(), Blocks.height(), Names.plain_name()) :: :ok
120120
def expire_name(txn, height, plain_name) do
121121
m_name = cache_through_read!(txn, Model.ActiveName, plain_name)
122-
m_exp = Model.expiration(index: {height, plain_name})
123122

124123
if Model.name(m_name, :expire) == height do
125-
owner = Model.name(m_name, :owner)
126-
cache_through_write(txn, Model.InactiveName, m_name)
127-
cache_through_write(txn, Model.InactiveNameOwner, Model.owner(index: {owner, plain_name}))
128-
cache_through_write(txn, Model.InactiveNameExpiration, m_exp)
129-
cache_through_delete(txn, Model.ActiveName, plain_name)
130-
cache_through_delete(txn, Model.ActiveNameOwner, {owner, plain_name})
131-
cache_through_delete(txn, Model.ActiveNameExpiration, {height, plain_name})
132-
124+
deactivate_name(txn, height, m_name)
133125
Ets.inc(:stat_sync_cache, :names_expired)
134126
else
135127
cache_through_delete(txn, Model.ActiveNameExpiration, {height, plain_name})
@@ -325,17 +317,10 @@ defmodule AeMdw.Db.Name do
325317
end
326318
end
327319

328-
@spec revoke_or_expire_height(nil | {Blocks.block_index(), AeMdw.Txs.txi()}, Blocks.height()) ::
329-
Blocks.height()
330-
def revoke_or_expire_height(nil = _revoke, expire),
331-
do: expire
332-
333-
def revoke_or_expire_height({{height, _}, _}, _expire),
334-
do: height
335-
336320
@spec revoke_or_expire_height(Model.name()) :: Blocks.height()
337-
def revoke_or_expire_height(m_name),
338-
do: revoke_or_expire_height(Model.name(m_name, :revoke), Model.name(m_name, :expire))
321+
def revoke_or_expire_height(m_name) do
322+
revoke_or_expire_height(Model.name(m_name, :revoke), Model.name(m_name, :expire))
323+
end
339324

340325
@spec cache_through_read(table(), cache_key()) :: {:ok, name_record()} | nil
341326
def cache_through_read(table, key) do
@@ -435,9 +420,37 @@ defmodule AeMdw.Db.Name do
435420
:ok
436421
end
437422

423+
@spec deactivate_name(transaction(), Blocks.height(), Model.name()) :: :ok
424+
def deactivate_name(
425+
txn,
426+
deactivate_height,
427+
Model.name(index: plain_name, owner: owner_pk) = m_name
428+
) do
429+
cache_through_delete_active(txn, m_name)
430+
431+
m_exp = Model.expiration(index: {deactivate_height, plain_name})
432+
m_owner = Model.owner(index: {owner_pk, plain_name})
433+
434+
cache_through_write(txn, Model.InactiveName, m_name)
435+
cache_through_write(txn, Model.InactiveNameExpiration, m_exp)
436+
cache_through_write(txn, Model.InactiveNameOwner, m_owner)
437+
end
438+
438439
#
439440
# Private functions
440441
#
442+
defp revoke_or_expire_height(nil = _revoke, expire), do: expire
443+
defp revoke_or_expire_height({{revoke_height, _}, _}, _expire), do: revoke_height
444+
445+
defp cache_through_delete_active(
446+
txn,
447+
Model.name(index: plain_name, expire: expire, owner: owner_pk)
448+
) do
449+
cache_through_delete(txn, Model.ActiveName, plain_name)
450+
cache_through_delete(txn, Model.ActiveNameOwner, {owner_pk, plain_name})
451+
cache_through_delete(txn, Model.ActiveNameExpiration, {expire, plain_name})
452+
end
453+
441454
defp pointer_kv_raw(ptr),
442455
do: {:aens_pointer.key(ptr), :aens_pointer.id(ptr)}
443456

lib/ae_mdw/db/sync/name.ex

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ defmodule AeMdw.Db.Sync.Name do
2323
cache_through_read: 3,
2424
cache_through_write: 3,
2525
cache_through_delete: 3,
26-
revoke_or_expire_height: 1,
27-
revoke_or_expire_height: 2
26+
deactivate_name: 3,
27+
revoke_or_expire_height: 1
2828
]
2929

3030
import AeMdw.Db.Util
@@ -81,12 +81,7 @@ defmodule AeMdw.Db.Sync.Name do
8181
log_name_change(height, plain_name, "extend")
8282

8383
delta_ttl == 0 and not internal? ->
84-
owner = Model.name(m_name, :owner)
85-
cache_through_delete(txn, Model.ActiveName, plain_name)
86-
cache_through_delete(txn, Model.ActiveNameOwner, {owner, plain_name})
87-
cache_through_delete(txn, Model.ActiveNameExpiration, {old_expire, plain_name})
88-
cache_through_write(txn, Model.InactiveName, new_m_name)
89-
cache_through_write(txn, Model.InactiveNameExpiration, new_m_name_exp)
84+
deactivate_name(txn, height, new_m_name)
9085

9186
inc(:stat_sync_cache, :names_expired)
9287

@@ -123,16 +118,8 @@ defmodule AeMdw.Db.Sync.Name do
123118
plain_name = plain_name!(name_hash)
124119

125120
m_name = cache_through_read!(txn, Model.ActiveName, plain_name)
126-
expire = Model.name(m_name, :expire)
127-
owner = Model.name(m_name, :owner)
128-
cache_through_delete(txn, Model.ActiveNameExpiration, {expire, plain_name})
129-
cache_through_delete(txn, Model.ActiveNameOwner, {owner, plain_name})
130-
cache_through_delete(txn, Model.ActiveName, plain_name)
131-
132121
m_name = Model.name(m_name, revoke: {bi, txi})
133-
m_exp = Model.expiration(index: {height, plain_name})
134-
cache_through_write(txn, Model.InactiveName, m_name)
135-
cache_through_write(txn, Model.InactiveNameExpiration, m_exp)
122+
deactivate_name(txn, height, m_name)
136123

137124
inc(:stat_sync_cache, :names_revoked)
138125

@@ -302,7 +289,7 @@ defmodule AeMdw.Db.Sync.Name do
302289

303290
cond do
304291
new_height >= active ->
305-
expire = revoke_or_expire_height(Model.name(m_name, :revoke), Model.name(m_name, :expire))
292+
expire = revoke_or_expire_height(m_name)
306293
lfcycle = (new_height < expire && :active) || :inactive
307294
updates = drop_bi_txi(Model.name(m_name, :updates), new_height)
308295
transfers = drop_bi_txi(Model.name(m_name, :transfers), new_height)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
defmodule AeMdw.Db.NameClaimMutationTest do
2+
use ExUnit.Case
3+
4+
alias AeMdw.Database
5+
alias AeMdw.Db.Model
6+
alias AeMdw.Db.Sync
7+
8+
import Mock
9+
10+
require Model
11+
12+
test "claim an inactive name with timeout 0" do
13+
plain_name = "claim.test"
14+
15+
new_owner_pk =
16+
<<11, 180, 237, 121, 39, 249, 123, 81, 225, 188, 181, 225, 52, 13, 18, 51, 91, 42, 43, 18,
17+
200, 188, 82, 33, 214, 60, 75, 203, 57, 212, 30, 97>>
18+
19+
tx =
20+
{:ns_claim_tx, {:id, :account, new_owner_pk}, 11_251, plain_name, 7, :prelima,
21+
1_000_000_000_000_000, 0}
22+
23+
tx_hash =
24+
<<159, 240, 103, 205, 63, 165, 186, 153, 226, 186, 128, 241, 61, 192, 66, 89, 156, 217, 200,
25+
247, 31, 137, 16, 129, 250, 190, 199, 100, 137, 179, 112, 165>>
26+
27+
claim_height = 200
28+
old_claim_height = 100
29+
old_claims = [{{old_claim_height, 1}, 123}]
30+
owner_pk = <<8435::256>>
31+
block_index = {claim_height, 0}
32+
txi = 223
33+
34+
inactive_name =
35+
Model.name(
36+
index: plain_name,
37+
active: old_claim_height,
38+
expire: 199,
39+
claims: old_claims,
40+
updates: [{{150, 0}, 173}],
41+
owner: owner_pk,
42+
previous: nil
43+
)
44+
45+
Database.dirty_write(Model.InactiveName, inactive_name)
46+
47+
Database.dirty_write(
48+
Model.InactiveNameExpiration,
49+
Model.expiration(index: {199, plain_name})
50+
)
51+
52+
Database.dirty_write(
53+
Model.InactiveNameOwner,
54+
Model.owner(index: {owner_pk, plain_name})
55+
)
56+
57+
with_mocks [
58+
{AeMdw.Db.Util, [], [proto_vsn: fn _height -> 3 end]}
59+
] do
60+
tx
61+
|> Sync.Name.name_claim_mutations(tx_hash, block_index, txi)
62+
|> Database.commit()
63+
end
64+
65+
assert {:ok,
66+
Model.name(
67+
index: ^plain_name,
68+
active: ^claim_height,
69+
claims: [{block_index, txi} | old_claims],
70+
expire: expire,
71+
owner: ^new_owner_pk,
72+
updates: []
73+
)} = Database.fetch(Model.ActiveName, plain_name)
74+
75+
assert Database.exists?(Model.ActiveNameExpiration, {expire, plain_name})
76+
assert Database.exists?(Model.ActiveNameOwner, {new_owner_pk, plain_name})
77+
end
78+
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
defmodule AeMdw.Db.NameRevokeMutationTest do
2+
use ExUnit.Case
3+
4+
alias AeMdw.Database
5+
alias AeMdw.Db.Model
6+
alias AeMdw.Db.NameRevokeMutation
7+
8+
require Model
9+
10+
test "revoke a active name" do
11+
plain_name = "revoke.test"
12+
13+
name_hash =
14+
case :aens.get_name_hash(plain_name) do
15+
{:ok, name_id_bin} -> :aeser_api_encoder.encode(:name, name_id_bin)
16+
_error -> nil
17+
end
18+
19+
revoke_height = 3
20+
revoke_block_index = {revoke_height, 0}
21+
revoke_txi = 124
22+
23+
expire = 100
24+
owner_pk = <<538_053::256>>
25+
26+
active_name =
27+
Model.name(
28+
index: plain_name,
29+
active: 1,
30+
expire: expire,
31+
claims: [{{1, 0}, 123}],
32+
updates: [],
33+
transfers: [],
34+
revoke: nil,
35+
owner: owner_pk,
36+
previous: nil
37+
)
38+
39+
Database.dirty_write(Model.PlainName, Model.plain_name(index: name_hash, value: plain_name))
40+
Database.dirty_write(Model.ActiveName, active_name)
41+
42+
Database.dirty_write(
43+
Model.ActiveNameExpiration,
44+
Model.expiration(index: {expire, plain_name})
45+
)
46+
47+
Database.dirty_write(Model.ActiveNameOwner, Model.owner(index: {owner_pk, plain_name}))
48+
49+
Database.commit([NameRevokeMutation.new(name_hash, revoke_txi, revoke_block_index)])
50+
51+
assert {:ok,
52+
Model.name(
53+
index: ^plain_name,
54+
expire: ^expire,
55+
owner: ^owner_pk,
56+
revoke: {^revoke_block_index, ^revoke_txi}
57+
)} = Database.fetch(Model.InactiveName, plain_name)
58+
59+
assert Database.exists?(Model.InactiveNameExpiration, {revoke_height, plain_name})
60+
assert Database.exists?(Model.InactiveNameOwner, {owner_pk, plain_name})
61+
end
62+
end

0 commit comments

Comments
 (0)