zold-io / wts.zold.io

Zold Web Wallets and RESTful HTTP API
https://wts.zold.io
MIT License
7 stars 0 forks source link

Payment failed because of Telepost::CantPost #162

Open g4s8 opened 5 years ago

g4s8 commented 5 years ago

0crat failed to pay because of this error:

Failed to pay via WTS: job=025add17-81a8-4a3d-a6d5-e569996a6e21 error=Telepost::CantPost: Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 350: "Payment sent by @0crat (https://github.com/0crat) from 860261987eb8d2d3 (http://www.zold.io/ledger.html?wallet=860261987eb8d2d3) with the balance of 110784.57ZLD to 3be3416c805e4371 (http://www.zold.io/ledger.html?wallet=3be3416c805e4371) for 10.24ZLD from 54.209.215.xx (US): "@g4s8: Payment for none: Adviser payment for @CAWJH9K0X project -ch1E8COHHUMSJnVjMYSwW5l76V-""
 /app/vendor/bundle/ruby/2.6.0/gems/telepost-0.2.3/lib/telepost.rb:114:in `rescue in post'
 /app/vendor/bundle/ruby/2.6.0/gems/telepost-0.2.3/lib/telepost.rb:105:in `post'
 /app/vendor/bundle/ruby/2.6.0/gems/telepost-0.2.3/lib/telepost.rb:96:in `block in spam'
 /app/vendor/bundle/ruby/2.6.0/gems/telepost-0.2.3/lib/telepost.rb:95:in `each'
 /app/vendor/bundle/ruby/2.6.0/gems/telepost-0.2.3/lib/telepost.rb:95:in `spam'
 /app/wts.rb:470:in `block (2 levels) in <top (required)>'
 /app/wts.rb:1164:in `block in job'
 /app/objects/updatejob.rb:47:in call'
 /app/objects/clean_job.rb:43:in call'
 /app/objects/versionedjob.rb:37:in `call'
 /app/objects/trackedjob.rb:34:in call'
 /app/objects/safe_job.rb:36:in call'
 /app/objects/asyncjob.rb:41:in `block (2 levels) in call'
 /app/vendor/bundle/ruby/2.6.0/gems/futex-0.8.6/lib/futex.rb:130:in `block in open'
 /app/vendor/bundle/ruby/2.6.0/gems/futex-0.8.6/lib/futex.rb:176:in `opensynchronized'
 /app/vendor/bundle/ruby/2.6.0/gems/futex-0.8.6/lib/futex.rb:103:in open'
 /app/objects/async_job.rb:40:in block in call'
 /app/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.3/lib/concurrent/executor/rubythreadpoolexecutor.rb:348:in `runtask'
 /app/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.3/lib/concurrent/executor/rubythreadpoolexecutor.rb:337:in `block (3 levels) in createworker'
 /app/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.3/lib/concurrent/executor/rubythreadpoolexecutor.rb:320:in `loop'
 /app/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.3/lib/concurrent/executor/rubythreadpoolexecutor.rb:320:in block (2 levels) in create_worker'
 /app/vendor/bundle/ruby/2.6.0/gems/concurrent-ruby-1.1.3/lib/concurrent/executor/ruby_thread_pool_executor.rb:319:in catch'

Update: actually I received the payment to zold wallet, so I'll remove it manually from 0crat debt.

0crat commented 5 years ago

@yegor256/z please, pay attention to this issue

yegor256 commented 5 years ago

@g4s8 even though this particular problem is fixed already, the problem is bigger than that. WTS can't 100% guarantee failure atomicity, since Zold network is distributed. In other words, we can accept some payment, send it to the network and then crash somewhere. We have to invent some mechanism to double check the status of the payment after it's failed... I'm thinking.

g4s8 commented 5 years ago

@yegor256 maybe wts will generate unique id (or hash) for transaction before sending to the network and return it to client, so client (0crat in this case) will be able to check that transaction was added to ledger by id/hash?

yegor256 commented 5 years ago

@g4s8 but WTS may fail to return the ID, just like it happened in the stacktrace above

yegor256 commented 5 years ago

@g4s8 so how about we just give programmable access to the General Ledger? The client-side scenario will look like this:

  1. Send /do-pay
  2. Get job ID
  3. Check job status via /job
  4. Get exception
  5. GET /gl-find to find the payment, maybe it's there
  6. If it's there - it's OK
  7. If not, it was definitely a failure.

WDYT?

g4s8 commented 5 years ago

@yegor256 it may work, but I have some doubts: can client check job status after WTS API failure but before transaction is listed in GL?

yegor256 commented 5 years ago

@g4s8 let's ask the client to check GL status for at least 10 minutes?

g4s8 commented 5 years ago

@yegor256 it should work, but in this scenario we need to store job id to be able to check payment status between client restarts

yegor256 commented 5 years ago

@g4s8 how about we add this: When a client sends /do-pay it also sends some unique ID of the request (anything the client makes up) and WTS keeps it in the database. Later, if the client comes back again with do-pay and the previous request is not fully closed, WTS doesn't allow to send any more payments until the client retrieves the info about the job, and returns that unique ID back to the client, suggesting to do something with the previous job. Something like this.

This way the client doesn't need to persist anything, the WTS will do it for them.

g4s8 commented 5 years ago

@yegor256 but client have to store some details in any case - e.g. if 0crat is paying a debt, it can generate unique id for debt payment to check it later, but debt may change between /do-pay call and status check.

Maybe WTS can allow to store some additional details about payment in do-pay? E.g. 0crat may send debt details or payment details (including author, reason, etc, to parse it later in case of error) in /do-pay, then retrieve a list of all payment jobs periodically (e.g. every hour) and check the status of each job, and the status can be OK, RUNNING or ERROR, if status is OK 0crat notifies a user about a payment and wts removes this job (or 0crat may ask to remove via API), if PENDING 0crat will skip it, if ERROR 0crat will parse payment details for this job and add this payment back to debts (WTS also removes this job).

0crat commented 5 years ago

Job #162 is now in scope, role is DEV

yegor256 commented 5 years ago

@g4s8 how about this idea. Every time you send a payment you add a date field to it. You create that date locally and send it over. And you send your requests via ReHTTP.net. The presence of the date inside the payment details will guarantee that the transaction will be added to the Zold wallet only once, no matter how many times WTS will receive the POST request, because all requests except the right one will be rejected -- their date field will conflict with the existing one. WDYT?

0crat commented 5 years ago

The job #162 assigned to @oltdaniel/z, here is why; the budget is 30 minutes, see §4; please, read §8 and §9; if the task is not clear, read this and this; there will be no monetary reward for this job

g4s8 commented 5 years ago

@yegor256 I think it should work

0crat commented 5 years ago

@oltdaniel/z this job was assigned to you 5days ago. It will be taken away from you soon, unless you close it, see §8. Read this and this, please.

0crat commented 5 years ago

Resigned on delay, see §8: -30 point(s) just awarded to @oltdaniel/z

0crat commented 5 years ago

The user @oltdaniel/z resigned from #162, please stop working. Reason for job resignation: It is older than 10 days, see §8