accumulate credits to pay nodes, return in assignments JSON

This commit is contained in:
Stephen Birarda 2014-05-20 16:57:19 -07:00
parent 8fb85110ac
commit 99a3fde8fa
6 changed files with 141 additions and 7 deletions

View file

@ -60,10 +60,10 @@ DomainServer::DomainServer(int argc, char* argv[]) :
// setup a timer to send transactions to pay assigned nodes every 30 seconds
QTimer* nodePaymentTimer = new QTimer(this);
connect(nodePaymentTimer, &QTimer::timeout, this, &DomainServer::payAssignedNodes);
connect(nodePaymentTimer, &QTimer::timeout, this, &DomainServer::setupPendingAssignmentCredits);
const qint64 NODE_PAYMENT_INTERVAL_MSECS = 30 * 1000;
nodePaymentTimer->start(NODE_PAYMENT_INTERVAL_MSECS);
const qint64 CREDIT_CHECK_INTERVAL = 5 * 1000;
nodePaymentTimer->start(CREDIT_CHECK_INTERVAL);
}
}
@ -656,14 +656,40 @@ void DomainServer::readAvailableDatagrams() {
}
}
void DomainServer::payAssignedNodes() {
void DomainServer::setupPendingAssignmentCredits() {
// enumerate the NodeList to find the assigned nodes
foreach (const SharedNodePointer& node, LimitedNodeList::getInstance()->getNodeHash()) {
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
if (!nodeData->getAssignmentUUID().isNull() && !nodeData->getWalletUUID().isNull()) {
// add a pending transaction for this node or increase the amount for the existing transaction
// check if we have a non-finalized transaction for this node to add this amount to
TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID());
WalletTransaction* existingTransaction = NULL;
while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) {
if (!i.value()->isFinalized()) {
existingTransaction = i.value();
break;
} else {
++i;
}
}
qint64 elapsedMsecsSinceLastPayment = nodeData->getPaymentIntervalTimer().elapsed();
nodeData->getPaymentIntervalTimer().restart();
const float CREDITS_PER_HOUR = 3;
const float CREDITS_PER_MSEC = CREDITS_PER_HOUR / (60 * 60 * 1000);
float pendingCredits = elapsedMsecsSinceLastPayment * CREDITS_PER_MSEC;
if (existingTransaction) {
existingTransaction->incrementAmount(pendingCredits);
} else {
// create a fresh transaction to pay this node, there is no transaction to append to
WalletTransaction* freshTransaction = new WalletTransaction(nodeData->getWalletUUID(), pendingCredits);
_pendingAssignmentCredits.insert(nodeData->getWalletUUID(), freshTransaction);
}
}
}
}
@ -717,6 +743,7 @@ const char JSON_KEY_TYPE[] = "type";
const char JSON_KEY_PUBLIC_SOCKET[] = "public";
const char JSON_KEY_LOCAL_SOCKET[] = "local";
const char JSON_KEY_POOL[] = "pool";
const char JSON_KEY_PENDING_CREDITS[] = "pending_credits";
const char JSON_KEY_WAKE_TIMESTAMP[] = "wake_timestamp";
QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
@ -745,6 +772,18 @@ QJsonObject DomainServer::jsonObjectForNode(const SharedNodePointer& node) {
SharedAssignmentPointer matchingAssignment = _allAssignments.value(nodeData->getAssignmentUUID());
if (matchingAssignment) {
nodeJson[JSON_KEY_POOL] = matchingAssignment->getPool();
if (!nodeData->getWalletUUID().isNull()) {
TransactionHash::iterator i = _pendingAssignmentCredits.find(nodeData->getWalletUUID());
double pendingCreditAmount = 0;
while (i != _pendingAssignmentCredits.end() && i.key() == nodeData->getWalletUUID()) {
pendingCreditAmount += i.value()->getAmount();
++i;
}
nodeJson[JSON_KEY_PENDING_CREDITS] = pendingCreditAmount;
}
}
return nodeJson;

View file

@ -24,9 +24,12 @@
#include <HTTPSConnection.h>
#include <LimitedNodeList.h>
#include "WalletTransaction.h"
#include "PendingAssignedNodeData.h"
typedef QSharedPointer<Assignment> SharedAssignmentPointer;
typedef QMultiHash<QUuid, WalletTransaction*> TransactionHash;
class DomainServer : public QCoreApplication, public HTTPSRequestHandler {
Q_OBJECT
@ -46,7 +49,7 @@ public slots:
private slots:
void readAvailableDatagrams();
void payAssignedNodes();
void setupPendingAssignmentCredits();
private:
void setupNodeListAndAssignments(const QUuid& sessionUUID = QUuid::createUuid());
bool optionallySetupOAuth();
@ -88,6 +91,7 @@ private:
QHash<QUuid, SharedAssignmentPointer> _allAssignments;
QQueue<SharedAssignmentPointer> _unfulfilledAssignments;
QHash<QUuid, PendingAssignedNodeData*> _pendingAssignedNodes;
TransactionHash _pendingAssignmentCredits;
QVariantMap _argumentVariantMap;

View file

@ -21,11 +21,12 @@ DomainServerNodeData::DomainServerNodeData() :
_sessionSecretHash(),
_assignmentUUID(),
_walletUUID(),
_paymentIntervalTimer(),
_statsJSONObject(),
_sendingSockAddr(),
_isAuthenticated(true)
{
_paymentIntervalTimer.start();
}
void DomainServerNodeData::parseJSONStatsPacket(const QByteArray& statsPacket) {

View file

@ -12,6 +12,8 @@
#ifndef hifi_DomainServerNodeData_h
#define hifi_DomainServerNodeData_h
#include <QtCore/QElapsedTimer>
#include <QtCore/QHash>
#include <QtCore/QUuid>
@ -33,6 +35,8 @@ public:
void setWalletUUID(const QUuid& walletUUID) { _walletUUID = walletUUID; }
const QUuid& getWalletUUID() const { return _walletUUID; }
QElapsedTimer& getPaymentIntervalTimer() { return _paymentIntervalTimer; }
void setSendingSockAddr(const HifiSockAddr& sendingSockAddr) { _sendingSockAddr = sendingSockAddr; }
const HifiSockAddr& getSendingSockAddr() { return _sendingSockAddr; }
@ -46,6 +50,7 @@ private:
QHash<QUuid, QUuid> _sessionSecretHash;
QUuid _assignmentUUID;
QUuid _walletUUID;
QElapsedTimer _paymentIntervalTimer;
QJsonObject _statsJSONObject;
HifiSockAddr _sendingSockAddr;
bool _isAuthenticated;

View file

@ -0,0 +1,43 @@
//
// WalletTransaction.cpp
// domain-server/src
//
// Created by Stephen Birarda on 2014-05-20.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <QtCore/QJsonObject>
#include <UUID.h>
#include "WalletTransaction.h"
WalletTransaction::WalletTransaction(const QUuid& destinationUUID, double amount) :
_uuid(QUuid::createUuid()),
_destinationUUID(destinationUUID),
_amount(amount),
_isFinalized(false)
{
}
QJsonDocument WalletTransaction::postJson() {
QJsonObject rootObject;
QJsonObject transactionObject;
const QString TRANSCATION_ID_KEY = "id";
const QString TRANSACTION_DESTINATION_WALLET_ID_KEY = "destination_wallet_id";
const QString TRANSACTION_AMOUNT_KEY = "amount";
transactionObject.insert(TRANSCATION_ID_KEY, uuidStringWithoutCurlyBraces(_uuid));
transactionObject.insert(TRANSACTION_DESTINATION_WALLET_ID_KEY, uuidStringWithoutCurlyBraces(_destinationUUID));
transactionObject.insert(TRANSACTION_AMOUNT_KEY, _amount);
const QString ROOT_OBJECT_TRANSACTION_KEY = "transaction";
rootObject.insert(ROOT_OBJECT_TRANSACTION_KEY, transactionObject);
return QJsonDocument(rootObject);
}

View file

@ -0,0 +1,42 @@
//
// WalletTransaction.h
// domain-server/src
//
// Created by Stephen Birarda on 2014-05-20.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_WalletTransaction_h
#define hifi_WalletTransaction_h
#include <QtCore/QJsonDocument>
#include <QtCore/QObject>
#include <QtCore/QUuid>
class WalletTransaction : public QObject {
public:
WalletTransaction(const QUuid& destinationUUID, double amount);
const QUuid& getUUID() const { return _uuid; }
void setDestinationUUID(const QUuid& destinationUUID) { _destinationUUID = destinationUUID; }
const QUuid& getDestinationUUID() const { return _destinationUUID; }
double getAmount() const { return _amount; }
void setAmount(double amount) { _amount = amount; }
void incrementAmount(double increment) { _amount += increment; }
bool isFinalized() const { return _isFinalized; }
QJsonDocument postJson();
private:
QUuid _uuid;
QUuid _destinationUUID;
double _amount;
bool _isFinalized;
};
#endif // hifi_WalletTransaction_h