Skip to content

Commit e185104

Browse files
fix terminal/.../collision.cxx and add some random project XD
1 parent e83e781 commit e185104

11 files changed

Lines changed: 852 additions & 59 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ else()
4242
endif()
4343

4444
add_subdirectory(terminal)
45+
add_subdirectory(swb)
4546

4647
find_package(OpenMP REQUIRED COMPONENTS CXX)

swb/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include_directories(include)
2+
file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cxx")
3+
add_executable(swb ${SOURCES})

swb/include/blockchain.hxx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#pragma once
2+
3+
#include <array>
4+
#include <bit>
5+
#include <cstdint>
6+
#include <string>
7+
8+
#include "sha3-512.hxx"
9+
#include "uint512_t.hxx"
10+
11+
struct Header {
12+
private:
13+
static constexpr std::array<char, 4> magicBE_raw = {0x0d, 0x0a, 0x12, 0x0e};
14+
15+
public:
16+
static constexpr std::array<char, 4> magic = []() constexpr {
17+
if constexpr (std::endian::native == std::endian::little) return std::array<char, 4>{magicBE_raw[3], magicBE_raw[2], magicBE_raw[1], magicBE_raw[0]};
18+
else return magicBE_raw;
19+
}();
20+
21+
static inline const std::string version_STR = "000001";
22+
static inline const uint64_t version = 1;
23+
};
24+
25+
class Block {
26+
Block *prev = nullptr;
27+
uint512_t hash{};
28+
std::string hashHex{};
29+
uint512_t nonce{};
30+
bool verified = false;
31+
32+
public:
33+
explicit Block() = default;
34+
35+
void generate_hash(const Block *prevBlock, const uint512_t &nonceVal) {
36+
using namespace std;
37+
string input;
38+
if (prevBlock) input += prevBlock->hashHex;
39+
input.append(Header::magic.begin(), Header::magic.end());
40+
input += Header::version_STR;
41+
input += to_string(Header::version);
42+
input += static_cast<std::string>(nonceVal);
43+
hash = SHA3_512::hash(input);
44+
hashHex = hash.to_hex();
45+
}
46+
47+
static bool check(double difficulty, Block chBlock) {
48+
uint512_t test = chBlock.hash;
49+
chBlock.generate_hash(chBlock.prev, chBlock.nonce);
50+
if (chBlock.hash == test) {
51+
chBlock.verified = true;
52+
return true;
53+
}
54+
chBlock.hash = test;
55+
return false;
56+
}
57+
};

swb/include/endian.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
5+
inline static bool is_big_endian() {
6+
uint16_t data = 0xff00;
7+
return *reinterpret_cast<uint8_t*>(&data);
8+
}

swb/include/miner.hxx

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#pragma once
2+
#include <array>
3+
#include <chrono>
4+
#include <cstdint>
5+
#include <iostream>
6+
#include <mutex>
7+
#include <sstream>
8+
#include <thread>
9+
#include <vector>
10+
11+
#include "sha3-512.hxx"
12+
#include "uint512_t.hxx"
13+
14+
struct Target512 {
15+
uint512_t value{};
16+
17+
static Target512 initial() {
18+
Target512 t;
19+
t.value[0] = 0x00;
20+
t.value[1] = 0x00;
21+
t.value[2] = 0x00;
22+
t.value[3] = 0xFF;
23+
return t;
24+
}
25+
26+
bool check(const uint512_t& i) const { return i <= value; }
27+
28+
void update_difficulty(double factor) {
29+
using namespace std;
30+
31+
constexpr uint64_t SCALE = 10000;
32+
uint512_t scale(SCALE);
33+
34+
if (factor < 1.0) {
35+
double inv = 1.0 / factor;
36+
uint64_t scaled = static_cast<uint64_t>(inv * SCALE);
37+
value /= scale;
38+
value *= uint512_t(scaled);
39+
} else {
40+
uint64_t scaled = static_cast<uint64_t>(factor * SCALE);
41+
value /= uint512_t(scaled);
42+
value *= scale;
43+
}
44+
}
45+
};
46+
47+
struct Miner512 {
48+
Target512 target;
49+
std::mutex print_mtx;
50+
std::mutex nonce_mtx;
51+
uint512_t winning_nonce{};
52+
int num_threads = 4;
53+
uint64_t sumTime = 0;
54+
55+
Miner512() : target(Target512::initial()), winning_nonce(0) {}
56+
57+
void mine_thread(const std::string& weight, int thread_id, bool& block_found, std::array<std::string, 64>& thread_hashes) {
58+
using namespace std;
59+
uint512_t local_nonce = uint512_t(static_cast<uint64_t>(thread_id));
60+
while (true) {
61+
{
62+
lock_guard<mutex> lg(nonce_mtx);
63+
if (block_found) break;
64+
}
65+
66+
stringstream ss;
67+
ss << local_nonce.to_hex() << weight;
68+
uint512_t hash = SHA3_512::hash(ss.str());
69+
thread_hashes[thread_id] = hash.to_hex();
70+
71+
if (target.check(hash)) {
72+
lock_guard<mutex> lg(nonce_mtx);
73+
if (winning_nonce == uint512_t(0) || local_nonce < winning_nonce) winning_nonce = local_nonce;
74+
block_found = true;
75+
break;
76+
}
77+
78+
local_nonce += uint512_t(num_threads);
79+
}
80+
}
81+
82+
void mine_concurrent(int threads = 4) {
83+
using namespace std;
84+
num_threads = threads;
85+
uint64_t total_found = 0;
86+
string prev_hash = "";
87+
88+
while (true) {
89+
bool block_found = false;
90+
winning_nonce = uint512_t(0);
91+
array<string, 64> thread_hashes;
92+
vector<thread> thread_pool;
93+
94+
{
95+
lock_guard<mutex> lg(print_mtx);
96+
cout << "Current target is " << target.value.to_hex() << endl << endl;
97+
}
98+
auto start = chrono::high_resolution_clock::now();
99+
100+
for (int i = 0; i < num_threads; ++i) thread_pool.emplace_back(&Miner512::mine_thread, this, ref(prev_hash), i, ref(block_found), ref(thread_hashes));
101+
102+
for (auto& t : thread_pool) t.join();
103+
104+
auto end = chrono::high_resolution_clock::now();
105+
auto duration = chrono::duration_cast<chrono::milliseconds>(end - start).count();
106+
if (duration == 0) duration = 1;
107+
sumTime += duration;
108+
{
109+
lock_guard<mutex> lg(print_mtx);
110+
cout << "Block found! Winning nonce = " << winning_nonce.to_hex() << " Time = " << duration << "ms Total blocks found = " << (++total_found) << endl;
111+
cout << "Hashes from threads:" << endl;
112+
for (int i = 0; i < num_threads; ++i) cout << "[Thread " << i << "] hash=" << thread_hashes[i] << endl;
113+
cout << endl;
114+
}
115+
116+
prev_hash = thread_hashes[0];
117+
for (int i = 1; i < num_threads; ++i)
118+
if (!thread_hashes[i].empty() && (winning_nonce % uint512_t(num_threads) == uint512_t(i))) prev_hash = thread_hashes[i];
119+
120+
if (!(total_found % 10)) {
121+
double factor = 60000.0 / static_cast<double>(sumTime) * 10; // target 60s per block }
122+
target.update_difficulty(factor);
123+
sumTime = 0;
124+
{
125+
lock_guard<mutex> lg(print_mtx);
126+
cout << "Difficulty updated with factor = " << factor << endl << endl;
127+
}
128+
}
129+
}
130+
}
131+
};

swb/include/peer.hxx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <sys/socket.h>
2+
#include <unistd.h>
3+
4+
#include <cstdint>
5+
#include <vector>
6+
7+
#include "uint512_t.hxx"
8+
9+
/*
10+
*/
11+
struct NetPool {
12+
std::vector<uint512_t> Id;
13+
std::vector<int> MostNewOffset;
14+
};

swb/include/sha3-512.hxx

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#pragma once
2+
#include <array>
3+
#include <cstddef>
4+
#include <cstdint>
5+
#include <cstring>
6+
#include <iomanip>
7+
#include <sstream>
8+
#include <string>
9+
#include <vector>
10+
11+
#include "uint512_t.hxx"
12+
13+
class SHA3_512 {
14+
private:
15+
static constexpr size_t KECCAKF_ROUNDS = 24;
16+
static constexpr uint64_t keccakf_rndc[24] = {
17+
0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL,
18+
0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL,
19+
0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL,
20+
0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000000008001ULL, 0x8000000080008008ULL};
21+
22+
static constexpr uint8_t keccakf_rotc[24] = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44};
23+
24+
static constexpr uint8_t keccakf_piln[24] = {10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1};
25+
26+
static inline uint64_t rol64(uint64_t x, unsigned s) { return (x << s) | (x >> (64 - s)); }
27+
28+
static void keccakf(uint64_t* st) {
29+
uint64_t t, bc[5];
30+
for (size_t round = 0; round < KECCAKF_ROUNDS; ++round) {
31+
for (int i = 0; i < 5; ++i) bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
32+
for (int i = 0; i < 5; ++i) {
33+
t = bc[(i + 4) % 5] ^ rol64(bc[(i + 1) % 5], 1);
34+
for (int j = 0; j < 25; j += 5) st[j + i] ^= t;
35+
}
36+
t = st[1];
37+
for (int i = 0; i < 24; ++i) {
38+
int j = keccakf_piln[i];
39+
bc[0] = st[j];
40+
st[j] = rol64(t, keccakf_rotc[i]);
41+
t = bc[0];
42+
}
43+
for (int j = 0; j < 25; j += 5) {
44+
for (int i = 0; i < 5; ++i) bc[i] = st[j + i];
45+
st[j + 0] = bc[0] ^ ((~bc[1]) & bc[2]);
46+
st[j + 1] = bc[1] ^ ((~bc[2]) & bc[3]);
47+
st[j + 2] = bc[2] ^ ((~bc[3]) & bc[4]);
48+
st[j + 3] = bc[3] ^ ((~bc[4]) & bc[0]);
49+
st[j + 4] = bc[4] ^ ((~bc[0]) & bc[1]);
50+
}
51+
st[0] ^= keccakf_rndc[round];
52+
}
53+
}
54+
55+
static inline bool is_little_endian() {
56+
uint16_t x = 1;
57+
return *reinterpret_cast<uint8_t*>(&x) == 1;
58+
}
59+
60+
static inline uint64_t swap64(uint64_t x) {
61+
return ((x & 0x00000000000000FFULL) << 56) | ((x & 0x000000000000FF00ULL) << 40) | ((x & 0x0000000000FF0000ULL) << 24) |
62+
((x & 0x00000000FF000000ULL) << 8) | ((x & 0x000000FF00000000ULL) >> 8) | ((x & 0x0000FF0000000000ULL) >> 24) | ((x & 0x00FF000000000000ULL) >> 40) |
63+
((x & 0xFF00000000000000ULL) >> 56);
64+
}
65+
66+
static void update(const uint8_t* data, size_t len, uint64_t (&st)[25], std::vector<uint8_t>& buf) {
67+
while (len--) {
68+
buf.push_back(*data++);
69+
if (buf.size() == 72) {
70+
for (size_t i = 0; i < 9; ++i) {
71+
uint64_t t = 0;
72+
for (size_t j = 0; j < 8; ++j) t |= ((uint64_t)buf[i * 8 + j]) << (8 * j);
73+
st[i] ^= t;
74+
}
75+
keccakf(st);
76+
buf.clear();
77+
}
78+
}
79+
}
80+
81+
static void finalize(uint64_t (&st)[25], std::vector<uint8_t>& buf) {
82+
buf.push_back(0x06);
83+
while (buf.size() < 72) buf.push_back(0x00);
84+
buf[71] |= 0x80;
85+
for (size_t i = 0; i < 9; ++i) {
86+
uint64_t t = 0;
87+
for (size_t j = 0; j < 8; ++j) t |= ((uint64_t)buf[i * 8 + j]) << (8 * j);
88+
st[i] ^= t;
89+
}
90+
keccakf(st);
91+
}
92+
93+
public:
94+
static uint512_t hash(const std::string& s) {
95+
using namespace std;
96+
uint64_t st[25]{};
97+
vector<uint8_t> buf;
98+
update(reinterpret_cast<const uint8_t*>(s.data()), s.size(), st, buf);
99+
finalize(st, buf);
100+
101+
array<uint8_t, 64> out{};
102+
bool little = is_little_endian();
103+
for (size_t i = 0; i < 8; ++i) {
104+
uint64_t lane = st[i];
105+
if (little) lane = swap64(lane);
106+
for (int j = 0; j < 8; ++j) out[i * 8 + j] = (lane >> (8 * (7 - j))) & 0xFF;
107+
}
108+
uint512_t val;
109+
for (int i = 0; i < 64; ++i) val.dataBE[i] = out[i];
110+
return val;
111+
}
112+
113+
static std::string hash_hex(const std::string& s) {
114+
using namespace std;
115+
uint64_t st[25]{};
116+
vector<uint8_t> buf;
117+
update(reinterpret_cast<const uint8_t*>(s.data()), s.size(), st, buf);
118+
finalize(st, buf);
119+
120+
ostringstream oss;
121+
bool little = is_little_endian();
122+
for (size_t i = 0; i < 8; ++i) {
123+
uint64_t lane = st[i];
124+
if (little) lane = swap64(lane);
125+
for (int j = 0; j < 8; ++j) {
126+
uint8_t b = (lane >> (8 * (7 - j))) & 0xFF;
127+
oss << hex << setw(2) << setfill('0') << (int)b;
128+
}
129+
}
130+
return oss.str();
131+
}
132+
};

0 commit comments

Comments
 (0)