Compare commits

...

5 Commits

@ -425,7 +425,7 @@ set(neroshop_price_src
set(neroshop_protocol_src
${NEROSHOP_CORE_SRC_DIR}/protocol/messages/msgpack.cpp
${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/mapper.cpp
${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/key_mapper.cpp
${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/node.cpp
${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/routing_table.cpp
${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/serializer.cpp
@ -480,7 +480,7 @@ endif()
######################################
# neroshop-daemon
set(daemon_executable "neromon")
set(daemon_src ${neroshop_crypto_src} ${neroshop_database_src} ${neroshop_network_src} ${NEROSHOP_CORE_SRC_DIR}/protocol/messages/msgpack.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/mapper.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/node.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/routing_table.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/rpc/json_rpc.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/client.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/ip_address.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/server.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/zmq_client.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/zmq_server.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/base64.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/logger.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/timestamp.cpp)
set(daemon_src ${neroshop_crypto_src} ${neroshop_database_src} ${neroshop_network_src} ${NEROSHOP_CORE_SRC_DIR}/protocol/messages/msgpack.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/key_mapper.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/node.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/p2p/routing_table.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/rpc/json_rpc.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/client.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/ip_address.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/server.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/zmq_client.cpp ${NEROSHOP_CORE_SRC_DIR}/protocol/transport/zmq_server.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/base64.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/logger.cpp ${NEROSHOP_CORE_SRC_DIR}/tools/timestamp.cpp)
add_executable(${daemon_executable} src/daemon/main.cpp ${daemon_src})#target_link_libraries(daemon ${curl_src} ${OPENSSL_LIBRARIES}) # curl requires both openssl(used in monero) and zlib(used in libi2pd)
install(TARGETS ${daemon_executable} DESTINATION bin)
target_compile_definitions(${daemon_executable} PRIVATE NEROSHOP_DEBUG)

@ -13,7 +13,7 @@ NeroShop is a decentralized peer-to-peer marketplace for trading goods and servi
## Table of contents
<!-- - [The history behind neroshop](#about)-->
- [Demo](#demo)
- [Feature Status](#feature-status) <!-- - [Documentation](#documentation)-->
- [Project Status](#project-status) <!-- - [Documentation](#documentation)-->
- [Building neroshop](#building-neroshop)
- [Dependencies](#dependencies)
- [Compiling neroshop from source](#compiling-neroshop-from-source)
@ -54,31 +54,9 @@ NeroShop is a decentralized peer-to-peer marketplace for trading goods and servi
</details>
## Feature Status
- [ ] Distributed P2P network (urgently seeking assistance with I2P integration/NAT traversal!!!)
- [ ] Buy and sell products and services with Monero
- [x] No KYC
- [x] No censorship (censorship-resistant)
- [ ] No listing fees, sales tax, or any other fees (except for miner transaction fees and shipping costs)
- there will be 0.5% fee for using one of the three payment options (specifically the 2-of-3 escrow system).
This is to incentivize arbitrators (who are chosen from sellers with the highest reputation) for disputing 2/3 escrow transactions.
- [x] Pseudonymous identities
- sellers and buyers are identified by their unique id (monero primary address) and optional display name
- [x] End-to-end encrypted messaging system for communications between sellers and buyers
- generated RSA-4096 private keys will be used to decrypt messages.
- [ ] Subaddress generator for direct payments without an escrow
- a unique subaddress will be generated from a seller's synced wallet account for each order placed by a customer
- [x] Built-in Monero wallet with basic functionalities (`transaction history`, `send`, and `receive`)
- [x] Option to run a local Monero node or connect to remote Monero nodes
- [ ] Payment address QR codes containing Monero URIs
- [ ] Option to choose between sending funds directly to a seller or by using a multisignature escrow.
- [ ] Native I2P support
- i2pd will be built-in (statically linked)
- [x] Seller reputation system
- [x] Product rating system (GUI Integration Pending)
- [x] Wishlists (GUI Integration Pending)
- [x] Built-in SQLite-powered search engine that can find any listing or seller
- [ ] Full-featured and user-friendly GUI application (WIP)
## Project Status
https://gist.github.com/layters/83efdef0c5ea3d8ff458bfc312d11be3
## Building neroshop
@ -233,11 +211,11 @@ See [Wiki](https://github.com/layters/testshop/wiki/Contributing)
## License
This project is licensed under the [GNU General Public License v3.0 (GPLv3)](LICENSE)
This project is licensed under the [GNU General Public License v3.0](LICENSE)
## Donations
~~Donate if you like, to any of the addresses below. Received payments will be used to reward developers for completing bounties and will also be used to keep the `neroshop.org` domain up and running.~~
Donate if you like, to any of the addresses below. Received payments will be used to reward developers for completing bounties and will also be used to keep the `neroshop.org` domain up and running.
**Monero (XMR):**
```
@ -278,17 +256,15 @@ WW2pQTQWHpyJf2CHrCmZG7Tn3zBnYRZTH8g4U3pSZf5s6xsTXrZc9odDWmrWzjRc9MMQWrKXxjHsRdzH
## Thanks
```
u/EchoingCat — for the revision of the official neroshop logo
* [u/EchoingCat](https://www.reddit.com/user/EchoingCat/) — for the revision of the official neroshop logo
woodser — for his guidance and for his work on the monero-cpp library which has made the development of this app possible
* [woodser](https://github.com/woodser) — for his guidance and for his work on the monero-cpp library which has made the development of this app possible
yuriio147 — for his work on various QML components, the currency converter, wallet address qr provider, fixing a major bug in the RSA encryption code, the RSA signing and verifying functions, and for teaching me some Qt/QML techniques
* [yuriio147](https://github.com/yuriio147) — for his work on various QML components, the currency converter, wallet address qr provider, fixing a major bug in the RSA encryption code, the RSA signing and verifying functions, and for teaching me some Qt/QML techniques
lza_menace — for creating the new monero.fail JSON API endpoint
* [lza_menace](https://twitter.com/lza_menace) — for creating the new monero.fail JSON API endpoint
everyone in our matrix room — for sharing many great ideas that have been useful to the project
```
* everyone in our matrix room — for sharing many great ideas that have been useful to the project
[//]: # (./clean.sh)
[//]: # (git checkout -b main)

@ -1,4 +1,4 @@
#include "mapper.hpp"
#include "key_mapper.hpp"
#include <nlohmann/json.hpp>
@ -10,7 +10,7 @@ namespace neroshop_string = neroshop::string;
//-----------------------------------------------------------------------------
neroshop::Mapper::~Mapper() {
neroshop::KeyMapper::~KeyMapper() {
product_ids.clear();
product_names.clear();
product_categories.clear();
@ -29,7 +29,7 @@ neroshop::Mapper::~Mapper() {
//-----------------------------------------------------------------------------
void neroshop::Mapper::add(const std::string& key, const std::string& value) {
void neroshop::KeyMapper::add(const std::string& key, const std::string& value) {
nlohmann::json json;
try {
json = nlohmann::json::parse(value);
@ -160,7 +160,7 @@ void neroshop::Mapper::add(const std::string& key, const std::string& value) {
sync(); // Sync to database
}
void neroshop::Mapper::sync() {
void neroshop::KeyMapper::sync() {
db::Sqlite3 * database = neroshop::get_database();
if(!database) throw std::runtime_error("database is NULL");
@ -457,7 +457,7 @@ void neroshop::Mapper::sync() {
//-----------------------------------------------------------------------------
std::pair<std::string, std::string> neroshop::Mapper::serialize() { // no longer in use
std::pair<std::string, std::string> neroshop::KeyMapper::serialize() { // no longer in use
nlohmann::json data;
//-----------------------------------------------
// Add user_ids
@ -610,7 +610,7 @@ std::pair<std::string, std::string> neroshop::Mapper::serialize() { // no longer
//-----------------------------------------------------------------------------
std::vector<std::string> neroshop::Mapper::search_product_by_name(const std::string& product_name) {
std::vector<std::string> neroshop::KeyMapper::search_product_by_name(const std::string& product_name) {
std::vector<std::string> matching_keys;
std::string product_name_lower = neroshop_string::lower(product_name);
@ -632,13 +632,13 @@ std::vector<std::string> neroshop::Mapper::search_product_by_name(const std::str
//-----------------------------------------------------------------------------
/*int main() {
neroshop::Mapper::product_names.insert(std::make_pair("Apple", std::vector<std::string>{"9341dd5ebbe0d457e1306bdb68f2cd13a0d3bac4e582012ae71c2bce47f8bb91"}));
neroshop::Mapper::product_names.insert(std::make_pair("Banana", std::vector<std::string>{"8063ed324ad571c0278a1d5d11b5d620a41e605d389e2ad7f268c196f7411035"}));
neroshop::Mapper::product_names.emplace(std::make_pair("Cherry", std::vector<std::string>{"f246efebbca8d633d2d9ce15ffd0ffeb6aabeddf19cdc060fe348c282e371b7a"}));
neroshop::Mapper::product_names.insert(std::make_pair("Watermelon", std::vector<std::string>{"0fe3907f0c4012aa9967e2dac81ef31c008ebf2b58f36e107c0c9bd61ba9d53e"}));
//neroshop::Mapper::product_names.insert(std::make_pair("", std::vector<std::string>{""}));
std::cout << "Number of products: " << neroshop::Mapper::product_names.size() << "\n";
auto products = neroshop::Mapper::search_product_by_name("er");//("ana");//("app");//"ban");
neroshop::KeyMapper::product_names.insert(std::make_pair("Apple", std::vector<std::string>{"9341dd5ebbe0d457e1306bdb68f2cd13a0d3bac4e582012ae71c2bce47f8bb91"}));
neroshop::KeyMapper::product_names.insert(std::make_pair("Banana", std::vector<std::string>{"8063ed324ad571c0278a1d5d11b5d620a41e605d389e2ad7f268c196f7411035"}));
neroshop::KeyMapper::product_names.emplace(std::make_pair("Cherry", std::vector<std::string>{"f246efebbca8d633d2d9ce15ffd0ffeb6aabeddf19cdc060fe348c282e371b7a"}));
neroshop::KeyMapper::product_names.insert(std::make_pair("Watermelon", std::vector<std::string>{"0fe3907f0c4012aa9967e2dac81ef31c008ebf2b58f36e107c0c9bd61ba9d53e"}));
//neroshop::KeyMapper::product_names.insert(std::make_pair("", std::vector<std::string>{""}));
std::cout << "Number of products: " << neroshop::KeyMapper::product_names.size() << "\n";
auto products = neroshop::KeyMapper::search_product_by_name("er");//("ana");//("app");//"ban");
for(const auto& name : products) {
std::cout << name << "\n";
}

@ -8,9 +8,9 @@
namespace neroshop {
struct Mapper { // maps search terms to DHT keys
Mapper() = default;
~Mapper();
struct KeyMapper { // maps search terms to DHT keys
KeyMapper() = default;
~KeyMapper();
std::unordered_map<std::string, std::vector<std::string>> product_ids;
std::unordered_map<std::string, std::vector<std::string>> product_names; // maps a product name to a list of corresponding listing keys

@ -8,7 +8,7 @@
#include "../messages/msgpack.hpp"
#include "../../version.hpp"
#include "../../tools/base64.hpp"
#include "mapper.hpp"
#include "key_mapper.hpp"
#include "../../tools/string.hpp"
#include "../../tools/timestamp.hpp"
#include "../../database/database.hpp"
@ -162,7 +162,7 @@ neroshop::Node::Node(const std::string& address, int port, bool local) : sockfd(
// Initialize key mapper
if(!key_mapper.get()) {
key_mapper = std::make_unique<Mapper>();
key_mapper = std::make_unique<KeyMapper>();
}
}
@ -204,32 +204,26 @@ std::string neroshop::Node::generate_node_id(const std::string& address, int por
//-----------------------------------------------------------------------------
// Define the list of bootstrap nodes
std::vector<neroshop::Peer> bootstrap_nodes = {
{"node.neroshop.org", NEROSHOP_P2P_DEFAULT_PORT},
////{"127.0.0.1", NEROSHOP_P2P_DEFAULT_PORT}, // Uncomment to test on local network (you are allowed to create multiple separate daemon instances too)
};
void neroshop::Node::join() {
if(sockfd < 0) throw std::runtime_error("socket is dead");
// Bootstrap the DHT node with a set of known nodes
for (const auto& bootstrap_node : bootstrap_nodes) {
std::cout << "\033[35;1mJoining bootstrap node - " << bootstrap_node.address << ":" << bootstrap_node.port << "\033[0m\n";
for (const auto& bootstrap_node : BOOTSTRAP_NODES) {
std::cout << "\033[35;1mJoining bootstrap node - " << bootstrap_node.first << ":" << bootstrap_node.second << "\033[0m\n";
// Ping each known node to confirm that it is online - the main bootstrapping primitive. If a node replies, and if there is space in the routing table, it will be inserted.
if(!ping(bootstrap_node.address, bootstrap_node.port)) {
if(!ping(bootstrap_node.first, bootstrap_node.second)) {
std::cerr << "ping: failed to ping bootstrap node\n"; continue;
}
// Add the bootstrap node to routing table (optional)
auto seed_node = std::make_unique<Node>((bootstrap_node.address == "127.0.0.1") ? this->public_ip_address : bootstrap_node.address, bootstrap_node.port, false);
auto seed_node = std::make_unique<Node>((bootstrap_node.first == "127.0.0.1") ? this->public_ip_address : bootstrap_node.first, bootstrap_node.second, false);
seed_node->set_bootstrap(true);
Node& seed_node_ref = *seed_node; // take a reference to the Node object (to avoid segfault)
//routing_table->add_node(std::move(seed_node)); // seed_node becomes invalid after we move ownership to routing table so it cannot be used
// Send a "find_node" message to the bootstrap node and wait for a response message
auto nodes = send_find_node(this->id, (bootstrap_node.address == "127.0.0.1") ? "127.0.0.1" : seed_node_ref.get_ip_address(), seed_node_ref.get_port());//std::cout << "Sending find_node message to " << seed_node_ref.get_ip_address() << ":" << seed_node_ref.get_port() << "\n";
auto nodes = send_find_node(this->id, (bootstrap_node.first == "127.0.0.1") ? "127.0.0.1" : seed_node_ref.get_ip_address(), seed_node_ref.get_port());//std::cout << "Sending find_node message to " << seed_node_ref.get_ip_address() << ":" << seed_node_ref.get_port() << "\n";
if(nodes.empty()) {
std::cerr << "find_node: No nodes found\n"; continue;
}
@ -1568,8 +1562,8 @@ bool neroshop::Node::has_value(const std::string& value) const {
}
bool neroshop::Node::is_hardcoded(const std::string& address, uint16_t port) {
for (const auto& bootstrap_node : bootstrap_nodes) {
if (neroshop::ip::resolve(bootstrap_node.address) == address && bootstrap_node.port == port) {
for (const auto& bootstrap_node : BOOTSTRAP_NODES) {
if (neroshop::ip::resolve(bootstrap_node.first) == address && bootstrap_node.second == port) {
return true;
}
}
@ -1577,16 +1571,16 @@ bool neroshop::Node::is_hardcoded(const std::string& address, uint16_t port) {
}
bool neroshop::Node::is_hardcoded() const {
for (const auto& bootstrap_node : bootstrap_nodes) {
auto bootstrap_node_ip = neroshop::ip::resolve(bootstrap_node.address);
for (const auto& bootstrap_node : BOOTSTRAP_NODES) {
auto bootstrap_node_ip = neroshop::ip::resolve(bootstrap_node.first);
if (bootstrap_node_ip == this->public_ip_address
&& bootstrap_node.port == this->get_port()) {
&& bootstrap_node.second == this->get_port()) {
return true;
}
if((bootstrap_node_ip == "127.0.0.1" || bootstrap_node_ip == "0.0.0.0")
&& bootstrap_node.port == NEROSHOP_P2P_DEFAULT_PORT
&& bootstrap_node.port == this->get_port()) { // For testing on localhost. Remove this soon!!
&& bootstrap_node.second == NEROSHOP_P2P_DEFAULT_PORT
&& bootstrap_node.second == this->get_port()) { // For testing on localhost. Remove this soon!!
return true;
}
}

@ -15,7 +15,7 @@ const int NUM_BITS = 256;
namespace neroshop {
class RoutingTable; // forward declaration
class Mapper;
class KeyMapper;
struct Peer {
std::string address;
@ -44,7 +44,7 @@ private:
// Declare a mutex to protect access to the routing table
std::shared_mutex node_read_mutex; // Shared mutex for routing table access
std::shared_mutex node_write_mutex; // Shared mutex for routing table access
std::unique_ptr<Mapper> key_mapper;
std::unique_ptr<KeyMapper> key_mapper;
// Generates a node id from address and port combination
std::string generate_node_id(const std::string& address, int port);
// Determines if node1 is closer to the target_id than node2

@ -33,7 +33,7 @@
// protocol
#include "core/protocol/messages/msgpack.hpp"
#include "core/protocol/p2p/kademlia.hpp"
#include "core/protocol/p2p/mapper.hpp"
#include "core/protocol/p2p/key_mapper.hpp"
#include "core/protocol/p2p/node.hpp"
#include "core/protocol/p2p/routing_table.hpp"
#include "core/protocol/p2p/serializer.hpp"

@ -10,6 +10,7 @@
#include <cstdint>
#include <initializer_list>
#include <string>
#include <utility> // std::pair
#if defined(NEROSHOP_USE_QT)
#include <QStandardPaths>
@ -111,11 +112,9 @@
#endif // endif NOT NEROSHOP_USE_QT
namespace neroshop {
//TODO Add here your network seed or bootstrap nodes
const std::initializer_list<std::string> BOOTSTRAP_NODES = {
"node.neroshop.org:" + std::to_string(NEROSHOP_P2P_DEFAULT_PORT),
//"your_seed_ip1.com:8080",
//"your_seed_ip2.com:8080",
const std::initializer_list<std::pair<std::string, uint16_t>> BOOTSTRAP_NODES = {
{"node.neroshop.org", NEROSHOP_P2P_DEFAULT_PORT},
};
}

Loading…
Cancel
Save