Browse Source

Documentation and reduction.

cl-refactor
Gav Wood 10 years ago
parent
commit
302c16ec44
  1. 37
      libethereum/Executive.cpp
  2. 75
      libethereum/Executive.h
  3. 4
      libethereum/ExtVM.cpp

37
libethereum/Executive.cpp

@ -40,15 +40,19 @@ u256 Executive::gasUsed() const
return m_t.gas() - m_endGas;
}
void Executive::accrueSubState(SubState& _parentContext)
{
if (m_ext)
_parentContext += m_ext->sub;
}
bool Executive::setup(bytesConstRef _rlp)
{
// Entry point for a user-executed transaction.
m_t = Transaction(_rlp);
m_sender = m_t.sender();
// Avoid invalid transactions.
auto nonceReq = m_s.transactionsFrom(m_sender);
auto nonceReq = m_s.transactionsFrom(m_t.sender());
if (m_t.nonce() != nonceReq)
{
clog(StateDetail) << "Invalid Nonce: Require" << nonceReq << " Got" << m_t.nonce();
@ -67,10 +71,10 @@ bool Executive::setup(bytesConstRef _rlp)
u256 cost = m_t.value() + m_t.gas() * m_t.gasPrice();
// Avoid unaffordable transactions.
if (m_s.balance(m_sender) < cost)
if (m_s.balance(m_t.sender()) < cost)
{
clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_sender);
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_sender)));
clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_t.sender());
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_t.sender())));
}
u256 startGasUsed = m_s.gasUsed();
@ -81,16 +85,16 @@ bool Executive::setup(bytesConstRef _rlp)
}
// Increment associated nonce for sender.
m_s.noteSending(m_sender);
m_s.noteSending(m_t.sender());
// Pay...
clog(StateDetail) << "Paying" << formatBalance(cost) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
m_s.subBalance(m_sender, cost);
m_s.subBalance(m_t.sender(), cost);
if (m_t.isCreation())
return create(m_sender, m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_sender);
return create(m_t.sender(), m_t.value(), m_t.gasPrice(), m_t.gas() - (u256)gasCost, &m_t.data(), m_t.sender());
else
return call(m_t.receiveAddress(), m_t.receiveAddress(), m_sender, m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_sender);
return call(m_t.receiveAddress(), m_t.receiveAddress(), m_t.sender(), m_t.value(), m_t.gasPrice(), bytesConstRef(&m_t.data()), m_t.gas() - (u256)gasCost, m_t.sender());
}
bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _senderAddress, u256 _value, u256 _gasPrice, bytesConstRef _data, u256 _gas, Address _originAddress)
@ -212,22 +216,17 @@ bool Executive::go(OnOpFunc const& _onOp)
return true;
}
/*u256 Executive::gas() const
{
return m_vm ? m_vm->gas() : m_endGas;
}*/
void Executive::finalize(OnOpFunc const&)
{
// SSTORE refunds.
// SSTORE refunds...
// must be done before the miner gets the fees.
if (m_ext)
m_endGas += min((m_t.gas() - m_endGas) / 2, m_ext->sub.refunds);
// cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")";
m_s.addBalance(m_sender, m_endGas * m_t.gasPrice());
m_s.addBalance(m_t.sender(), m_endGas * m_t.gasPrice());
u256 feesEarned = (m_t.gas() - m_endGas) * m_t.gasPrice();
// cnote << "Transferring" << formatBalance(gasSpent) << "to miner.";
m_s.addBalance(m_s.m_currentBlock.coinbaseAddress, feesEarned);
// Suicides...
@ -235,7 +234,7 @@ void Executive::finalize(OnOpFunc const&)
for (auto a: m_ext->sub.suicides)
m_s.m_cache[a].kill();
// Logs
// Logs..
if (m_ext)
m_logs = m_ext->sub.logs;
}

75
libethereum/Executive.h

@ -39,53 +39,82 @@ struct Manifest;
struct VMTraceChannel: public LogChannel { static const char* name() { return "EVM"; } static const int verbosity = 11; };
/**
* @brief Message-call/contract-creation executor; useful for executing transactions.
*
* Two ways of using this class - either as a transaction executive or a CALL/CREATE executive.
* In the first use, after construction, begin with setup() and end with finalize(). Call go()
* after setup() only if it returns false.
* In the second use, after construction, begin with call() or create() and end with
* accrueSubState(). Call go() after call()/create() only if it returns false.
*/
class Executive
{
public:
/// Basic constructor.
Executive(State& _s, unsigned _level): m_s(_s), m_depth(_level) {}
/// Basic destructor.
~Executive() = default;
Executive(Executive const&) = delete;
void operator=(Executive) = delete;
/// Set up the executive for evaluating a transaction. You must call finalize() following this.
/// @returns true iff go() must be called (and thus a VM execution in required).
bool setup(bytesConstRef _transaction);
/// Finalise a transaction previously set up with setup().
/// @warning Only valid after setup(), and possibly go().
void finalize(OnOpFunc const& _onOp = OnOpFunc());
/// @returns the transaction from setup().
/// @warning Only valid after setup().
Transaction const& t() const { return m_t; }
/// @returns the log entries created by this operation.
/// @warning Only valid after finalise().
LogEntries const& logs() const { return m_logs; }
/// @returns total gas used in the transaction/operation.
/// @warning Only valid after finalise().
u256 gasUsed() const;
/// Set up the executive for evaluating a bare CREATE (contract-creation) operation.
/// @returns false iff go() must be called (and thus a VM execution in required).
bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress);
/// Set up the executive for evaluating a bare CALL (message call) operation.
/// @returns false iff go() must be called (and thus a VM execution in required).
bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress);
/// Finalise an operation through accruing the substate into the parent context.
void accrueSubState(SubState& _parentContext);
/// Executes (or continues execution of) the VM.
/// @returns false iff go() must be called again to finish the transction.
bool go(OnOpFunc const& _onOp = OnOpFunc());
void finalize(OnOpFunc const& _onOp = OnOpFunc());
u256 gasUsed() const;
/// Operation function for providing a simple trace of the VM execution.
static OnOpFunc simpleTrace();
Transaction const& t() const { return m_t; }
/// @returns gas remaining after the transaction/operation.
u256 endGas() const { return m_endGas; }
/// @returns output data of the transaction/operation.
bytesConstRef out() const { return m_out; }
/// @returns the new address for the created contract in the CREATE operation.
h160 newAddress() const { return m_newAddress; }
LogEntries const& logs() const { return m_logs; }
/// @returns true iff the operation ended with a VM exception.
bool excepted() const { return m_excepted; }
VMFace const& vm() const { return *m_vm; }
ExtVM const& ext() const { return *m_ext; }
State const& state() const { return m_s; }
private:
State& m_s;
std::shared_ptr<ExtVM> m_ext;
std::unique_ptr<VMFace> m_vm;
State& m_s; ///< The state to which this operation/transaction is applied.
std::shared_ptr<ExtVM> m_ext; ///< The VM externality object for the VM execution or null if no VM is required.
std::unique_ptr<VMFace> m_vm; ///< The VM object or null if no VM is required.
bytes m_precompiledOut; ///< Used for the output when there is no VM for a contract (i.e. precompiled).
bytesConstRef m_out; ///< Holds the copyable output.
Address m_newAddress;
bytesConstRef m_out; ///< The copyable output.
Address m_newAddress; ///< The address of the created contract in the case of create() being called.
Transaction m_t;
bool m_isCreation;
bool m_excepted = false;
unsigned m_depth = 0;
Address m_sender;
u256 m_endGas;
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.
bool m_excepted = false; ///< True if the VM execution resulted in an exception.
u256 m_endGas; ///< The final amount of gas for the transaction.
LogEntries m_logs;
Transaction m_t; ///< The original transaction in the case that setup() was called.
LogEntries m_logs; ///< The log entries created by this transaction. Only valid
};
}

4
libethereum/ExtVM.cpp

@ -32,7 +32,7 @@ bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData,
if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin))
{
e.go(_onOp);
sub += e.ext().sub;
e.accrueSubState(sub);
}
io_gas = e.endGas();
e.out().copyTo(_out);
@ -49,7 +49,7 @@ h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc
if (!e.create(myAddress, _endowment, gasPrice, io_gas, _code, origin))
{
e.go(_onOp);
sub += e.ext().sub;
e.accrueSubState(sub);
}
io_gas = e.endGas();
return e.newAddress();

Loading…
Cancel
Save