mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 11:29:23 +00:00
Added varint unit tests
This commit is contained in:
parent
32533e3c96
commit
dee66c3f32
5 changed files with 117 additions and 34 deletions
|
@ -109,9 +109,9 @@ bool check_keys(const hash& pub, const hash& sec)
|
|||
return pub == pub_check;
|
||||
}
|
||||
|
||||
static FORCEINLINE void hash_to_scalar(const uint8_t* data, size_t length, uint8_t(&res)[HASH_SIZE])
|
||||
static FORCEINLINE void hash_to_scalar(const uint8_t* data, int length, uint8_t (&res)[HASH_SIZE])
|
||||
{
|
||||
keccak(data, static_cast<int>(length), res, HASH_SIZE);
|
||||
keccak(data, length, res, HASH_SIZE);
|
||||
sc_reduce32(res);
|
||||
}
|
||||
|
||||
|
@ -122,18 +122,13 @@ static FORCEINLINE void derivation_to_scalar(const hash& derivation, size_t outp
|
|||
uint8_t output_index[(sizeof(size_t) * 8 + 6) / 7];
|
||||
} buf;
|
||||
|
||||
uint8_t* begin = buf.derivation;
|
||||
uint8_t* end = buf.output_index;
|
||||
memcpy(buf.derivation, derivation.h, sizeof(buf.derivation));
|
||||
|
||||
size_t k = output_index;
|
||||
while (k >= 0x80) {
|
||||
*(end++) = (static_cast<uint8_t>(k) & 0x7F) | 0x80;
|
||||
k >>= 7;
|
||||
}
|
||||
*(end++) = static_cast<uint8_t>(k);
|
||||
uint8_t* p = buf.output_index;
|
||||
writeVarint(output_index, [&p](uint8_t b) { *(p++) = b; });
|
||||
|
||||
hash_to_scalar(begin, end - begin, res);
|
||||
const uint8_t* data = buf.derivation;
|
||||
hash_to_scalar(data, static_cast<int>(p - data), res);
|
||||
}
|
||||
|
||||
class Cache
|
||||
|
|
|
@ -46,29 +46,7 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, SideChain& sidechai
|
|||
#define READ_BYTE(x) do { if (!read_byte(x)) return __LINE__; } while (0)
|
||||
#define EXPECT_BYTE(value) do { uint8_t tmp; READ_BYTE(tmp); if (tmp != (value)) return __LINE__; } while (0)
|
||||
|
||||
auto read_varint = [&data, data_end](auto& b) -> bool
|
||||
{
|
||||
uint64_t result = 0;
|
||||
int k = 0;
|
||||
|
||||
while (data < data_end) {
|
||||
if (k >= static_cast<int>(sizeof(b)) * 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint64_t cur_byte = *(data++);
|
||||
result |= (cur_byte & 0x7F) << k;
|
||||
k += 7;
|
||||
|
||||
if ((cur_byte & 0x80) == 0) {
|
||||
b = result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
#define READ_VARINT(x) do { if (!read_varint(x)) return __LINE__; } while(0)
|
||||
#define READ_VARINT(x) do { data = readVarint(data, data_end, x); if (!data) return __LINE__; } while(0)
|
||||
|
||||
auto read_buf = [&data, data_end](void* buf, size_t size) -> bool
|
||||
{
|
||||
|
|
24
src/util.h
24
src/util.h
|
@ -109,6 +109,30 @@ FORCEINLINE void writeVarint(T value, std::vector<uint8_t>& out)
|
|||
writeVarint(value, [&out](uint8_t b) { out.emplace_back(b); });
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const uint8_t* readVarint(const uint8_t* data, const uint8_t* data_end, T& b)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
int k = 0;
|
||||
|
||||
while (data < data_end) {
|
||||
if (k >= static_cast<int>(sizeof(T)) * 8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const uint64_t cur_byte = *(data++);
|
||||
result |= (cur_byte & 0x7F) << k;
|
||||
k += 7;
|
||||
|
||||
if ((cur_byte & 0x80) == 0) {
|
||||
b = result;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T, size_t N> FORCEINLINE constexpr size_t array_size(T(&)[N]) { return N; }
|
||||
template<typename T, typename U, size_t N> FORCEINLINE constexpr size_t array_size(T(U::*)[N]) { return N; }
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ set(SOURCES
|
|||
src/keccak_tests.cpp
|
||||
src/main.cpp
|
||||
src/pool_block_tests.cpp
|
||||
src/varint_tests.cpp
|
||||
src/wallet_tests.cpp
|
||||
../external/src/cryptonote/crypto-ops-data.c
|
||||
../external/src/cryptonote/crypto-ops.c
|
||||
|
|
85
tests/src/varint_tests.cpp
Normal file
85
tests/src/varint_tests.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This file is part of the Monero P2Pool <https://github.com/SChernykh/p2pool>
|
||||
* Copyright (c) 2021-2022 SChernykh <https://github.com/SChernykh>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
TEST(varint, read_write)
|
||||
{
|
||||
std::vector<uint8_t> v;
|
||||
v.reserve(16);
|
||||
|
||||
uint64_t check;
|
||||
|
||||
// 0...2^7 - 1
|
||||
for (uint64_t value = 0; value < 0x80; ++value) {
|
||||
v.clear();
|
||||
writeVarint(value, v);
|
||||
ASSERT_EQ(v.size(), 1);
|
||||
ASSERT_EQ(v[0], value);
|
||||
ASSERT_EQ(readVarint(v.data(), v.data() + v.size(), check), v.data() + v.size());
|
||||
ASSERT_EQ(check, value);
|
||||
}
|
||||
|
||||
// 2^7...2^14 - 1
|
||||
for (uint64_t value = 0x80; value < 0x4000; ++value) {
|
||||
v.clear();
|
||||
writeVarint(value, v);
|
||||
ASSERT_EQ(v.size(), 2);
|
||||
ASSERT_EQ(v[0], (value & 0x7F) | 0x80);
|
||||
ASSERT_EQ(v[1], value >> 7);
|
||||
ASSERT_EQ(readVarint(v.data(), v.data() + v.size(), check), v.data() + v.size());
|
||||
ASSERT_EQ(check, value);
|
||||
}
|
||||
|
||||
// 2^14...2^21 - 1
|
||||
for (uint64_t value = 0x4000; value < 0x200000; ++value) {
|
||||
v.clear();
|
||||
writeVarint(value, v);
|
||||
ASSERT_EQ(v.size(), 3);
|
||||
ASSERT_EQ(v[0], (value & 0x7F) | 0x80);
|
||||
ASSERT_EQ(v[1], ((value >> 7) & 0x7F) | 0x80);
|
||||
ASSERT_EQ(v[2], value >> 14);
|
||||
ASSERT_EQ(readVarint(v.data(), v.data() + v.size(), check), v.data() + v.size());
|
||||
ASSERT_EQ(check, value);
|
||||
}
|
||||
|
||||
// 2^64 - 1
|
||||
v.clear();
|
||||
writeVarint(std::numeric_limits<uint64_t>::max(), v);
|
||||
ASSERT_EQ(v.size(), 10);
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
ASSERT_EQ(v[i], 0xFF);
|
||||
}
|
||||
ASSERT_EQ(v[9], 1);
|
||||
ASSERT_EQ(readVarint(v.data(), v.data() + v.size(), check), v.data() + v.size());
|
||||
ASSERT_EQ(check, std::numeric_limits<uint64_t>::max());
|
||||
|
||||
// Invalid value 1
|
||||
uint8_t buf[16];
|
||||
memset(buf, -1, sizeof(buf));
|
||||
ASSERT_EQ(readVarint(buf, buf + sizeof(buf), check), nullptr);
|
||||
|
||||
// Invalid value 2
|
||||
uint8_t buf2[1] = { 0x80 };
|
||||
ASSERT_EQ(readVarint(buf2, buf2 + 1, check), nullptr);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue