std::error_code TestWallet::init() { CryptoNote::account_base walletAccount; walletAccount.generate(); WalletAccountKeys walletKeys; walletKeys.spendPublicKey = reinterpret_cast<const WalletPublicKey&>(walletAccount.get_keys().m_account_address.m_spendPublicKey); walletKeys.spendSecretKey = reinterpret_cast<const WalletSecretKey&>(walletAccount.get_keys().m_spend_secret_key); walletKeys.viewPublicKey = reinterpret_cast<const WalletPublicKey&>(walletAccount.get_keys().m_account_address.m_viewPublicKey); walletKeys.viewSecretKey = reinterpret_cast<const WalletSecretKey&>(walletAccount.get_keys().m_view_secret_key); m_wallet->initWithKeys(walletKeys, TEST_PASSWORD); m_synchronizationCompleted.wait(); return m_lastSynchronizationResult; }
bool init_output_indices(map_output_idx_t& outs, std::map<uint64_t, std::vector<size_t> >& outs_mine, const std::vector<cryptonote::Block>& blockchain, const map_hash2tx_t& mtx, const cryptonote::account_base& from) { BOOST_FOREACH (const Block& blk, blockchain) { vector<const Transaction*> vtx; vtx.push_back(&blk.minerTx); for (const crypto::hash& h : blk.txHashes) { const map_hash2tx_t::const_iterator cit = mtx.find(h); if (mtx.end() == cit) throw std::runtime_error("block contains an unknown tx hash"); vtx.push_back(cit->second); } //vtx.insert(vtx.end(), blk.); // TODO: add all other txes for (size_t i = 0; i < vtx.size(); i++) { const Transaction &tx = *vtx[i]; size_t keyIndex = 0; for (size_t j = 0; j < tx.vout.size(); ++j) { const TransactionOutput &out = tx.vout[j]; if (out.target.type() == typeid(TransactionOutputToKey)) { output_index oi(out.target, out.amount, boost::get<TransactionInputGenerate>(*blk.minerTx.vin.begin()).height, i, j, &blk, vtx[i]); outs[out.amount].push_back(oi); size_t tx_global_idx = outs[out.amount].size() - 1; outs[out.amount][tx_global_idx].idx = tx_global_idx; // Is out to me? if (is_out_to_acc(from.get_keys(), boost::get<TransactionOutputToKey>(out.target), get_tx_pub_key_from_extra(tx), keyIndex)) { outs_mine[out.amount].push_back(tx_global_idx); } ++keyIndex; } else if (out.target.type() == typeid(TransactionOutputMultisignature)) { keyIndex += boost::get<TransactionOutputMultisignature>(out.target).keys.size(); } } } }
bool test_generator::constructMaxSizeBlock(CryptoNote::Block& blk, const CryptoNote::Block& blkPrev, const CryptoNote::account_base& minerAccount, size_t medianBlockCount/* = 0*/, const std::list<CryptoNote::Transaction>& txList/* = std::list<CryptoNote::Transaction>()*/) { std::vector<size_t> blockSizes; medianBlockCount = medianBlockCount == 0 ? m_currency.rewardBlocksWindow() : medianBlockCount; getLastNBlockSizes(blockSizes, get_block_hash(blkPrev), medianBlockCount); size_t median = Common::medianValue(blockSizes); size_t blockGrantedFullRewardZone = defaultMajorVersion <= BLOCK_MAJOR_VERSION_1 ? CryptoNote::parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 : m_currency.blockGrantedFullRewardZone(); median = std::max(median, blockGrantedFullRewardZone); uint64_t totalFee = 0; size_t txsSize = 0; std::vector<crypto::hash> txHashes; for (auto& tx : txList) { uint64_t fee = 0; bool r = get_tx_fee(tx, fee); CHECK_AND_ASSERT_MES(r, false, "wrong transaction passed to construct_max_size_block"); totalFee += fee; txsSize += get_object_blobsize(tx); txHashes.push_back(get_transaction_hash(tx)); } Transaction minerTx; bool r = constructMinerTxBySize(m_currency, minerTx, get_block_height(blkPrev) + 1, getAlreadyGeneratedCoins(blkPrev), minerAccount.get_keys().m_account_address, blockSizes, 2 * median - txsSize, 2 * median, totalFee, defaultMajorVersion > BLOCK_MAJOR_VERSION_1); if (!r) { return false; } return constructBlockManually(blk, blkPrev, minerAccount, test_generator::bf_miner_tx | test_generator::bf_tx_hashes, 0, 0, 0, crypto::hash(), 0, minerTx, txHashes, txsSize, totalFee); }
bool test_generator::constructBlock(CryptoNote::Block& blk, uint32_t height, const crypto::hash& prevId, const CryptoNote::account_base& minerAcc, uint64_t timestamp, uint64_t alreadyGeneratedCoins, std::vector<size_t>& blockSizes, const std::list<CryptoNote::Transaction>& txList) { blk.majorVersion = defaultMajorVersion; blk.minorVersion = defaultMinorVersion; blk.timestamp = timestamp; blk.prevId = prevId; blk.txHashes.reserve(txList.size()); for (const Transaction &tx : txList) { crypto::hash tx_hash; get_transaction_hash(tx, tx_hash); blk.txHashes.push_back(tx_hash); } uint64_t totalFee = 0; size_t txsSize = 0; for (auto& tx : txList) { uint64_t fee = 0; bool r = get_tx_fee(tx, fee); CHECK_AND_ASSERT_MES(r, false, "wrong transaction passed to construct_block"); totalFee += fee; txsSize += get_object_blobsize(tx); } blk.minerTx = boost::value_initialized<Transaction>(); size_t targetBlockSize = txsSize + get_object_blobsize(blk.minerTx); while (true) { if (!m_currency.constructMinerTx(height, Common::medianValue(blockSizes), alreadyGeneratedCoins, targetBlockSize, totalFee, minerAcc.get_keys().m_account_address, blk.minerTx, blobdata(), 10)) { return false; } size_t actualBlockSize = txsSize + get_object_blobsize(blk.minerTx); if (targetBlockSize < actualBlockSize) { targetBlockSize = actualBlockSize; } else if (actualBlockSize < targetBlockSize) { size_t delta = targetBlockSize - actualBlockSize; blk.minerTx.extra.resize(blk.minerTx.extra.size() + delta, 0); actualBlockSize = txsSize + get_object_blobsize(blk.minerTx); if (actualBlockSize == targetBlockSize) { break; } else { CHECK_AND_ASSERT_MES(targetBlockSize < actualBlockSize, false, "Unexpected block size"); delta = actualBlockSize - targetBlockSize; blk.minerTx.extra.resize(blk.minerTx.extra.size() - delta); actualBlockSize = txsSize + get_object_blobsize(blk.minerTx); if (actualBlockSize == targetBlockSize) { break; } else { CHECK_AND_ASSERT_MES(actualBlockSize < targetBlockSize, false, "Unexpected block size"); blk.minerTx.extra.resize(blk.minerTx.extra.size() + delta, 0); targetBlockSize = txsSize + get_object_blobsize(blk.minerTx); } } } else { break; } } if (blk.majorVersion >= BLOCK_MAJOR_VERSION_2) { blk.parentBlock.majorVersion = BLOCK_MAJOR_VERSION_1; blk.parentBlock.minorVersion = BLOCK_MINOR_VERSION_0; blk.parentBlock.numberOfTransactions = 1; CryptoNote::tx_extra_merge_mining_tag mmTag; mmTag.depth = 0; if (!CryptoNote::get_aux_block_header_hash(blk, mmTag.merkle_root)) { return false; } blk.parentBlock.minerTx.extra.clear(); if (!CryptoNote::append_mm_tag_to_extra(blk.parentBlock.minerTx.extra, mmTag)) { return false; } } // Nonce search... blk.nonce = 0; crypto::cn_context context; while (!miner::find_nonce_for_given_block(context, blk, getTestDifficulty())) { blk.timestamp++; } addBlock(blk, txsSize, totalFee, blockSizes, alreadyGeneratedCoins); return true; }
TEST(parse_and_validate_tx_extra, fails_on_big_extra_nonce) { Logging::LoggerGroup logger; CryptoNote::Currency currency = CryptoNote::CurrencyBuilder(logger).currency(); CryptoNote::Transaction tx = AUTO_VAL_INIT(tx); CryptoNote::account_base acc; acc.generate(); CryptoNote::blobdata b(TX_EXTRA_NONCE_MAX_COUNT + 1, 0); ASSERT_FALSE(currency.constructMinerTx(0, 0, 10000000000000, 1000, currency.minimumFee(), acc.get_keys().m_account_address, tx, b, 1)); }
TEST(parse_and_validate_tx_extra, is_valid_tx_extra_parsed) { Logging::LoggerGroup logger; CryptoNote::Currency currency = CryptoNote::CurrencyBuilder(logger).currency(); CryptoNote::Transaction tx = AUTO_VAL_INIT(tx); CryptoNote::account_base acc; acc.generate(); CryptoNote::blobdata b = "dsdsdfsdfsf"; ASSERT_TRUE(currency.constructMinerTx(0, 0, 10000000000000, 1000, currency.minimumFee(), acc.get_keys().m_account_address, tx, b, 1)); crypto::public_key tx_pub_key = CryptoNote::get_tx_pub_key_from_extra(tx); ASSERT_NE(tx_pub_key, CryptoNote::null_pkey); }