Browse Source

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

cl-refactor
Vlad Gluhovsky 10 years ago
parent
commit
5d92225be5
  1. 18
      mix/ContractCallDataEncoder.cpp
  2. 1
      mix/ContractCallDataEncoder.h
  3. 25
      mix/MixClient.cpp
  4. 4
      mix/MixClient.h

18
mix/ContractCallDataEncoder.cpp

@ -36,6 +36,14 @@ using namespace dev::mix;
bytes ContractCallDataEncoder::encodedData() bytes ContractCallDataEncoder::encodedData()
{ {
bytes r(m_encodedData); bytes r(m_encodedData);
size_t headerSize = m_encodedData.size() & ~0x1fUL; //ignore any prefix that is not 32-byte aligned
//apply offsets
for (auto const& p: m_offsetMap)
{
vector_ref<byte> offsetRef(r.data() + p.first, 32);
toBigEndian<size_t, vector_ref<byte>>(p.second + headerSize, offsetRef); //add header size minus signature hash
}
r.insert(r.end(), m_dynamicData.begin(), m_dynamicData.end()); r.insert(r.end(), m_dynamicData.begin(), m_dynamicData.end());
return r; return r;
} }
@ -64,6 +72,9 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const&
if (_type.dynamicSize) if (_type.dynamicSize)
{ {
bytes empty(32);
size_t sizePos = m_dynamicData.size();
m_dynamicData += empty; //reserve space for count
if (_type.type == SolidityType::Type::Bytes) if (_type.type == SolidityType::Type::Bytes)
count = encodeSingleItem(_data.toString(), _type, m_dynamicData); count = encodeSingleItem(_data.toString(), _type, m_dynamicData);
else else
@ -72,9 +83,10 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const&
for (auto const& item: strList) for (auto const& item: strList)
encodeSingleItem(item, _type, m_dynamicData); encodeSingleItem(item, _type, m_dynamicData);
} }
bytes sizeEnc(32); vector_ref<byte> sizeRef(m_dynamicData.data() + sizePos, 32);
toBigEndian(count, sizeEnc); toBigEndian(count, sizeRef);
m_encodedData.insert(m_encodedData.end(), sizeEnc.begin(), sizeEnc.end()); m_offsetMap.push_back(std::make_pair(m_encodedData.size(), sizePos));
m_encodedData += empty; //reserve space for offset
} }
else else
{ {

1
mix/ContractCallDataEncoder.h

@ -73,6 +73,7 @@ private:
private: private:
bytes m_encodedData; bytes m_encodedData;
bytes m_dynamicData; bytes m_dynamicData;
std::vector<std::pair<size_t, size_t>> m_offsetMap;
}; };
} }

25
mix/MixClient.cpp

@ -98,22 +98,30 @@ void MixClient::resetState(std::unordered_map<Address, Account> const& _accounts
m_executions.clear(); m_executions.clear();
} }
Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas) Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret)
{ {
Transaction ret; Transaction ret;
if (_secret)
{
if (_t.isCreation())
ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret);
else
ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret);
}
else
{
if (_t.isCreation()) if (_t.isCreation())
ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce());
else else
ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce());
ret.forceSender(_t.safeSender()); ret.forceSender(_t.safeSender());
}
return ret; return ret;
} }
void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto) void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto, Secret const& _secret)
{ {
Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t; Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t;
bytes rlp = t.rlp();
// do debugging run first // do debugging run first
LastHashes lastHashes(256); LastHashes lastHashes(256);
lastHashes[0] = bc().numberHash(bc().number()); lastHashes[0] = bc().numberHash(bc().number());
@ -123,7 +131,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
State execState = _state; State execState = _state;
execState.addBalance(t.sender(), t.gas() * t.gasPrice()); //give it enough balance for gas estimation execState.addBalance(t.sender(), t.gas() * t.gasPrice()); //give it enough balance for gas estimation
Executive execution(execState, lastHashes, 0); Executive execution(execState, lastHashes, 0);
execution.initialize(&rlp); execution.initialize(t);
execution.execute(); execution.execute();
std::vector<MachineState> machineStates; std::vector<MachineState> machineStates;
std::vector<unsigned> levels; std::vector<unsigned> levels;
@ -222,7 +230,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c
// execute on a state // execute on a state
if (!_call) if (!_call)
{ {
t = _gasAuto ? replaceGas(_t, d.gasUsed) : _t; t = _gasAuto ? replaceGas(_t, d.gasUsed, _secret) : _t;
er =_state.execute(lastHashes, t); er =_state.execute(lastHashes, t);
if (t.isCreation() && _state.code(d.contractAddress).empty()) if (t.isCreation() && _state.code(d.contractAddress).empty())
BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment"));
@ -285,7 +293,7 @@ void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, by
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret);
executeTransaction(t, m_state, false, _gasAuto); executeTransaction(t, m_state, false, _gasAuto, _secret);
} }
Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto)
@ -293,7 +301,7 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons
WriteGuard l(x_state); WriteGuard l(x_state);
u256 n = m_state.transactionsFrom(toAddress(_secret)); u256 n = m_state.transactionsFrom(toAddress(_secret));
eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret);
executeTransaction(t, m_state, false, _gasAuto); executeTransaction(t, m_state, false, _gasAuto, _secret);
Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); Address address = right160(sha3(rlpList(t.sender(), t.nonce())));
return address; return address;
} }
@ -307,7 +315,6 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add
t.forceSender(_from); t.forceSender(_from);
if (_ff == FudgeFactor::Lenient) if (_ff == FudgeFactor::Lenient)
temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value()));
bytes rlp = t.rlp();
WriteGuard lw(x_state); //TODO: lock is required only for last execution state WriteGuard lw(x_state); //TODO: lock is required only for last execution state
executeTransaction(t, temp, true, _gasAuto); executeTransaction(t, temp, true, _gasAuto);
return lastExecution().result; return lastExecution().result;

4
mix/MixClient.h

@ -87,9 +87,9 @@ protected:
virtual void prepareForTransaction() override {} virtual void prepareForTransaction() override {}
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto, dev::Secret const& _secret = dev::Secret());
void noteChanged(h256Set const& _filters); void noteChanged(h256Set const& _filters);
dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas); dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::u256 const& _gas, dev::Secret const& _secret = dev::Secret());
eth::State m_state; eth::State m_state;
eth::State m_startState; eth::State m_startState;

Loading…
Cancel
Save