Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions libraries/plugins/apis/contract_api/contract_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ DEFINE_API_IMPL( contract_api_impl, get_contract )
ilog( "machine::message msg.flags ${f}", ("f",msg.flags) );

get_contract_return result;
result.example = true;
return result;
}

Expand Down Expand Up @@ -90,7 +89,7 @@ machine::chain_adapter make_chain_adapter(chain::database& _db)
return {};
};

std::function< std::string(std::string, uint64_t, machine::big_word, std::vector<machine::word>) > contract_call = [](std::string address, uint64_t energy, machine::big_word value, std::vector<machine::word> args) -> std::string
std::function< std::vector<machine::word>(std::string, uint64_t, machine::big_word, std::vector<machine::word>) > contract_call = [](std::string address, uint64_t energy, machine::big_word value, std::vector<machine::word> args) -> std::vector<machine::word>
{
return {};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ namespace detail { class contract_api_impl; }

struct get_contract_args
{
bool example = true;
protocol::contract_hash_type hash;
};

struct api_contract_object
{
bool example = true;
};

struct get_contract_return
{
bool example = true;
api_contract_object contract;
};


Expand Down Expand Up @@ -64,8 +68,9 @@ class contract_api

} } } // xgt::plugins::contract

FC_REFLECT( xgt::plugins::contract::get_contract_args, (example) )
FC_REFLECT( xgt::plugins::contract::get_contract_return, (example) )
FC_REFLECT( xgt::plugins::contract::get_contract_args, (hash) )
FC_REFLECT( xgt::plugins::contract::get_contract_return, (contract) )
FC_REFLECT( xgt::plugins::contract::api_contract_object, (example) )
FC_REFLECT( xgt::plugins::contract::list_owner_contracts_args, (owner) )
FC_REFLECT( xgt::plugins::contract::list_owner_contracts_return, (contracts) )
FC_REFLECT( xgt::plugins::contract::invoke_args, (owner) (code) )
Expand Down
168 changes: 129 additions & 39 deletions libraries/vendor/xgtvm/libraries/machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ namespace machine
return x.convert_to<size_t>();
}

big_word to_big_word(int64_t a)
{
return a;
}

big_word to_big_word(size_t a)
{
return a;
Expand Down Expand Up @@ -231,7 +236,7 @@ namespace machine
big_word va, vb, vc, vd, ve, vf, vg, vh, vi, vj, vk, vl, vm, vn, vo, vp, vq;
stack_variant sv;
signed_big_word sa, sb, sc;
size_t offset, dest_offset, length, code_size;
size_t offset, dest_offset, length, code_size = 0;
std::vector<word> contract_args;
std::vector<word> ext_contract_code;
std::vector<word>::const_iterator first, last;
Expand Down Expand Up @@ -460,7 +465,6 @@ namespace machine
push_word( msg.destination );
break;
case balance_opcode:
std::cout << 1 << std::endl;
logger << "op balance" << std::endl;
{
sv = stack.front(); // addr
Expand Down Expand Up @@ -579,25 +583,24 @@ namespace machine
stack.pop_front();
ext_contract_code = adapter.get_code_at_addr(*ss);
code_size = sizeof(ext_contract_code) / sizeof(ext_contract_code[0]);
dest_offset = static_cast<size_t>( pop_word() );
offset = static_cast<size_t>( pop_word() );
length = static_cast<size_t>( pop_word() );

if ((offset + length) > code_size) {
logger << "codecopy end index exceeds external contract code length";
break;
}

for (size_t i = 0; i < length; ++i)
memory[dest_offset + i] = ext_contract_code[offset + i];
}
else
{
state = machine_state::error;
error_message.emplace("Extcodecopy operation type error");
}

dest_offset = static_cast<size_t>( pop_word() );
offset = static_cast<size_t>( pop_word() );
length = static_cast<size_t>( pop_word() );

if ((offset + length) > code_size) {
logger << "codecopy end index exceeds external contract code length";
break;
}

for (size_t i = 0; i < length; ++i)
memory[dest_offset + i] = ext_contract_code[offset + i];

break;
case returndatasize_opcode:
logger << "op returndatasize" << std::endl;
Expand Down Expand Up @@ -2629,22 +2632,53 @@ namespace machine

contract_args = std::vector<word>(first, last);

adapter.contract_call(*ss, static_cast<uint64_t>(va), vb, contract_args);
}
std::vector<word> contract_call_return = adapter.contract_call(*ss, static_cast<uint64_t>(va), vb, contract_args);

for (size_t i = 0; i < static_cast<size_t>(vf); i++)
memory[static_cast<size_t>(ve) + i] = contract_call_return[i];

// TODO
// TODO revise stack return value?
push_word("Success"); // success
}
else {
push_word("Failure"); // success
state = machine_state::error;
error_message.emplace("Call operation type error");
}
break;
case callcode_opcode:
logger << "op callcode" << std::endl;
va = pop_word(); // energy
vb = pop_word(); // addr
vc = pop_word(); // value
vd = pop_word(); // argsOffset
ve = pop_word(); // argsLength
vf = pop_word(); // retOffset
vg = pop_word(); // retLength

// TODO
sv = stack.front(); // addr
ss = boost::get<std::string>(&sv);
if (ss)
{
stack.pop_front();
vb = pop_word(); // value
vc = pop_word(); // argsOffset
vd = pop_word(); // argsLength
ve = pop_word(); // retOffset
vf = pop_word(); // retLength

first = memory.begin() + static_cast<size_t>(vc);
last = memory.begin() + static_cast<size_t>(vc) + static_cast<size_t>(vd);

contract_args = std::vector<word>(first, last);

std::vector<word> contract_callcode_return = adapter.contract_callcode(*ss, static_cast<uint64_t>(va), vb, contract_args);

for (size_t i = 0; i < static_cast<size_t>(vf); i++)
memory[static_cast<size_t>(ve) + i] = contract_callcode_return[i];

// TODO revise stack return value?
push_word("Success"); // success
}
else {
push_word("Failure"); // success
state = machine_state::error;
error_message.emplace("Callcode operation type error");
}
break;
case return_opcode:
logger << "op return" << std::endl;
Expand All @@ -2671,32 +2705,88 @@ namespace machine
case delegatecall_opcode:
logger << "op delegatecall" << std::endl;
va = pop_word(); // energy
vb = pop_word(); // addr
vc = pop_word(); // argsOffset
vd = pop_word(); // argsLength
ve = pop_word(); // retOffset
vf = pop_word(); // retLength

// TODO
sv = stack.front(); // addr
ss = boost::get<std::string>(&sv);
if (ss)
{
stack.pop_front();
vb = pop_word(); // argsOffset
vc = pop_word(); // argsLength
vd = pop_word(); // retOffset
ve = pop_word(); // retLength

first = memory.begin() + static_cast<size_t>(vb);
last = memory.begin() + static_cast<size_t>(vb) + static_cast<size_t>(vc);

contract_args = std::vector<word>(first, last);

std::vector<word> contract_delegatecall_return = adapter.contract_delegatecall(*ss, static_cast<uint64_t>(va), contract_args);

for (size_t i = 0; i < static_cast<size_t>(ve); i++)
memory[static_cast<size_t>(vd) + i] = contract_delegatecall_return[i];

// TODO revise stack return value?
push_word("Success"); // success
}
else {
push_word("Failure"); // success
state = machine_state::error;
error_message.emplace("Delegatecall operation type error");
}
break;
case create2_opcode:
logger << "op create2" << std::endl;
va = pop_word(); // value
vb = pop_word(); // offset
vc = pop_word(); //length
vd = pop_word(); // salt
// TODO
vc = pop_word(); // length

sv = stack.front(); // salt
ss = boost::get<std::string>(&sv);
if (ss)
{
first = memory.begin() + static_cast<size_t>(vb);
last = memory.begin() + static_cast<size_t>(vb) + static_cast<size_t>(vc);

push_word( adapter.contract_create2( std::vector<word>(first, last), va, *ss ) );
}
else {
state = machine_state::error;
error_message.emplace("Create2 operation type error");
}
break;
case staticcall_opcode:
logger << "op staticcall" << std::endl;
va = pop_word(); // energy
vb = pop_word(); // addr
vc = pop_word(); // argsOffset
vd = pop_word(); // argsLength
ve = pop_word(); // retOffset
vf = pop_word(); // retLength

// TODO
sv = stack.front(); // addr
ss = boost::get<std::string>(&sv);
if (ss)
{
stack.pop_front();
vb = pop_word(); // argsOffset
vc = pop_word(); // argsLength
vd = pop_word(); // retOffset
ve = pop_word(); // retLength

first = memory.begin() + static_cast<size_t>(vb);
last = memory.begin() + static_cast<size_t>(vb) + static_cast<size_t>(vc);

contract_args = std::vector<word>(first, last);

std::vector<word> contract_staticcall_return = adapter.contract_staticcall(*ss, static_cast<uint64_t>(va), contract_args);

for (size_t i = 0; i < static_cast<size_t>(ve); i++)
memory[static_cast<size_t>(vd) + i] = contract_staticcall_return[i];

// TODO revise stack return value?
push_word("Success"); // success
}
else {
push_word("Failure"); // success
state = machine_state::error;
error_message.emplace("Staticcall operation type error");
}
break;
case revert_opcode:
logger << "op revert" << std::endl;
Expand Down
27 changes: 18 additions & 9 deletions libraries/vendor/xgtvm/libraries/machine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,12 @@ enum opcode
log4_opcode = 0xA4,

create_opcode = 0xF0,
call_opcode = 0xF1, // TODO
callcode_opcode = 0xF2, // TODO
call_opcode = 0xF1,
callcode_opcode = 0xF2,
return_opcode = 0xF3,
delegatecall_opcode = 0xF4, // TODO
create2_opcode = 0xF5, // TODO
staticcall_opcode = 0xFA, // TODO
delegatecall_opcode = 0xF4,
create2_opcode = 0xF5,
staticcall_opcode = 0xFA,
revert_opcode = 0xFD,
selfdestruct_opcode = 0xFF,
};
Expand Down Expand Up @@ -215,7 +215,7 @@ struct context
uint64_t block_number;
uint64_t block_difficulty;
uint64_t block_energylimit;
uint64_t tx_energyprice;
int64_t tx_energyprice;
std::string tx_origin;
std::string block_coinbase;
};
Expand All @@ -225,7 +225,6 @@ struct chain_adapter
// TODO sha3 opcode
std::function< std::string(std::vector<word>) > sha3;

// TODO retrieves balance at addr -- used for balance opcode
std::function< uint64_t(std::string) > get_balance;

// TODO for hashing address -- extcodehash opcode
Expand All @@ -241,10 +240,20 @@ struct chain_adapter
std::function< std::string(std::vector<word>, big_word) > contract_create;

// TODO call a method from another contract -- call opcode -- address, energy, value, args
std::function< std::string(std::string, uint64_t, big_word, std::vector<word>) > contract_call;
std::function< std::vector<word>(std::string, uint64_t, big_word, std::vector<word>) > contract_call;

// TODO call a method from another contract(?) -- callcode opcode -- address, energy, value, args
std::function< std::vector<word>(std::string, uint64_t, big_word, std::vector<word>) > contract_callcode;

// TODO call a method from another contract using the storage of the current
// opcode -- delegatecall opcode -- address, energy, args
std::function< std::vector<word>(std::string, uint64_t, std::vector<word>) > contract_delegatecall;

// TODO call a method from another contract with state changes disallowed -- staticcall opcode -- address, energy, args
std::function< std::vector<word>(std::string, uint64_t, std::vector<word>) > contract_staticcall;

// TODO creates a child contract -- create2 opcode
std::function< std::string(big_word, std::vector<word>, std::string) > contract_create2;
std::function< std::string(std::vector<word>, big_word, std::string) > contract_create2;

// TODO revert opcode
std::function< bool(std::vector<word>) > revert;
Expand Down
22 changes: 20 additions & 2 deletions libraries/vendor/xgtvm/programs/xgtvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,27 @@ machine::chain_adapter make_chain_adapter()
return {};
};

std::function< std::string(std::string, uint64_t, machine::big_word, std::vector<machine::word>) > contract_call = [](std::string address, uint64_t energy, machine::big_word value, std::vector<machine::word> args) -> std::string
std::function< std::vector<machine::word>(std::string, uint64_t, machine::big_word, std::vector<machine::word>) > contract_call = [](std::string address, uint64_t energy, machine::big_word value, std::vector<machine::word> args) -> std::vector<machine::word>
{
return {};
};

std::function< std::string(machine::big_word, std::vector<machine::word>, std::string) > contract_create2 = [](machine::big_word value, std::vector<machine::word> memory, std::string salt) -> std::string
std::function< std::vector<machine::word>(std::string, uint64_t, machine::big_word, std::vector<machine::word>) > contract_callcode = [](std::string address, uint64_t energy, machine::big_word value, std::vector<machine::word> args) -> std::vector<machine::word>
{
return {};
};

std::function< std::vector<machine::word>(std::string, uint64_t, std::vector<machine::word>) > contract_delegatecall = [](std::string address, uint64_t energy, std::vector<machine::word> args) -> std::vector<machine::word>
{
return {};
};

std::function< std::vector<machine::word>(std::string, uint64_t, std::vector<machine::word>) > contract_staticcall = [](std::string address, uint64_t energy, std::vector<machine::word> args) -> std::vector<machine::word>
{
return {};
};

std::function< std::string(std::vector<machine::word>, machine::big_word, std::string) > contract_create2 = [](std::vector<machine::word> memory, machine::big_word value, std::string salt) -> std::string
{
return {};
};
Expand Down Expand Up @@ -133,6 +148,9 @@ machine::chain_adapter make_chain_adapter()
get_code_at_addr,
contract_create,
contract_call,
contract_callcode,
contract_delegatecall,
contract_staticcall,
contract_create2,
revert,
access_storage,
Expand Down
Loading