提交 69f0bb13 编写于 作者: B Brian Johnson

Merged in upstream changes

......@@ -82,6 +82,11 @@ extern "C" {
*/
int32_t store_i64( AccountName scope, TableName table, const void* data, uint32_t datalen );
/**
* @return 1 if the record was updated, 0 if no record with key was found
*/
int32_t update_i64( AccountName scope, TableName table, const void* data, uint32_t datalen );
/**
* @param scope - the account scope that will be read, must exist in the transaction scopes list
* @param code - identifies the code that controls write-access to the data
......@@ -94,11 +99,17 @@ int32_t store_i64( AccountName scope, TableName table, const void* data, uint32_
int32_t load_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t front_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t back_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t next_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t previous_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t lower_bound_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
int32_t upper_bound_i64( AccountName scope, AccountName code, TableName table, void* data, uint32_t datalen );
/**
* @param data - must point to at lest 8 bytes containing primary key
*
* @return 1 if a record was removed, and 0 if no record with key was found
*/
int32_t remove_i64( AccountName scope, TableName table, uint64_t key );
int32_t remove_i64( AccountName scope, TableName table, void* data );
///@} db_i64
......@@ -145,34 +156,34 @@ int32_t previous_primary_i128i128( AccountName scope, AccountName code, TableNam
int32_t load_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t upper_bound_primary_i128i128( AccountName scope, AccountName code, TableName table,
const void* key, void* data, uint32_t len );
int32_t lower_bound_primary_i128i128( AccountName scope, AccountName code, TableName table,
const void* key, void* data, uint32_t len );
int32_t upper_bound_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_primary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t front_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t back_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t next_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t previous_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t upper_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table,
const void* key, void* data, uint32_t len );
int32_t lower_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table,
const void* key, void* data, uint32_t len );
int32_t upper_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t lower_bound_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
int32_t load_secondary_i128i128( AccountName scope, AccountName code, TableName table, void* data, uint32_t len );
/**
* @param data - must point to at lest 32 bytes containing {primary,secondary}
*
* @return true if the record was removed, false if no record was found
* @return 1 if a record was removed, and 0 if no record with key was found
*/
bool remove_i128i128( AccountName scope, TableName table, const void* data );
int32_t remove_i128i128( AccountName scope, TableName table, const void* data );
/**
* @return 1 if a new record was created, 0 if an existing record was updated
*/
int32_t store_i128i128( AccountName scope, TableName table, const void* data, uint32_t len );
/**
* Creates or updates a record and returns true if successful
* @return 1 if the record was updated, 0 if no record with key was found
*/
bool store_i128i128( AccountName scope, TableName table, const void* data, uint32_t len );
int32_t update_i128i128( AccountName scope, TableName table, const void* data, uint32_t len );
///@} dbi128i128
}
......@@ -56,19 +56,50 @@ struct table_impl<sizeof(uint128_t),sizeof(uint128_t)> {
static int32_t load_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return load_primary_i128i128( scope, code, table, data, len );
}
static int32_t front_secondary( AccountName scope, AccountName code, TableName table, void* data, uint32_t len ) {
return front_secondary_i128i128( scope, code, table, data, len );
static int32_t next_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return next_primary_i128i128( scope, code, table, data, len );
}
static int32_t back_secondary( AccountName scope, AccountName code, TableName table, void* data, uint32_t len ) {
return back_secondary_i128i128( scope, code, table, data, len );
static int32_t previous_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return previous_primary_i128i128( scope, code, table, data, len );
}
static int32_t upper_bound_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return upper_bound_primary_i128i128( scope, code, table, data, len );
}
static int32_t lower_bound_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return lower_bound_primary_i128i128( scope, code, table, data, len );
}
static int32_t front_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return front_secondary_i128i128( scope, code, table, data, len );
}
static int32_t back_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return back_secondary_i128i128( scope, code, table, data, len );
}
static int32_t load_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return load_secondary_i128i128( scope, code, table, data, len );
}
static int32_t next_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return next_secondary_i128i128( scope, code, table, data, len );
}
static int32_t previous_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return previous_secondary_i128i128( scope, code, table, data, len );
}
static int32_t upper_bound_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return upper_bound_secondary_i128i128( scope, code, table, data, len );
}
static int32_t lower_bound_secondary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return lower_bound_secondary_i128i128( scope, code, table, data, len );
}
static bool remove( uint64_t scope, uint64_t table, const void* data ) {
static int32_t remove( uint64_t scope, uint64_t table, const void* data ) {
return remove_i128i128( scope, table, data );
}
static bool store( AccountName scope, TableName table, const void* data, uint32_t len ) {
static int32_t store( AccountName scope, TableName table, const void* data, uint32_t len ) {
return store_i128i128( scope, table, data, len );
}
static int32_t update( AccountName scope, TableName table, const void* data, uint32_t len ) {
return update_i128i128( scope, table, data, len );
}
};
template<>
......@@ -79,15 +110,31 @@ struct table_impl<sizeof(uint64_t),0> {
static int32_t back_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return back_i64( scope, code, table, data, len );
}
static bool remove( uint64_t scope, uint64_t table, const void* data ) {
return remove_i64( scope, table, *((uint64_t*)data) );
}
static int32_t load_primary( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return load_i64( scope, code, table, data, len );
}
static bool store( AccountName scope, TableName table, const void* data, uint32_t len ) {
static int32_t next( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return next_i64( scope, code, table, data, len );
}
static int32_t previous( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return previous_i64( scope, code, table, data, len );
}
static int32_t lower_bound( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return lower_bound_i64( scope, code, table, data, len );
}
static int32_t upper_bound( uint64_t scope, uint64_t code, uint64_t table, void* data, uint32_t len ) {
return upper_bound_i64( scope, code, table, data, len );
}
static int32_t remove( uint64_t scope, uint64_t table, const void* data ) {
return remove_i64( scope, table, (uint64_t*)data);
}
static int32_t store( AccountName scope, TableName table, const void* data, uint32_t len ) {
return store_i64( scope, table, data, len );
}
static int32_t update( AccountName scope, TableName table, const void* data, uint32_t len ) {
return update_i64( scope, table, data, len );
}
};
......@@ -142,7 +189,7 @@ struct Table {
return impl::upper_bound_primary( scope, code, table, &p &r, sizeof(Record) ) == sizeof(Record);
}
static bool remove( const Record& r, uint64_t s = scope ) {
return impl::remove( s, table, &r );
return impl::remove( s, table, &r ) != 0;
}
};
......@@ -169,7 +216,7 @@ struct Table {
return impl::upper_bound_secondary( s, code, table, &p &r, sizeof(Record) ) == sizeof(Record);
}
static bool remove( const Record& r, uint64_t s = scope ) {
return impl::remove( s, table, &r );
return impl::remove( s, table, &r ) != 0;
}
};
......@@ -182,8 +229,12 @@ struct Table {
assert( impl::store( s, table, &r, sizeof(r) ), "error storing record" );
return true;
}
static bool update( const Record& r, uint64_t s = scope ) {
assert( impl::update( s, table, &r, sizeof(r) ), "error updating record" );
return true;
}
static bool remove( const Record& r, uint64_t s = scope ) {
return impl::remove( s, table, &r );
return impl::remove( s, table, &r ) != 0;
}
};
......@@ -232,7 +283,7 @@ struct Table<scope,code,table,Record,PrimaryType,void> {
return impl::upper_bound_primary( scope, code, table, &p &r, sizeof(Record) ) == sizeof(Record);
}
static bool remove( const Record& r ) {
return impl::remove( scope, table, &r );
return impl::remove( scope, table, &r ) != 0;
}
};
......@@ -249,11 +300,15 @@ struct Table<scope,code,table,Record,PrimaryType,void> {
}
static bool store( const Record& r, uint64_t s = scope ) {
return impl::store( s, table, &r, sizeof(r) );
return impl::store( s, table, &r, sizeof(r) ) != 0;
}
static bool update( const Record& r, uint64_t s = scope ) {
return impl::update( s, table, &r, sizeof(r) ) != 0;
}
static bool remove( const Record& r, uint64_t s = scope ) {
return impl::remove( s, table, &r );
return impl::remove( s, table, &r ) != 0;
}
};
......
......@@ -46,6 +46,8 @@ extern "C" {
WASM_TEST_HANDLER(test_db, key_i64_store_scope);
WASM_TEST_HANDLER(test_db, key_i64_remove_scope);
WASM_TEST_HANDLER(test_db, key_i64_not_found);
WASM_TEST_HANDLER(test_db, key_i64_front_back);
WASM_TEST_HANDLER(test_db, key_i128i128_general);
//test crypto
......
......@@ -84,6 +84,7 @@ struct test_db {
static unsigned int key_i64_store_scope();
static unsigned int key_i64_remove_scope();
static unsigned int key_i64_not_found();
static unsigned int key_i64_front_back();
static unsigned int key_i128i128_general();
};
......
此差异已折叠。
......@@ -91,7 +91,8 @@ namespace eos { namespace chain {
member<key128x128_value_object, AccountName, &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> >
>
>
>;
......
......@@ -20,29 +20,106 @@ class apply_context {
TransactionAuthorizationChecker* authChecker)
:controller(con),db(db),trx(t),msg(m),code(code),mutable_controller(con),mutable_db(db),authChecker(authChecker){}
int32_t store_i64( Name scope, Name table, Name key, const char* data, uint32_t len);
int32_t remove_i64( Name scope, Name table, Name key );
int32_t remove_i128i128( Name scope, Name table, uint128_t primary, uint128_t secondary );
int32_t store_i128i128( Name scope, Name table, uint128_t primary, uint128_t secondary,
const char* data, uint32_t len );
int32_t store_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t len);
int32_t load_i64( Name scope, Name code, Name table, Name Key, char* data, uint32_t maxlen );
int32_t update_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t len);
int32_t remove_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t len);
int32_t load_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t front_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t back_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t next_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t previous_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t lower_bound_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t upper_bound_i64( Name scope, Name code, Name table, uint64_t *key, char* data, uint32_t maxlen );
int32_t store_i128i128( Name scope, Name code, Name table, uint128_t* primary, uint128_t* secondary,
char* data, uint32_t len );
int32_t update_i128i128( Name scope, Name code, Name table, uint128_t* primary, uint128_t* secondary,
char* data, uint32_t len );
int32_t remove_i128i128( Name scope, Name code, Name table, uint128_t *primary, uint128_t *secondary,
char* data, uint32_t len );
template <typename T>
int32_t load_i128i128( Name scope, Name code, Name table, uint128_t* primary,
uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t front_i128i128( Name scope, Name code, Name table, uint128_t* primary,
uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t back_i128i128( Name scope, Name code, Name table, uint128_t* primary,
uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t next_i128i128( Name scope, Name code, Name table, uint128_t* primary,
uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t previous_i128i128( Name scope, Name code, Name table, uint128_t* primary,
uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t lower_bound_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen );
template <typename T>
int32_t upper_bound_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* value, uint32_t valuelen );
int32_t load_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t front_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t back_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t next_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t previous_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t lower_bound_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t upper_bound_primary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t load_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t front_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t back_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t load_primary_i128i128( Name scope, Name code, Name table,
int32_t next_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t load_secondary_i128i128( Name scope, Name code, Name table,
int32_t previous_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t lowerbound_primary_i128i128( Name scope, Name code, Name table,
int32_t lower_bound_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
int32_t lowerbound_secondary_i128i128( Name scope, Name code, Name table,
int32_t upper_bound_secondary_i128i128( Name scope, Name code, Name table,
uint128_t* primary, uint128_t* secondary, char* data, uint32_t maxlen );
void require_authorization(const types::AccountName& account);
......
......@@ -8,8 +8,6 @@
namespace eos { namespace chain {
class chain_controller;
typedef int32_t (apply_context::*load_i128i128_fnc)(Name, Name, Name, uint128_t* , uint128_t*, char* , uint32_t);
/**
* @class wasm_interface
*
......@@ -64,7 +62,11 @@ class wasm_interface {
wasm_interface();
int32_t load_i128i128_object( uint64_t scope, uint64_t code, uint64_t table, int32_t valueptr, int32_t valuelen, load_i128i128_fnc function );
template <typename Function>
int32_t validate_i128i128(int32_t valueptr, int32_t valuelen, Function&& func);
template <typename Function>
int32_t validate_i64(int32_t valueptr, int32_t valuelen, Function&& func);
};
......
......@@ -33,15 +33,15 @@ DEFINE_INTRINSIC_FUNCTION0(env,checktime,checktime,none) {
throw checktime_exceeded();
}
}
int32_t load_i128i128_object( uint64_t scope, uint64_t code, uint64_t table, int32_t valueptr, int32_t valuelen, load_i128i128_fnc function ) {
template <typename Function>
int32_t validate_i128i128(int32_t valueptr, int32_t valuelen, Function&& func) {
static const uint32_t keylen = 2*sizeof(uint128_t);
FC_ASSERT( valuelen >= keylen, "insufficient data passed" );
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_validate_context, "no validate context found" );
FC_ASSERT( wasm.current_apply_context, "no apply context found" );
char* value = memoryArrayPtr<char>( wasm.current_memory, valueptr, valuelen );
uint128_t* primary = reinterpret_cast<uint128_t*>(value);
......@@ -50,14 +50,54 @@ DEFINE_INTRINSIC_FUNCTION0(env,checktime,checktime,none) {
valuelen -= keylen;
value += keylen;
auto res = (wasm.current_validate_context->*function)(
Name(scope), Name(code), Name(table),
primary, secondary, value, valuelen
);
return func(wasm.current_apply_context, primary, secondary, value, valuelen);
}
template <typename Function>
int32_t validate_i64(int32_t valueptr, int32_t valuelen, Function&& func) {
static const uint32_t keylen = sizeof(uint64_t);
FC_ASSERT( valuelen >= keylen );
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "no apply context found" );
auto mem = wasm.current_memory;
char* value = memoryArrayPtr<char>( mem, valueptr, valuelen);
uint64_t* key = reinterpret_cast<uint64_t*>(value);
if(res > 0) res += keylen;
return res;
valuelen -= keylen;
value += keylen;
return func(wasm.current_apply_context, key, value, valuelen);
}
#define READ_i64_OBJ(func_name) \
validate_i64(valueptr, valuelen, [&](apply_context* ctx, uint64_t* key, char *data, uint32_t datalen) -> int32_t { \
auto res = ctx->func_name( Name(scope), Name(code), Name(table), key, data, datalen); \
if (res >= 0) res += sizeof(uint64_t); \
return res; \
});
#define UPDATE_i64_OBJ(func_name, data_size) \
validate_i64(valueptr, data_size, [&](apply_context* ctx, uint64_t* key, char *data, uint32_t datalen) -> int32_t { \
return ctx->func_name( Name(scope), Name(ctx->code.value), Name(table), key, data, datalen); \
});
#define READ_i128i128_OBJ(func_name) \
validate_i128i128(valueptr, valuelen, [&](apply_context* ctx, uint128_t* primary, uint128_t* secondary, char *data, uint32_t datalen) -> int32_t { \
auto res = ctx->func_name( Name(scope), Name(code), Name(table), primary, secondary, data, datalen); \
if (res >= 0) res += 2*sizeof(uint128_t); \
return res; \
});
#define UPDATE_i128i128_OBJ(func_name, data_size) \
validate_i128i128(valueptr, data_size, [&](apply_context* ctx, uint128_t* primary, uint128_t* secondary, char *data, uint32_t datalen) -> int32_t { \
return ctx->func_name( Name(scope), Name(ctx->code.value), Name(table), primary, secondary, data, datalen); \
});
DEFINE_INTRINSIC_FUNCTION3(env, assert_sha256,assert_sha256,none,i32,dataptr,i32,datalen,i32,hash) {
FC_ASSERT( datalen > 0 );
......@@ -104,25 +144,44 @@ DEFINE_INTRINSIC_FUNCTION0(env,now,now,i32) {
return wasm_interface::get().current_validate_context->controller.head_block_time().sec_since_epoch();
}
DEFINE_INTRINSIC_FUNCTION4(env,store_i128i128,store_i128i128,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen) {
static const uint32_t keylen = 2*sizeof(uint128_t);
FC_ASSERT( valuelen >= keylen, "insufficient data passed" );
DEFINE_INTRINSIC_FUNCTION4(env,store_i64,store_i64,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen) {
return UPDATE_i64_OBJ(store_i64, valuelen);
}
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "no apply context found" );
DEFINE_INTRINSIC_FUNCTION4(env,update_i64,update_i64,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen) {
return UPDATE_i64_OBJ(update_i64, valuelen);
}
DEFINE_INTRINSIC_FUNCTION3(env,remove_i64,remove_i64,i32,i64,scope,i64,table,i32,valueptr) {
return UPDATE_i64_OBJ(remove_i64, sizeof(uint64_t));
}
DEFINE_INTRINSIC_FUNCTION5(env,load_i64,load_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(load_i64);
}
DEFINE_INTRINSIC_FUNCTION5(env,front_i64,front_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(front_i64);
}
DEFINE_INTRINSIC_FUNCTION5(env,back_i64,back_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(back_i64);
}
DEFINE_INTRINSIC_FUNCTION5(env,next_i64,next_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(next_i64);
}
char* value = memoryArrayPtr<char>( wasm.current_memory, valueptr, valuelen );
uint128_t* primary = reinterpret_cast<uint128_t*>(value);
uint128_t* secondary = primary + 1;
valuelen -= keylen;
value += keylen;
DEFINE_INTRINSIC_FUNCTION5(env,previous_i64,previous_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(previous_i64);
}
//wdump((datalen)(valuelen)(result));
return wasm.current_apply_context->store_i128i128( Name(scope), Name(table),
*primary, *secondary, value, valuelen );
DEFINE_INTRINSIC_FUNCTION5(env,lower_bound_i64,lower_bound_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(lower_bound_i64);
}
DEFINE_INTRINSIC_FUNCTION5(env,upper_bound_i64,upper_bound_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i64_OBJ(upper_bound_i64);
}
struct i128_keys {
......@@ -130,36 +189,72 @@ struct i128_keys {
uint128_t secondary;
};
DEFINE_INTRINSIC_FUNCTION3(env,remove_i128i128,remove_i128i128,i32,i64,scope,i64,table,i32,data) {
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "not a valid apply context" );
DEFINE_INTRINSIC_FUNCTION4(env,store_i128i128,store_i128i128,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen) {
return UPDATE_i128i128_OBJ(store_i128i128, valuelen);
}
const i128_keys& keys = memoryRef<const i128_keys>( wasm.current_memory, data );
return wasm_interface::get().current_apply_context->remove_i128i128( Name(scope), Name(table), keys.primary, keys.secondary );
DEFINE_INTRINSIC_FUNCTION4(env,update_i128i128,update_i128i128,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen) {
return UPDATE_i128i128_OBJ(update_i128i128, valuelen);
}
DEFINE_INTRINSIC_FUNCTION3(env,remove_i128i128,remove_i128i128,i32,i64,scope,i64,table,i32,valueptr) {
return UPDATE_i128i128_OBJ(remove_i128i128, 2*sizeof(uint128_t));
}
DEFINE_INTRINSIC_FUNCTION5(env,load_primary_i128i128,load_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::load_primary_i128i128);
return READ_i128i128_OBJ(load_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,load_secondary_i128i128,load_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::load_secondary_i128i128);
DEFINE_INTRINSIC_FUNCTION5(env,front_primary_i128i128,front_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(front_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,back_primary_i128i128,back_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::back_primary_i128i128);
return READ_i128i128_OBJ(back_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,front_primary_i128i128,front_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::front_primary_i128i128);
DEFINE_INTRINSIC_FUNCTION5(env,next_primary_i128i128,next_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(next_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,previous_primary_i128i128,previous_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(previous_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,upper_bound_primary_i128i128,upper_bound_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(upper_bound_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,lower_bound_primary_i128i128,lower_bound_primary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(lower_bound_primary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,load_secondary_i128i128,load_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(load_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,back_secondary_i128i128,back_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::back_secondary_i128i128);
return READ_i128i128_OBJ(back_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,front_secondary_i128i128,front_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return load_i128i128_object(scope, code, table, valueptr, valuelen, &apply_context::front_secondary_i128i128);
return READ_i128i128_OBJ(front_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,next_secondary_i128i128,next_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(next_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,previous_secondary_i128i128,previous_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(previous_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,upper_bound_secondary_i128i128,upper_bound_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(upper_bound_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION5(env,lower_bound_secondary_i128i128,lower_bound_secondary_i128i128,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen) {
return READ_i128i128_OBJ(lower_bound_secondary_i128i128);
}
DEFINE_INTRINSIC_FUNCTION0(env,currentCode,currentCode,i64) {
......@@ -182,55 +277,6 @@ DEFINE_INTRINSIC_FUNCTION1(env,requireScope,requireScope,none,i64,scope) {
wasm_interface::get().current_validate_context->require_scope( scope );
}
DEFINE_INTRINSIC_FUNCTION4(env,store_i64,store_i64,i32,i64,scope,i64,table,i32,valueptr,i32,valuelen)
{
static const uint32_t keylen = sizeof(uint64_t);
FC_ASSERT( valuelen >= sizeof(uint64_t) );
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "no apply context found" );
auto mem = wasm.current_memory;
char* value = memoryArrayPtr<char>( mem, valueptr, valuelen);
uint64_t* key = reinterpret_cast<uint64_t*>(value);
valuelen -= keylen;
value += keylen;
//idump((Name(scope))(Name(code))(Name(table))(Name(key))(valuelen) );
return wasm.current_apply_context->store_i64( scope, table, *key, value, valuelen );
}
DEFINE_INTRINSIC_FUNCTION5(env,load_i64,load_i64,i32,i64,scope,i64,code,i64,table,i32,valueptr,i32,valuelen)
{
//idump((Name(scope))(Name(code))(Name(table))(Name(key))(valuelen) );
static const uint32_t keylen = sizeof(uint64_t);
FC_ASSERT( valuelen >= keylen );
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_validate_context, "no validate context found" );
auto mem = wasm.current_memory;
char* value = memoryArrayPtr<char>( mem, valueptr, valuelen);
uint64_t* key = reinterpret_cast<uint64_t*>(value);
valuelen -= keylen;
value += keylen;
auto res = wasm.current_validate_context->load_i64( scope, code, table, *key, value, valuelen );
if(res > 0) res += keylen;
return res;
}
DEFINE_INTRINSIC_FUNCTION3(env,remove_i64,remove_i64,i32,i64,scope,i64,table,i64,key) {
auto& wasm = wasm_interface::get();
FC_ASSERT( wasm.current_apply_context, "no apply context found" );
return wasm.current_apply_context->remove_i64( scope, table, key );
}
DEFINE_INTRINSIC_FUNCTION3(env,memcpy,memcpy,i32,i32,dstp,i32,srcp,i32,len) {
auto& wasm = wasm_interface::get();
auto mem = wasm.current_memory;
......
此差异已折叠。
......@@ -109,7 +109,7 @@ uint32_t CallFunction( testing_blockchain& chain, const types::Message& msg, con
vector<char>& dest = *(vector<char> *)(&msg.data);
std::copy(data.begin(), data.end(), std::back_inserter(dest));
std::cout << "MANDO: " << msg.code << " " << msg.type << std::endl;
//std::cout << "MANDO: " << msg.code << " " << msg.type << std::endl;
trx.emplaceMessage(msg);
trx.expiration = chain.head_block_time() + expiration++;
......@@ -197,8 +197,8 @@ uint32_t last_fnc_err = 0;
BOOST_FIXTURE_TEST_CASE(test_all, testing_fixture)
{ try {
std::string test_api_wast_str(test_api_wast);
//auto test_api_wast = readFile2("/home/matu/Documents/Dev/eos/contracts/test_api/test_api.wast");
//std::string test_api_wast_str(test_api_wast);
auto test_api_wast_str = readFile2("/home/matu/Documents/Dev/eos/contracts/test_api/test_api.wast");
//std::cout << test_api_wast << std::endl;
Make_Blockchain(chain);
......@@ -365,6 +365,7 @@ BOOST_FIXTURE_TEST_CASE(test_all, testing_fixture)
tx_missing_scope, is_tx_missing_scope );
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_db", "key_i64_not_found"), {}, {} ) == WASM_TEST_PASS, "test_db::key_i64_not_found()" );
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_db", "key_i64_front_back"), {}, {} ) == WASM_TEST_PASS, "test_db::key_i64_front_back()" );
//Test db (i128i128)
BOOST_CHECK_MESSAGE( CALL_TEST_FUNCTION( TEST_METHOD("test_db", "key_i128i128_general"), {}, {} ) == WASM_TEST_PASS, "test_db::key_i128i128_general()" );
......
#!/usr/bin/perl
use strict;
use Getopt::Long;
use Env;
use File::Basename;
use File::copy;
use File::Spec;
use File::Path;
use Cwd;
my $eos_home = defined $ENV{EOS_HOME} ? $ENV{EOS_HOME} : getcwd;
my $eosd = $eos_home . "/programs/eosd/eosd";
my $eosc = $eos_home . "/programs/eosc/eosc";
my $nodes = defined $ENV{EOS_TEST_RING} ? $ENV{EOS_TEST_RING} : "1";
my $pnodes = defined $ENV{EOS_TEST_PRODUCERS} ? $ENV{EOS_TEST_PRODUCERS} : "1";
my $prods = 21;
my $genesis = "$eos_home/genesis.json";
my $http_port_base = 8888;
my $p2p_port_base = 9876;
my $data_dir_base = "tdn";
my $hostname = "127.0.0.1";
my $first_pause = 0;
my $launch_pause = 0;
my $run_duration = 60;
my $topo = "ring";
my $override_gts = "";
my $no_delay=0;
my $test=1;
if (!GetOptions("nodes=i" => \$nodes,
"first-pause=i" => \$first_pause,
"launch-pause=i" => \$launch_pause,
"duration=i" => \$run_duration,
"topo=s" => \$topo,
"test=i" => \$test,
"time-stamp=s" => \$override_gts,
"pnodes=i" => \$pnodes)) {
print "usage: $ARGV[0] [--nodes=<n>] [--pnodes=<n>] [--topo=<ring|star>] [--first-pause=<n>] [--launch-pause=<n>] [--duration=<n>] [--time-stamp=<time> \n";
print "where:\n";
print "--nodes=n (default = 1) sets the number of eosd instances to launch\n";
print "--pnodes=n (default = 1) sets the number nodes that will also be producers\n";
print "--topo=s (default = ring) sets the network topology to eithar a ring shape or a star shape\n";
print "--first-pause=n (default = 0) sets the seconds delay after starting the first instance\n";
print "--launch-pause=n (default = 0) sets the seconds delay after starting subsequent nodes\n";
print "--duration=n (default = 60) sets the seconds delay after starting the last node before shutting down the test\n";
print "--time-stamp=s (defsult \"\") sets the timestsmp in UTC for the genesis block. use \"now\" to mean the current time.\n";
print "\nproducer count currently fixed at $prods\n";
exit
}
die "pnodes value must be between 1 and $prods\n" if ($pnodes < 1 || $pnodes > $prods);
$nodes = $pnodes if ($nodes < $pnodes);
my $per_node = int ($prods / $pnodes);
my $extra = $prods - ($per_node * $pnodes);
my @pcount;
for (my $p = 0; $p < $pnodes; $p++) {
$pcount[$p] = $per_node;
if ($extra) {
$pcount[$p]++;
$extra--;
}
}
my @pid;
my @data_dir;
my @p2p_port;
my @http_port;
my @peers;
$launch_pause = 0 if ($no_delay);
$first_pause = 0 if ($no_delay);
my $rhost = $hostname; # from a list for multihost tests
for (my $i = 0; $i < $nodes; $i++) {
$p2p_port[$i] = $p2p_port_base + $i;
$http_port[$i] = $http_port_base + $i;
$data_dir[$i] = "$data_dir_base-$i";
}
opendir(DIR, ".") or die $!;
while (my $d = readdir(DIR)) {
if ($d =~ $data_dir_base) {
rmtree ($d) or die $!;
}
}
closedir(DIR);
sub write_config {
my $i = shift;
my $producer = shift;
mkdir ($data_dir[$i]);
mkdir ($data_dir[$i]."/blocks");
mkdir ($data_dir[$i]."/blockchain");
open (my $cfg, '>', "$data_dir[$i]/config.ini") ;
print $cfg "genesis-json = \"$genesis\"\n";
print $cfg "block-log-dir = blocks\n";
print $cfg "readonly = 0\n";
print $cfg "shared-file-dir = blockchain\n";
print $cfg "shared-file-size = 64\n";
print $cfg "http-server-endpoint = 127.0.0.1:$http_port[$i]\n";
print $cfg "listen-endpoint = 0.0.0.0:$p2p_port[$i]\n";
print $cfg "public-endpoint = $hostname:$p2p_port[$i]\n";
foreach my $peer (@peers) {
print $cfg "remote-endpoint = $peer\n";
}
if (defined $producer) {
print $cfg "enable-stale-production = true\n";
print $cfg "required-participation = true\n";
print $cfg "private-key = [\"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\",\"5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\"]\n";
print $cfg "plugin = eos::producer_plugin\n";
print $cfg "plugin = eos::chain_api_plugin\n";
my $prod_ndx = ord('a') + $producer;
my $num_prod = $pcount[$producer];
for (my $p = 0; $p < $num_prod; $p++) {
print $cfg "producer-name = init" . chr($prod_ndx) . "\n";
$prod_ndx += $pnodes; # ($p < $per_node-1) ? $pnodes : 1;
}
}
close $cfg;
}
#connect each producer to the one ahead in the list, last to the first
#if bidir set then double connect to the one behind as well
sub make_ring_topology {
my $bidir = shift;
if ($nodes == 1) {
write_config (0,0);
return 1;
}
for (my $i = 0; $i < $nodes; $i++) {
my $pi = $i if ($i < $pnodes);
my $rport = ($i == $nodes - 1) ? $p2p_port_base : $p2p_port[$i] + 1;
$peers[0] = "$rhost:$rport";
if ($nodes > 2 && $bidir) {
$rport = $p2p_port[$i] - 1;
$rport += $nodes if ($i == 0);
$peers[1] = "$rhost:$rport";
}
write_config ($i, $pi);
}
return 1;
}
#connect each producer to three others, index+1, index + 1 + delta, index + 2(1 + delta)
#delta determined by total number of producer nodes. between 4 and 7, delta = pnodes-4
sub make_star_topology {
if ($pnodes < 4) {
return make_ring_topology(0);
}
my $numconn = 3;
my @ports;
my $delta = $pnodes > 6 ? 4 : $pnodes - $numconn;
for (my $i = 0; $i < $nodes; $i++) {
my $pi = $i if ($i < $pnodes);
$ports[0] = $p2p_port[$i];
for (my $d = 1; $d <= $numconn; $d++) {
my $rind = ($i + ($d) * ($delta)) % $nodes;
$rind++ if ($rind == $i);
my $rport = $p2p_port[$rind];
for (my $chk = 0; $chk < $d; $chk++) {
if ($rport == $ports[$chk]) {
$rport++;
$chk = -1;
}
}
$ports[$d] = $rport;
$peers[$d-1] = "$rhost:$rport";
}
write_config ($i, $pi);
}
return 1;
}
sub launch_nodes {
my $gtsarg;
if ($override_gts) {
my $GTS = $override_gts;
print "override gts = $override_gts\n";
if ($override_gts =~ "now" ) {
chomp ($GTS = `date -u "+%Y-%m-%dT%H:%M:%S"`);
my @s = split (':',$GTS);
$s[2] = substr ((100 + (int ($s[2]/3) * 3)),1);
$GTS = join (':', @s);
print "using genesis time stamp $GTS\n";
}
$gtsarg = "--genesis-timestamp=$GTS";
}
for (my $i = 0; $i < $nodes; $i++) {
my @cmdline = ($eosd,
$gtsarg,
"--data-dir=$data_dir[$i]");
$pid[$i] = fork;
if ($pid[$i] > 0) {
my $pause = $i == 0 ? $first_pause : $launch_pause;
print "parent process looping, child pid = $pid[$i]";
if ($i < $nodes - 1) {
print ", pausing $pause seconds\n";
sleep ($pause);
}
else {
print "\n";
}
}
elsif (defined ($pid[$i])) {
print "child execing now, pid = $$\n";
open OUTPUT, '>', "$data_dir[$i]/stdout.txt" or die $!;
open ERROR, '>', "$data_dir[$i]/stderr.txt" or die $!;
STDOUT->fdopen ( \*OUTPUT, 'w') or die $!;
STDERR->fdopen ( \*ERROR, 'w') or die $!;
print "$cmdline[0], $cmdline[1], $cmdline[2]\n";
exec @cmdline;
print "child terminating now\n";
exit;
}
else {
print "fork failed\n";
exit;
}
}
}
sub perform_work {
my $mode = shift;
sleep (5);
print "all nodes launched, network running for $run_duration seconds\n";
if ($mode == 0) {
sleep ($run_duration);
}
elsif ($mode == 1) {
my $stoptime = time () + $run_duration;
my $counter = 0;
while (time () < $stoptime) {
`$eosc transfer eos inita 10 >> eosc.out 2>> eosc.err`;
$counter++;
if ($counter % 1000 == 0) {
print "$counter client iterations\n";
}
}
print "minimal contract ran $counter times.\n";
}
else {
print "test mode $mode not defined\n";
}
}
sub kill_nodes {
foreach my $pp (@pid) {
print "killing $pp\n";
if (kill (2, $pp) != 0) {
sleep (1);
kill 9, $pp;
}
}
}
###################################################
# main
if ( $topo =~ "ring" ) { make_ring_topology (1) or die; }
elsif ( $topo =~ "star" ) { make_star_topology () or die; }
else { print "$topo is not a known topology" and die; }
launch_nodes ();
perform_work ($test);
kill_nodes () if ($run_duration > 0);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册