protected function execute(InputInterface $input, OutputInterface $output) { $this->init(); $this->output = $output; $this->input = $input; try { $lock = Lock::lock('scanner_' . $this->nameShort); } catch (UnableToLockException $e) { $this->writeln('Already running'); return; } $this->writeln('Started wallet scanner ' . date('Y-m-d H:i:s')); if (!($this->round = $this->roundRepo->findOneBy(['started' => true, 'finished' => false]))) { $this->writeln('No running round'); return; } $this->writeln('Creating new incoming transactions'); if ($newTransactions = $this->walletManager->getNewIncomingTransactions()) { $this->writeln('Found ' . count($newTransactions) . ' new transactions'); $this->depositManager->saveNewDeposits($newTransactions); } else { $this->writeln('No new transactions found'); } $this->writeln('Updating deposits'); $updated = $this->depositManager->updatePendingDeposits(); $this->writeln('Updated/checked ' . $updated . ' deposits'); $this->writeln('Realising payouts'); $payouts = $this->payoutManager->realisePayouts(); $this->writeln('Realised ' . count($payouts) . ' payouts'); $this->writeln('Checking round end'); $this->checkRoundEnd(); }
/** * @return int */ public function updatePendingDeposits() { $deposits = $this->depositRepo->findBy(['confirmed' => false, 'round' => $this->round], ['id' => 'asc']); foreach ($deposits as $deposit) { $confirmations = $this->walletManager->getConfirmations($deposit); $deposit->setConfirmations($confirmations); if ($deposit->getConfirmations() >= $this->round->getMinConfirmations()) { $deposit->setConfirmed(true); // updating payout status // we could put this in listener together with persist // but it does not matter cause this status is updated only in 3 places foreach ($deposit->getPayouts() as $payout) { $payout->setReadyForPayout(true); } } } $this->em->flush(); return count($deposits); }
/** * @param array|Payout[] $payouts * @return array|Payout[] * @throws \Bml\CoinBundle\Exception\RequestException * @throws \Exception */ private function _realisePayouts(array $payouts) { $sumPayout = 0; foreach ($payouts as $payout) { $sumPayout += $payout->getAmount(); } do { if ($sumPayout < $this->round->getMinDeposit()) { // we will not payout less than min deposit // this is probably only paying out referrer // referrer payout amount is less than payout tx fee // it makes no sense to pay it out alone return []; } try { $tx = $this->walletManager->sendPayouts($payouts); } catch (RequestException $e) { if ($e->getCode() != -6) { throw $e; } // this is probably insufficient founds error // that's because of fee added by client // we will try to pop last payout to see if then we will fit within fee+payout_amount<balance $last = array_pop($payouts); /* @var $payout Payout */ $sumPayout -= $last->getAmount(); continue; } foreach ($payouts as $payout) { $payout->setPaid(true); $payout->setTx($tx); $payout->setPaidOutTime(new \DateTime()); } $this->em->flush(); break; } while (!empty($payouts)); return $payouts; }