Skip to content
Permalink
Browse files

v0.2.2

  • Loading branch information...
RocksteadyTC committed Jan 1, 2018
1 parent f81303d commit 9752ee48d919bf2faccc2e23ec3daf179c608b3e
@@ -0,0 +1,2 @@
.git* export-ignore
/CMakeLists.txt export-subst
@@ -0,0 +1,8 @@
.DS_Store
/build
/tags
.idea
.ycm_extra_conf.py
.ycm_extra_conf.pyc
Release
Debug
@@ -72,19 +72,6 @@ struct WalletEvent {
};
};

struct WalletOutput {
// output info
uint8_t type;
uint64_t amount;
uint32_t globalOutputIndex;
uint32_t outputInTransaction;

// transaction info
std::string transactionHash;
std::string transactionPublicKey;
std::string outputKey; // Type: Key
};

struct WalletTransaction {
WalletTransactionState state;
uint64_t timestamp;
@@ -164,7 +151,6 @@ class IWallet {
virtual std::string createAddress(const Crypto::SecretKey& spendSecretKey) = 0;
virtual std::string createAddress(const Crypto::PublicKey& spendPublicKey) = 0;
virtual std::vector<std::string> createAddressList(const std::vector<Crypto::SecretKey>& spendSecretKeys) = 0;
virtual std::vector<WalletOutput> getAddressOutputs(const std::string& address) const = 0;
virtual void deleteAddress(const std::string& address) = 0;

virtual uint64_t getActualBalance() const = 0;
@@ -120,15 +120,16 @@ const uint64_t P2P_DEFAULT_INVOKE_TIMEOUT = 60 * 2 * 1000; //
const size_t P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT = 5000; // 5 seconds
const char P2P_STAT_TRUSTED_PUB_KEY[] = "";

const char* const SEED_NODES[] = { "104.236.227.176:11897", "104.236.55.84:11897", "163.172.147.52:11897", "51.15.138.214:11897", "51.15.137.77" };
const char* const SEED_NODES[] = { "104.236.227.176:11897", "104.236.55.84:11897", "163.172.147.52:11897", "51.15.138.214:11897", "51.15.137.77:11897" };


struct CheckpointData {
uint32_t index;
const char* blockId;
};

const std::initializer_list<CheckpointData> CHECKPOINTS = { };
const std::initializer_list<CheckpointData> CHECKPOINTS = { {50000, "dd40ba6a33e7c6ff84927d510881e285eba9a17cbde43da587aa6cc41883b852"}
};

} // CryptoNote

@@ -1200,7 +1200,7 @@ std::error_code Core::validateTransaction(const CachedTransaction& cachedTransac
IBlockchainCache* cache, uint64_t& fee, uint32_t blockIndex) {
// TransactionValidatorState currentState;
const auto& transaction = cachedTransaction.getTransaction();
auto error = validateSemantic(transaction, fee);
auto error = validateSemantic(transaction, fee, blockIndex);
if (error != error::TransactionValidationError::VALIDATION_SUCCESS) {
return error;
}
@@ -1257,7 +1257,7 @@ std::error_code Core::validateTransaction(const CachedTransaction& cachedTransac
return error::TransactionValidationError::VALIDATION_SUCCESS;
}

std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& fee) {
std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t& fee, uint32_t blockIndex) {
if (transaction.inputs.empty()) {
return error::TransactionValidationError::EMPTY_INPUTS;
}
@@ -1283,6 +1283,11 @@ std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t&
summaryOutputAmount += output.amount;
}

// parameters used for the additional key_image check
static const Crypto::KeyImage Z = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
static const Crypto::KeyImage I = { {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } };
static const Crypto::KeyImage L = { {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 } };

uint64_t summaryInputAmount = 0;
std::unordered_set<Crypto::KeyImage> ki;
std::set<std::pair<uint64_t, uint32_t>> outputsUsage;
@@ -1301,6 +1306,11 @@ std::error_code Core::validateSemantic(const Transaction& transaction, uint64_t&

// outputIndexes are packed here, first is absolute, others are offsets to previous,
// so first can be zero, others can't
// Fix discovered by Monero Lab and suggested by "fluffypony" (bitcointalk.org)
if (!(scalarmultKey(in.keyImage, L) == I) && blockIndex > parameters::KEY_IMAGE_CHECKING_BLOCK_INDEX) {
return error::TransactionValidationError::INPUT_INVALID_DOMAIN_KEYIMAGES;
}

if (std::find(++std::begin(in.outputIndexes), std::end(in.outputIndexes), 0) != std::end(in.outputIndexes)) {
return error::TransactionValidationError::INPUT_IDENTICAL_OUTPUT_INDEXES;
}
@@ -142,7 +142,7 @@ class Core : public ICore, public ICoreInformation {
void throwIfNotInitialized() const;
bool extractTransactions(const std::vector<BinaryArray>& rawTransactions, std::vector<CachedTransaction>& transactions, uint64_t& cumulativeSize);

std::error_code validateSemantic(const Transaction& transaction, uint64_t& fee);
std::error_code validateSemantic(const Transaction& transaction, uint64_t& fee, uint32_t blockIndex);
std::error_code validateTransaction(const CachedTransaction& transaction, TransactionValidatorState& state, IBlockchainCache* cache, uint64_t& fee, uint32_t blockIndex);

uint32_t findBlockchainSupplement(const std::vector<Crypto::Hash>& remoteBlockIds) const;
@@ -533,6 +533,7 @@ m_moneySupply(currency.m_moneySupply),
m_emissionSpeedFactor(currency.m_emissionSpeedFactor),
m_rewardBlocksWindow(currency.m_rewardBlocksWindow),
m_blockGrantedFullRewardZone(currency.m_blockGrantedFullRewardZone),
m_isBlockexplorer(currency.m_isBlockexplorer),
m_minerTxBlobReservedSize(currency.m_minerTxBlobReservedSize),
m_numberOfDecimalPlaces(currency.m_numberOfDecimalPlaces),
m_coin(currency.m_coin),
@@ -620,6 +621,7 @@ genesisBlockReward(parameters::GENESIS_BLOCK_REWARD);
blockIndexesFileName(parameters::CRYPTONOTE_BLOCKINDEXES_FILENAME);
txPoolFileName(parameters::CRYPTONOTE_POOLDATA_FILENAME);

isBlockexplorer(false);
testnet(false);
}

@@ -91,6 +91,7 @@ class Currency {
const std::string& blockIndexesFileName() const { return m_blockIndexesFileName; }
const std::string& txPoolFileName() const { return m_txPoolFileName; }

bool isBlockexplorer() const { return m_isBlockexplorer; }
bool isTestnet() const { return m_testnet; }

const BlockTemplate& genesisBlock() const { return cachedGenesisBlock->getBlock(); }
@@ -192,6 +193,7 @@ class Currency {
static const std::vector<uint64_t> PRETTY_AMOUNTS;

bool m_testnet;
bool m_isBlockexplorer;

BlockTemplate genesisBlockTemplate;
std::unique_ptr<CachedBlock> cachedGenesisBlock;
@@ -267,6 +269,7 @@ class CurrencyBuilder : boost::noncopyable {
CurrencyBuilder& blockIndexesFileName(const std::string& val) { m_currency.m_blockIndexesFileName = val; return *this; }
CurrencyBuilder& txPoolFileName(const std::string& val) { m_currency.m_txPoolFileName = val; return *this; }

CurrencyBuilder& isBlockexplorer(const bool val) { m_currency.m_isBlockexplorer = val; return *this; }
CurrencyBuilder& testnet(bool val) { m_currency.m_testnet = val; return *this; }

private:
@@ -20,6 +20,7 @@
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <unordered_map>
#include <string>
@@ -28,6 +28,7 @@ enum class TransactionValidationError {
EMPTY_INPUTS,
INPUT_UNKNOWN_TYPE,
INPUT_EMPTY_OUTPUT_USAGE,
INPUT_INVALID_DOMAIN_KEYIMAGES,
INPUT_IDENTICAL_KEYIMAGES,
INPUT_IDENTICAL_OUTPUT_INDEXES,
INPUT_KEYIMAGE_ALREADY_SPENT,
@@ -69,6 +70,7 @@ class TransactionValidationErrorCategory : public std::error_category {
case TransactionValidationError::EMPTY_INPUTS: return "Transaction has no inputs";
case TransactionValidationError::INPUT_UNKNOWN_TYPE: return "Transaction has input with unknown type";
case TransactionValidationError::INPUT_EMPTY_OUTPUT_USAGE: return "Transaction's input uses empty output";
case TransactionValidationError::INPUT_INVALID_DOMAIN_KEYIMAGES: return "Transaction uses key image not in the valid domain";
case TransactionValidationError::INPUT_IDENTICAL_KEYIMAGES: return "Transaction has identical key images";
case TransactionValidationError::INPUT_IDENTICAL_OUTPUT_INDEXES: return "Transaction has identical output indexes";
case TransactionValidationError::INPUT_KEYIMAGE_ALREADY_SPENT: return "Transaction uses spent key image";
@@ -136,7 +136,7 @@ CryptoNoteProtocolHandler::CryptoNoteProtocolHandler(const Currency& currency, S
m_observedHeight(0),
m_peersCount(0),
logger(log, "protocol") {

if (!m_p2p) {
m_p2p = &m_p2p_stub;
}
@@ -181,7 +181,7 @@ void CryptoNoteProtocolHandler::onConnectionClosed(CryptoNoteConnectionContext&
void CryptoNoteProtocolHandler::stop() {
m_stop = true;
}

bool CryptoNoteProtocolHandler::start_sync(CryptoNoteConnectionContext& context) {
logger(Logging::TRACE) << context << "Starting synchronization";

@@ -356,7 +356,7 @@ int CryptoNoteProtocolHandler::handle_notify_new_transactions(int command, NOTIF

for (auto tx_blob_it = arg.txs.begin(); tx_blob_it != arg.txs.end();) {
if (!m_core.addTransactionToPool(*tx_blob_it)) {
logger(Logging::INFO) << context << "Tx verification failed";
logger(Logging::DEBUGGING) << context << "Tx verification failed";
tx_blob_it = arg.txs.erase(tx_blob_it);
} else {
++tx_blob_it;
@@ -564,7 +564,7 @@ bool CryptoNoteProtocolHandler::request_missing_objects(CryptoNoteConnectionCont
<< "\r\nm_last_response_height=" << context.m_last_response_height
<< "\r\nm_remote_blockchain_height=" << context.m_remote_blockchain_height
<< "\r\nm_needed_objects.size()=" << context.m_needed_objects.size()
<< "\r\nm_requested_objects.size()=" << context.m_requested_objects.size()
<< "\r\nm_requested_objects.size()=" << context.m_requested_objects.size()
<< "\r\non connection [" << context << "]";
return false;
}
@@ -689,7 +689,12 @@ void CryptoNoteProtocolHandler::updateObservedHeight(uint32_t peerHeight, const
std::lock_guard<std::mutex> lock(m_observedHeightMutex);

uint32_t height = m_observedHeight;
if (peerHeight > context.m_remote_blockchain_height) {
if (context.m_remote_blockchain_height != 0 && context.m_last_response_height <= context.m_remote_blockchain_height - 1) {
m_observedHeight = context.m_remote_blockchain_height - 1;
if (m_observedHeight != height) {
updated = true;
}
} else if (peerHeight > context.m_remote_blockchain_height) {
m_observedHeight = std::max(m_observedHeight, peerHeight);
if (m_observedHeight != height) {
updated = true;
@@ -719,6 +724,9 @@ void CryptoNoteProtocolHandler::recalculateMaxObservedHeight(const CryptoNoteCon
});

m_observedHeight = std::max(peerHeight, m_core.getTopBlockIndex() + 1);
if (context.m_state == CryptoNoteConnectionContext::state_normal) {
m_observedHeight = m_core.getTopBlockIndex();
}
}

uint32_t CryptoNoteProtocolHandler::getObservedHeight() const {
@@ -67,6 +67,7 @@ namespace
const command_line::arg_descriptor<bool> arg_console = {"no-console", "Disable daemon console commands"};
const command_line::arg_descriptor<bool> arg_print_genesis_tx = { "print-genesis-tx", "Prints genesis' block tx hex to insert it to config and exits" };
const command_line::arg_descriptor<std::vector<std::string>> arg_genesis_block_reward_address = { "genesis-block-reward-address", "" };
const command_line::arg_descriptor<bool> arg_blockexplorer_on = {"enable_blockexplorer", "Enable blockchain explorer RPC", false};
const command_line::arg_descriptor<std::vector<std::string>> arg_enable_cors = { "enable-cors", "Adds header 'Access-Control-Allow-Origin' to the daemon's RPC responses. Uses the value as domain. Use * for all" };
const command_line::arg_descriptor<bool> arg_testnet_on = {"testnet", "Used to deploy test nets. Checkpoints and hardcoded seeds are ignored, "
"network id is changed. Use it with --data-dir flag. The wallet must be launched with --testnet flag.", false};
@@ -77,6 +78,8 @@ void print_genesis_tx_hex(const po::variables_map& vm, LoggerManager& logManager
std::vector<CryptoNote::AccountPublicAddress> targets;
auto genesis_block_reward_addresses = command_line::get_arg(vm, arg_genesis_block_reward_address);
CryptoNote::CurrencyBuilder currencyBuilder(logManager);
bool blockexplorer_mode = command_line::get_arg(vm, arg_blockexplorer_on);
currencyBuilder.isBlockexplorer(blockexplorer_mode);
CryptoNote::Currency currency = currencyBuilder.currency();
for (const auto& address_string : genesis_block_reward_addresses) {
CryptoNote::AccountPublicAddress address;
@@ -149,6 +152,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_cmd_sett, arg_console);
command_line::add_arg(desc_cmd_sett, arg_testnet_on);
command_line::add_arg(desc_cmd_sett, arg_enable_cors);
command_line::add_arg(desc_cmd_sett, arg_blockexplorer_on);
command_line::add_arg(desc_cmd_sett, arg_print_genesis_tx);
command_line::add_arg(desc_cmd_sett, arg_genesis_block_reward_address);

@@ -227,6 +231,8 @@ command_line::add_arg(desc_cmd_sett, arg_print_genesis_tx);

//create objects and link them
CryptoNote::CurrencyBuilder currencyBuilder(logManager);
bool blockexplorer_mode = command_line::get_arg(vm, arg_blockexplorer_on);
currencyBuilder.isBlockexplorer(blockexplorer_mode);
currencyBuilder.testnet(testnet_mode);
try {
currencyBuilder.currency();
@@ -313,32 +313,6 @@ void SendDelayedTransaction::Request::serialize(CryptoNote::ISerializer& seriali
void SendDelayedTransaction::Response::serialize(CryptoNote::ISerializer& serializer) {
}

void GetUnspendOuts::Request::serialize(CryptoNote::ISerializer& serializer) {
if (!serializer(address, "address")) {
throw RequestSerializationError();
}

serializer(viewKey, "viewKey");
serializer(amount, "amount");
serializer(mixIn, "mixIn");
serializer(useDust, "useDust");
serializer(dustThreshold, "dustThreshold");
}

void GetUnspendOuts::Response::serialize(CryptoNote::ISerializer& serializer) {
serializer(outputs, "outputs");
}

void TransactionOutputInformationSerialized::serialize(CryptoNote::ISerializer& serializer) {
serializer(type, "type");
serializer(amount, "amount");
serializer(globalOutputIndex, "globalOutputIndex");
serializer(outputInTransaction, "outputInTransaction");
serializer(transactionHash, "transactionHash");
serializer(transactionPublicKey, "transactionPublicKey");
serializer(outputKey, "outputKey");
}

void SendFusionTransaction::Request::serialize(CryptoNote::ISerializer& serializer) {
if (!serializer(threshold, "threshold")) {
throw RequestSerializationError();
@@ -378,40 +378,6 @@ struct SendDelayedTransaction {
};
};

struct TransactionOutputInformationSerialized {
// output info
uint8_t type;
uint64_t amount;
uint32_t globalOutputIndex;
uint32_t outputInTransaction;

// transaction info
std::string transactionHash;
std::string transactionPublicKey;
std::string outputKey; // Type: Key

void serialize(CryptoNote::ISerializer& serializer);
};

struct GetUnspendOuts {
struct Request {
std::string address;
std::string viewKey;
uint64_t amount;
uint32_t mixIn;
bool useDust;
uint64_t dustThreshold;

void serialize(CryptoNote::ISerializer& serializer);
};

struct Response {
std::vector<TransactionOutputInformationSerialized> outputs;

void serialize(CryptoNote::ISerializer& serializer);
};
};

struct SendFusionTransaction {
struct Request {
uint64_t threshold;
@@ -53,7 +53,6 @@ PaymentServiceJsonRpcServer::PaymentServiceJsonRpcServer(System::Dispatcher& sys
handlers.emplace("getViewKey", jsonHandler<GetViewKey::Request, GetViewKey::Response>(std::bind(&PaymentServiceJsonRpcServer::handleGetViewKey, this, std::placeholders::_1, std::placeholders::_2)));
handlers.emplace("getStatus", jsonHandler<GetStatus::Request, GetStatus::Response>(std::bind(&PaymentServiceJsonRpcServer::handleGetStatus, this, std::placeholders::_1, std::placeholders::_2)));
handlers.emplace("getAddresses", jsonHandler<GetAddresses::Request, GetAddresses::Response>(std::bind(&PaymentServiceJsonRpcServer::handleGetAddresses, this, std::placeholders::_1, std::placeholders::_2)));
handlers.emplace("getUnspendOuts", jsonHandler<GetUnspendOuts::Request, GetUnspendOuts::Response>(std::bind(&PaymentServiceJsonRpcServer::handleGetUnspendOuts, this, std::placeholders::_1, std::placeholders::_2)));
handlers.emplace("sendFusionTransaction", jsonHandler<SendFusionTransaction::Request, SendFusionTransaction::Response>(std::bind(&PaymentServiceJsonRpcServer::handleSendFusionTransaction, this, std::placeholders::_1, std::placeholders::_2)));
handlers.emplace("estimateFusion", jsonHandler<EstimateFusion::Request, EstimateFusion::Response>(std::bind(&PaymentServiceJsonRpcServer::handleEstimateFusion, this, std::placeholders::_1, std::placeholders::_2)));
}
@@ -203,10 +202,6 @@ std::error_code PaymentServiceJsonRpcServer::handleGetAddresses(const GetAddress
return service.getAddresses(response.addresses);
}

std::error_code PaymentServiceJsonRpcServer::handleGetUnspendOuts(const GetUnspendOuts::Request& request, GetUnspendOuts::Response& response) {
return service.getUnspendOuts(request, response.outputs);
}

std::error_code PaymentServiceJsonRpcServer::handleSendFusionTransaction(const SendFusionTransaction::Request& request, SendFusionTransaction::Response& response) {
return service.sendFusionTransaction(request.threshold, request.anonymity, request.addresses, request.destinationAddress, response.transactionHash);
}
@@ -93,7 +93,6 @@ class PaymentServiceJsonRpcServer : public CryptoNote::JsonRpcServer {
std::error_code handleGetStatus(const GetStatus::Request& request, GetStatus::Response& response);
std::error_code handleGetAddresses(const GetAddresses::Request& request, GetAddresses::Response& response);

std::error_code handleGetUnspendOuts(const GetUnspendOuts::Request& request, GetUnspendOuts::Response& response);
std::error_code handleSendFusionTransaction(const SendFusionTransaction::Request& request, SendFusionTransaction::Response& response);
std::error_code handleEstimateFusion(const EstimateFusion::Request& request, EstimateFusion::Response& response);
};

0 comments on commit 9752ee4

Please sign in to comment.
You can’t perform that action at this time.