Operação injetada para o nó, mas não adicionado ao blockchain | Counter Counter Error
1 responda
- votos
-
- 2020-01-02
tldr : Aprimeira operação que vocêinjetouem seunó é válida,masnunca seráinjetadapor outrosnós/padeirosporquetem taxasmuitobaixas. Ele éentãopresono Mempoole faça aspróximas operações que vocêestátentandoforjarinválidaporque opróximo contador válido que você deseja usarjáestá sendofeitopela operação detaxamuitobaixa. Vocêpode reiniciar seunó ouesperarpor 60blocospara desbloquear a situação.
.O queeu acredito que acontece aqui é que aprimeira operação que vocêinjectou é consideradainválidapor seus outrospares. Como você disse,pode ser rejeitadopor várias razões (taxasnão suficientes sendo o casomais comum).
Então,vocêforjou uma operação válidaem relação aoprotocoloe,portanto,válidano Mempool. Seunó aceitouinjetando a operaçãoporque algunspadeirospodemestar aceitandoe incluindo 0 operações detaxas. Noentanto,porpadrão,estenão é o caso. A operação que vocêinjetounonó é,portanto,viverno Mempoolesperandopor umpadeiroparaincluí-loem umbloco.
Então agora vem apartetécnica. Quando você solicita que onóforja uma operaçãopara você,o cliente (ou a API que vocêestá usando) solicitará onó o contador associado à sua conta (Nota lateral: O contadorestá aquiparaevitar ataques de replay). Parapegaressasinformações,onó consultará os dados usando o estado atual da cadeia (ou seja,oestado que resulta da aplicação do últimobloco recebido)e retornará,porexemplo,
1000 . Para a operação,você é válido,seu contador deve ser 1001
. Seestenãofor o caso,elefornecerá um contadorno contadorpassado
ounofuturo
quando onóestivertentando validá-lo.No seu caso,vocêinjetou um Taxamuitobaixa operação com um contador
128324
. Seunó considera que você sabe o queestáfazendo (porexemplo,tentando obter umpadeiro debaixataxaparainjetá-lo)e,portanto,não verifica astaxas. Senão houver Baker debaixataxaexecutandona rede,sua operaçãonunca seráincluídae presano MEMPOOLpara60
Blocos (20minmínimona Babilonnet). Apósesses 60blocos,a operação consideramuito antigae purgada domempool. Éporisso que,depois de algumas vezes,a situaçãofoi desbloqueada.Agora,enquantoesta operaçãoinválidaestiverpresano Mempool,apróxima operação que vocêforja usando o clientetambém solicitará o contador donóe,como sua última operaçãonãofoiincluída,o contador anterior 128324 será usadonovamente que colide com atransação anterior. Quandoisso acontece,omempoolnão éfelizporquetentará validar as operações uma após a outra. Àmedida que suaprimeira operação é válida (mesmo queelanunca sejaincluída),ela será aplicadaem seuestadointerno ,que é umestadointermediárioem que suaprimeira operaçãofoi aplicada,fazendo com que opróximo contadoresperado aumentado 1. Napróxima vez,uma operação é recebida (para amesma conta),o Mempoolespera que o contador seja aumentadopara
128325
. Seessenãofor o caso,eleirá rejeitá-lo com um contadornoerropassado
. Se vocêtentar aumentarmanualmente o contador,poderá obtercontadornofuturo
.Como sair dessa situação:
- Vocêpodeesperarpor 60blocospassareme,em seguida,suatransação será descartadapor sermuito antiga;
- Vocêpode reiniciar o seunó setiver controle sobreele. Omempool é apagado quando onópára;
- Vocêpodeforjare injetar suatransação usando outronó. Um,quenãoterá a operaçãoinválidapresaem seumempool.
Napróxima versão do shell,pretendemosincluir um RPC admin que será usadopara remover uma operaçãoespecífica do Mempool.
p.s. Vocêpode verificar quais operações vivemno Mempool usando o RPC
/Correntes/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
-
Como vocêenviaria váriastransaçõesnomesmobloco?Issonão significa que,desde que a antiga operação aindanãoesteja confirmada,nãopodemostransmitirnenhumanova operaçãopor causa desseincompatibilidade lá?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
Eu usomeupróprionó BabbyLone anteriormenteeu adicionei alguma carteira da Tezos Tornee enviei algumasmoedasparaminha carteiragerada com Tezos-Cliente:
Enviar via EZTZ.js
Agoraestoutentandoenviar Tezos de uma carteirageradapara outra com o Eztz.js lib. Useeste código:
Quandoeuexecuto aprimeira vez -nóinjetarminha operaçãoe atémesmo devolver oendereço detransação,masestatransferêncianãofoi adicionada aoblockchain,meu saldonãofoi alterado. Registros de operaçãopelaprimeira vez:
Quandotentouenviar uma segunda vez - Obtererro de contador:
Logs do segundotempo:
Se definirmanualmente o contadorpara 128326 - receberáerro
counter_in_the_future
.Contador deerroido depois demeia hora,mas ainda assimtentarenviarmoedas - operaçãonão seráincluídanoblockchaine recebereierro de contagemnovamente.
Enviar via Tezos-Cliente
Euimporteiminha chaveprivadagerada comotest_w2e tenteenviarmoedas com Tezos-Cliente:
primeira vezeu recebo omesmoerro de contador:
Mas depois demeia horafuncionou:
Então significa,erronãoem carteirasgerando outezosnó,erropode ser apenasno clienteeztz.js ou valorespassados. Talvezeutenhapassado ataxaerrada/gas_limit/quantidade?
Comoposso consertarisso?
Nota. Na verdade,eu usobibliotecaempilhadatz.net (c #),mastem omesmofluxo detrabalho comoeztz.jse recebo osmesmoserros.