Skip to content
Permalink
Browse files

Merge pull request #46 from mceme/masterendecrypt

Image.dat Isolation
  • Loading branch information...
mceme committed Jun 6, 2019
2 parents 870175d + 284f9cb commit cf3883257156703662b25b373046aa13fd4a5544
@@ -1,4 +1,6 @@

_build
depends
src/test/data
src/RCa10760
build-dash-qt-dat-Debug/debug/dash-qt.exe
build-dash-qt-dat-Debug/ui_transactiondescdialog.h
@@ -25,3 +27,37 @@ build-dash-qt-dat-Debug/Makefile.Release
build-dash-qt-dat-Debug/Makefile.Debug
build-dash-qt-dat-Debug/Makefile
build-dash-qt-dat-Debug/debug/dash-qt.exe
Makefile.in
Makefile
.deps
.libs
*.o
*.lo
.idea
autom4te.cache
build-aux
*.a
.dirstamp
src/qt
run-bitcoind-for-test.sh
tests_config.py
aclocal.m4
libimagecoinconsensus.pc
setup.nsi
src/config
src/ImageCoin*
libimagecoinconsensus.la
buildenv.py
share/qt
config.*
configure
libtool
daemon.usage.txt
test_dash
__wallet_code
__home
wallet.dat
debug.log
image.wallet.dat
libbitcoin_server_a*
cache
@@ -0,0 +1,75 @@
# 版本升级
* image core和wallet.dat从 v0.13.1.2 升级到 v0.13.1.3
* v0.13.1.2和v0.13.1.3的imagecoind可以在网络中共存
* 低版本imagecoind不能读高版本的wallet.dat
* 高版本imagecoind可以读低版本的wallet.dat

# 使用场景
## 1. 创建新地址, 导入已经存在的地址
* 该地址的相关交易, 除imagebase64字段以外的其他数据仍然会保存到wallet.dat
* imagebase64字段则保存在~/.imagecoind/image/image.dat

## 2. imagecoin-qt
* 使用无任何变化
* 对图币分离完全无感知

## 3. imagecoind 重启
* wallet.dat仍然会在~/.imagecoind/backups里做备份
* image.dat不做备份

## 4. wallet.dat 损坏或者丢失
* 用备份的wallet.dat导入私钥, 系统会重新下载相关交易
* 随后流程参照case#1

## 5. image.dat 损坏或者丢失
* imagecoind启动时如果发现image.dat不可读或者与wallet.dat不匹配
* imagecoind会去网络下载wallet.dat里所有地址的相关交易
* 随后流程参照case#1

## 6. -salvagewallet参数
* 会重新下载tx和image数据
* 随后流程参照case#1

## 7. -rescan参数
* 会重新下载tx和image数据
* 随后流程参照case#1

## 8. 兼容性1
* 升级的程序(>=v0.13.1.3)在第一次启动时会把旧的wallet.dat里的image数据移动到~/.imagecoind/image/image.dat
* wallet.dat里只留除imagebase64字段以外的其他数据
* 随后流程参照case#1

## 9. 兼容性2
* 旧程序(<=v0.13.1.2)启动时如果发现wallet.dat版本比自己高(>=v0.13.1.3), 则报错退出.

## 10. movecmd, 转账
* 不受任何影响

# 图币分离程序使用
## 下载编译代码
* git clone https://github.com/zhongqiuwood/ImageCoin -b dev
* 编译步骤不变

## case1: 先备份再升级
* 升级之前用<ImageCoin-cli dumpwallet backup.txt>备份wallet.dat, 然后删除wallet.dat
* 升级ImageCoind/ImageCoind-qt, 启动ImageCoind/ImageCoind-qt
* 从backup.txt导入备份的key
* 系统会重新下载相关tx, image数据会被保存在~/.imagecoind/image/image.dat
* 其他数据保存在~/.imagecoind/wallet.dat

## case2: 不做备份直接升级
* 升级ImageCoind/ImageCoind-qt, 启动ImageCoind/ImageCoind-qt
* 系统会因找不到~/.imagecoind/image/image.dat而重新下载相关tx
* 如果是ImageCoind-qt, 会弹出下图对话框, 点OK按钮继续
* https://github.com/zhongqiuwood/ImageCoin/blob/dev/src/wbuild/imageErr.jpg
* 之后image数据会被保存在~/.imagecoind/image/image.dat
* 其他数据保存在~/.imagecoind/wallet.dat

## config
```
./configure LDFLAGS="-L/root/qzhong/imagec/db4/lib/" CPPFLAGS="-I/root/qzhong/imagec/db4/include/" --enable-debug --disable-bench --disable-gui-tests --disable-tests
./configure --enable-debug --disable-bench --disable-gui-tests --disable-tests
./configure --enable-debug --disable-bench --disable-gui-tests --without-gui
./configure --enable-debug --disable-bench --disable-gui-tests --without-gui --disable-tests
```
0 autogen.sh 100644 → 100755
No changes.
@@ -0,0 +1,18 @@
#!/bin/bash
DASH_ROOT=$(pwd)

# Pick some path to install BDB to, here we create a directory within the dash directory
BDB_PREFIX="${DASH_ROOT}/db4"
mkdir -p $BDB_PREFIX

# Fetch the source and verify that it is not tampered with
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
echo '12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz' | sha256sum -c
# -> db-4.8.30.NC.tar.gz: OK
tar -xzvf db-4.8.30.NC.tar.gz

# Build the library and install to our prefix
cd db-4.8.30.NC/build_unix/
# Note: Do a static build so that it can be embedded into the executable, instead of having to find a .so at runtime
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=$BDB_PREFIX
make install
0 share/genbuild.sh 100644 → 100755
No changes.
@@ -496,6 +496,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-hdseed", _("User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)"));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup"));
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), "wallet.dat"));
strUsage += HelpMessageOpt("-image=<file>", _("Specify image file (within ${datadir}/image directory)") + " " + strprintf(_("(default: %s)"), "image.dat"));
strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
@@ -1680,9 +1681,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Wallet disabled!\n");
} else {

// 0. recover wallet


// needed to restore wallet transaction meta data after -zapwallettxes
std::vector<CWalletTx> vWtx;

// 1. zapwallettxes
if (GetBoolArg("-zapwallettxes", false)) {
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));

@@ -1702,6 +1707,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nStart = GetTimeMillis();
bool fFirstRun = true;
pwalletMain = new CWallet(strWalletFile);


// 2. LoadWallet

DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK)
{
@@ -1712,6 +1721,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
InitWarning(_("Error reading wallet.dat! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect."));
}
else if (nLoadWalletRet == DB_RESCAN_IMAGE)
{
InitWarning(_("Error reading image.dat! Will rescan blockchain to recover image.dat."));
}
else if (nLoadWalletRet == DB_TOO_NEW)
strErrors << _("Error loading wallet.dat: Wallet requires newer version of ImageCoin Core") << "\n";
else if (nLoadWalletRet == DB_NEED_REWRITE)
@@ -1724,6 +1737,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
strErrors << _("Error loading wallet.dat") << "\n";
}


if (GetBoolArg("-upgradewallet", fFirstRun))
{
int nMaxVersion = GetArg("-upgradewallet", 0);
@@ -1740,6 +1754,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
pwalletMain->SetMaxVersion(nMaxVersion);
}

std::string imageFile = GetArg("-image", DEFAULT_IMAGE_FILE);
if (imageFile.length() > 0) {

if (FEATURE_IMAGE_ISOLATION > pwalletMain->GetVersion()) {
pwalletMain->SetMinVersion(FEATURE_IMAGE_ISOLATION); // permanently upgrade the wallet immediately
}
}

if (fFirstRun)
{
// Create new keyUser and set as default key
@@ -1794,8 +1816,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterValidationInterface(pwalletMain);

CBlockIndex *pindexRescan = chainActive.Tip();
bool rescan = false;
if (GetBoolArg("-rescan", false))
{

LogPrintf("rescan is set to true\n");

pindexRescan = chainActive.Genesis();
rescan = true;
}
else
{
CWalletDB walletdb(strWalletFile);
@@ -1805,8 +1834,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
else
pindexRescan = chainActive.Genesis();
}
if (chainActive.Tip() && chainActive.Tip() != pindexRescan)

if (rescan || (chainActive.Tip() && chainActive.Tip() != pindexRescan))
{
LogPrintf("rescan: chainActive.Tip() && chainActive.Tip() != pindexRescan\n");

//We can't rescan beyond non-pruned blocks, stop and throw an error
//this might happen if a user uses a old wallet within a pruned node
// or if he ran -disablewallet for a longer time, then decided to re-enable
@@ -1854,6 +1886,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
}
}
pwalletMain->SetBroadcastTransactions(GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));


} // (!fDisableWallet)
#else // ENABLE_WALLET
LogPrintf("No wallet support compiled in!\n");
@@ -136,6 +136,7 @@ class CTxOut
CAmount nValue;
CScript scriptPubKey;
std::string imgbase64;

int nRounds;

CTxOut()
@@ -216,6 +217,7 @@ class CTransaction
private:
/** Memory only. */
const uint256 hash;
protected:
void UpdateHash() const;

public:
@@ -181,7 +181,7 @@ enum
* code. Adding "ADD_SERIALIZE_METHODS" in the body of the class causes these wrappers to be
* added as members.
*/
#define ADD_SERIALIZE_METHODS \
#define ADD_SERIALIZE_METHODS \
size_t GetSerializeSize(int nType, int nVersion) const { \
CSizeComputer s(nType, nVersion); \
NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\
@@ -79,8 +79,16 @@ bool CDBEnv::Open(const boost::filesystem::path& pathIn)
boost::this_thread::interruption_point();

strPath = pathIn.string();


LogPrintf("CDBEnv::Open: %s\n", strPath.c_str());

boost::filesystem::path pathLogDir = pathIn / "database";
TryCreateDirectory(pathLogDir);

boost::filesystem::path pathImageDir = pathIn / "image";
TryCreateDirectory(pathImageDir);

boost::filesystem::path pathErrorFile = pathIn / "db.log";
LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string());

@@ -460,3 +468,52 @@ void CDBEnv::Flush(bool fShutdown)
}
}
}


Dbc* CDB::GetCursor()
{
if (!pdb)
return NULL;
Dbc* pcursor = NULL;
int ret = pdb->cursor(NULL, &pcursor, 0);
if (ret != 0)
return NULL;
return pcursor;
}

int CDB::ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags)
{
// Read at cursor
Dbt datKey;
if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
datKey.set_data(ssKey.data());
datKey.set_size(ssKey.size());
}
Dbt datValue;
if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) {
datValue.set_data(&ssValue[0]);
datValue.set_size(ssValue.size());
}
datKey.set_flags(DB_DBT_MALLOC);
datValue.set_flags(DB_DBT_MALLOC);
int ret = pcursor->get(&datKey, &datValue, fFlags);
if (ret != 0)
return ret;
else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
return 99999;

// Convert to streams
ssKey.SetType(SER_DISK);
ssKey.clear();
ssKey.write((char*)datKey.get_data(), datKey.get_size());
ssValue.SetType(SER_DISK);
ssValue.clear();
ssValue.write((char*)datValue.get_data(), datValue.get_size());

// Clear and free memory
memset(datKey.get_data(), 0, datKey.get_size());
memset(datValue.get_data(), 0, datValue.get_size());
free(datKey.get_data());
free(datValue.get_data());
return 0;
}

0 comments on commit cf38832

Please sign in to comment.
You can’t perform that action at this time.