Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/omnicore/createpayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ std::vector<unsigned char> CreatePayload_SimpleSend(uint32_t propertyId, uint64_
return payload;
}

std::vector<unsigned char> CreatePayload_SendAll(uint8_t ecosystem)
{
std::vector<unsigned char> payload;
uint16_t messageVer = 0;
uint16_t messageType = 4;
mastercore::swapByteOrder16(messageVer);
mastercore::swapByteOrder16(messageType);

PUSH_BACK_BYTES(payload, messageVer);
PUSH_BACK_BYTES(payload, messageType);
PUSH_BACK_BYTES(payload, ecosystem);

return payload;
}

std::vector<unsigned char> CreatePayload_DExSell(uint32_t propertyId, uint64_t amountForSale, uint64_t amountDesired, uint8_t timeLimit, uint64_t minFee, uint8_t subAction)
{
std::vector<unsigned char> payload;
Expand Down
1 change: 1 addition & 0 deletions src/omnicore/createpayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdint.h>

std::vector<unsigned char> CreatePayload_SimpleSend(uint32_t propertyId, uint64_t amount);
std::vector<unsigned char> CreatePayload_SendAll(uint8_t ecosystem);
std::vector<unsigned char> CreatePayload_DExSell(uint32_t propertyId, uint64_t amountForSale, uint64_t amountDesired, uint8_t timeLimit, uint64_t minFee, uint8_t subAction);
std::vector<unsigned char> CreatePayload_DExAccept(uint32_t propertyId, uint64_t amount);
std::vector<unsigned char> CreatePayload_SendToOwners(uint32_t propertyId, uint64_t amount);
Expand Down
22 changes: 20 additions & 2 deletions src/omnicore/doc/rpc-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ Create new tokens with manageable supply.
1. ***fromaddress (string, required):*** the address to send from
2. ***propertyid (number, required):*** the identifier of the tokens to distribute
3. ***amount (string, required):*** the amount to distribute
4. ***redeemaddress (string, optional):*** an address that can spent the transaction dust (sender by default)
4. ***redeemaddress (string, optional):*** an address that can spend the transaction dust (sender by default)

**Example:**

Expand Down Expand Up @@ -293,6 +293,24 @@ Change the issuer on record of the given tokens.
$ omnicore-cli "omni_sendchangeissuer" "1ARjWDkZ7kT9fwjPrjcQyvbXDkEySzKHwu" "3HTHRxu3aSDV4deakjC7VmsiUp7c6dfbvs" 3
```

### omni_sendall

Transfers all available tokens in the given ecosystem to the recipient.

**Arguments:**

1. ***fromaddress (string, required):*** the address to send from
2. ***toaddress (string, required):*** the address of the receiver
3. ***ecosystem (number, required):*** the ecosystem of the tokens to send: (1) main, (2) test
4. ***redeemaddress (string, optional):*** an address that can spend the transaction dust (sender by default)
5. ***referenceamount (string, optional):*** a bitcoin amount that is sent to the receiver (minimal by default)

**Example:**

```bash
$ omnicore-cli "omni_sendall" "3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY" "37FaKponF7zqoMLUjEiko25pDiuVH5YLEa" 2
```

### omni_sendrawtx

Broadcasts a raw Omni Layer transaction.
Expand All @@ -302,7 +320,7 @@ Broadcasts a raw Omni Layer transaction.
1. ***fromaddress (string, required):*** the address to send from
2. ***rawtransaction (string, required):*** the hex-encoded raw transaction
3. ***referenceaddress (string, optional):*** a reference address (empty by default)
4. ***redeemaddress (string, optional):*** an address that can spent the transaction dust (sender by default)
4. ***redeemaddress (string, optional):*** an address that can spend the transaction dust (sender by default)
5. ***referenceamount (string, optional):*** a bitcoin amount that is sent to the receiver (minimal by default)

**Example:**
Expand Down
61 changes: 47 additions & 14 deletions src/omnicore/omnicore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3111,24 +3111,24 @@ int CMPTxList::getNumberOfMetaDExCancels(const uint256 txid)
return numberOfCancels;
}

int CMPTxList::getNumberOfPurchases(const uint256 txid)
/**
* Returns the number of sub records.
*/
int CMPTxList::getNumberOfSubRecords(const uint256& txid)
{
if (!pdb) return 0;
int numberOfPurchases = 0;
std::vector<std::string> vstr;
string strValue;
int numberOfSubRecords = 0;

std::string strValue;
Status status = pdb->Get(readoptions, txid.ToString(), &strValue);
if (status.ok())
{
// parse the string returned
boost::split(vstr, strValue, boost::is_any_of(":"), token_compress_on);
// obtain the number of purchases
if (4 <= vstr.size())
{
numberOfPurchases = atoi(vstr[3]);
if (status.ok()) {
std::vector<std::string> vstr;
boost::split(vstr, strValue, boost::is_any_of(":"), boost::token_compress_on);
if (4 <= vstr.size()) {
numberOfSubRecords = boost::lexical_cast<int>(vstr[3]);
}
}
return numberOfPurchases;

return numberOfSubRecords;
}

int CMPTxList::getMPTransactionCountTotal()
Expand Down Expand Up @@ -3177,6 +3177,26 @@ string CMPTxList::getKeyValue(string key)
if (status.ok()) { return strValue; } else { return ""; }
}

/**
* Retrieves details about a "send all" record.
*/
bool CMPTxList::getSendAllDetails(const uint256& txid, int subSend, uint32_t& propertyId, int64_t& amount)
{
std::string strKey = strprintf("%s-%d", txid.ToString(), subSend);
std::string strValue;
leveldb::Status status = pdb->Get(readoptions, strKey, &strValue);
if (status.ok()) {
std::vector<std::string> vstr;
boost::split(vstr, strValue, boost::is_any_of(":"), boost::token_compress_on);
if (2 == vstr.size()) {
propertyId = boost::lexical_cast<uint32_t>(vstr[0]);
amount = boost::lexical_cast<int64_t>(vstr[1]);
return true;
}
}
return false;
}

bool CMPTxList::getPurchaseDetails(const uint256 txid, int purchaseNumber, string *buyer, string *seller, uint64_t *vout, uint64_t *propertyId, uint64_t *nValue)
{
if (!pdb) return 0;
Expand Down Expand Up @@ -3253,6 +3273,19 @@ void CMPTxList::recordMetaDExCancelTX(const uint256 &txidMaster, const uint256 &
}
}

/**
* Records a "send all" sub record.
*/
void CMPTxList::recordSendAllSubRecord(const uint256& txid, int subRecordNumber, uint32_t propertyId, int64_t nValue)
{
std::string strKey = strprintf("%s-%d", txid.ToString(), subRecordNumber);
std::string strValue = strprintf("%d:%d", propertyId, nValue);

leveldb::Status status = pdb->Put(writeoptions, strKey, strValue);
++nWritten;
if (msc_debug_txdb) PrintToLog("%s(): store: %s=%s, status: %s\n", __func__, strKey, strValue, status.ToString());
}

void CMPTxList::recordPaymentTX(const uint256 &txid, bool fValid, int nBlock, unsigned int vout, unsigned int propertyId, uint64_t nValue, string buyer, string seller)
{
if (!pdb) return;
Expand Down
9 changes: 8 additions & 1 deletion src/omnicore/omnicore.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ enum TransactionType {
MSC_TYPE_SIMPLE_SEND = 0,
MSC_TYPE_RESTRICTED_SEND = 2,
MSC_TYPE_SEND_TO_OWNERS = 3,
MSC_TYPE_SEND_ALL = 4,
MSC_TYPE_SAVINGS_MARK = 10,
MSC_TYPE_SAVINGS_COMPROMISED = 11,
MSC_TYPE_RATELIMITED_MARK = 12,
Expand Down Expand Up @@ -123,6 +124,7 @@ enum FILETYPES {
#define PKT_ERROR_METADEX (-80000)
#define METADEX_ERROR (-81000)
#define PKT_ERROR_TOKENS (-82000)
#define PKT_ERROR_SEND_ALL (-83000)

#define OMNI_PROPERTY_BTC 0
#define OMNI_PROPERTY_MSC 1
Expand Down Expand Up @@ -222,12 +224,17 @@ class CMPTxList : public CDBBase
void recordTX(const uint256 &txid, bool fValid, int nBlock, unsigned int type, uint64_t nValue);
void recordPaymentTX(const uint256 &txid, bool fValid, int nBlock, unsigned int vout, unsigned int propertyId, uint64_t nValue, string buyer, string seller);
void recordMetaDExCancelTX(const uint256 &txidMaster, const uint256 &txidSub, bool fValid, int nBlock, unsigned int propertyId, uint64_t nValue);
/** Records a "send all" sub record. */
void recordSendAllSubRecord(const uint256& txid, int subRecordNumber, uint32_t propertyId, int64_t nvalue);

string getKeyValue(string key);
uint256 findMetaDExCancel(const uint256 txid);
int getNumberOfPurchases(const uint256 txid);
/** Returns the number of sub records. */
int getNumberOfSubRecords(const uint256& txid);
int getNumberOfMetaDExCancels(const uint256 txid);
bool getPurchaseDetails(const uint256 txid, int purchaseNumber, string *buyer, string *seller, uint64_t *vout, uint64_t *propertyId, uint64_t *nValue);
/** Retrieves details about a "send all" record. */
bool getSendAllDetails(const uint256& txid, int subSend, uint32_t& propertyId, int64_t& amount);
int getMPTransactionCountTotal();
int getMPTransactionCountBlock(int block);

Expand Down
59 changes: 57 additions & 2 deletions src/omnicore/rpctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Value omni_send(const Array& params, bool fHelp)
"2. toaddress (string, required) the address of the receiver\n"
"3. propertyid (number, required) the identifier of the tokens to send\n"
"4. amount (string, required) the amount to send\n"
"5. redeemaddress (string, optional) an address that can spent the transaction dust (sender by default)\n"
"5. redeemaddress (string, optional) an address that can spend the transaction dust (sender by default)\n"
"6. referenceamount (string, optional) a bitcoin amount that is sent to the receiver (minimal by default)\n"

"\nResult:\n"
Expand Down Expand Up @@ -93,6 +93,61 @@ Value omni_send(const Array& params, bool fHelp)
}
}

// omni_sendall - send all
Value omni_sendall(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 3 || params.size() > 5)
throw runtime_error(
"omni_sendall \"fromaddress\" \"toaddress\" ecosystem ( \"redeemaddress\" \"referenceamount\" )\n"

"\nTransfers all available tokens in the given ecosystem to the recipient.\n"

"\nArguments:\n"
"1. fromaddress (string, required) the address to send from\n"
"2. toaddress (string, required) the address of the receiver\n"
"3. ecosystem (number, required) the ecosystem of the tokens to send: (1) main, (2) test\n"
"4. redeemaddress (string, optional) an address that can spend the transaction dust (sender by default)\n"
"5. referenceamount (string, optional) a bitcoin amount that is sent to the receiver (minimal by default)\n"

"\nResult:\n"
"\"hash\" (string) the hex-encoded transaction hash\n"

"\nExamples:\n"
+ HelpExampleCli("omni_sendall", "\"3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY\" \"37FaKponF7zqoMLUjEiko25pDiuVH5YLEa\" 2")
+ HelpExampleRpc("omni_sendall", "\"3M9qvHKtgARhqcMtM5cRT9VaiDJ5PSfQGY\", \"37FaKponF7zqoMLUjEiko25pDiuVH5YLEa\" 2")
);

// obtain parameters & info
std::string fromAddress = ParseAddress(params[0]);
std::string toAddress = ParseAddress(params[1]);
uint8_t ecosystem = ParseEcosystem(params[2]);
std::string redeemAddress = (params.size() > 3 && !ParseText(params[3]).empty()) ? ParseAddress(params[3]): "";
int64_t referenceAmount = (params.size() > 4) ? ParseAmount(params[4], true): 0;

// perform checks
RequireSaneReferenceAmount(referenceAmount);

// create a payload for the transaction
std::vector<unsigned char> payload = CreatePayload_SendAll(ecosystem);

// request the wallet build the transaction (and if needed commit it)
uint256 txid;
std::string rawHex;
int result = ClassAgnosticWalletTXBuilder(fromAddress, toAddress, redeemAddress, referenceAmount, payload, txid, rawHex, autoCommit);

// check error and return the txid (or raw hex depending on autocommit)
if (result != 0) {
throw JSONRPCError(result, error_str(result));
} else {
if (!autoCommit) {
return rawHex;
} else {
// TODO: pending
return txid.GetHex();
}
}
}

// omni_senddexsell - DEx sell offer
Value omni_senddexsell(const Array& params, bool fHelp)
{
Expand Down Expand Up @@ -480,7 +535,7 @@ Value omni_sendsto(const Array& params, bool fHelp)
"1. fromaddress (string, required) the address to send from\n"
"2. propertyid (number, required) the identifier of the tokens to distribute\n"
"3. amount (string, required) the amount to distribute\n"
"4. redeemaddress (string, optional) an address that can spent the transaction dust (sender by default)\n"
"4. redeemaddress (string, optional) an address that can spend the transaction dust (sender by default)\n"

"\nResult:\n"
"\"hash\" (string) the hex-encoded transaction hash\n"
Expand Down
44 changes: 43 additions & 1 deletion src/omnicore/rpctxobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ void populateRPCTypeInfo(CMPTransaction& mp_obj, Object& txobj, uint32_t txType,
case MSC_TYPE_SEND_TO_OWNERS:
populateRPCTypeSendToOwners(mp_obj, txobj, extendedDetails, extendedDetailsFilter);
break;
case MSC_TYPE_SEND_ALL:
populateRPCTypeSendAll(mp_obj, txobj);
break;
case MSC_TYPE_TRADE_OFFER:
populateRPCTypeTradeOffer(mp_obj, txobj);
break;
Expand Down Expand Up @@ -201,6 +204,7 @@ bool showRefForTx(uint32_t txType)
case MSC_TYPE_GRANT_PROPERTY_TOKENS: return true;
case MSC_TYPE_REVOKE_PROPERTY_TOKENS: return false;
case MSC_TYPE_CHANGE_ISSUER_ADDRESS: return true;
case MSC_TYPE_SEND_ALL: return true;
}
return true; // default to true, shouldn't be needed but just in case
}
Expand Down Expand Up @@ -243,6 +247,14 @@ void populateRPCTypeSendToOwners(CMPTransaction& omniObj, Object& txobj, bool ex
if (extendedDetails) populateRPCExtendedTypeSendToOwners(omniObj.getHash(), extendedDetailsFilter, txobj);
}

void populateRPCTypeSendAll(CMPTransaction& omniObj, Object& txobj)
{
Array subSends;
if (omniObj.getEcosystem() == 1) txobj.push_back(Pair("ecosystem", "main"));
if (omniObj.getEcosystem() == 2) txobj.push_back(Pair("ecosystem", "test"));
if (populateRPCSendAllSubSends(omniObj.getHash(), subSends) > 0) txobj.push_back(Pair("subsends", subSends));
}

void populateRPCTypeTradeOffer(CMPTransaction& omniObj, Object& txobj)
{
CMPOffer temp_offer(omniObj);
Expand Down Expand Up @@ -519,6 +531,36 @@ void populateRPCExtendedTypeMetaDExCancel(const uint256& txid, Object& txobj)
txobj.push_back(Pair("cancelledtransactions", cancelArray));
}

/* Function to enumerate sub sends for a given txid and add to supplied JSON array
* Note: this function exists as send all has the potential to carry multiple sends in a single transaction.
*/
int populateRPCSendAllSubSends(const uint256& txid, Array& subSends)
{
int numberOfSubSends = 0;
{
LOCK(cs_tally);
numberOfSubSends = p_txlistdb->getNumberOfSubRecords(txid);
}
if (numberOfSubSends <= 0) {
PrintToLog("TXLISTDB Error: Transaction %s parsed as a send all but could not locate sub sends in txlistdb.\n", txid.GetHex());
return -1;
}
for (int subSend = 1; subSend <= numberOfSubSends; subSend++) {
Object subSendObj;
uint32_t propertyId;
int64_t amount;
{
LOCK(cs_tally);
p_txlistdb->getSendAllDetails(txid, subSend, propertyId, amount);
}
subSendObj.push_back(Pair("propertyid", (uint64_t)propertyId));
subSendObj.push_back(Pair("divisible", isPropertyDivisible(propertyId)));
subSendObj.push_back(Pair("amount", FormatMP(propertyId, amount)));
subSends.push_back(subSendObj);
}
return subSends.size();
}

/* Function to enumerate DEx purchases for a given txid and add to supplied JSON array
* Note: this function exists as it is feasible for a single transaction to carry multiple outputs
* and thus make multiple purchases from a single transaction
Expand All @@ -528,7 +570,7 @@ int populateRPCDExPurchases(const CTransaction& wtx, Array& purchases, std::stri
int numberOfPurchases = 0;
{
LOCK(cs_tally);
numberOfPurchases = p_txlistdb->getNumberOfPurchases(wtx.GetHash());
numberOfPurchases = p_txlistdb->getNumberOfSubRecords(wtx.GetHash());
}
if (numberOfPurchases <= 0) {
PrintToLog("TXLISTDB Error: Transaction %s parsed as a DEx payment but could not locate purchases in txlistdb.\n", wtx.GetHash().GetHex());
Expand Down
3 changes: 3 additions & 0 deletions src/omnicore/rpctxobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ void populateRPCTypeInfo(CMPTransaction& mp_obj, json_spirit::Object& txobj, uin

void populateRPCTypeSimpleSend(CMPTransaction& omniObj, json_spirit::Object& txobj);
void populateRPCTypeSendToOwners(CMPTransaction& omniObj, json_spirit::Object& txobj, bool extendedDetails, std::string extendedDetailsFilter);
void populateRPCTypeSendAll(CMPTransaction& omniObj, json_spirit::Object& txobj);
void populateRPCTypeTradeOffer(CMPTransaction& omniObj, json_spirit::Object& txobj);
void populateRPCTypeMetaDExTrade(CMPTransaction& omniObj, json_spirit::Object& txobj, bool extendedDetails);
void populateRPCTypeMetaDExCancelPrice(CMPTransaction& omniObj, json_spirit::Object& txobj, bool extendedDetails);
Expand All @@ -33,6 +34,8 @@ void populateRPCExtendedTypeMetaDExTrade(const uint256& txid, uint32_t propertyI
void populateRPCExtendedTypeMetaDExCancel(const uint256& txid, json_spirit::Object& txobj);

int populateRPCDExPurchases(const CTransaction& wtx, json_spirit::Array& purchases, std::string filterAddress);
int populateRPCSendAllSubSends(const uint256& txid, json_spirit::Array& subSends);

bool showRefForTx(uint32_t txType);

#endif // OMNICORE_RPCTXOBJECT_H
Loading