提交 fb2fa941 编写于 作者: D Daniel Larimer

progress on testing exchange contract

上级 a1c52eed
......@@ -31,7 +31,7 @@ int32_t remove_i64( AccountName scope, TableName table, uint64_t key );
* 32 bytes are the primary and secondary keys. These keys will be interpreted and sorted as unsigned
* 128 bit integers.
*
* @return the total number of bytes read or -1 for "not found" or "end".
* @return the total number of bytes read or -1 for "not found" or "end" where bytes read includes 32 bytes of the key
*/
///@{
int32_t front_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
......
......@@ -138,7 +138,8 @@ struct Table {
};
static bool store( const Record& r ) {
return impl::store( scope, table, &r, sizeof(r) );
assert( impl::store( scope, table, &r, sizeof(r) ), "error storing record" );
return true;
}
static bool remove( const Record& r ) {
return impl::remove( scope, table, &r );
......
......@@ -28,6 +28,11 @@ namespace eos {
printn(name.value);
}
template<typename T>
inline void print_native( T&& t ) {
t.print();
}
template<typename Arg>
inline void print( Arg a ) {
print_native(a);
......
#pragma once
#include <eoslib/math.hpp>
#include <eoslib/print.hpp>
namespace eos {
template<typename NumberType, uint64_t CurrencyType = N(eos) >
struct token {
static const uint64_t currency_type = CurrencyType;
token(){}
explicit token( NumberType v ):quantity(v){};
NumberType quantity = 0;
......@@ -41,6 +44,10 @@ namespace eos {
friend bool operator != ( const token& a, const token& b ) { return a.quantity != b.quantity; }
explicit operator bool()const { return quantity != 0; }
inline void print() {
eos::print( quantity, " ", Name(CurrencyType) );
}
};
/**
......@@ -49,6 +56,8 @@ namespace eos {
template<typename BaseToken, typename QuoteToken>
struct price
{
typedef BaseToken base_token_type;
typedef QuoteToken quote_token_type;
/**
* The largest base 10 integer that can be represented with 53 bits of
* a double. This number keeps the math in range of JavaScript. By
......@@ -84,7 +93,10 @@ namespace eos {
friend bool operator == ( const price& a, const price& b ) { return a.base_per_quote == b.base_per_quote; }
friend bool operator != ( const price& a, const price& b ) { return a.base_per_quote != b.base_per_quote; }
// private:
inline void print() {
eos::print( base_per_quote, ".", " ", Name(base_token_type::currency_type), "/", Name(quote_token_type::currency_type) );
}
private:
/**
* represented as number of base tokens to purchase 1 quote token
*/
......
......@@ -65,20 +65,12 @@ inline void modifyAccount( AccountName a, Lambda&& modify ) {
void apply_currency_transfer( const currency::Transfer& transfer ) {
if( transfer.to == N(exchange) ) {
modifyAccount( transfer.from, [&]( Account& account ){
print( "balance: " );
printi( account.currency_balance.quantity );
print( "deposit: " );
printi( transfer.quantity.quantity );
account.currency_balance += transfer.quantity;
});
} else if( transfer.from == N(exchange) ) {
requireAuth( transfer.to ); /// require the reciever of funds (account owner) to authorize this transfer
modifyAccount( transfer.to, [&]( Account& account ){
print( "balance: " );
printi( account.currency_balance.quantity );
print( "withdraw: " );
printi( transfer.quantity.quantity );
account.currency_balance -= transfer.quantity;
});
} else {
......@@ -140,7 +132,7 @@ void apply_exchange_buy( BuyOrder order ) {
assert( bid.quantity > eos::Tokens(0), "invalid quantity" );
assert( bid.expiration > now(), "order expired" );
print( Name(bid.buyer.name), " created bid for ", order.quantity.quantity, " currency at price: ", order.price.base_per_quote, "\n" );
print( Name(bid.buyer.name), " created bid for ", order.quantity, " currency at price: ", order.price, "\n" );
Bid existing_bid;
assert( !BidsById::get( bid.buyer, existing_bid ), "order with this id already exists" );
......@@ -183,7 +175,7 @@ void apply_exchange_buy( BuyOrder order ) {
save( buyer_account );
print( "saving buyer's account\n" );
if( bid.quantity ) {
print( bid.quantity.quantity, " eos left over" );
print( bid.quantity, " eos left over" );
assert( !order.fill_or_kill, "order not completely filled" );
Bids::store( bid );
return;
......@@ -199,8 +191,8 @@ void apply_exchange_sell( SellOrder order ) {
assert( ask.quantity > currency::Tokens(0), "invalid quantity" );
assert( ask.expiration > now(), "order expired" );
print( "\n\n", Name(ask.seller.name), " created sell for ", order.quantity.quantity,
" currency at price: ", order.price.base_per_quote, "\n");
print( "\n\n", Name(ask.seller.name), " created sell for ", order.quantity,
" currency at price: ", order.price, "\n");
Ask existing_ask;
assert( !AsksById::get( ask.seller, existing_ask ), "order with this id already exists" );
......
......@@ -606,6 +606,7 @@ void chain_controller::process_message( const Transaction& trx, const Message& m
apply_message(apply_ctx);
for (const auto& recipient : message.recipients) {
if( recipient == message.code ) continue; /// we already ran it above
try {
apply_context recipient_ctx(*this,_db, trx, message, recipient);
validate_message_precondition(recipient_ctx);
......
......@@ -216,8 +216,9 @@ namespace eos { namespace chain {
uint32_t last_irreversible_block_num() const;
protected:
// protected:
const chainbase::database& get_database() const { return _db; }
chainbase::database& get_mutable_database() { return _db; }
private:
......
......@@ -61,9 +61,9 @@ namespace eos { namespace chain {
OBJECT_CTOR(key128x128_value_object, (value))
id_type id;
AccountName scope;
AccountName code;
AccountName table;
uint64_t scope;
uint64_t code;
uint64_t table;
uint128_t primary_key;
uint128_t secondary_key;
shared_string value;
......@@ -77,9 +77,9 @@ namespace eos { namespace chain {
ordered_unique<tag<by_id>, member<key128x128_value_object, key128x128_value_object::id_type, &key128x128_value_object::id>>,
ordered_unique<tag<by_scope_primary>,
composite_key< key128x128_value_object,
member<key128x128_value_object, AccountName, &key128x128_value_object::scope>,
member<key128x128_value_object, AccountName, &key128x128_value_object::code>,
member<key128x128_value_object, AccountName, &key128x128_value_object::table>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::scope>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::code>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::table>,
member<key128x128_value_object, uint128_t, &key128x128_value_object::primary_key>,
member<key128x128_value_object, uint128_t, &key128x128_value_object::secondary_key>
>,
......@@ -87,13 +87,12 @@ namespace eos { namespace chain {
>,
ordered_unique<tag<by_scope_secondary>,
composite_key< key128x128_value_object,
member<key128x128_value_object, AccountName, &key128x128_value_object::scope>,
member<key128x128_value_object, AccountName, &key128x128_value_object::code>,
member<key128x128_value_object, AccountName, &key128x128_value_object::table>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::scope>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::code>,
member<key128x128_value_object, uint64_t, &key128x128_value_object::table>,
member<key128x128_value_object, uint128_t, &key128x128_value_object::secondary_key>,
member<key128x128_value_object, uint128_t, &key128x128_value_object::primary_key>
>,
composite_key_compare< std::less<AccountName>,std::less<AccountName>,std::less<AccountName>,std::less<uint128_t>, std::less<uint128_t> >
>
>
>
>;
......
......@@ -61,10 +61,12 @@ int32_t message_validate_context::load_i64( Name scope, Name code, Name table, N
int32_t message_validate_context::back_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
return -1;
/*
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_primary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(scope),
uint64_t(code),
table.value+1,
*primary, uint128_t(0) ) );
......@@ -86,11 +88,13 @@ int32_t message_validate_context::back_primary_i128i128( Name scope, Name code,
itr->value.copy(value, copylen);
}
return copylen;
*/
}
int32_t message_validate_context::back_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
/*
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_secondary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
......@@ -116,17 +120,20 @@ int32_t message_validate_context::back_secondary_i128i128( Name scope, Name code
itr->value.copy(value, copylen);
}
return copylen;
*/
return -1;
}
int32_t message_validate_context::front_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
/*
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_primary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
AccountName(table),
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(scope),
uint64_t(code),
uint64_t(table),
*primary, uint128_t(0) ) );
if( itr == idx.end() )
......@@ -147,20 +154,55 @@ int32_t message_validate_context::front_primary_i128i128( Name scope, Name code,
itr->value.copy(value, copylen);
}
return copylen;
*/
return -1;
}
int32_t message_validate_context::front_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_secondary>();
/*
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
AccountName(table),
*secondary, uint128_t(0) ) );
uint128_t(0), uint128_t(0) ) );
*/
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(0ull),
uint64_t(0ull),
uint64_t(0ull),
uint128_t(0),
uint128_t(0)) );
wdump((scope)(code)(table));
idump((idx.size()));
for( const auto& item : idx ) {
auto tup = boost::make_tuple( item.scope, item.code, item.table, item.primary_key, item.secondary_key );
auto in = boost::make_tuple( AccountName(scope), AccountName(code), AccountName(table),
uint128_t(1), uint128_t(1) );
idump( (scope)(code)(table)(fc::uint128(*primary))(fc::uint128(*secondary)) );
if( item.scope == uint64_t(scope) )
if( item.code == uint64_t(code) )
if( item.table == uint64_t(table) )
{
ilog( "matching scope, code, table" );
/*
if( item.secondary_key >= uint128_t(0) ) {
idump( "secondary_key >= 0" );
if( item.primary_key >= uint128_t(0) )
idump( "primary_key >= 0" );
}
*/
}
wdump( (item.scope)(item.code)(item.table)(fc::uint128(item.primary_key))(fc::uint128(item.secondary_key)) );
}
ilog(".");
if( itr == idx.end() )
return -1;
/*
--itr;
if( itr->scope != scope ||
......@@ -176,6 +218,8 @@ int32_t message_validate_context::front_secondary_i128i128( Name scope, Name cod
itr->value.copy(value, copylen);
}
return copylen;
*/
return -1;
}
......@@ -184,15 +228,15 @@ int32_t message_validate_context::load_primary_i128i128( Name scope, Name code,
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_primary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
AccountName(table),
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(scope),
uint64_t(code),
uint64_t(table),
*primary, uint128_t(0) ) );
if( itr == idx.end() ||
itr->scope != scope ||
itr->code != code ||
itr->table != table ||
itr->scope != uint64_t(scope) ||
itr->code != uint64_t(code) ||
itr->table != uint64_t(table) ||
itr->primary_key != *primary ) return -1;
*secondary = itr->secondary_key;
......@@ -206,11 +250,12 @@ int32_t message_validate_context::load_primary_i128i128( Name scope, Name code,
int32_t message_validate_context::lowerbound_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
/*
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_primary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
AccountName(table),
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(scope),
uint64_t(code),
uint64_t(table),
*primary, uint128_t(0) ) );
if( itr == idx.end() ||
......@@ -226,16 +271,19 @@ int32_t message_validate_context::lowerbound_primary_i128i128( Name scope, Name
itr->value.copy(value, copylen);
}
return copylen;
*/
return -1;
}
int32_t message_validate_context::lowerbound_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen ) {
/*
require_scope( scope );
const auto& idx = db.get_index<key128x128_value_index,by_scope_secondary>();
auto itr = idx.lower_bound( boost::make_tuple( AccountName(scope),
AccountName(code),
AccountName(table),
auto itr = idx.lower_bound( boost::make_tuple( uint64_t(scope),
uint64_t(code),
uint64_t(table),
uint128_t(0), *secondary ) );
if( itr == idx.end() ||
......@@ -251,6 +299,8 @@ int32_t message_validate_context::lowerbound_secondary_i128i128( Name scope, Nam
itr->value.copy(value, copylen);
}
return copylen;
*/
return -1;
}
int32_t apply_context::remove_i64( Name scope, Name table, Name key ) {
......@@ -300,14 +350,18 @@ int32_t apply_context::store_i128i128( Name scope, Name table, uint128_t primary
AccountName(code),
AccountName(table),
primary, secondary ) );
idump(( *((fc::uint128_t*)&primary)) );
idump(( *((fc::uint128_t*)&secondary)) );
if( obj ) {
wlog( "modify" );
mutable_db.modify( *obj, [&]( auto& o ) {
o.primary_key = primary;
o.secondary_key = secondary;
o.value.assign(value, valuelen);
});
return 0;
return valuelen;
} else {
wlog( "new" );
mutable_db.create<key128x128_value_object>( [&](auto& o) {
o.scope = scope;
o.code = code;
......
......@@ -41,16 +41,24 @@ DEFINE_INTRINSIC_FUNCTION0(env,now,now,i32) {
}
DEFINE_INTRINSIC_FUNCTION4(env,store_i128i128,store_i128i128,i32,i64,scope,i64,table,i32,data,i32,datalen) {
static const uint32_t keylen = 2*sizeof(uint128_t);
FC_ASSERT( datalen >= keylen, "insufficient data passed" );
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "not a valid apply context" );
char* v = &memoryRef<char>( wasm.current_memory, data );
uint128_t& primary = *((uint128_t*)v);
uint128_t& secondary = *(((uint128_t*)v)+1);
char* value = v + 2*sizeof(uint128_t);
return wasm_interface::get().current_apply_context->store_i128i128(
char* v = memoryArrayPtr<char>( wasm.current_memory, data, datalen );
uint128_t* primary = ((uint128_t*)v);
uint128_t* secondary = primary + 1;
char* value = (char*)(secondary+1);
uint32_t valuelen = datalen - keylen;
auto result = wasm_interface::get().current_apply_context->store_i128i128(
Name(scope), Name(table),
primary, secondary, value, datalen - 2*sizeof(uint128_t) );
*primary, *secondary, value, valuelen ) + keylen;
wdump((datalen)(valuelen)(result));
return result;
}
DEFINE_INTRINSIC_FUNCTION3(env,remove_i128i128,remove_i128i128,i32,i64,scope,i64,table,i32,data) {
......@@ -72,31 +80,52 @@ DEFINE_INTRINSIC_FUNCTION5(env,load_secondary_i128i128,load_secondary_i128i128,i
}
DEFINE_INTRINSIC_FUNCTION5(env,back_primary_i128i128,back_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,data,i32,datalen) {
wlog( "back primary" );
auto& wasm = wasm_interface::get();
char* v = &memoryRef<char>( wasm.current_memory, data );
return wasm_interface::get().current_validate_context->back_primary_i128i128( Name(scope), Name(code), Name(table),
(uint128_t*)v, (uint128_t*)(v+sizeof(uint128_t)), v, datalen-(2*sizeof(uint128_t)) );
}
DEFINE_INTRINSIC_FUNCTION5(env,front_primary_i128i128,front_primary,i32,i64,scope,i64,code,i64,table,i32,data,i32,datalen) {
wlog( "front primary" );
auto& wasm = wasm_interface::get();
char* v = &memoryRef<char>( wasm.current_memory, data );
return wasm_interface::get().current_validate_context->front_primary_i128i128( Name(scope), Name(code), Name(table),
(uint128_t*)v, (uint128_t*)(v+sizeof(uint128_t)), v, datalen-(2*sizeof(uint128_t)) );
(uint128_t*)v, (uint128_t*)(v+sizeof(uint128_t)),
v, datalen-(2*sizeof(uint128_t)) ) + 2*sizeof(uint128_t);
}
DEFINE_INTRINSIC_FUNCTION5(env,back_secondary_i128i128,back_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,data,i32,datalen) {
wlog( "back secondary" );
auto& wasm = wasm_interface::get();
char* v = &memoryRef<char>( wasm.current_memory, data );
char* v = memoryArrayPtr<char>( wasm.current_memory, data, datalen );
return wasm_interface::get().current_validate_context->back_secondary_i128i128( Name(scope), Name(code), Name(table),
(uint128_t*)v, (uint128_t*)(v+sizeof(uint128_t)), v, datalen-(2*sizeof(uint128_t)) );
return 0;
}
DEFINE_INTRINSIC_FUNCTION5(env,front_secondary_i128i128,front_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,data,i32,datalen) {
wlog( "front secondary" );
FC_ASSERT( datalen >= 2*sizeof(uint128_t), "insufficient data passed" );
auto& wasm = wasm_interface::get();
char* v = &memoryRef<char>( wasm.current_memory, data );
return wasm_interface::get().current_validate_context->front_secondary_i128i128( Name(scope), Name(code), Name(table),
(uint128_t*)v, (uint128_t*)(v+sizeof(uint128_t)), v, datalen-(2*sizeof(uint128_t)) );
char* v = memoryArrayPtr<char>( wasm.current_memory, data, datalen );
uint128_t* primary = (uint128_t*)v;
uint128_t* secondary = primary+1;
const uint32_t keylen = 2*sizeof(uint128_t);
char* value = v + keylen;
uint64_t valuelen = datalen - keylen;
auto result = wasm_interface::get().current_validate_context->front_secondary_i128i128( Name(scope), Name(code), Name(table),
primary, secondary, value, valuelen);
if( result >= 0) {
result += keylen;
}
wdump((result)(datalen));
return result;
}
DEFINE_INTRINSIC_FUNCTION0(env,currentCode,currentCode,i64) {
......@@ -236,7 +265,8 @@ DEFINE_INTRINSIC_FUNCTION2(env,readMessage,readMessage,i32,i32,destptr,i32,dests
}
DEFINE_INTRINSIC_FUNCTION2(env,assert,assert,none,i32,test,i32,msg) {
std::string message = &Runtime::memoryRef<char>( wasm_interface::get().current_memory, msg );
const char* m = &Runtime::memoryRef<char>( wasm_interface::get().current_memory, msg );
std::string message( m );
if( !test ) edump((message));
FC_ASSERT( test, "assertion failed: ${s}", ("s",message)("ptr",msg) );
}
......@@ -474,12 +504,12 @@ DEFINE_INTRINSIC_FUNCTION1(env,toUpper,toUpper,none,i32,charptr) {
char* memstart = &memoryRef<char>( current_memory, 0 );
// state.init_memory.resize(1<<16); /// TODO: actually get memory size
std::cerr <<"INIT MEMORY: \n";
for( uint32_t i = 0; i < 10000; ++i )
if( memstart[i] ) {
state.mem_end = i;
state.mem_end = i+1;
//std::cerr << (char)memstart[i];
}
ilog( "INIT MEMORY: ${size}", ("size", state.mem_end) );
state.init_memory.resize(state.mem_end);
memcpy( state.init_memory.data(), memstart, state.mem_end ); //state.init_memory.size() );
......
......@@ -32,6 +32,9 @@ namespace fc
uint128( uint64_t _h, uint64_t _l )
:hi(_h),lo(_l){}
uint128( const fc::bigint& bi );
uint128( unsigned __int128 i ) {
memcpy(this, (char*)&i, sizeof(i) );
}
operator std::string()const;
operator fc::bigint()const;
......@@ -122,6 +125,8 @@ namespace fc
void to_variant( const uint128& var, variant& vo );
void from_variant( const variant& var, uint128& vo );
void to_variant( const unsigned __int128& var, variant& vo );
void from_variant( const variant& var, unsigned __int128& vo );
namespace raw
{
......
......@@ -376,6 +376,8 @@ namespace fc
void to_variant( const uint128& var, variant& vo ) { vo = std::string(var); }
void from_variant( const variant& var, uint128& vo ){ vo = uint128(var.as_string()); }
void to_variant( const unsigned __int128& var, variant& vo ) { to_variant( *((uint128*)var), vo); }
void from_variant( const variant& var, unsigned __int128& vo ) { from_variant( var, *((uint128*)&vo)); }
} // namespace fc
......
......@@ -131,7 +131,9 @@ namespace eos { namespace types {
}
friend bool operator < ( const Name& a, const Name& b ) { return a.value < b.value; }
friend bool operator <= ( const Name& a, const Name& b ) { return a.value <= b.value; }
friend bool operator > ( const Name& a, const Name& b ) { return a.value > b.value; }
friend bool operator >=( const Name& a, const Name& b ) { return a.value >= b.value; }
friend bool operator == ( const Name& a, const Name& b ) { return a.value == b.value; }
friend bool operator != ( const Name& a, const Name& b ) { return a.value != b.value; }
......
......@@ -67,8 +67,99 @@ FC_REFLECT( OrderID, (name)(number) );
FC_REFLECT( Bid, (buyer)(price)(quantity)(expiration) );
FC_REFLECT( Ask, (seller)(price)(quantity)(expiration) );
struct record {
uint64_t a = 0;
uint64_t b = 0;
uint64_t c = 0;
fc::uint128 d = 0;
fc::uint128 e = 0;
};
struct by_abcde;
struct by_abced;
using test_index = boost::multi_index_container<
record,
indexed_by<
ordered_unique<tag<by_abcde>,
composite_key< record,
member<record, uint64_t, &record::a>,
member<record, uint64_t, &record::b>,
member<record, uint64_t, &record::c>,
member<record, fc::uint128, &record::d>,
member<record, fc::uint128, &record::e>
>
>,
ordered_unique<tag<by_abced>,
composite_key< record,
member<record, uint64_t, &record::a>,
member<record, uint64_t, &record::b>,
member<record, uint64_t, &record::c>,
member<record, fc::uint128, &record::e>,
member<record, fc::uint128, &record::d>
>
>
>
>;
// FC_REFLECT( record, (a)(b)(c)(d)(e) );
BOOST_AUTO_TEST_SUITE(slow_tests)
BOOST_FIXTURE_TEST_CASE(multiindex, testing_fixture)
{
test_index idx;
idx.emplace( record{1,0,0,1,9} );
idx.emplace( record{1,1,1,2,8} );
idx.emplace( record{1,2,3,3,7} );
idx.emplace( record{1,2,3,5,6} );
idx.emplace( record{1,2,3,6,5} );
idx.emplace( record{1,2,3,7,5} );
idx.emplace( record{1,2,3,8,3} );
auto& by_de = idx.get<by_abcde>();
auto& by_ed = idx.get<by_abced>();
auto itr = by_de.lower_bound( boost::make_tuple(1,2,3,0,0) );
BOOST_REQUIRE( itr != by_de.end() );
BOOST_REQUIRE( itr->d == 3 );
auto itr2 = by_ed.lower_bound( boost::make_tuple(1,2,3,0,0) );
BOOST_REQUIRE( itr2 != by_ed.end() );
BOOST_REQUIRE( itr2->e == 3 );
//BOOST_REQUIRE( itr2 == by_ed.begin() );
Make_Blockchain(chain)
auto& db = chain.get_mutable_database();
db.create<key128x128_value_object>( [&]( auto& obj ) {
obj.scope = 1;
obj.code = 1;
obj.table = 1;
obj.primary_key = 1;
obj.secondary_key = 2;
});
db.create<key128x128_value_object>( [&]( auto& obj ) {
obj.scope = 1;
obj.code = 1;
obj.table = 1;
obj.primary_key = 2;
obj.secondary_key = 3;
});
db.create<key128x128_value_object>( [&]( auto& obj ) {
obj.scope = 1;
obj.code = 1;
obj.table = 1;
obj.primary_key = 3;
obj.secondary_key = 2;
});
{
auto& sidx = db.get_index< key128x128_value_index, by_scope_secondary> ();
auto lower = sidx.lower_bound( boost::make_tuple( 1, 1, 1, 0, 0 ) );
BOOST_REQUIRE( lower != sidx.end() );
BOOST_REQUIRE( lower->primary_key == 1 );
BOOST_REQUIRE( lower->secondary_key == 2 );
}
}
// Test that TaPoS still works after block 65535 (See Issue #55)
BOOST_FIXTURE_TEST_CASE(tapos_wrap, testing_fixture)
{ try {
......@@ -297,7 +388,7 @@ void SellCurrency( testing_blockchain& chain, AccountName seller, AccountName ex
eos::chain::SignedTransaction trx;
trx.scope = sort_names({"exchange"});
trx.emplaceMessage("exchange", sort_names( {"exchange"} ),
trx.emplaceMessage("exchange", sort_names( {} ),
vector<types::AccountPermission>{ {seller,"active"} },
"sell", b );
trx.expiration = chain.head_block_time() + 100;
......@@ -314,7 +405,7 @@ void BuyCurrency( testing_blockchain& chain, AccountName buyer, AccountName exch
eos::chain::SignedTransaction trx;
trx.scope = sort_names({"exchange"});
trx.emplaceMessage("exchange", sort_names( {"exchange"} ),
trx.emplaceMessage("exchange", sort_names( {} ),
vector<types::AccountPermission>{ {buyer,"active"} },
"buy", b );
trx.expiration = chain.head_block_time() + 100;
......@@ -366,15 +457,18 @@ BOOST_FIXTURE_TEST_CASE(create_exchange, testing_fixture) {
TransferCurrency( chain, "initb", "exchange", 2000 );
chain.produce_blocks(1);
wlog( "start buy and sell" );
SellCurrency( chain, "initb", "exchange", 1, 100, .5 );
SellCurrency( chain, "initb", "exchange", 1, 100, .75 );
SellCurrency( chain, "initb", "exchange", 1, 100, .85 );
//BOOST_REQUIRE_THROW( SellCurrency( chain, "initb", "exchange", 1, 100, .5 ), fc::exception ); // order id already exists
SellCurrency( chain, "initb", "exchange", 2, 100, .75 );
//SellCurrency( chain, "initb", "exchange", 2, 100, .75 );
BuyCurrency( chain, "initb", "exchange", 1, 50, .25 );
//BOOST_REQUIRE_THROW( BuyCurrency( chain, "initb", "exchange", 1, 50, .25 ), fc::exception ); // order id already exists
/// this should buy 5 from initb order 2 at a price of .75
BuyCurrency( chain, "initb", "exchange", 2, 50, .8 );
//BuyCurrency( chain, "initb", "exchange", 2, 50, .8 );
} FC_LOG_AND_RETHROW()
}catch(...) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册