Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into mix_test

cl-refactor
arkpar 10 years ago
parent
commit
dfdcdfa0c3
  1. 2
      alethzero/Transact.cpp
  2. 20
      libethcore/Ethasher.cpp
  3. 6
      libethcore/Params.h
  4. 5
      libethereum/Executive.cpp
  5. 2
      libethereum/Executive.h
  6. 40
      libethereum/State.cpp
  7. 8
      libethereum/Transaction.cpp
  8. 27
      libethereum/Transaction.h
  9. 2
      libp2p/Host.h
  10. 104
      libsolidity/ArrayUtils.cpp
  11. 6
      libsolidity/ArrayUtils.h
  12. 107
      libsolidity/ExpressionCompiler.cpp
  13. 53
      libtestutils/BlockChainLoader.cpp
  14. 4
      libwhisper/Message.cpp

2
alethzero/Transact.cpp

@ -338,7 +338,7 @@ void Transact::rejigData()
}
if (er.codeDeposit == CodeDeposit::Failed)
{
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas</div>");
bail("<div class=\"error\"><span class=\"icon\">ERROR</span> Code deposit failed due to insufficient gas; " + QString::fromStdString(toString(er.gasForDeposit)) + " GAS &lt; " + QString::fromStdString(toString(er.depositSize)) + " bytes * " + QString::fromStdString(toString(c_createDataGas)) + "GAS/byte</div>");
return;
}

20
libethcore/Ethasher.cpp

@ -112,17 +112,24 @@ bool Ethasher::verify(BlockInfo const& _header)
h256 boundary = u256((bigint(1) << 256) / _header.difficulty);
bool ret = ethash_quick_check_difficulty(
bool quick = ethash_quick_check_difficulty(
_header.headerHash(WithoutNonce).data(),
(uint64_t)(u64)_header.nonce,
_header.mixHash.data(),
boundary.data());
#if ETH_DEBUG
#if !ETH_DEBUG
if (!quick)
return false;
#endif
auto result = eval(_header);
if ((result.value <= boundary && result.mixHash == _header.mixHash) != ret)
bool slow = result.value <= boundary && result.mixHash == _header.mixHash;
#if ETH_DEBUG
if (!quick && slow)
{
cwarn << "Assertion failure coming: evaluated result gives different outcome to ethash_quick_check_difficulty";
cwarn << "WARNING: evaluated result gives true whereas ethash_quick_check_difficulty gives false.";
cwarn << "headerHash:" << _header.headerHash(WithoutNonce);
cwarn << "nonce:" << _header.nonce;
cwarn << "mixHash:" << _header.mixHash;
@ -131,12 +138,9 @@ bool Ethasher::verify(BlockInfo const& _header)
cwarn << "result.value:" << result.value;
cwarn << "result.mixHash:" << result.mixHash;
}
assert((result.value <= boundary) == ret);
if (result.value <= boundary)
assert(result.mixHash == _header.mixHash);
#endif
return ret;
return slow;
}
Ethasher::Result Ethasher::eval(BlockInfo const& _header, Nonce const& _nonce)

6
libethcore/Params.h

@ -29,15 +29,15 @@ namespace eth
{
//--- BEGIN: AUTOGENERATED FROM /feeStructure.json
extern u256 const c_genesisDifficulty;
extern u256 const c_maximumExtraDataSize;
extern u256 const c_epochDuration;
extern u256 const c_genesisGasLimit;
extern u256 const c_minGasLimit;
extern u256 const c_gasLimitBoundDivisor;
extern u256 const c_genesisDifficulty;
extern u256 const c_minimumDifficulty;
extern u256 const c_difficultyBoundDivisor;
extern u256 const c_durationLimit;
extern u256 const c_maximumExtraDataSize;
extern u256 const c_epochDuration;
extern u256 const c_stackLimit;
extern u256 const c_tierStepGas[8]; ///< Once per operation, for a selection of them.

5
libethereum/Executive.cpp

@ -46,7 +46,7 @@ u256 Executive::gasUsed() const
ExecutionResult Executive::executionResult() const
{
return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0);
return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0, m_depositSize, m_gasForDeposit);
}
void Executive::accrueSubState(SubState& _parentContext)
@ -221,6 +221,8 @@ bool Executive::go(OnOpFunc const& _onOp)
if (m_isCreation)
{
m_gasForDeposit = m_endGas;
m_depositSize = m_out.size();
if (m_out.size() * c_createDataGas <= m_endGas)
{
m_codeDeposit = CodeDeposit::Success;
@ -228,6 +230,7 @@ bool Executive::go(OnOpFunc const& _onOp)
}
else
{
m_codeDeposit = CodeDeposit::Failed;
m_out.reset();
}

2
libethereum/Executive.h

@ -128,6 +128,8 @@ private:
unsigned m_depth = 0; ///< The context's call-depth.
bool m_isCreation = false; ///< True if the transaction creates a contract, or if create() is called.
unsigned m_depositSize = 0; ///< Amount of code of the creation's attempted deposit.
u256 m_gasForDeposit; ///< Amount of gas remaining for the code deposit phase.
CodeDeposit m_codeDeposit = CodeDeposit::None; ///< True if an attempted deposit failed due to lack of gas.
TransactionException m_excepted = TransactionException::None; ///< Details if the VM's execution resulted in an exception.
u256 m_endGas; ///< The final amount of gas for the transaction.

40
libethereum/State.cpp

@ -111,22 +111,36 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h):
m_state(&m_db),
m_blockReward(c_blockReward)
{
// TODO THINK: is this necessary?
m_state.init();
auto b = _bc.block(_h);
BlockInfo bi;
BlockInfo bip;
if (_h)
bi.populate(b);
if (bi && bi.number)
bip.populate(_bc.block(bi.parentHash));
if (!_h || !bip)
BlockInfo bi(b);
if (!bi)
{
// Might be worth throwing here.
cwarn << "Invalid block given for state population: " << _h;
return;
m_ourAddress = bi.coinbaseAddress;
}
sync(_bc, bi.parentHash, bip);
enact(&b, _bc);
if (bi.number)
{
// Non-genesis:
// 1. Start at parent's end state (state root).
BlockInfo bip;
bip.populate(_bc.block(bi.parentHash));
sync(_bc, bi.parentHash, bip);
// 2. Enact the block's transactions onto this state.
m_ourAddress = bi.coinbaseAddress;
enact(&b, _bc);
}
else
{
// Genesis required:
// We know there are no transactions, so just populate directly.
m_state.init();
sync(_bc, _h, bi);
}
}
State::State(State const& _s):

8
libethereum/Transaction.cpp

@ -88,12 +88,12 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
}
catch (Exception& _e)
{
_e << errinfo_name("invalid transaction format") << BadFieldError(field,toHex(rlp[field].data().toBytes()));
_e << errinfo_name("invalid transaction format") << BadFieldError(field, toHex(rlp[field].data().toBytes()));
throw;
}
}
Address Transaction::safeSender() const noexcept
Address const& Transaction::safeSender() const noexcept
{
try
{
@ -102,11 +102,11 @@ Address Transaction::safeSender() const noexcept
catch (...)
{
cwarn << "safeSender() did throw an exception: " << boost::current_exception_diagnostic_information();
return Address();
return NullAddress;
}
}
Address Transaction::sender() const
Address const& Transaction::sender() const
{
if (!m_sender)
{

27
libethereum/Transaction.h

@ -75,17 +75,30 @@ TransactionException toTransactionException(VMException const& _e);
struct ExecutionResult
{
ExecutionResult() = default;
ExecutionResult(u256 _gasUsed, TransactionException _excepted, Address _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit, u256 _gasRefund): gasUsed(_gasUsed), excepted(_excepted), newAddress(_newAddress), output(_output.toBytes()), codeDeposit(_codeDeposit), gasRefunded(_gasRefund) {}
ExecutionResult(u256 const& _gasUsed, TransactionException _excepted, Address const& _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit, u256 const& _gasRefund, unsigned _depositSize, u256 const& _gasForDeposit):
gasUsed(_gasUsed),
excepted(_excepted),
newAddress(_newAddress),
output(_output.toBytes()),
codeDeposit(_codeDeposit),
gasRefunded(_gasRefund),
depositSize(_depositSize),
gasForDeposit(_gasForDeposit)
{}
u256 gasUsed = 0;
TransactionException excepted = TransactionException::Unknown;
Address newAddress;
bytes output;
CodeDeposit codeDeposit = CodeDeposit::None;
u256 gasRefunded = 0;
unsigned depositSize = 0;
u256 gasForDeposit;
};
std::ostream& operator<<(std::ostream& _out, ExecutionResult const& _er);
static const Address NullAddress;
/// Encodes a transaction, ready to be exported to or freshly imported from RLP.
class Transaction
{
@ -94,16 +107,16 @@ public:
Transaction() {}
/// Constructs a signed message-call transaction.
Transaction(u256 _value, u256 _gasPrice, u256 _gas, Address const& _dest, bytes const& _data, u256 _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
/// Constructs a signed contract-creation transaction.
Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data, u256 _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); }
/// Constructs an unsigned message-call transaction.
Transaction(u256 _value, u256 _gasPrice, u256 _gas, Address const& _dest, bytes const& _data): m_type(MessageCall), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data): m_type(MessageCall), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs an unsigned contract-creation transaction.
Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs a transaction from the given RLP.
explicit Transaction(bytesConstRef _rlp, CheckSignature _checkSig);
@ -118,9 +131,9 @@ public:
bool operator!=(Transaction const& _c) const { return !operator==(_c); }
/// @returns sender of the transaction from the signature (and hash).
Address sender() const;
Address const& sender() const;
/// Like sender() but will never throw. @returns a null Address if the signature is invalid.
Address safeSender() const noexcept;
Address const& safeSender() const noexcept;
/// @returns true if transaction is non-null.
explicit operator bool() const { return m_type != NullTransaction; }

2
libp2p/Host.h

@ -96,7 +96,7 @@ public:
static std::string pocHost();
/// Register a peer-capability; all new peer connections will have this capability.
template <class T> std::shared_ptr<T> registerCapability(T* _t) { _t->m_host = this; auto ret = std::shared_ptr<T>(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; }
template <class T> std::shared_ptr<T> registerCapability(T* _t) { _t->m_host = this; std::shared_ptr<T> ret(_t); m_capabilities[std::make_pair(T::staticName(), T::staticVersion())] = ret; return ret; }
bool haveCapability(CapDesc const& _name) const { return m_capabilities.count(_name) != 0; }
CapDescs caps() const { CapDescs ret; for (auto const& i: m_capabilities) ret.push_back(i.first); return ret; }

104
libsolidity/ArrayUtils.cpp

@ -440,6 +440,110 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType) const
}
}
void ArrayUtils::accessIndex(ArrayType const& _arrayType) const
{
ArrayType::Location location = _arrayType.getLocation();
eth::Instruction load =
location == ArrayType::Location::Storage ? eth::Instruction::SLOAD :
location == ArrayType::Location::Memory ? eth::Instruction::MLOAD :
eth::Instruction::CALLDATALOAD;
// retrieve length
if (!_arrayType.isDynamicallySized())
m_context << _arrayType.getLength();
else if (location == ArrayType::Location::CallData)
// length is stored on the stack
m_context << eth::Instruction::SWAP1;
else
m_context << eth::Instruction::DUP2 << load;
// stack: <base_ref> <index> <length>
// check out-of-bounds access
m_context << eth::Instruction::DUP2 << eth::Instruction::LT;
eth::AssemblyItem legalAccess = m_context.appendConditionalJump();
// out-of-bounds access throws exception (just STOP for now)
m_context << eth::Instruction::STOP;
m_context << legalAccess;
// stack: <base_ref> <index>
if (_arrayType.isByteArray())
switch (location)
{
case ArrayType::Location::Storage:
// byte array index storage lvalue on stack (goal):
// <ref> <byte_number> = <base_ref + index / 32> <index % 32>
m_context << u256(32) << eth::Instruction::SWAP2;
CompilerUtils(m_context).computeHashStatic();
// stack: 32 index data_ref
m_context
<< eth::Instruction::DUP3 << eth::Instruction::DUP3
<< eth::Instruction::DIV << eth::Instruction::ADD
// stack: 32 index (data_ref + index / 32)
<< eth::Instruction::SWAP2 << eth::Instruction::SWAP1
<< eth::Instruction::MOD;
break;
case ArrayType::Location::CallData:
// no lvalue, just retrieve the value
m_context
<< eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
<< ((u256(0xff) << (256 - 8))) << eth::Instruction::AND;
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
}
else
{
// stack: <base_ref> <index>
m_context << eth::Instruction::SWAP1;
if (_arrayType.isDynamicallySized())
{
if (location == ArrayType::Location::Storage)
CompilerUtils(m_context).computeHashStatic();
else if (location == ArrayType::Location::Memory)
m_context << u256(32) << eth::Instruction::ADD;
}
// stack: <index> <data_ref>
switch (location)
{
case ArrayType::Location::CallData:
m_context
<< eth::Instruction::SWAP1 << _arrayType.getBaseType()->getCalldataEncodedSize()
<< eth::Instruction::MUL << eth::Instruction::ADD;
if (_arrayType.getBaseType()->isValueType())
CompilerUtils(m_context).loadFromMemoryDynamic(*_arrayType.getBaseType(), true, true, false);
break;
case ArrayType::Location::Storage:
m_context << eth::Instruction::SWAP1;
if (_arrayType.getBaseType()->getStorageBytes() <= 16)
{
// stack: <data_ref> <index>
// goal:
// <ref> <byte_number> = <base_ref + index / itemsPerSlot> <(index % itemsPerSlot) * byteSize>
unsigned byteSize = _arrayType.getBaseType()->getStorageBytes();
solAssert(byteSize != 0, "");
unsigned itemsPerSlot = 32 / byteSize;
m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2;
// stack: itemsPerSlot index data_ref
m_context
<< eth::Instruction::DUP3 << eth::Instruction::DUP3
<< eth::Instruction::DIV << eth::Instruction::ADD
// stack: itemsPerSlot index (data_ref + index / itemsPerSlot)
<< eth::Instruction::SWAP2 << eth::Instruction::SWAP1
<< eth::Instruction::MOD
<< u256(byteSize) << eth::Instruction::MUL;
}
else
{
if (_arrayType.getBaseType()->getStorageSize() != 1)
m_context << _arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
m_context << eth::Instruction::ADD << u256(0);
}
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
}
}
}
void ArrayUtils::incrementByteOffset(unsigned _byteSize, unsigned _byteOffsetPosition, unsigned _storageOffsetPosition) const
{
solAssert(_byteSize < 32, "");

6
libsolidity/ArrayUtils.h

@ -70,6 +70,12 @@ public:
/// Stack pre: reference (excludes byte offset for dynamic storage arrays)
/// Stack post: reference length
void retrieveLength(ArrayType const& _arrayType) const;
/// Retrieves the value at a specific index. If the location is storage, only retrieves the
/// position.
/// Stack pre: reference [length] index
/// Stack post for storage: slot byte_offset
/// Stack post for calldata: value
void accessIndex(ArrayType const& _arrayType) const;
private:
/// Adds the given number of bytes to a storage byte offset counter and also increments

107
libsolidity/ExpressionCompiler.cpp

@ -755,113 +755,20 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
{
ArrayType const& arrayType = dynamic_cast<ArrayType const&>(baseType);
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
ArrayType::Location location = arrayType.getLocation();
eth::Instruction load =
location == ArrayType::Location::Storage ? eth::Instruction::SLOAD :
location == ArrayType::Location::Memory ? eth::Instruction::MLOAD :
eth::Instruction::CALLDATALOAD;
// remove storage byte offset
if (location == ArrayType::Location::Storage)
if (arrayType.getLocation() == ArrayType::Location::Storage)
m_context << eth::Instruction::POP;
// stack layout: <base_ref> [<length>] <index>
_indexAccess.getIndexExpression()->accept(*this);
// retrieve length
if (!arrayType.isDynamicallySized())
m_context << arrayType.getLength();
else if (location == ArrayType::Location::CallData)
// length is stored on the stack
m_context << eth::Instruction::SWAP1;
else
m_context << eth::Instruction::DUP2 << load;
// stack: <base_ref> <index> <length>
// check out-of-bounds access
m_context << eth::Instruction::DUP2 << eth::Instruction::LT;
eth::AssemblyItem legalAccess = m_context.appendConditionalJump();
// out-of-bounds access throws exception (just STOP for now)
m_context << eth::Instruction::STOP;
m_context << legalAccess;
// stack: <base_ref> <index>
if (arrayType.isByteArray())
switch (location)
{
case ArrayType::Location::Storage:
// byte array index storage lvalue on stack (goal):
// <ref> <byte_number> = <base_ref + index / 32> <index % 32>
m_context << u256(32) << eth::Instruction::SWAP2;
CompilerUtils(m_context).computeHashStatic();
// stack: 32 index data_ref
m_context
<< eth::Instruction::DUP3 << eth::Instruction::DUP3
<< eth::Instruction::DIV << eth::Instruction::ADD
// stack: 32 index (data_ref + index / 32)
<< eth::Instruction::SWAP2 << eth::Instruction::SWAP1
<< eth::Instruction::MOD;
setLValue<StorageByteArrayElement>(_indexAccess);
break;
case ArrayType::Location::CallData:
// no lvalue, just retrieve the value
m_context
<< eth::Instruction::ADD << eth::Instruction::CALLDATALOAD
<< ((u256(0xff) << (256 - 8))) << eth::Instruction::AND;
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
}
else
// stack layout: <base_ref> [<length>] <index>
ArrayUtils(m_context).accessIndex(arrayType);
if (arrayType.getLocation() == ArrayType::Location::Storage)
{
// stack: <base_ref> <index>
m_context << eth::Instruction::SWAP1;
if (arrayType.isDynamicallySized())
{
if (location == ArrayType::Location::Storage)
CompilerUtils(m_context).computeHashStatic();
else if (location == ArrayType::Location::Memory)
m_context << u256(32) << eth::Instruction::ADD;
}
// stack: <index> <data_ref>
switch (location)
{
case ArrayType::Location::CallData:
m_context
<< eth::Instruction::SWAP1 << arrayType.getBaseType()->getCalldataEncodedSize()
<< eth::Instruction::MUL << eth::Instruction::ADD;
if (arrayType.getBaseType()->isValueType())
CompilerUtils(m_context).loadFromMemoryDynamic(*arrayType.getBaseType(), true, true, false);
break;
case ArrayType::Location::Storage:
m_context << eth::Instruction::SWAP1;
if (arrayType.getBaseType()->getStorageBytes() <= 16)
{
// stack: <data_ref> <index>
// goal:
// <ref> <byte_number> = <base_ref + index / itemsPerSlot> <(index % itemsPerSlot) * byteSize>
unsigned byteSize = arrayType.getBaseType()->getStorageBytes();
solAssert(byteSize != 0, "");
unsigned itemsPerSlot = 32 / byteSize;
m_context << u256(itemsPerSlot) << eth::Instruction::SWAP2;
// stack: itemsPerSlot index data_ref
m_context
<< eth::Instruction::DUP3 << eth::Instruction::DUP3
<< eth::Instruction::DIV << eth::Instruction::ADD
// stack: itemsPerSlot index (data_ref + index / itemsPerSlot)
<< eth::Instruction::SWAP2 << eth::Instruction::SWAP1
<< eth::Instruction::MOD
<< u256(byteSize) << eth::Instruction::MUL;
}
else
{
if (arrayType.getBaseType()->getStorageSize() != 1)
m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
m_context << eth::Instruction::ADD << u256(0);
}
if (arrayType.isByteArray())
setLValue<StorageByteArrayElement>(_indexAccess);
else
setLValueToStorageItem(_indexAccess);
break;
case ArrayType::Location::Memory:
solAssert(false, "Memory lvalues not yet implemented.");
}
}
}
else

53
libtestutils/BlockChainLoader.cpp

@ -28,57 +28,6 @@ using namespace dev;
using namespace dev::test;
using namespace dev::eth;
namespace dev
{
namespace test
{
dev::eth::BlockInfo toBlockInfo(Json::Value const& _json);
bytes toGenesisBlock(Json::Value const& _json);
}
}
dev::eth::BlockInfo dev::test::toBlockInfo(Json::Value const& _json)
{
RLPStream rlpStream;
auto size = _json.getMemberNames().size();
rlpStream.appendList(_json["hash"].empty() ? size : (size - 1));
rlpStream << fromHex(_json["parentHash"].asString());
rlpStream << fromHex(_json["uncleHash"].asString());
rlpStream << fromHex(_json["coinbase"].asString());
rlpStream << fromHex(_json["stateRoot"].asString());
rlpStream << fromHex(_json["transactionsTrie"].asString());
rlpStream << fromHex(_json["receiptTrie"].asString());
rlpStream << fromHex(_json["bloom"].asString());
rlpStream << bigint(_json["difficulty"].asString());
rlpStream << bigint(_json["number"].asString());
rlpStream << bigint(_json["gasLimit"].asString());
rlpStream << bigint(_json["gasUsed"].asString());
rlpStream << bigint(_json["timestamp"].asString());
rlpStream << fromHex(_json["extraData"].asString());
rlpStream << fromHex(_json["mixHash"].asString());
rlpStream << fromHex(_json["nonce"].asString());
BlockInfo result;
RLP rlp(rlpStream.out());
result.populateFromHeader(rlp, IgnoreNonce);
return result;
}
bytes dev::test::toGenesisBlock(Json::Value const& _json)
{
BlockInfo bi = toBlockInfo(_json);
RLPStream rlpStream;
bi.streamRLP(rlpStream, WithNonce);
RLPStream fullStream(3);
fullStream.appendRaw(rlpStream.out());
fullStream.appendRaw(RLPEmptyList);
fullStream.appendRaw(RLPEmptyList);
bi.verifyInternals(&fullStream.out());
return fullStream.out();
}
BlockChainLoader::BlockChainLoader(Json::Value const& _json)
{
// load pre state
@ -86,7 +35,7 @@ BlockChainLoader::BlockChainLoader(Json::Value const& _json)
m_state = sl.state();
// load genesisBlock
m_bc.reset(new BlockChain(toGenesisBlock(_json["genesisBlockHeader"]), m_dir.path(), true));
m_bc.reset(new BlockChain(fromHex(_json["genesisRLP"].asString()), m_dir.path(), true));
// load blocks
for (auto const& block: _json["blocks"])

4
libwhisper/Message.cpp

@ -58,10 +58,10 @@ Message::Message(Envelope const& _e, FullTopic const& _fk, Secret const& _s)
// get key from decrypted topic key: just xor
h256 tk = h256(bytesConstRef(&(_e.data())).cropped(32 * topicIndex, 32));
bytesConstRef cipherText = bytesConstRef(&(_e.data())).cropped(32 * _e.topic().size());
cnote << "Decrypting(" << topicIndex << "): " << topicSecret << tk << (topicSecret ^ tk) << toHex(cipherText);
// cdebug << "Decrypting(" << topicIndex << "): " << topicSecret << tk << (topicSecret ^ tk) << toHex(cipherText);
if (!decryptSym(topicSecret ^ tk, cipherText, b))
return;
cnote << "Got: " << toHex(b);
// cdebug << "Got: " << toHex(b);
}
if (populate(b))

Loading…
Cancel
Save