Opération injectée au nœud, mais non ajoutée à Blockchain | Erreur de compteur de portefeuille
1 réponses
- votes
-
- 2020-01-02
TLDR : lapremière opération que vous avezinjectée dans votrenœudest validemaisne serajamaisinjectéepar d'autresnœuds/boulangers caril a desfraistropbas. Ilestensuitebloqué dans lamémoire MEMPOOLet effectuez les opérations suivantes que vousessayez deforger unproblèmenon valide car leprochain compteur valide que vous souhaitez utiliserest déjàprispar l'opération defraistropbasse. Vouspouvez redémarrer votrenoeud ou attendre 60blocs depasserpour déverrouiller la situation.
Ce queje crois arriveici,c'est que lapremière opération que vous avezinjectéeest considérée commeinvalidepar vos autrespairs. Comme vous l'avez dit,ilpeut être rejetépourplusieurs raisons (pas suffisamment defrais étant la case laplus courante).
Donc,vous avezforgé une opération valide concernant leprotocoleet donc valable dans lamémoire MEMPOOL. Votrenoeud a accepté l'injection de l'opération car certainsboulangerspourraient accepteret y compris les opérations de 0 redevances. Cependant,par défaut,cen'estpas le cas. L'opération que vous avezinjectée dans lenœud vit ainsi dans lamémoire MEMPOOL d'attendre unboulanger l'inclure dans unbloc.
vient donc lapartietechnique. Lorsque vous demandez aunœud deforger une opérationpour vous,le client (ou l'API que vous utilisez) demandera aunœud du compteur associé à votre compte (Note latérale: le compteuresticipourempêcher les attaques de replay). Pour saisir cetteinformation,lenœudinterrogera les données à l'aide de l'état actuel
de la chaîne (c'est-à-dire que l'état résultant de l'application du dernierbloc reçu)et reviendra,parexemple, 1000
. Pour l'opération que vous avezforgéepour être valide,son compteur doit alors être1001
. Si cen'estpas le cas,cela vous donnera un compteurdans le député
oudans l'erreurfuture
lorsque lenœudtente de le valider.Dans votre cas,vous avezinjecté une opération
Fraistropbas avec un compteur128324
. Votrenoeudestime que vous savez ce que vousfaites (parexemple,essayer d'obtenir unboulanger àfaiblefraispour l'injecter)et ne vérifie doncpas lesfrais. S'iln'y apas deboulangerbasse-fraisen cours d'exécution dans le réseau,votre opérationne serajamaisincluseet bloquée dans lamémoire MEMPOOLpour60
(20minminimum à Babylonnet). Après ces 60blocs,l'opération sera considérée commetrop ancienneet purgée de lamémoiremémoire. C'estpourquoi,aprèsparfois,la situation a été déverrouillée.Maintenant,alors que cette opérationnon valideestbloquée dans lamémoire MEMPOOL,laprochaine opération que vous avezforgée à l'aide du client demandera également le compteur dunœudet que votre dernière opérationn'apas étéincluse,le compteurprécédent
128324
sera utilisé ànouveau qui collime avec latransactionprécédente. Lorsque cela seproduit,lamémoire MEMPOOLn'estpas heureuse carelleessaiera de valider les opérations l'une après l'autre. Comme votrepremière opérationest valide (même siellene serajamaisincluse),il sera appliqué sur son étatinterne quiest un étatintermédiaire où votrepremière opération a été appliquée ainsi leprochain contrain attendu augmentépar une. Laprochainefois qu'une opérationest reçue (pour lemême compte),lamémoire MEMPOOL s'attendra à ce que le compteur soit augmenté à128325
. Si cen'estpas le cas,alorsil le rejetera avec un compteurdans lepassé
. Si vousessayez d'augmentermanuellement le compteur,vouspourriez obtenircompteur à l'avenir
.Comment sortir de cette situation:
- Vouspouvez attendre que 60pâtés demaisons réussissentpuis que votretransaction soit suppriméepour êtretrop âgée;
- Vouspouvez redémarrer votrenoeud si vous le contrôlez. Lamémoiremempoolesteffacée lorsque lenœud s'arrête;
- Vouspouvezforgeret injecter votretransactionen utilisant un autrenoeud. Un,quin'aurapas l'opérationinvalidebloquée dans samémoire MEMPOOL.
Dans laprochaine version Shell,nous visons àinclure un RPC d'administrateur qui sera utilisépour supprimer une opération spécifique de lamémoire MEMPOOL.
P.s. Vouspouvez vérifier quelles opérations vivent dans lamémoire MEMPOOL à l'aide du RPC
/CHAKINES/MAIN/MEMPOOL/PENDING_OPERATIONS
TLDR: the first operation you injected in your node is valid but will be never be injected by other nodes/bakers because it has too low fees. It is then stuck in the mempool and make the the next operations you're trying to forge invalid because the next valid counter you want to use is already being taken by the too low fee operation. You can restart your node or wait for 60 blocks to pass to unlock the situation.
What I believe happens here is that the first operation you injected is considered invalid by your other peers. As you said, it can be rejected for multiple reasons (not enough fees being the most common case).
So, you forged an operation which is valid regarding the protocol and therefore valid in the mempool. Your node accepted injecting the operation because some bakers might be accepting and including 0 fees operations. However, by default, this is not the case. The operation you injected in the node is thus living in the mempool waiting for a baker to include it in a block.
So now comes the technical part. When you request the node to forge an operation for you, the client (or the API you're using) will request from the node the counter associated to your account (side note: the counter is here to prevent replay attacks). To grab this information, the node will query the data using the current state of the chain (i.e. the state that results from the application of the last block received) and will return, for example,
1000
. For the operation you're forging to be valid, its counter must then be1001
. If this is not the case, it will give you acounter in the past
orcounter in the future
error when the node is trying to validate it.In your case, you injected a too low fee operation with a counter
128324
. Your node considers that you know what you're doing (e.g. trying to get a low-fee baker to inject it) and thus does not check for the fees. If there are no low-fee baker running in the network, your operation will never be included and stuck in the mempool for60
blocks (20min minimum in babylonnet). After those 60 blocks, the operation will considered too old and purged from the mempool. This is why, after some times, the situation was unlocked.Now, while this invalid operation is stuck in the mempool, the next operation you forge using the client will also request the counter from the node and as your last operation was not included, the previous counter
128324
will be used again which collides with the previous transaction. When this happens, the mempool is not happy because it will try to validate the operations one after the other. As your first operation is valid (even if it will never be included), it will be applied on its internal state which is an intermediate state where your first operation was applied thus making the next expected counter increased by one. The next time an operation is received (for the same account) the mempool will expect the counter to be increased to128325
. If that's not the case, then it will reject it with acounter in the past
error. If you try to manually increase the counter, you might getcounter in the future
.How to get out of this situation:
- you may wait for 60 blocks to pass by and then your transaction will be discarded for being too old;
- you can restart your node if you have control over it. The mempool is erased when the node stops;
- you can forge and inject your transaction using another node. One, which will not have the invalid operation stuck in its mempool.
In the next shell release, we aim to include an admin RPC that will be used to remove a specific operation from the mempool.
P.S. You may check which operations live in the mempool using the RPC
/chains/main/mempool/pending_operations
-
Commentenverriez-vousplusieurstransactions dans lemêmebloc?Celane signifie-t-ilpas quetant que l'ancienne opérationn'estpasencore confirmée,nousne pouvons diffuser aucunenouvelle opération à cause de cetteinadéquation là-bas?How would you then send multiple transactions in the same block? Doesn't that mean that as long as the old operation is not yet confirmed, we can't broadcast any new operation because of this mismatch there?
- 0
- 2020-05-09
- CherryDT
J'utilisemonproprenœud Babbylonet j'ai déjà ajouté duportefeuille du robinet Tezoset envoyez despièces àmonportefeuillegénéré avec Tezos-Client:
Envoyer viaeztz.js
Maintenant,j'essaie d'envoyer destezos d'unportefeuillegénéré à un autre avec Eztz.js lib. Utilisez ce code:
Quandje l'exécutepour lapremièrefois - lenœudinjectemonfonctionnementet même l'adresse de retour de latransaction,mais cetransfertne s'estpas ajouté à Blockchain,mon solden'apas été changé. Première opération defonctionnement:
Lorsque vous avezessayé d'envoyer la deuxièmefois - obtenez l'erreur du compteur:
Logs de deuxièmefois:
Si définitmanuellement le compteur sur 128326 - recevoir uneerreur
compteur_in_the_future
.L'erreur du compteur disparu après une demi-heure,maistoujours sij'essaie d'envoyer despièces demonnaie - l'opérationne serapasincluse à Blockchainet je recevrai denouveau contre l'erreur.
Envoyer via Tezos-Client
J'aiimportéma cléprivéegénérée commetest_w2et essayer d'envoyer despièces avec Tezos-Client:
premièrefois quej'ai lamêmeerreur de compteur:
Mais après une demi-heure,celafonctionnait:
Cela signifie donc,uneerreurpas dans lesportefeuillesgénérant ou lenœud Tezos,uneerreurpeut être uniquement dans le client EZTZ.JS ou les valeurs réussies. Peut-être quej'aipassé demauvaisfrais/gas_limit/montant?
Commentpuis-je résoudre ceproblème?
note. Enfait,j'utilise labibliothèque Tz.Net Forked (C #),maiselle a lemêmeflux detravail que Eztz.jset je reçois lesmêmeserreurs.