define output stack;

cleanup daemon model impl
This commit is contained in:
woodser
2019-06-21 17:32:51 -04:00
parent 8fadd95f75
commit f3c095ae6a
6 changed files with 132 additions and 86 deletions
+83 -72
View File
@@ -6,8 +6,6 @@
/**
* Public library interface.
*
* TODO: separate per model class like wallet (cleanup)
*/
namespace monero {
@@ -15,12 +13,14 @@ namespace monero {
const string MoneroTx::DEFAULT_PAYMENT_ID = string("0000000000000000");
// -------------------------- MODEL SERIALIZATION ---------------------------
// ------------------------- SERIALIZABLE STRUCT ----------------------------
string SerializableStruct::serialize() const {
return MoneroUtils::serialize(toPropertyTree());
}
// ------------------------- MONERO BLOCK HEADER ----------------------------
boost::property_tree::ptree MoneroBlockHeader::toPropertyTree() const {
//cout << "MoneroBlockHeader::toPropertyTree(block)" << endl;
boost::property_tree::ptree node;
@@ -45,6 +45,31 @@ namespace monero {
return node;
}
void MoneroBlockHeader::merge(const shared_ptr<MoneroBlockHeader>& self, const shared_ptr<MoneroBlockHeader>& other) {
if (this != self.get()) throw runtime_error("this != self");
if (self == other) return;
id = MoneroUtils::reconcile(id, other->id);
height = MoneroUtils::reconcile(height, other->height, boost::none, boost::none, true); // height can increase
timestamp = MoneroUtils::reconcile(timestamp, other->timestamp, boost::none, boost::none, true); // timestamp can increase
size = MoneroUtils::reconcile(size, other->size);
weight = MoneroUtils::reconcile(weight, other->weight);
longTermWeight = MoneroUtils::reconcile(longTermWeight, other->longTermWeight);
depth = MoneroUtils::reconcile(depth, other->depth);
difficulty = MoneroUtils::reconcile(difficulty, other->difficulty);
cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, other->cumulativeDifficulty);
majorVersion = MoneroUtils::reconcile(majorVersion, other->majorVersion);
minorVersion = MoneroUtils::reconcile(minorVersion, other->minorVersion);
nonce = MoneroUtils::reconcile(nonce, other->nonce);
coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, other->coinbaseTxId);
numTxs = MoneroUtils::reconcile(numTxs, other->numTxs);
orphanStatus = MoneroUtils::reconcile(orphanStatus, other->orphanStatus);
prevId = MoneroUtils::reconcile(prevId, other->prevId);
reward = MoneroUtils::reconcile(reward, other->reward);
powHash = MoneroUtils::reconcile(powHash, other->powHash);
}
// ----------------------------- MONERO BLOCK -------------------------------
boost::property_tree::ptree MoneroBlock::toPropertyTree() const {
//cout << "MoneroBlock::toPropertyTree(block)" << endl;
boost::property_tree::ptree node = MoneroBlockHeader::toPropertyTree();
@@ -55,6 +80,48 @@ namespace monero {
return node;
}
void MoneroBlock::merge(const shared_ptr<MoneroBlock>& self, const shared_ptr<MoneroBlock>& other) {
if (this != self.get()) throw runtime_error("this != self");
if (self == other) return;
// merge header fields
MoneroBlockHeader::merge(self, other);
// convert other to MoneroBlock*
MoneroBlock* otherBlock = static_cast<MoneroBlock*>(other.get());
// merge coinbase tx
if (coinbaseTx == boost::none) coinbaseTx = otherBlock->coinbaseTx;
else if (otherBlock->coinbaseTx != boost::none) (**coinbaseTx).merge(*coinbaseTx, *otherBlock->coinbaseTx);
// merge non-coinbase txs
if (txs.empty()) txs = otherBlock->txs;
else if (!otherBlock->txs.empty()) {
for (const shared_ptr<MoneroTx>& thatTx : otherBlock->txs) {
bool found = false;
for (const shared_ptr<MoneroTx>& thisTx : txs) {
if (thatTx->id == thisTx->id) {
thisTx->merge(thisTx, thatTx);
found = true;
break;
}
}
if (!found) txs.push_back(thatTx);
}
}
if (!txs.empty()) {
for (const shared_ptr<MoneroTx>& tx : txs) {
tx->block = static_pointer_cast<MoneroBlock>(self);
}
}
// merge other fields
hex = MoneroUtils::reconcile(hex, otherBlock->hex);
//txIds = MoneroUtils::reconcile(txIds, otherBlock->txIds); // TODO: implement
}
// ------------------------------- MONERO TX --------------------------------
boost::property_tree::ptree MoneroTx::toPropertyTree() const {
//cout << "MoneroTx::txToPropertyTree(tx)" << endl;
boost::property_tree::ptree node;
@@ -98,71 +165,6 @@ namespace monero {
return node;
}
// -------------------------- MODEL IMPLEMENTATION --------------------------
void MoneroBlockHeader::merge(const shared_ptr<MoneroBlockHeader>& self, const shared_ptr<MoneroBlockHeader>& other) {
if (this != self.get()) throw runtime_error("this != self");
if (self == other) return;
id = MoneroUtils::reconcile(id, other->id);
height = MoneroUtils::reconcile(height, other->height, boost::none, boost::none, true); // height can increase
timestamp = MoneroUtils::reconcile(timestamp, other->timestamp, boost::none, boost::none, true); // timestamp can increase
size = MoneroUtils::reconcile(size, other->size);
weight = MoneroUtils::reconcile(weight, other->weight);
longTermWeight = MoneroUtils::reconcile(longTermWeight, other->longTermWeight);
depth = MoneroUtils::reconcile(depth, other->depth);
difficulty = MoneroUtils::reconcile(difficulty, other->difficulty);
cumulativeDifficulty = MoneroUtils::reconcile(cumulativeDifficulty, other->cumulativeDifficulty);
majorVersion = MoneroUtils::reconcile(majorVersion, other->majorVersion);
minorVersion = MoneroUtils::reconcile(minorVersion, other->minorVersion);
nonce = MoneroUtils::reconcile(nonce, other->nonce);
coinbaseTxId = MoneroUtils::reconcile(coinbaseTxId, other->coinbaseTxId);
numTxs = MoneroUtils::reconcile(numTxs, other->numTxs);
orphanStatus = MoneroUtils::reconcile(orphanStatus, other->orphanStatus);
prevId = MoneroUtils::reconcile(prevId, other->prevId);
reward = MoneroUtils::reconcile(reward, other->reward);
powHash = MoneroUtils::reconcile(powHash, other->powHash);
}
void MoneroBlock::merge(const shared_ptr<MoneroBlock>& self, const shared_ptr<MoneroBlock>& other) {
if (this != self.get()) throw runtime_error("this != self");
if (self == other) return;
// merge header fields
MoneroBlockHeader::merge(self, other);
// convert other to MoneroBlock*
MoneroBlock* otherBlock = static_cast<MoneroBlock*>(other.get());
// merge coinbase tx
if (coinbaseTx == boost::none) coinbaseTx = otherBlock->coinbaseTx;
else if (otherBlock->coinbaseTx != boost::none) (**coinbaseTx).merge(*coinbaseTx, *otherBlock->coinbaseTx);
// merge non-coinbase txs
if (txs.empty()) txs = otherBlock->txs;
else if (!otherBlock->txs.empty()) {
for (const shared_ptr<MoneroTx>& thatTx : otherBlock->txs) {
bool found = false;
for (const shared_ptr<MoneroTx>& thisTx : txs) {
if (thatTx->id == thisTx->id) {
thisTx->merge(thisTx, thatTx);
found = true;
break;
}
}
if (!found) txs.push_back(thatTx);
}
}
if (!txs.empty()) {
for (const shared_ptr<MoneroTx>& tx : txs) {
tx->block = static_pointer_cast<MoneroBlock>(self);
}
}
// merge other fields
hex = MoneroUtils::reconcile(hex, otherBlock->hex);
//txIds = MoneroUtils::reconcile(txIds, otherBlock->txIds); // TODO: implement
}
boost::optional<uint64_t> MoneroTx::getHeight() const {
if (block == boost::none) return boost::none;
return *((*block)->height);
@@ -278,9 +280,14 @@ namespace monero {
}
}
void MoneroKeyImage::merge(const shared_ptr<MoneroKeyImage>& self, const shared_ptr<MoneroKeyImage>& other) {
cout << "MoneroKeyImage::merge()" << endl;
throw runtime_error("Not implemented");
// ------------------------------ MONERO OUTPUT -----------------------------
boost::property_tree::ptree MoneroOutput::toPropertyTree() const {
//cout << "MoneroOutput::txToPropertyTree(tx)" << endl;
boost::property_tree::ptree node;
//if (id != boost::none) node.put("id", *id); TODO
throw runtime_error("MoneroOutput toPropertyTree() not implemented");
return node;
}
void MoneroOutput::merge(const shared_ptr<MoneroOutput>& self, const shared_ptr<MoneroOutput>& other) {
@@ -288,6 +295,10 @@ namespace monero {
throw runtime_error("Not implemented");
}
// ---------------------------- PRIVATE HELPERS -----------------------------
// --------------------------- MONERO KEY IMAGE -----------------------------
void MoneroKeyImage::merge(const shared_ptr<MoneroKeyImage>& self, const shared_ptr<MoneroKeyImage>& other) {
cout << "MoneroKeyImage::merge()" << endl;
throw runtime_error("Not implemented");
}
}
+2 -1
View File
@@ -160,7 +160,7 @@ namespace monero {
/**
* Models a Monero transaction output.
*/
struct MoneroOutput {
struct MoneroOutput : public SerializableStruct {
shared_ptr<MoneroTx> tx;
boost::optional<shared_ptr<MoneroKeyImage>> keyImage;
boost::optional<uint64_t> amount;
@@ -168,6 +168,7 @@ namespace monero {
vector<uint32_t> ringOutputIndices;
boost::optional<string> stealthPublicKey;
boost::property_tree::ptree toPropertyTree() const;
void merge(const shared_ptr<MoneroOutput>& self, const shared_ptr<MoneroOutput>& other);
};
}
+1 -1
View File
@@ -639,7 +639,7 @@ namespace monero {
return transfers;
}
vector<MoneroOutputWallet> MoneroWallet::getOutputs(const MoneroOutputRequest& request) const {
vector<shared_ptr<MoneroOutputWallet>> MoneroWallet::getOutputs(const MoneroOutputRequest& request) const {
cout << "getOutputs(request)" << endl;
throw runtime_error("Not implemented");
}
+1 -1
View File
@@ -586,7 +586,7 @@ namespace monero {
* @param request specifies request options (optional)
* @return List<MoneroOutputWallet> are wallet outputs per the request
*/
vector<MoneroOutputWallet> getOutputs(const MoneroOutputRequest& request) const;
vector<shared_ptr<MoneroOutputWallet>> getOutputs(const MoneroOutputRequest& request) const;
//
// /**
// * Get all signed key images.
+27
View File
@@ -308,4 +308,31 @@ namespace monero {
if (txRequest != boost::none && !(*txRequest)->meetsCriteria(transfer->tx.get())) return false;
return true;
}
// ------------------------- MONERO OUTPUT WALLET ---------------------------
boost::property_tree::ptree MoneroOutputWallet::toPropertyTree() const {
//cout << "MoneroTransfer::toPropertyTree(node)" << endl;
boost::property_tree::ptree node = MoneroOutput::toPropertyTree();
if (accountIndex != boost::none) node.put("accountIndex", *accountIndex);
if (subaddressIndex != boost::none) node.put("subaddressIndex", *subaddressIndex);
if (isSpent != boost::none) node.put("isSpent", *isSpent);
if (isUnlocked != boost::none) node.put("isUnlocked", *isUnlocked);
if (isFrozen != boost::none) node.put("isFrozen", *isFrozen);
return node;
}
// ------------------------ MONERO OUTPUT REQUEST ---------------------------
boost::property_tree::ptree MoneroOutputRequest::toPropertyTree() const {
cout << "MoneroOutputRequest::toPropertyTree(node)" << endl;
boost::property_tree::ptree node = MoneroOutputWallet::toPropertyTree();
if (!subaddressIndices.empty()) throw runtime_error("MoneroOutputRequest toPropertyTree() subaddressIndices not implemented");
return node;
}
bool MoneroOutputRequest::meetsCriteria(MoneroOutputWallet* output) const {
cout << "MoneroOutputRequest::meetsCriteria()" << endl;
throw runtime_error("Not implemented");
}
}
+18 -11
View File
@@ -141,6 +141,7 @@ namespace monero {
vector<shared_ptr<MoneroDestination>> destinations;
boost::optional<bool> hasDestinations;
boost::optional<shared_ptr<MoneroTxRequest>> txRequest;
boost::optional<bool> getIsIncoming() const;
boost::property_tree::ptree toPropertyTree() const;
bool meetsCriteria(MoneroTransfer* transfer) const;
@@ -155,6 +156,22 @@ namespace monero {
boost::optional<bool> isSpent;
boost::optional<bool> isUnlocked;
boost::optional<bool> isFrozen;
boost::property_tree::ptree toPropertyTree() const;
};
/**
* Configures a request to retrieve wallet outputs (i.e. outputs that the wallet has or had the
* ability to spend).
*
* All outputs are returned except those that do not meet the criteria defined in this request.
*/
struct MoneroOutputRequest : public MoneroOutputWallet {
vector<uint32_t> subaddressIndices;
boost::optional<shared_ptr<MoneroTxRequest>> txRequest;
boost::property_tree::ptree toPropertyTree() const;
bool meetsCriteria(MoneroOutputWallet* output) const;
};
/**
@@ -185,19 +202,9 @@ namespace monero {
boost::optional<uint64_t> maxHeight;
boost::optional<uint64_t> includeOutputs;
boost::optional<shared_ptr<MoneroTransferRequest>> transferRequest;
boost::optional<shared_ptr<MoneroOutputRequest>> outputRequest;
boost::property_tree::ptree toPropertyTree() const;
bool meetsCriteria(MoneroTxWallet* tx) const;
};
/**
* Configures a request to retrieve wallet outputs (i.e. outputs that the wallet has or had the
* ability to spend).
*
* All outputs are returned except those that do not meet the criteria defined in this request.
*/
struct MoneroOutputRequest : public MoneroOutput {
vector<uint32_t> subaddressIndices;
boost::optional<shared_ptr<MoneroTxRequest>> txRequest;
};
}