Cardano-db-sync: 未从“块”表中删除孤立块

创建于 2020-05-30  ·  10评论  ·  资料来源: input-output-hk/cardano-db-sync

验证程序报告:

All transactions for blocks in epoch 195 are present: Failed on block no 4224831: 
expected tx count of 2 but got 3

和一个简单的查询:

select * from block where block_no = 4224831 ; 

结果在两行中只应有一行。

# select id, slot_no, block_no,previous,tx_count,time from block where 
    block_no = 4224831 ; 
   id    | slot_no | block_no | previous | tx_count |        time         
---------+---------+----------+----------+----------+---------------------
 4265744 | 4226980 |  4224831 |  4265742 |        2 | 2020-05-29 08:58:11
 4265743 | 4226979 |  4224831 |  4265742 |        3 | 2020-05-29 08:57:51

具有较低插槽号的块显然是孤立的,但是没有后来的块扩展该链的事实未被检测到,因此该块也没有从数据库中删除。

像这样孤立的块应该从数据库中删除,或者在验证过程中避免使用。

bug priority high

最有用的评论

我认为应该在回滚时删除该块,并且我们应该使用级联删除来删除逻辑上在已删除块中的所有内容。

试图保留已回滚的块没有任何意义。 这不是用于监视网络内块传播的监视工具。 它只是作为节点客户端在一个地方进行观察,因此在该角色中使用时将非常不可靠。

所有10条评论

最简单的解决方案是删除像这样孤立的块。

作为删除它们的替代方法,我们可以将它们移动到单独的orphaned_blocks表中,但是随后我们需要确定要对附加到该块的tx做些什么。 我最初的感觉是应该将它们忽略/删除。

当我们切换到Praos时,拥有orphaned_block表可能很有用,但是即使在db-sync实际上仅支持Byron的情况下,也可以轻松实现。

我的第一个想法也是:清理孤立的块,但将其保留在某个地方。

该节点甚至可以选择将所有检测到的分叉(包括来自废弃侧臂的所有块)存储在此表中。 在x个插槽后进行清除很简单。 然后,对发生的事情进行诊断和跟踪要容易得多。

关于丢失TX的问题很有趣。 作为一个快速的主意,在不知道加密是否可行和100%安全的情况下:

如果(启用了db-sync的)节点从孤立的块中检测到TX,则他可以尝试将其重新插入到其内存池中。 不再广播它,只有在轮到他制作一个块时才进行处理。
(广播是不必要的,因为许多其他池会检测带有其TX的孤立块并将其从该源重新插入到其内存池中)

如果同时utxo所有者(直到解决了分叉并检测到孤立块)再次进行了尝试,则先前的TX无效。 相反,如果tx仍然有效,它将再次自动出现在新的有效块中。

钱包需要能够处理这样的情况,即他们可能会在一个区块中看到自己的tx,然后将其孤立,然后在某些区块中将相同的tx放置在另一个有效的区块中。

如果(启用了db-sync的)节点从孤立的块中检测到TX,则他可以尝试将其重新插入到其内存池中。 不再广播它,只有在轮到他制作一个块时才进行处理。

重要的是要注意, db-syncnode db-sync是分开的,并且仅遵循node的链。
具体来说, db-sync不会维护自己的内存池副本。 在我检测到的情况下,孤立块中的事务几乎可以肯定地包含在以后的非孤立块中,因此db-sync应该删除它们。

当然,钱包的行为与db-sync

如果几乎可以肯定TX是由其他块生产者处理的,那么off不需要使用某种工具将它们“重新注入”从db到节点的内存池。
问题是所有插槽/高度战斗版本是否都是这种情况。 如果不是,那么下一个问题是让一个孤立的块中检测未处理的TX的节点之一有用(打算),然后基于db-sync数据库将其重新插入其内存池中。

db-sync实际上应该仅用于查看过去发生的情况。 节点本身会将事务从孤立的块中拉出,然后将其放回自己的内存池中。 db-sync并不打算成为其中的一部分。

但是,在最后100个左右的插槽中保留孤立的块列表可能对调试很有用。

我认为应该在回滚时删除该块,并且我们应该使用级联删除来删除逻辑上在已删除块中的所有内容。

试图保留已回滚的块没有任何意义。 这不是用于监视网络内块传播的监视工具。 它只是作为节点客户端在一个地方进行观察,因此在该角色中使用时将非常不可靠。

我同意我们应该保持db-sync尽可能纯净,以反映实际的链状态。

但是,如果将所有块都放入db-sync,然后在回滚时将其删除,那将大大简化我的生活。 这样,我可以触发postgres删除并使用数据做我想做的事情。

其他客户端也需要这样做,Sam说这对于任何数据库同步发行版(包括Testnet)都是至关重要的。

回滚似乎没有按预期进行。 我们在数据库中看到了多个块高度相同的块。 这是一个示例(在主网上):

cexplorer =#选择* FROM块WHERE block_no = 4224831;
id | 哈希| slot_no | block_no | 上一个| merkel_root | slot_leader | 尺寸 epoch_no | 时间| tx_count
--------- + ---------------------------------------- ---------------------------- + --------- + ---------- + ---------- + --------------------------------------- ----------------------------- + ------------- + ------ + ---------- + --------------------- + ----------
4225044 | \ x941a71094c7b10243845a82e53dc45959d8fde5f6d87e463efe660aa9611b965 | 4226979 | 4224831 | 4225043 | \ x95549f5fcfc370eb4b24c981a6053f909bdef6418ce896828c6be18fa31ab406 | 6 | 1731 | 195 | 2020-05-29 08:57:51 | 3
4225045 | \ x275ee8b9ae441e6e32e1f7f36290e6a048722619d91195773a07b06682418209 | 4226980 | 4224831 | 4225043 | \ x6eb04497431d77657a94b0eee70dae59e7403980d4fc9d06ba5295436b8f0f54 | 7 | 1418 | 195 | 2020-05-29 08:58:11 | 2个
(2列)

此页面是否有帮助?
0 / 5 - 0 等级