Skip to content

Commit

Permalink
init, net: Allow embedding asmap file into source code
Browse files Browse the repository at this point in the history
  • Loading branch information
fjahr committed Nov 4, 2023
1 parent feae4e0 commit 9caf241
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ BITCOIN_CORE_H = \
indirectmap.h \
init.h \
init/common.h \
init/ip_asn.h \
interfaces/chain.h \
interfaces/echo.h \
interfaces/handler.h \
Expand Down
27 changes: 21 additions & 6 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <index/coinstatsindex.h>
#include <index/txindex.h>
#include <init/common.h>
#include <init/ip_asn.h>
#include <interfaces/chain.h>
#include <interfaces/init.h>
#include <interfaces/node.h>
Expand Down Expand Up @@ -67,6 +68,7 @@
#include <scheduler.h>
#include <script/sigcache.h>
#include <shutdown.h>
#include <span.h>
#include <sync.h>
#include <timedata.h>
#include <torcontrol.h>
Expand Down Expand Up @@ -1199,22 +1201,35 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)

{

// Read asmap file if configured
// Read asmap file or embedded data if configured
std::vector<bool> asmap;
if (args.IsArgSet("-asmap")) {
const bool asmap_file_set{args.GetPathArg("-asmap") != ""};
fs::path asmap_path = args.GetPathArg("-asmap", DEFAULT_ASMAP_FILENAME);
if (!asmap_path.is_absolute()) {
asmap_path = args.GetDataDirNet() / asmap_path;
}
if (!fs::exists(asmap_path)) {

if (!fs::exists(asmap_path) && asmap_file_set) {
InitError(strprintf(_("Could not find asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
return false;
}
asmap = DecodeAsmap(asmap_path);
if (asmap.size() == 0) {
InitError(strprintf(_("Could not parse asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
return false;

if (fs::exists(asmap_path)) {
asmap = DecodeAsmap(asmap_path);
if (asmap.size() == 0) {
InitError(strprintf(_("Could not parse asmap file %s"), fs::quoted(fs::PathToString(asmap_path))));
return false;
}
} else {
Span<const unsigned char> asmap_data(reinterpret_cast<const unsigned char*>(ip_asn), static_cast<size_t>(ip_asn_len));
asmap = DecodeAsmap(asmap_data);
if (asmap.size() == 0) {
InitError(strprintf(_("Could not read embedded asmap data")));
return false;
}
}

const uint256 asmap_version = (HashWriter{} << asmap).GetHash();
LogPrintf("Using asmap version %s for IP bucketing\n", asmap_version.ToString());
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/init/ip_asn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef BITCOIN_INIT_IP_ASN_H
#define BITCOIN_INIT_IP_ASN_H

unsigned char ip_asn[] = {
};

unsigned int ip_asn_len = 0;

#endif // BITCOIN_INIT_IP_ASN_H
45 changes: 31 additions & 14 deletions src/util/asmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <crypto/common.h>
#include <logging.h>
#include <serialize.h>
#include <span.h>
#include <streams.h>
#include <util/fs.h>

Expand Down Expand Up @@ -194,30 +195,46 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits)
return false; // Reached EOF without RETURN instruction
}

std::vector<bool> DecodeAsmap(fs::path path)
{
std::vector<bool> Decode(const Span<const uint8_t>& data) {
std::vector<bool> bits;
FILE *filestr = fsbridge::fopen(path, "rb");
AutoFile file{filestr};
if (file.IsNull()) {
LogPrintf("Failed to open asmap file from disk\n");
if (data.empty()) {
return bits;
}
fseek(filestr, 0, SEEK_END);
int length = ftell(filestr);
LogPrintf("Opened asmap file %s (%d bytes) from disk\n", fs::quoted(fs::PathToString(path)), length);
fseek(filestr, 0, SEEK_SET);
uint8_t cur_byte;
for (int i = 0; i < length; ++i) {
file >> cur_byte;

for (auto cur_byte : data) {
for (int bit = 0; bit < 8; ++bit) {
bits.push_back((cur_byte >> bit) & 1);
}
}

if (!SanityCheckASMap(bits, 128)) {
LogPrintf("Sanity check of asmap file %s failed\n", fs::quoted(fs::PathToString(path)));
LogPrintf("Sanity check of asmap data failed\n");
return {};
}
return bits;
}

std::vector<bool> DecodeAsmap(fs::path path) {
FILE *filestr = fsbridge::fopen(path, "rb");
AutoFile file{filestr};
if (file.IsNull()) {
LogPrintf("Failed to open asmap file from disk\n");
return {};
}

fseek(filestr, 0, SEEK_END);
int length = ftell(filestr);
LogPrintf("Opened asmap file %s (%d bytes) from disk\n", fs::quoted(fs::PathToString(path)), length);
fseek(filestr, 0, SEEK_SET);

std::vector<uint8_t> buffer(length);
size_t length_read = fread(buffer.data(), 1, length, file.Get());
assert(length_read == static_cast<size_t>(length));

return Decode(buffer);
}

std::vector<bool> DecodeAsmap(Span<const uint8_t> data) {
LogPrintf("Opened asmap data (%zu bytes) from embedded byte array\n", data.size());
return Decode(data);
}
3 changes: 3 additions & 0 deletions src/util/asmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BITCOIN_UTIL_ASMAP_H

#include <util/fs.h>
#include <span.h>

#include <cstdint>
#include <vector>
Expand All @@ -16,5 +17,7 @@ bool SanityCheckASMap(const std::vector<bool>& asmap, int bits);

/** Read asmap from provided binary file */
std::vector<bool> DecodeAsmap(fs::path path);
/** Read asmap from embedded byte array */
std::vector<bool> DecodeAsmap(Span<const uint8_t> data);

#endif // BITCOIN_UTIL_ASMAP_H

0 comments on commit 9caf241

Please sign in to comment.