From d24b48853dcd444c2bf0844c967da50e88cf20ee Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 8 May 2015 16:45:23 +0200 Subject: [PATCH 1/4] new abi --- mix/ContractCallDataEncoder.cpp | 18 +++++++++++++++--- mix/ContractCallDataEncoder.h | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 6b29d8b98..9ea1c3510 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -36,6 +36,14 @@ using namespace dev::mix; bytes ContractCallDataEncoder::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 offsetRef(r.data() + p.first, 32); + toBigEndian>(p.second + headerSize, offsetRef); //add header size minus signature hash + } + r.insert(r.end(), m_dynamicData.begin(), m_dynamicData.end()); return r; } @@ -64,6 +72,9 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& if (_type.dynamicSize) { + bytes empty(32); + size_t sizePos = m_dynamicData.size(); + m_dynamicData.insert(m_dynamicData.end(), empty.begin(), empty.end()); //reserve space for count if (_type.type == SolidityType::Type::Bytes) count = encodeSingleItem(_data.toString(), _type, m_dynamicData); else @@ -72,9 +83,10 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& for (auto const& item: strList) encodeSingleItem(item, _type, m_dynamicData); } - bytes sizeEnc(32); - toBigEndian(count, sizeEnc); - m_encodedData.insert(m_encodedData.end(), sizeEnc.begin(), sizeEnc.end()); + vector_ref sizeRef(m_dynamicData.data() + sizePos, 32); + toBigEndian(count, sizeRef); + m_offsetMap.push_back(std::make_pair(m_encodedData.size(), sizePos)); + m_encodedData.insert(m_encodedData.end(), empty.begin(), empty.end()); //reserve space for offset } else { diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index cab00dd93..2707845ae 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -73,6 +73,7 @@ private: private: bytes m_encodedData; bytes m_dynamicData; + std::vector> m_offsetMap; }; } From b75a90bc722d51b2790a9b2dad18b814f327533c Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 8 May 2015 21:52:20 +0200 Subject: [PATCH 2/4] used operator+= for bytes --- mix/ContractCallDataEncoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 9ea1c3510..07ab8dd73 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -74,7 +74,7 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& { bytes empty(32); size_t sizePos = m_dynamicData.size(); - m_dynamicData.insert(m_dynamicData.end(), empty.begin(), empty.end()); //reserve space for count + m_dynamicData += empty; //reserve space for count if (_type.type == SolidityType::Type::Bytes) count = encodeSingleItem(_data.toString(), _type, m_dynamicData); else @@ -86,7 +86,7 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& vector_ref sizeRef(m_dynamicData.data() + sizePos, 32); toBigEndian(count, sizeRef); m_offsetMap.push_back(std::make_pair(m_encodedData.size(), sizePos)); - m_encodedData.insert(m_encodedData.end(), empty.begin(), empty.end()); //reserve space for offset + m_encodedData += empty; //reserve space for offset } else { From 10aec68f63132c57091a995dae15aeb5df551b7d Mon Sep 17 00:00:00 2001 From: arkpar Date: Sat, 9 May 2015 21:52:21 +0200 Subject: [PATCH 3/4] fixed transaction signatures --- mix/MixClient.cpp | 39 +++++++++++++++++++++++---------------- mix/MixClient.h | 4 ++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 94bd0d71f..09fed6fc6 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -98,22 +98,30 @@ void MixClient::resetState(std::unordered_map const& _accounts m_executions.clear(); } -Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas) +Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, u256 const& _gas) { Transaction ret; - if (_t.isCreation()) - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); + 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 - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); - ret.forceSender(_t.safeSender()); + { + if (_t.isCreation()) + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); + else + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); + ret.forceSender(_t.safeSender()); + } return ret; } -void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto) +void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, State& _state, bool _call, bool _gasAuto) { - Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t; - bytes rlp = t.rlp(); - + Transaction t = _gasAuto ? replaceGas(_t, Secret(), m_state.gasLimitRemaining()) : _t; // do debugging run first LastHashes lastHashes(256); lastHashes[0] = bc().numberHash(bc().number()); @@ -123,7 +131,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c State execState = _state; execState.addBalance(t.sender(), t.gas() * t.gasPrice()); //give it enough balance for gas estimation Executive execution(execState, lastHashes, 0); - execution.initialize(&rlp); + execution.initialize(t); execution.execute(); std::vector machineStates; std::vector levels; @@ -222,7 +230,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c // execute on a state if (!_call) { - t = _gasAuto ? replaceGas(_t, d.gasUsed) : _t; + t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t; er =_state.execute(lastHashes, t); if (t.isCreation() && _state.code(d.contractAddress).empty()) 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); u256 n = m_state.transactionsFrom(toAddress(_secret)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - executeTransaction(t, m_state, false, _gasAuto); + executeTransaction(t, _secret, m_state, false, _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); u256 n = m_state.transactionsFrom(toAddress(_secret)); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, m_state, false, _gasAuto); + executeTransaction(t, _secret, m_state, false, _gasAuto); Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); return address; } @@ -307,9 +315,8 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add t.forceSender(_from); if (_ff == FudgeFactor::Lenient) 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 - executeTransaction(t, temp, true, _gasAuto); + executeTransaction(t, Secret(), temp, true, _gasAuto); return lastExecution().result; } @@ -343,7 +350,7 @@ dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, b if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, temp, true, false); + executeTransaction(t, Secret(), temp, true, false); return lastExecution().result; } diff --git a/mix/MixClient.h b/mix/MixClient.h index f7687c488..5988286d0 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -87,9 +87,9 @@ protected: virtual void prepareForTransaction() override {} private: - void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call, bool _gasAuto); + void executeTransaction(dev::eth::Transaction const& _t, dev::Secret const& _secret, eth::State& _state, bool _call, bool _gasAuto); 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::Secret const& _secret, dev::u256 const& _gas); eth::State m_state; eth::State m_startState; From 9b80352a7c4549c123dbac621e8a6609b0f31961 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 11 May 2015 07:45:05 +0200 Subject: [PATCH 4/4] made _secret parameter optional --- mix/MixClient.cpp | 16 ++++++++-------- mix/MixClient.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 09fed6fc6..cac208ba4 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -98,7 +98,7 @@ void MixClient::resetState(std::unordered_map const& _accounts m_executions.clear(); } -Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, u256 const& _gas) +Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret) { Transaction ret; if (_secret) @@ -119,9 +119,9 @@ Transaction MixClient::replaceGas(Transaction const& _t, Secret const& _secret, return ret; } -void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, 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, Secret(), m_state.gasLimitRemaining()) : _t; + Transaction t = _gasAuto ? replaceGas(_t, m_state.gasLimitRemaining()) : _t; // do debugging run first LastHashes lastHashes(256); lastHashes[0] = bc().numberHash(bc().number()); @@ -230,7 +230,7 @@ void MixClient::executeTransaction(Transaction const& _t, Secret const& _secret, // execute on a state if (!_call) { - t = _gasAuto ? replaceGas(_t, _secret, d.gasUsed) : _t; + t = _gasAuto ? replaceGas(_t, d.gasUsed, _secret) : _t; er =_state.execute(lastHashes, t); if (t.isCreation() && _state.code(d.contractAddress).empty()) BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); @@ -293,7 +293,7 @@ void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, by WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - executeTransaction(t, _secret, 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) @@ -301,7 +301,7 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons WriteGuard l(x_state); u256 n = m_state.transactionsFrom(toAddress(_secret)); eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, _secret, m_state, false, _gasAuto); + executeTransaction(t, m_state, false, _gasAuto, _secret); Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); return address; } @@ -316,7 +316,7 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, Secret(), temp, true, _gasAuto); + executeTransaction(t, temp, true, _gasAuto); return lastExecution().result; } @@ -350,7 +350,7 @@ dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, b if (_ff == FudgeFactor::Lenient) temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, Secret(), temp, true, false); + executeTransaction(t, temp, true, false); return lastExecution().result; } diff --git a/mix/MixClient.h b/mix/MixClient.h index 5988286d0..2c6734234 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -87,9 +87,9 @@ protected: virtual void prepareForTransaction() override {} private: - void executeTransaction(dev::eth::Transaction const& _t, dev::Secret const& _secret, 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); - dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, 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_startState;