Affichage étonnant Silkaj - refus de transaction

Bonjour,

J’ai rencontré un souci sur G1cotis, et je fais une transaction manuellement sur Silkaj, j’ai un affichage étonnant :

silkaj -p g1.cgeek.fr --auth-file --file ~/g1-cotis-master.old/auth_g1cotis/GTsYayS6wkrKUrRhVBR6avybBqSAmu3betnSYojyiskp.auth tx  --output HeZJHAc58PB8PjE3aX9NydeALCdQZkECkrmz1ViZjXo4 --amount 141.89
╒════════════════════════════╤══════════════════════════════════════════════╕
│ pubkey’s balance before tx │ 141.89 Ğ1                                    │
├────────────────────────────┼──────────────────────────────────────────────┤
│ tx amount (unit)           │ 141.89 Ğ1                                    │
├────────────────────────────┼──────────────────────────────────────────────┤
│ tx amount (relative)       │ 14.0904 UD Ğ1                                │
├────────────────────────────┼──────────────────────────────────────────────┤
│ pubkey’s balance after tx  │ 1.8189894035458565e-14 Ğ1                    │
├────────────────────────────┼──────────────────────────────────────────────┤
│ from (pubkey)              │ GTsYayS6wkrKUrRhVBR6avybBqSAmu3betnSYojyiskp │
├────────────────────────────┼──────────────────────────────────────────────┤
│ to (pubkey)                │ HeZJHAc58PB8PjE3aX9NydeALCdQZkECkrmz1ViZjXo4 │
├────────────────────────────┼──────────────────────────────────────────────┤
│ comment                    │                                              │
╘════════════════════════════╧══════════════════════════════════════════════╛
Do you confirm sending this transaction? [yes/no]: yes    
Generate Transaction:  
   - From:    GTsYayS6wkrKUrRhVBR6avybBqSAmu3betnSYojyiskp  
   - To:      HeZJHAc58PB8PjE3aX9NydeALCdQZkECkrmz1ViZjXo4   
   - Amount:  141.89
Traceback (most recent call last):
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/bin/silkaj", line 7, in <module>
    exec(compile(f.read(), __file__, 'exec'))
  File "/home/dunitertest/silkaj/bin/silkaj", line 23, in <module>
    cli(obj={})
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/lib/python3.7/site-packages/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/lib/python3.7/site-packages/click/core.py", line 717, in main
    rv = self.invoke(ctx)
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/lib/python3.7/site-packages/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/dunitertest/.local/share/virtualenvs/silkaj-EzvhOxyi/lib/python3.7/site-packages/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
  File "/home/dunitertest/silkaj/silkaj/tools.py", line 70, in wrapper
    return loop.run_until_complete(f(*args, **kwargs))
  File "/usr/local/lib/python3.7/asyncio/base_events.py", line 568, in run_until_complete
    return future.result()
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 99, in send_transaction
    key, issuer_pubkey, tx_amount, outputAddresses, comment, outputbackchange
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 237, in handle_intermediaries_transactions
    OutputbackChange,
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 277, in generate_and_send_transaction
    OutputbackChange,
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 329, in generate_transaction_document
    generate_output(listoutput, curentUnitBase, AmountTransfered, outputAddress)
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 364, in generate_output
    outputAmount = truncBase(rest, unitbase)
  File "/home/dunitertest/silkaj/silkaj/tx.py", line 392, in truncBase
    return math.trunc(amount / pow) * pow
ZeroDivisionError: float division by zero
ERROR:asyncio:Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0xb59bcd98>
ERROR:asyncio:Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0xb581c8b8>, 559035.958879131)]']
connector: <aiohttp.connector.TCPConnector object at 0xb58e3a50>

Vous observez le “Pubkey’s balance after tx” en 10^-14 Ğ1. Je ne sais pas si ça vient de Silkaj ou du noeud Duniter.

A noter que cette erreur est arrivée il y a un peu moins d’une semaine, suite à une série de transactions envoyées en erreur.

Silkaj sur Debian Stretch, version 0.7.1

1 Like

Merci pour le rapport de bug.
Ça pourrait être plus intéressant que tu remontes les bugs sur le dépôt GitLab maintenant que t’es confirmé.

Au premier coup d’œil, je vois que tu envoies la somme exacte contenue sur cette clé. Pour information, il existe l’option --allSources qui permet d’envoyer toutes les sources sans te soucier de savoir combien contient la clé :

silkaj tx --help
  --allSources             Send all sources

Faut que je regarde plus en détail pourquoi ce bug se produit. En attendant, si tu peux conserver les sources sur cette clé pour faire des tests, ça serait top. Sinon, tant pis.

Je sais pas encore comment reproduire ce bug de mon côté. Peut-être essayé d’envoyer toutes les sources d’une mes clés ĞTest.

Je sais pas si tu essayes avec --allSources ou avec Silkaj 0.6.5, si ce bug se reproduit.

La conséquence de ce bug est assez étrange à reproduire. La source, j’ai pas idée.

Contacte-moi en privé pour qu’on débogue ça.

3 Likes

La seule manière que j’ai trouvé pour obtenir pow = 0 c’est avec math.pow(0, 1).
Ce qui est étrange, car la première valeur est fixée à 10 et la seconde valeur unitbase devrait être à 0.
Même si elle a été incrémentée positivement ou négativement, ça ne donne pas pow = 0.

Est-ce que ça pourrait être un problème d’arrondi binaire (comme 1-0.9 == 0.09999999999999998), ou parce qu’il calcule le montant à partir du montant en DU (et donc fait une division) ?

1 Like
def truncBase(amount, base):
    pow = math.pow(10, base)
    if amount < pow:
        return 0
    return math.trunc(amount / pow) * pow

Voici le code incriminé. Comment pow peux valoir zéro ?

À moins d’un bug de Python, il faut que base < -323.6072 pour faire un ZeroDivisionError… Donc il faut regarder le code qui donne base.

Edit: Il y a une boucle qui décrémente la base et le montant ici, c’est peut-être là le problème (comme la condition est rest > 0, ça voudrait dire que rest n’est jamais égal à 0 à cause d’un arrondi binaire, d’où le « 1.8e-14 », et ça laisse le temps à unitbase d’arriver à -324)  :

3 Likes

Ok, j’ai trouvé la source du problème.

C’est simplement lié à comment sont géré les float (nombres à virgules) dans les langages de programmation :

141.89 * 100
14188.999999999998
1 Like

Du coup il suffirait de passer tous les montants en int, l’unité étant le centime ? C’est déjà le cas dans duniterpy et dans BMA je crois, donc ça serait plus cohérent.

1 Like

Oui, mais en entrée tu dois pouvoir entrer un nombre à virgule.
Tu vas pas demander à l’utilisateur d’un client d’entrer 14189 pour envoyer 141.89 Ğ1.

1 Like

Corrigé avec Silkaj v0.7.2. Bonnes transactions !

3 Likes