验证程序报告:
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
具有较低插槽号的块显然是孤立的,但是没有后来的块扩展该链的事实未被检测到,因此该块也没有从数据库中删除。
像这样孤立的块应该从数据库中删除,或者在验证过程中避免使用。
最简单的解决方案是删除像这样孤立的块。
作为删除它们的替代方法,我们可以将它们移动到单独的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-sync
与node
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列)
最有用的评论
我认为应该在回滚时删除该块,并且我们应该使用级联删除来删除逻辑上在已删除块中的所有内容。
试图保留已回滚的块没有任何意义。 这不是用于监视网络内块传播的监视工具。 它只是作为节点客户端在一个地方进行观察,因此在该角色中使用时将非常不可靠。