Skip to content

Commit

Permalink
miner and wallet nodes, commands for wallet node
Browse files Browse the repository at this point in the history
  • Loading branch information
aizuon committed May 7, 2021
1 parent e37d266 commit f7943ff
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 63 deletions.
65 changes: 36 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,58 @@ Windows 10 with Visual Studio 2019 for build environment and vcpkg for library m

## Quick start

- Run a miner instance
- Run a miner node
```
$ tiny-sandbox.exe --port 9901 --wallet miner.dat --mine
$ tiny-sandbox.exe --port 9901 --node_type miner --wallet miner.dat
[ 03:04:45 ] [ tc ] Generating new wallet miner.dat
[ 03:04:45 ] [ tc ] Your address is 172eJPtmt5wMq71bnT1fS55FYLHw1syhWB
[ 03:04:47 ] [ tc ] Load chain failed, starting from genesis
[ 17:17:23 ] [ tc ] Generating new wallet miner.dat
[ 17:17:25 ] [ tc ] Your address is 172eJPtmt5wMq71bnT1fS55FYLHw1syhWB
[ 17:17:26 ] [ tc ] Load chain failed, starting from genesis
```
- Wait for a few blocks to go by
```
[ 03:04:47 ] [ tc ] Block found => 1 s, 726 KH/s, 0000001ec4d7580bf8b0459af362857d148112c8a38e5b039ca423558bf28ca3, 13835058055282350115
[ 03:04:47 ] [ tc ] Connecting block 0000001ec4d7580bf8b0459af362857d148112c8a38e5b039ca423558bf28ca3 to chain 0
[ 03:04:47 ] [ tc ] Adding TxOutPoint f353379e1dce17f3964bd1e673eb268faabaf8e6a24cc866f46389f54d920b25 to UTXO map
[ 03:04:47 ] [ tc ] Block accepted with height 1 and txs 1
[ 03:04:47 ] [ tc ] Saving chain with 2 blocks
[ 17:17:27 ] [ tc ] Block found => 2 s, 835 KH/s, 000000fe05062373c95152a779915f25d75cfc519395a120d3bba466b88b9bc5, 422750
[ 17:17:27 ] [ tc ] Connecting block 000000fe05062373c95152a779915f25d75cfc519395a120d3bba466b88b9bc5 to chain 0
[ 17:17:27 ] [ tc ] Adding TxOutPoint f353379e1dce17f3964bd1e673eb268faabaf8e6a24cc866f46389f54d920b25 to UTXO map
[ 17:17:27 ] [ tc ] Block accepted with height 1 and txs 1
[ 17:17:27 ] [ tc ] Saving chain with 2 blocks
...
```
- Generate an empty wallet
- Run a wallet node
```
$ tiny-sandbox.exe --port 9902 --wallet receiver.dat --balance
$ tiny-sandbox.exe --port 9902 --node_type wallet --wallet miner.dat
[ 03:04:53 ] [ tc ] Generating new wallet receiver.dat
[ 03:04:53 ] [ tc ] Your address is 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi
[ 03:04:55 ] [ tc ] Address 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi holds 0 coins
[ 17:17:31 ] [ tc ] Your address is 172eJPtmt5wMq71bnT1fS55FYLHw1syhWB
```
- Generate an empty wallet
```
$ address receiver.dat
[ 17:21:06 ] [ tc ] receiver.dat belongs to address is 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi
```
- Send coins from miner wallet to empty wallet
```
$ tiny-sandbox.exe --port 9902 --wallet miner.dat --send_address 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi --send_value 50
$ send 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi 50
[ 03:05:27 ] [ tc ] Built transaction bc74ea19c1eb5fd5d5571d2926f7f247e8c54844085aeb4902dddd3c587d934b, broadcasting
[ 17:21:52 ] [ tc ] Built transaction df02039631785fe23eb047bf8222f6cb89e767c6ee9e56c2e06d14ac0624c843, broadcasting
```
- Wait for transaction to get mined in a block
```
[ 03:05:33 ] [ tc ] Added transaction bc74ea19c1eb5fd5d5571d2926f7f247e8c54844085aeb4902dddd3c587d934b to block 3d202ec5dda4e5bad64c52d29cb03d9342c9eac9062503613665fb606da15e51
[ 03:05:50 ] [ tc ] Block found => 17 s, 1177 KH/s, 00000079f33dc7c0b50d51a425b8eae0c3bf406f71094b33a016aee05fdf26c7, 13835058055287314157
[ 03:05:50 ] [ tc ] Connecting block 00000079f33dc7c0b50d51a425b8eae0c3bf406f71094b33a016aee05fdf26c7 to chain 0
[ 03:05:50 ] [ tc ] Adding TxOutPoint e08baa6462a7a406879248f914cf8bb5a1758a73129f07f82aea7209769a754e to UTXO map
[ 03:05:50 ] [ tc ] Adding TxOutPoint bc74ea19c1eb5fd5d5571d2926f7f247e8c54844085aeb4902dddd3c587d934b to UTXO map
[ 03:05:50 ] [ tc ] Block accepted with height 8 and txs 2
[ 03:05:50 ] [ tc ] Saving chain with 9 blocks
...
[ 17:22:03 ] [ tc ] Added transaction df02039631785fe23eb047bf8222f6cb89e767c6ee9e56c2e06d14ac0624c843 to block 02f30dcb19d2fdda6a2e2dd556aacb22197f0d66170c37d5bc3bc479a7cd583f
[ 17:22:28 ] [ tc ] Block found => 25 s, 1146 KH/s, 0000009d480d7d6fb74541c35553a4e030461d3ee890312c152d209f12fa9dfd, 9223372036861901087
[ 17:22:28 ] [ tc ] Connecting block 0000009d480d7d6fb74541c35553a4e030461d3ee890312c152d209f12fa9dfd to chain 0
[ 17:22:28 ] [ tc ] Adding TxOutPoint 1972eeeea6949504e763fd0c22de36091ffddb734b546db3336c78d169c1a294 to UTXO map
[ 17:22:28 ] [ tc ] Adding TxOutPoint df02039631785fe23eb047bf8222f6cb89e767c6ee9e56c2e06d14ac0624c843 to UTXO map
[ 17:22:28 ] [ tc ] Block accepted with height 23 and txs 2
[ 17:22:28 ] [ tc ] Saving chain with 24 blocks
...
```
- Check balance of reciever wallet
- Check balance of receiver wallet
```
$ tiny-sandbox.exe --port 9902 --wallet receiver.dat --balance
[ 03:05:54 ] [ tc ] Address 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi holds 50 coins
$ balance 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi
[ 17:23:41 ] [ tc ] Address 16KHYopvjuY3mVLtEPHDLTzemWbPV6agoi holds 50 coins
```

## TODO
Expand All @@ -71,4 +77,5 @@ Windows 10 with Visual Studio 2019 for build environment and vcpkg for library m
- Mempool sorting by fee
- Orphan blocks
- Chainwork
- Peer discovery
- Peer discovery
- Full node
2 changes: 1 addition & 1 deletion tiny-lib/Connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ class Connection

std::mutex WriteMutex;

NodeType NodeType = Unspecified;
NodeType NodeType = NodeType::Unspecified;
};
14 changes: 12 additions & 2 deletions tiny-lib/Enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ enum class TxStatus : uint8_t
NotFound
};

enum NodeType : uint8_t
enum class NodeType : uint8_t
{
Unspecified = 0,
Miner = 1,
Wallet = 2,
Full = Miner | Wallet //TODO: implement full node
Full = Miner | Wallet
};

using NodeTypeType = std::underlying_type<NodeType>::type;
Expand All @@ -23,3 +23,13 @@ inline NodeType operator|(NodeType a, NodeType b)
{
return static_cast<NodeType>(static_cast<NodeTypeType>(a) | static_cast<NodeTypeType>(b));
}

inline NodeType& operator|=(NodeType& a, NodeType b)
{
return reinterpret_cast<NodeType&>(reinterpret_cast<int&>(a) |= static_cast<int>(b));
}

inline bool operator&(NodeType a, NodeType b)
{
return static_cast<NodeTypeType>(a) & static_cast<NodeTypeType>(b);
}
5 changes: 3 additions & 2 deletions tiny-lib/NetClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void NetClient::Stop()
ConnectionsMutex.unlock();

IO_Service.stop();
IO_Thread.join();
if (IO_Thread.joinable())
IO_Thread.join();

ConnectionsMutex.lock();
MinerConnections.clear();
Expand Down Expand Up @@ -361,7 +362,7 @@ void NetClient::RemoveConnection(std::shared_ptr<Connection>& con)
soc.shutdown(boost::asio::socket_base::shutdown_both);
soc.close();
}
if (con->NodeType & Miner)
if (con->NodeType & NodeType::Miner)
{
const auto vec_it2 = std::ranges::find_if(MinerConnections,
[&con](const std::shared_ptr<Connection>& o)
Expand Down
2 changes: 1 addition & 1 deletion tiny-lib/NodeConfig.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "pch.hpp"
#include "NodeConfig.hpp"

NodeType NodeConfig::Type = Unspecified;
NodeType NodeConfig::Type = NodeType::Unspecified;
2 changes: 1 addition & 1 deletion tiny-lib/PeerHelloMsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
void PeerHelloMsg::Handle(std::shared_ptr<Connection>& con)
{
con->NodeType = NodeType;
if (con->NodeType & Miner)
if (con->NodeType & NodeType::Miner)
{
std::lock_guard lock(NetClient::ConnectionsMutex);

Expand Down
20 changes: 17 additions & 3 deletions tiny-lib/Wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ std::string Wallet::PubKeyToAddress(const std::vector<uint8_t>& pubKey)
return PubKeyHashVersion + Base58::Encode(ripe);
}

std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> Wallet::InitWallet(const std::string& walletPath)
std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> Wallet::GetWallet(const std::string& walletPath)
{
WalletPath = walletPath;

std::vector<uint8_t> privKey;
std::vector<uint8_t> pubKey;
std::string address;
Expand All @@ -77,6 +75,22 @@ std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> Wallet::Init
wallet_out.close();
}

return {privKey, pubKey, address};
}

void Wallet::PrintWalletAddress(const std::string& walletPath)
{
const auto [privKey, pubKey, address] = GetWallet(walletPath);

LOG_INFO("{} belongs to address is {}", walletPath, address);
}

std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> Wallet::InitWallet(const std::string& walletPath)
{
WalletPath = walletPath;

const auto [privKey, pubKey, address] = GetWallet(WalletPath);

static bool printedAddress = false;
if (!printedAddress)
{
Expand Down
2 changes: 2 additions & 0 deletions tiny-lib/Wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class Wallet
public:
static std::string PubKeyToAddress(const std::vector<uint8_t>& pubKey);

static std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> GetWallet(const std::string& walletPath);
static void PrintWalletAddress(const std::string& walletPath);
static std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string>
InitWallet(const std::string& walletPath);
static std::tuple<std::vector<uint8_t>, std::vector<uint8_t>, std::string> InitWallet();
Expand Down
103 changes: 79 additions & 24 deletions tiny-sandbox/main.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
#include <cstdint>
#include <cstdlib>
#include <future>
#include <iostream>
#include <string>
#include <vector>
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>

#include "../tiny-lib/Log.hpp"
#include "../tiny-lib/NetClient.hpp"
#include "../tiny-lib/NodeConfig.hpp"
#include "../tiny-lib/PoW.hpp"
#include "../tiny-lib/Wallet.hpp"
#include "../tiny-lib/NodeConfig.hpp"

namespace po = boost::program_options;

Expand All @@ -18,42 +20,53 @@ void atexit_handler()
Log::StopLog();
}

int main(int ac, char** av)
int main(int argc, char** argv)
{
Log::StartLog();
if (std::atexit(atexit_handler) != 0)
return EXIT_FAILURE;

po::options_description desc("allowed options");
desc.add_options()
("wallet", po::value<std::string>(), "path to wallet")
("mine", "sets up a mining node")
("node_type", po::value<std::string>(), "specify node type")
("port", po::value<uint16_t>(), "port to listen on network connections")
("balance", "shows balance for this wallet")
("send_address", po::value<std::string>(), "sends coins to address")
("send_value", po::value<uint64_t>(), "sends coins to address")
("tx_status", po::value<std::string>(), "shows status for transaction");
("wallet", po::value<std::string>(), "path to wallet");

po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);

if (!vm.contains("port"))
{
LOG_ERROR("A port for network connection must be specified");

Log::StopLog();
return EXIT_FAILURE;
}

if (!vm.contains("node_type"))
{
LOG_ERROR("Node type must be specified");

return EXIT_FAILURE;
}

if (vm.contains("mine"))
if (vm["node_type"].as<std::string>() == "miner")
{
NodeConfig::Type = NodeType::Miner;
}
else if (vm["node_type"].as<std::string>() == "wallet")
{
NodeConfig::Type = NodeConfig::Type | Miner;
NodeConfig::Type = NodeType::Wallet;
}
else if (vm["node_type"].as<std::string>() == "full")
{
NodeConfig::Type = NodeType::Full; //TODO: implement full node
}
else
{
NodeConfig::Type = NodeConfig::Type | Wallet;
LOG_ERROR("Invalid node type");

return EXIT_FAILURE;
}

const auto [privKey, pubKey, address] = vm.contains("wallet")
Expand All @@ -76,23 +89,65 @@ int main(int ac, char** av)
for (const auto& pendingConnection : pendingConnections)
pendingConnection.wait();

if (NodeConfig::Type & Miner)
if (NodeConfig::Type == NodeType::Miner)
{
PoW::MineForever();
}
else
{
if (vm.contains("balance"))
{
Wallet::PrintBalance(address);
}
else if (vm.contains("tx_status"))
{
Wallet::PrintTxStatus(vm["tx_status"].as<std::string>());
}
else if (vm.contains("send_address") && vm.contains("send_value"))
std::string wallet_address = "address ";
std::string balance_address = "balance ";
std::string balance_own = "balance";
std::string send = "send ";
std::string tx_status = "tx_status ";
while (true)
{
Wallet::SendValue(vm["send_value"].as<uint64_t>(), vm["send_address"].as<std::string>(), privKey);
std::string command;
std::getline(std::cin, command);

if (command == "exit" || command == "quit")
{
break;
}

if (command.starts_with(wallet_address))
{
command.erase(0, wallet_address.length());
Wallet::PrintWalletAddress(command);
}
else if (command.starts_with(balance_address))
{
command.erase(0, balance_address.length());
Wallet::PrintBalance(command);
}
else if (command.starts_with(balance_own))
{
Wallet::PrintBalance(address);
}
else if (command.starts_with(send))
{
command.erase(0, send.length());
std::vector<std::string> send_args;
boost::split(send_args, command, boost::is_any_of(" "));
if (send_args.size() != 2)
{
LOG_ERROR("Send command requires 2 arguments, receiver address and send value");

continue;
}
const auto& send_address = send_args[0];
const auto& send_value = send_args[1];
Wallet::SendValue(std::stoull(send_value), send_address, privKey);
}
else if (command.starts_with(tx_status))
{
command.erase(0, tx_status.length());
Wallet::PrintTxStatus(command);
}
else
{
LOG_ERROR("Unknown command");
}
}
}

Expand Down

0 comments on commit f7943ff

Please sign in to comment.