Skip to content

Commit

Permalink
Merge pull request #169 from adshares/stability-fixes
Browse files Browse the repository at this point in the history
Stability fixes
  • Loading branch information
jzemlo authored Oct 9, 2018
2 parents fdb7a1d + 38cae33 commit 6f276ed
Show file tree
Hide file tree
Showing 15 changed files with 732 additions and 160 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.0.3] - 2018-10-09
### Changed
- Modified DB rollback mechanism to support starting from backup

### Fixed
- Accounts database snapshots during dividend block
- Further stability improvements for peer communication
- Node debug logs cleanup

## [1.0.2] - 2018-09-27
### Fixed
- Node did not stop when there was not enough signatures
Expand Down Expand Up @@ -54,8 +63,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update default parameters
- Creating a dev version with reference to the last tag

[Unreleased]: https://github.com/adshares/ads/compare/v1.0.2...HEAD
[Unreleased]: https://github.com/adshares/ads/compare/v1.0.3...HEAD

[1.0.3]: https://github.com/adshares/ads/compare/v1.0.2...v1.0.3
[1.0.2]: https://github.com/adshares/ads/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/adshares/ads/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/adshares/ads/compare/v0.0.6...v1.0.0
Expand Down
2 changes: 1 addition & 1 deletion src/common/command/getbroadcastmsg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ bool GetBroadcastMsg::send(INetworkClient& netClient) {
return false;
}

ELOG("size %ud %08X\n", m_header.fileSize, m_data.info.block);
DLOG("size %ud %08X\n", m_header.fileSize, m_data.info.block);

unsigned char *readBuffer = new unsigned char[m_header.fileSize];
if (!netClient.readData(readBuffer, m_header.fileSize)) {
Expand Down
120 changes: 75 additions & 45 deletions src/common/helper/blocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "default.h"
#include "libarchive.h"
#include "servers.h"

namespace Helper {

Expand Down Expand Up @@ -96,79 +97,110 @@ uint32_t get_users_count(uint16_t bank) {
return (st.st_size/sizeof(user_t));
}

void db_backup(uint32_t block_path, uint16_t nodes) {
void db_backup(uint32_t block_path, uint16_t nodes)
{
// used to temporary name for snapshot, resolve names colision between sparse local und/* file and currently creating db snapshot.
const char* const snapshot_postfix = "tmp";
char backupFilePath[64];

if (!is_snapshot_directory(block_path)) {
return;
}

char previousSnapshotPath[64];
char backupFilePath[64];
unsigned int usert_size = sizeof(user_t);
Helper::FileName::getName(backupFilePath, block_path, "servers.srv");
Helper::Servers servers(backupFilePath);
servers.load();

// for each node
for (uint16_t bank = 1; bank < nodes; ++bank)
{
// get undo files, youngest at begin

// open snapshot file
Helper::FileName::getUndo(backupFilePath, block_path, bank);
strncat(backupFilePath, snapshot_postfix, sizeof(backupFilePath) - strlen(backupFilePath) - 1);
Helper::FileWrapper snapshotFile;
if (!snapshotFile.open(backupFilePath, O_WRONLY | O_CREAT, 0644))
{
WLOG("Can't open snapshot file: %s\n" , backupFilePath);
return;
}

// open bank file
char filePath[64];
Helper::FileName::getUsr(filePath, bank);
Helper::FileWrapper bankFile;
if (!bankFile.open(filePath))
{
WLOG("Can't open bank file: %s\n", filePath);
return;
}

// open undos from now to block_path
uint32_t current_block = time(NULL);
current_block -= current_block%BLOCKSEC;
std::vector<std::shared_ptr<Helper::FileWrapper>> undoFiles;
std::shared_ptr<Helper::FileWrapper> undo_file;
for (int i=0; i<BLOCKDIV; ++i) {
uint32_t block = block_path - (i*BLOCKSEC);
for (uint32_t block = block_path; block <= current_block; block+=BLOCKSEC) {
char undoPath[64];
Helper::FileName::getBlk(undoPath, block);
if (!boost::filesystem::exists(undoPath))
{
WLOG("Gap in block chain: %d %s\n", block, undoPath);
break;
}

Helper::FileName::getUndo(undoPath, block, bank);

undo_file.reset(new FileWrapper(std::string(undoPath), O_RDONLY, true));
undo_file.reset(new FileWrapper(std::string(undoPath), O_RDONLY | O_CREAT, 0644));
if (undo_file->isOpen()) {
undoFiles.push_back(undo_file);
}
}

// load previous snapshot or usr/* for initial run
uint32_t users = get_users_count(bank);
Helper::FileName::getUndo(previousSnapshotPath, (block_path - (BLOCKDIV*BLOCKSEC)), bank);
if (!boost::filesystem::exists(previousSnapshotPath)) {
Helper::FileName::getUsr(previousSnapshotPath, bank);
}

Helper::FileWrapper last_snapshot(previousSnapshotPath, O_RDONLY, false);
if (!last_snapshot.isOpen()) {
return;
}

user_t u;
Helper::FileName::getUndo(backupFilePath, block_path, bank);
strncat(backupFilePath, snapshot_postfix, sizeof(backupFilePath) - strlen(backupFilePath) - 1);

int current_snapshot = open(backupFilePath, O_WRONLY | O_CREAT, 0644);
if (current_snapshot < 0) {
return;
}

// for each user
uint32_t users = servers.getNode(bank).accountCount;
for (uint32_t user = 0; user < users; ++user)
{
u = {};
user_t usr = {};
// read undos and find user (user->msid != 0)
for (auto it=undoFiles.begin(); it != undoFiles.end(); ++it)
{
(*it)->seek(user * usert_size, SEEK_SET);
(*it)->read((char*)&u, usert_size);
if (u.msid != 0) // user found, get from undo
(*it)->seek(user * sizeof(user_t), SEEK_SET);
(*it)->read((char*)&usr, sizeof(user_t));
if (usr.msid != 0)
{
last_snapshot.seek(usert_size, SEEK_CUR);
if (!write(current_snapshot, (char*)&u, usert_size)) break;
// user found
bankFile.seek(sizeof(user_t), SEEK_CUR);
break;
}
} // end of undo
if (u.msid != 0) continue; // user already found
// not found in undo, get from last snapshot
last_snapshot.read((char*)&u, usert_size);
if (!write(current_snapshot, (char*)&u, usert_size)) break;
} // foreach user

close(current_snapshot);
} // foreach bank
if (usr.msid == 0)
{
// if not found read user from bank file
bankFile.read((char*)&usr, sizeof(user_t));

if (!undoFiles.empty())
{
user_t latest_record = {};
auto latest_undo = undoFiles.back();
latest_undo->seek(user * sizeof(user_t), SEEK_SET);
latest_undo->read((char*)&latest_record, sizeof(user_t));
if (latest_record.msid != 0)
{
memcpy((char*)&usr, &latest_record, sizeof(user_t));
}
}
}

// write user to snapshot file
if (!snapshotFile.write((char*)&usr, sizeof(user_t)))
{
WLOG("Can't write to bank file\n");
return;
}

} // end of for each user
} // end of for each node

// change snapshot temp file name to correct one
for (uint16_t bank = 1; bank < nodes; ++bank)
Expand All @@ -178,8 +210,6 @@ void db_backup(uint32_t block_path, uint16_t nodes) {
std::rename(backupFilePath,
std::string(backupFilePath).substr(0, Helper::FileName::kUndoNameFixedLength).c_str());
}

return;
}

}
4 changes: 2 additions & 2 deletions src/common/helper/filewrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ FileWrapper::FileWrapper() :
{
}

FileWrapper::FileWrapper(const std::string filepath, int mask, bool removeOnClose) :
FileWrapper::FileWrapper(const std::string filepath, int mask, int mode, bool removeOnClose) :
m_file_descriptor(-1), m_filepath(filepath), m_remove_on_close(removeOnClose)
{
m_file_descriptor = ::open(m_filepath.c_str(), mask);
m_file_descriptor = ::open(m_filepath.c_str(), mask, mode);
}

FileWrapper::~FileWrapper()
Expand Down
2 changes: 1 addition & 1 deletion src/common/helper/filewrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class FileWrapper
{
public:
FileWrapper();
FileWrapper(const std::string filepath, int mask, bool removeOnClose = false);
FileWrapper(const std::string filepath, int mask, int mode = 0644, bool removeOnClose = false);
~FileWrapper();

bool isOpen();
Expand Down
9 changes: 3 additions & 6 deletions src/common/message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ class message :
memcpy(data+4+64+6,&now,4);
memcpy(data+4+64+10,text,text_len);

DLOG("INI:%016lX\n",*(uint64_t*)mypk);

if(text_type==MSGTYPE_BLK) {
if(mysk==NULL) { // creating message from network
memcpy(data+4,mypk,64);
Expand Down Expand Up @@ -475,13 +473,13 @@ class message :

char hash[2*SHA256_DIGEST_LENGTH];
ed25519_key2text(hash,nhash,SHA256_DIGEST_LENGTH);
ELOG("nhash %.*s\n", 2*SHA256_DIGEST_LENGTH,hash);
ILOG("nhash %.*s\n", 2*SHA256_DIGEST_LENGTH,hash);
ed25519_key2text(hash, mhash,SHA256_DIGEST_LENGTH);
ELOG("mhash %.*s\n", 2*SHA256_DIGEST_LENGTH,hash);
ILOG("mhash %.*s\n", 2*SHA256_DIGEST_LENGTH,hash);


if(memcmp(mhash,nhash,32)){
DLOG("HASHTREE failed (path len:%d)\n",(int)hashes.size());
ELOG("HASHTREE failed (path len:%d)\n",(int)hashes.size());
return(false);}
return(true);
}
Expand Down Expand Up @@ -797,7 +795,6 @@ class message :
return(ed25519_sign_open(data+4+64,10+sizeof(hash_t),svpk,data+4));
}
if(data[0]==MSGTYPE_INI) {
DLOG("INI:%016lX\n",*(uint64_t*)svpk);
return(ed25519_sign_open(data+4+64,len-4-64,svpk,data+4));
}
assert(0);
Expand Down
18 changes: 9 additions & 9 deletions src/common/servers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class servers { // also a block

void create_genesis_block(const std::string genesis_file) {
assert(nodes.size() == 0);
ELOG("INIT: using genesis file %s\n", genesis_file.c_str());
ILOG("INIT: using genesis file %s\n", genesis_file.c_str());

boost::property_tree::ptree data;
boost::property_tree::read_json(genesis_file, data);
Expand All @@ -137,7 +137,7 @@ class servers { // also a block

char hash_text[2 * SHA256_DIGEST_LENGTH];
ed25519_key2text(hash_text, genesis_hash, SHA256_DIGEST_LENGTH);
ELOG("genesis hash: %.*s\n", 2 * SHA256_DIGEST_LENGTH, hash_text);
ILOG("genesis hash: %.*s\n", 2 * SHA256_DIGEST_LENGTH, hash_text);

boost::property_tree::ptree dataConfig = data.get_child("config");

Expand All @@ -147,7 +147,7 @@ class servers { // also a block
ELOG("Invalid genesis start time: %d, must be divisible by %d\n", startTimeOpt.get(), BLOCKSEC);
exit(-1);
} else {
ELOG("Genesis start time: %d\n", startTimeOpt.get());
ILOG("Genesis start time: %d\n", startTimeOpt.get());

}

Expand All @@ -158,7 +158,7 @@ class servers { // also a block
uint64_t clockNow = time(NULL);
while (clockNow < waitUntil) {
boost::this_thread::sleep(boost::posix_time::seconds(1));
ELOG("Awaiting for genesis block time: %lu s\n", waitUntil - clockNow);
ILOG("Awaiting for genesis block time: %lu s\n", waitUntil - clockNow);
clockNow = time(NULL);
RETURN_ON_SHUTDOWN()
;
Expand Down Expand Up @@ -285,7 +285,7 @@ class servers { // also a block
}
}

ELOG("INIT: weight diff: %016lX\n", TOTALMASS-sum);
ILOG("INIT: weight diff: %016lX\n", TOTALMASS-sum);
//nodes.begin()->weight=TOTALMASS-sum;
assert(num > 0);
//vtot=(uint16_t)(num<VIP_MAX?num:VIP_MAX); // probably not needed !!!
Expand Down Expand Up @@ -1033,7 +1033,7 @@ class servers { // also a block
tree.finish(nodhash);
char hash[2*SHA256_DIGEST_LENGTH];
ed25519_key2text(hash,nodhash,SHA256_DIGEST_LENGTH);
ELOG("NODHASH sync %.*s\n",2*SHA256_DIGEST_LENGTH,hash);
ILOG("NODHASH sync %.*s\n",2*SHA256_DIGEST_LENGTH,hash);
hashnow();
//char filename[64];
//sprintf(filename,"blk/%03X/%05X/servers.txt",now>>20,now&0xFFFFF);
Expand Down Expand Up @@ -1636,7 +1636,7 @@ class servers { // also a block
tree.finish(tmphash);
char hash[2*SHA256_DIGEST_LENGTH];
ed25519_key2text(hash,tmphash,SHA256_DIGEST_LENGTH);
ELOG("NODHASH sync %.*s\n",2*SHA256_DIGEST_LENGTH,hash);
ILOG("NODHASH sync %.*s\n",2*SHA256_DIGEST_LENGTH,hash);
return(memcmp(tmphash,peer_nodehash,SHA256_DIGEST_LENGTH));
}

Expand Down Expand Up @@ -1689,7 +1689,7 @@ class servers { // also a block
div=0;
}
//ELOG("NEW DIVIDEND %08X (%.8f)\n",div,(float)(div)/0xFFFFFFFF);
ELOG("NEW DIVIDEND %08X (%.8f) (diff:%016lX,div:%.8lf)\n",
ILOG("NEW DIVIDEND %08X (%.8f) (diff:%016lX,div:%.8lf)\n",
div,(float)(div)/0xFFFF,TOTALMASS-sum,(double)(TOTALMASS-sum)/(double)sum);
}
blockdir();
Expand Down Expand Up @@ -1750,7 +1750,7 @@ class servers { // also a block
void clean_old(uint16_t svid) {
if (MAX_UNDO > 0) {
char pat[8];
ELOG("CLEANING by %04X\n",svid);
ILOG("CLEANING by %04X\n",svid);
sprintf(pat,"%04X",svid);
for(int i=MAX_UNDO; i<MAX_UNDO+100; i+=10) {
#ifdef DEBUG
Expand Down
4 changes: 2 additions & 2 deletions src/escd/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ int main(int argc, char* argv[]) {
opt.init=false;
opt.comm=true;
opt.genesis="";
ELOG("\n\nRESTARTING\n\n\n");
ILOG("\n\nRESTARTING\n\n\n");
} else {
ELOG("Shutting down\n");
ILOG("Shutting down\n");
}
o.stop();
s.stop();
Expand Down
Loading

0 comments on commit 6f276ed

Please sign in to comment.