Is it possible to pause a initiated flashloan and resume after some parameter met.
I read on solidity docs, all function are require some sort of user action to execute.
Just incase I miss out if there any method to achieve it.
A flashloan needs to be repaid in the same transaction in which it was initiated. If it's not repaid, the whole transaction reverts as if it never happened (however the transaction sender still pays the gas fees).
So it is not really possible to pause and resume a flash loan, as it either happens all in one instance - or it doesn't.
The user action is usually executing one contract, that performs several internal calls within the same transaction:
initiate the flash loan
perform some kind of trade with the loaned funds
give aproval to the flash loan contract to pull the funds back
repay the flash loan
Related
I'm doing an ad server (sort of RTB), there are advertisers who pay to promote their ad campaigns.
When the user watched the ad I want to charge the advertiser.
Ad campaigns should participate in auctions without blocking, means he can bid for multiple ad requests at the same time. It would make it difficult to charge advertiser immediately since I'll have to block his balance.
Another approach is to not charge him immediately, but in the separate process once every N seconds, and hope so he didn't buy more impressions than he can afford. I can make some sort of threshold credit he should have to participate in auctions, it would eliminate most of the overruns but what if the process is exited and the advertiser wasn't charged and overrun a lot, that would be a problem.
Can someone please advise me how these things are usually handled, maybe recommend some book/article on the topic, please?
If this is a problem of asynchronous programming, meaning that you are concerned about overcharging a bidder when they place too many impression bids at once. Then I suggest using a mutex (i.e. locking system). You can set a threshold on the number of locks a bidder can have in your system at any given time. This threshold can be equivalent to the maximum amount the bidder is willing to spend on impressions. When the bidder requests a bid a lock for that bid on his account should be sent to your server. When the server responds with the ok response that the lock has been created, then the bid can take place. The bid is active until the lock is released by your server. This makes it so the server keeps track of all the bids and places locks on all of them. If the bidder has a threshold of 10 bids and he tries to make a bid for the 11th the server will not release a lock to the bidder to make this bid. Furthermore, if you are using a microservice architecture I suggest making a transaction manager service to handle all these requests and even use Saga based transactions for rollback functionally in case of a server failure.
Today, I am thinking a simplified scenario as follows:
I have my own payment system and when user come to save money, I use a form to save transaction data in my own DB. Before saving my own record, I need call Bank payment system which has a Webservice API like
public boolean pay(userInfo userInfo, float money).
Based on the result returned, I determine whether save my own data or not.
My question is if after calling the Bank payment API, my own network is off, and no result back. How to determine whether I need to save my own Form record or not. Maybe bank payment system has already processed this transaction? How to make two part data synchronized?
We cannot change bank payment API because bank spec is fixed. Webservice API is SOAP or Restful
Your implementation may be something like this:
Always save transaction data to your database and mark it as "unprocessed".
Use separate "worker" process, that fetches all unprocessed transaction from your database, and calls pay method of Bank payment system.
Accordingly to pay method result, choose to change/not change the status of the transaction.
Worker may by a scheduled process (each XX sec/minutes/etc) or some service that queries unprocessed transactions constantly (maybe with some delay between loops).
So in case of "no result" from Bank payment system, transaction state will not be changed and "pay" method will be retried on next worker run.
Given that I am a bit confused with CQRS I would like to understand it further in the following scenario.
I have an Actor that charge Users' credit card. To do so it contact a bank external service that does the operation, get a confirmation result. I would like to know how can I apply this with CQRS.
The information that needs to be written here is that a specific user has been charge a certain amount. So the event generated is Charged (UserID, Card, Amount). Something like that.
The problem is that all the examples I have seen especially with AKKA, would only generate the event after a Command is validated, such that it is persisted in a journal, and used to update the state of the actor. The Journal could then be red on the other side, such that to create a Reading view here.
Also usually, in those examples, the update state function has a logic that somewhat execute the command, because the command correspond straightforwardly to a state update at the end of the day. This is the typical BasketShoping example: CreateOrder, AddLineItem. All Of this Command, are directly translated in Event, that correspond to a specific code of the Update state function.
However in this example, one needs to actually contact an external service, charge the user and then generate an event. Contacting the external service can't be done in the update state, or after reading the journal. It would not make sense.
How is that done, and where, and when exactly, in the spirit of CQRS?
I can think of 2 ways of doing this.
First is a simple way. The command is DoCharge(UserId, Card, Amount). Upon reception of this command, you call the external payment service. If this has been successfully completed, you generate an event, Charged(UserId, Card, Amount, TransactionId) and store it in the journal.
Now, of course, it's not completely safe way, because your Actor can crash after it has sent the request to payment service, but before it has received and persisted the confirmation of the successful completion. Then you risk of charging the user twice. To overcome this risk, you have to make your payment operation idempotent. Here's how to do it. This example is based on the classic "RESTify Day trader" article. I'll summarize it here.
You need to split the payment operation in 2 phases. In first one, payment service creates a transaction token. It just identifies the transaction, and no financial operations are performed yet. Upon the creation, the identifier is received by your service and persisted in the journal.
In next phase you perform a payment associated with the identifier from phase one. If your actor now fails in the middle, while operation is performed successfully on the payment service side, the transaction token will already be marked as processed by the payment service, and it won't let you charge the customer twice. Now, if you restart the failed Actor, and it tries to run the payment associated with the existing transaction token, the payment service should return result like "Already executed" or such. Of course, at the end you also persist the result of the operation in the journal.
Every time a customer completes a transaction a reminder workflow starts for that customer which tries to remind a customer about few actions that he/she has to perform. There are points in the flow where I know for sure that there is no task to be performed. So in this case I want the workflow to go to sleep for some time and come back to life later. I want this sleep feature to avoid database call as my decider does one database query every time it gets a task.
I have gone through the AWS documentation here . But found nothing there (Please point me to document if the feature exists). Does AWS-SWF provide such a feature. If it does not provide a feature of this type then what is smart and clean way of doing this.
A small example of flow I want to create :
1. End of transaction initiates a "simple workflow"
2. Decider gets a task. Decider decides to give it to a Customer
Reminder activity worker or PUT IT TO SLEEP.
3. The decider keeps poling but never gets the workflow till the sleep
time of work flow is over.
4. The sleep time is over so SWF starts giving it the decider which has
been polling all along.
Please tell me if you need any more clarification on this.
Use StartTimerDecision to create a timer.
Refer to the timer documentation.
http://docs.aws.amazon.com/amazonswf/latest/developerguide/swf-dg-timers.html
Imagine 3 system components:
1. External ecommerce web service to process credit card transactions
2. Local Database to store processing results
3. Local UI (or win service) to perform payment processing of the customer order document
The external web service is obviously not transactional, so how to guarantee:
1. results to be eventually persisted to database when received from web service even in case the database is not accessible at that moment(network issue, db timeout)
2. prevent clients from processing the customer order while payment initiated by other client but results not successfully persisted to database yet(and waiting in some kind of recovery queue)
The aim is to do processing having non transactional system components and guarantee the transaction won't be repeated by other process in case of failure.
(please look at it in the context of post sell payment processing, where multiple operators might attempt manual payment processing; not web checkout application)
Ask the payment processor whether they can detect duplicate transactions based on an order ID you supply. Then if you are unable to store the response due to a database failure, you can safely resubmit the request without fear of double-charging (at least one PSP I've used returned the same response/auth code in this scenario, along with a flag to say that this was a duplicate).
Alternatively, just set a flag on your order immediately before attempting payment, and don't attempt payment if the flag was already set. If an error then occurs during payment, you can investigate and fix the data at your leisure.
I'd be reluctant to go down the route of trying to automatically cancel the order and resubmitting, as this just gets confusing (e.g. what if cancelling fails - should you retry or not?). Best to keep the logic simple so when something goes wrong you know exactly where you stand.
In any system like this, you need robust error handling and error reporting. This is doubly true when it comes to dealing with payments, where you absolutely do not want to accidentaly take someone's money and not deliver the goods.
Because you're outsourcing your payment handling to a 3rd party, you're ultimately very reliant on the gateway having robust error handling and reporting systems.
In general then, you hand off control to the payment gateway and start a task that waits for a response from the gateway, which is either 'payment accepted' or 'payment declined'. When you get that response you move onto the next step in your process and everything is good.
When you don't get a response at all (time out), or the response is invalid, then how you proceed very much depends on the payment gateway:
If the gateway supports it send a 'cancel payment' style request. If the payment cancels successfully then you probably want to send the user to a 'sorry, please try again' style page.
If the gateway doesn't support canceling, or you have no communications to the gateway then you will need to manually (in person, such as telephone) contact the 3rd party to discover what went wrong and how to proceed. To aid this you need to dump as much detail as you have to error logs, such as date/time, customer id, transaction value, product ids etc.
Once you're back on your site (and payment is accepted) then you're much more in control of errors, but in brief if you cant complete the order, then you should either dump the details to disk (such as csv file for manual handling) or contact the gateway to cancel the payment.
Its also worth having a system in place to track errors as they occur, and if an excessive number occur then consider what should happen. If its a high traffic site for example you may want to temporarily prevent further customers from placing orders whilst the issue is investigated.
Distributed messaging.
When your payment gateway returns submit a message to a durable queue that guarantees a handler will eventually get it and process it. The handler would update the database. Should failure occur at that point the handler can leave the message in the queue or repost it to the queue, or post an alternate message.
Should something occur later that invalidates the transaction, another message could be queued to "undo" the change.
There's a fair amount of buzz lately about eventual consistency and distribute messaging. NServiceBus is the new component hotness. I suggest looking into this, I know we are.