2015-04-23 16:07:22 +00:00
|
|
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
#include "SynchronizationState.h"
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "Common/StdInputStream.h"
|
|
|
|
#include "Common/StdOutputStream.h"
|
|
|
|
#include "Serialization/BinaryInputStreamSerializer.h"
|
|
|
|
#include "Serialization/BinaryOutputStreamSerializer.h"
|
|
|
|
#include "CryptoNoteCore/CryptoNoteSerialization.h"
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
using namespace Common;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
namespace CryptoNote {
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
SynchronizationState::ShortHistory SynchronizationState::getShortHistory(uint32_t localHeight) const {
|
2015-04-06 16:13:07 +00:00
|
|
|
ShortHistory history;
|
2015-07-30 15:22:07 +00:00
|
|
|
uint32_t i = 0;
|
|
|
|
uint32_t current_multiplier = 1;
|
|
|
|
uint32_t sz = std::min(static_cast<uint32_t>(m_blockchain.size()), localHeight + 1);
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
if (!sz)
|
|
|
|
return history;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
uint32_t current_back_offset = 1;
|
2015-04-06 16:13:07 +00:00
|
|
|
bool genesis_included = false;
|
|
|
|
|
|
|
|
while (current_back_offset < sz) {
|
|
|
|
history.push_back(m_blockchain[sz - current_back_offset]);
|
|
|
|
if (sz - current_back_offset == 0)
|
|
|
|
genesis_included = true;
|
|
|
|
if (i < 10) {
|
|
|
|
++current_back_offset;
|
|
|
|
} else {
|
|
|
|
current_back_offset += current_multiplier *= 2;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!genesis_included)
|
|
|
|
history.push_back(m_blockchain[0]);
|
|
|
|
|
|
|
|
return history;
|
|
|
|
}
|
|
|
|
|
|
|
|
SynchronizationState::CheckResult SynchronizationState::checkInterval(const BlockchainInterval& interval) const {
|
|
|
|
assert(interval.startHeight <= m_blockchain.size());
|
|
|
|
|
|
|
|
CheckResult result = { false, 0, false, 0 };
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
uint32_t intervalEnd = interval.startHeight + static_cast<uint32_t>(interval.blocks.size());
|
|
|
|
uint32_t iterationEnd = std::min(static_cast<uint32_t>(m_blockchain.size()), intervalEnd);
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
for (uint32_t i = interval.startHeight; i < iterationEnd; ++i) {
|
2015-04-06 16:13:07 +00:00
|
|
|
if (m_blockchain[i] != interval.blocks[i - interval.startHeight]) {
|
|
|
|
result.detachRequired = true;
|
|
|
|
result.detachHeight = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (result.detachRequired) {
|
|
|
|
result.hasNewBlocks = true;
|
|
|
|
result.newBlockHeight = result.detachHeight;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (intervalEnd > m_blockchain.size()) {
|
|
|
|
result.hasNewBlocks = true;
|
2015-07-30 15:22:07 +00:00
|
|
|
result.newBlockHeight = static_cast<uint32_t>(m_blockchain.size());
|
2015-04-06 16:13:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
void SynchronizationState::detach(uint32_t height) {
|
2015-04-06 16:13:07 +00:00
|
|
|
assert(height < m_blockchain.size());
|
|
|
|
m_blockchain.resize(height);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
void SynchronizationState::addBlocks(const Crypto::Hash* blockHashes, uint32_t height, uint32_t count) {
|
2015-04-06 16:13:07 +00:00
|
|
|
assert(blockHashes);
|
|
|
|
auto size = m_blockchain.size();
|
|
|
|
assert( size == height);
|
|
|
|
m_blockchain.insert(m_blockchain.end(), blockHashes, blockHashes + count);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
uint32_t SynchronizationState::getHeight() const {
|
|
|
|
return static_cast<uint32_t>(m_blockchain.size());
|
2015-04-06 16:13:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SynchronizationState::save(std::ostream& os) {
|
2015-07-30 15:22:07 +00:00
|
|
|
StdOutputStream stream(os);
|
|
|
|
CryptoNote::BinaryOutputStreamSerializer s(stream);
|
2015-04-06 16:13:07 +00:00
|
|
|
serialize(s, "state");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SynchronizationState::load(std::istream& in) {
|
2015-07-30 15:22:07 +00:00
|
|
|
StdInputStream stream(in);
|
|
|
|
CryptoNote::BinaryInputStreamSerializer s(stream);
|
2015-04-06 16:13:07 +00:00
|
|
|
serialize(s, "state");
|
|
|
|
}
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CryptoNote::ISerializer& SynchronizationState::serialize(CryptoNote::ISerializer& s, const std::string& name) {
|
2015-04-06 16:13:07 +00:00
|
|
|
s.beginObject(name);
|
|
|
|
s(m_blockchain, "blockchain");
|
|
|
|
s.endObject();
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|