Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
YottaChain
YTBP
提交
fee30e1c
Y
YTBP
项目概览
YottaChain
/
YTBP
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
YTBP
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
fee30e1c
编写于
3月 02, 2018
作者:
D
Daniel Larimer
提交者:
GitHub
3月 02, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1522 from EOSIO/updated-multi_index
Updated multi_index and new C DB API
上级
a6faa2db
02bd1472
变更
42
展开全部
隐藏空白更改
内联
并排
Showing
42 changed file
with
2403 addition
and
926 deletion
+2403
-926
.gitignore
.gitignore
+1
-0
contracts/CMakeLists.txt
contracts/CMakeLists.txt
+1
-0
contracts/eosiolib/datastream.hpp
contracts/eosiolib/datastream.hpp
+20
-21
contracts/eosiolib/db.h
contracts/eosiolib/db.h
+39
-25
contracts/eosiolib/fixed_key.hpp
contracts/eosiolib/fixed_key.hpp
+217
-0
contracts/eosiolib/generic_currency.hpp
contracts/eosiolib/generic_currency.hpp
+32
-12
contracts/eosiolib/multi_index.hpp
contracts/eosiolib/multi_index.hpp
+254
-179
contracts/eosiolib/print.h
contracts/eosiolib/print.h
+1
-1
contracts/eosiolib/print.hpp
contracts/eosiolib/print.hpp
+24
-5
contracts/eosiolib/singleton.hpp
contracts/eosiolib/singleton.hpp
+40
-41
contracts/eosiolib/types.h
contracts/eosiolib/types.h
+0
-4
contracts/eosiolib/types.hpp
contracts/eosiolib/types.hpp
+1
-2
contracts/identity/identity.abi
contracts/identity/identity.abi
+0
-1
contracts/identity/identity.hpp
contracts/identity/identity.hpp
+140
-137
contracts/identity/test/identity_test.cpp
contracts/identity/test/identity_test.cpp
+2
-16
contracts/multi_index_test/multi_index_test.abi
contracts/multi_index_test/multi_index_test.abi
+8
-34
contracts/multi_index_test/multi_index_test.cpp
contracts/multi_index_test/multi_index_test.cpp
+153
-31
contracts/proxy/proxy.cpp
contracts/proxy/proxy.cpp
+13
-4
contracts/proxy/proxy.hpp
contracts/proxy/proxy.hpp
+1
-1
contracts/simpledb/simpledb.cpp
contracts/simpledb/simpledb.cpp
+8
-8
contracts/test_api/test_api.hpp
contracts/test_api/test_api.hpp
+12
-3
contracts/test_api/test_types.cpp
contracts/test_api/test_types.cpp
+4
-4
contracts/test_api_db/test_db.cpp
contracts/test_api_db/test_db.cpp
+61
-63
contracts/test_api_multi_index/CMakeLists.txt
contracts/test_api_multi_index/CMakeLists.txt
+5
-0
contracts/test_api_multi_index/test_api_multi_index.cpp
contracts/test_api_multi_index/test_api_multi_index.cpp
+30
-0
contracts/test_api_multi_index/test_multi_index.cpp
contracts/test_api_multi_index/test_multi_index.cpp
+403
-0
libraries/chain/apply_context.cpp
libraries/chain/apply_context.cpp
+57
-29
libraries/chain/chain_controller.cpp
libraries/chain/chain_controller.cpp
+1
-0
libraries/chain/include/eosio/chain/apply_context.hpp
libraries/chain/include/eosio/chain/apply_context.hpp
+248
-91
libraries/chain/include/eosio/chain/contracts/contract_table_objects.hpp
.../include/eosio/chain/contracts/contract_table_objects.hpp
+32
-1
libraries/chain/include/eosio/chain/contracts/types.hpp
libraries/chain/include/eosio/chain/contracts/types.hpp
+1
-3
libraries/chain/include/eosio/chain/fixed_key.hpp
libraries/chain/include/eosio/chain/fixed_key.hpp
+265
-0
libraries/chain/include/eosio/chain/types.hpp
libraries/chain/include/eosio/chain/types.hpp
+3
-1
libraries/chain/wasm_interface.cpp
libraries/chain/wasm_interface.cpp
+171
-139
libraries/fc/include/fc/crypto/sha256.hpp
libraries/fc/include/fc/crypto/sha256.hpp
+2
-0
libraries/testing/tester.cpp
libraries/testing/tester.cpp
+2
-1
plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp
.../chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp
+10
-0
tests/api_tests/api_tests.cpp
tests/api_tests/api_tests.cpp
+70
-50
tests/tests/abi_tests.cpp
tests/tests/abi_tests.cpp
+3
-6
tests/wasm_tests/identity_tests.cpp
tests/wasm_tests/identity_tests.cpp
+22
-10
tests/wasm_tests/multi_index_tests.cpp
tests/wasm_tests/multi_index_tests.cpp
+42
-2
tests/wasm_tests/wasm_tests.cpp
tests/wasm_tests/wasm_tests.cpp
+4
-1
未找到文件。
.gitignore
浏览文件 @
fee30e1c
...
...
@@ -55,6 +55,7 @@ tests/chain_bench
tests/chain_test
tests/intense_test
tests/performance_test
tests/tests/config.hpp
doxygen
...
...
contracts/CMakeLists.txt
浏览文件 @
fee30e1c
...
...
@@ -22,6 +22,7 @@ add_subdirectory(proxy)
add_subdirectory
(
test_api
)
add_subdirectory
(
test_api_mem
)
add_subdirectory
(
test_api_db
)
add_subdirectory
(
test_api_multi_index
)
add_subdirectory
(
simpledb
)
#add_subdirectory(storage)
#add_subdirectory(social)
...
...
contracts/eosiolib/datastream.hpp
浏览文件 @
fee30e1c
...
...
@@ -19,14 +19,14 @@ class datastream {
public:
datastream
(
T
start
,
size_t
s
)
:
_start
(
start
),
_pos
(
start
),
_end
(
start
+
s
){}
/**
* Skips a specified number of bytes from this stream
* @brief Skips a specific number of bytes from this stream
* @param s The number of bytes to skip
*/
inline
void
skip
(
size_t
s
){
_pos
+=
s
;
}
/**
* Reads a specified number of bytes from the stream into a buffer
* @brief Reads a specified number of bytes from this stream into a buffer
...
...
@@ -52,30 +52,30 @@ class datastream {
_pos
+=
s
;
return
true
;
}
/**
* Writes a byte into the stream
* @brief Writes a byte into the stream
* @param c byte to write
*/
inline
bool
put
(
char
c
)
{
inline
bool
put
(
char
c
)
{
eosio_assert
(
_pos
<
_end
,
"put"
);
*
_pos
=
c
;
++
_pos
;
*
_pos
=
c
;
++
_pos
;
return
true
;
}
/**
* Reads a byte from the stream
* @brief Reads a byte from the stream
* @param c reference to destination byte
*/
inline
bool
get
(
unsigned
char
&
c
)
{
return
get
(
*
(
char
*
)
&
c
);
}
inline
bool
get
(
char
&
c
)
inline
bool
get
(
char
&
c
)
{
eosio_assert
(
_pos
<
_end
,
"get"
);
c
=
*
_pos
;
++
_pos
;
++
_pos
;
return
true
;
}
...
...
@@ -86,7 +86,7 @@ class datastream {
*/
T
pos
()
const
{
return
_pos
;
}
inline
bool
valid
()
const
{
return
_pos
<=
_end
&&
_pos
>=
_start
;
}
/**
* Sets the position within the current stream
* @brief Sets the position within the current stream
...
...
@@ -100,7 +100,7 @@ class datastream {
* @return p the position within the current stream
*/
inline
size_t
tellp
()
const
{
return
size_t
(
_pos
-
_start
);
}
/**
* Returns the number of remaining bytes that can be read/skipped
* @brief Returns the number of remaining bytes that can be read/skipped
...
...
@@ -132,25 +132,25 @@ class datastream<size_t> {
};
/**
* Serialize a
uint
256 into a stream
* @brief Serialize a
uint
256
* Serialize a
key
256 into a stream
* @brief Serialize a
key
256
* @param ds stream to write
* @param d value to serialize
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
uint
256
d
)
{
ds
.
write
(
(
const
char
*
)
&
d
,
sizeof
(
d
)
);
inline
datastream
<
Stream
>&
operator
<<
(
datastream
<
Stream
>&
ds
,
const
key
256
d
)
{
ds
.
write
(
(
const
char
*
)
d
.
data
(),
d
.
size
(
)
);
return
ds
;
}
/**
* Deserialize a
uint
256 from a stream
* @brief Deserialize a
uint
256
* Deserialize a
key
256 from a stream
* @brief Deserialize a
key
256
* @param ds stream to read
* @param d destination for deserialized value
*/
template
<
typename
Stream
>
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
uint
256
&
d
)
{
ds
.
read
((
char
*
)
&
d
,
sizeof
(
d
)
);
inline
datastream
<
Stream
>&
operator
>>
(
datastream
<
Stream
>&
ds
,
key
256
&
d
)
{
ds
.
read
((
char
*
)
d
.
data
(),
d
.
size
(
)
);
return
ds
;
}
...
...
@@ -430,7 +430,7 @@ T unpack( const char* buffer, size_t len ) {
template
<
typename
T
>
size_t
pack_size
(
const
T
&
value
)
{
datastream
<
size_t
>
ps
;
datastream
<
size_t
>
ps
;
ps
<<
value
;
return
ps
.
tellp
();
}
...
...
@@ -446,4 +446,3 @@ bytes pack( const T& value ) {
}
}
contracts/eosiolib/db.h
浏览文件 @
fee30e1c
...
...
@@ -15,23 +15,23 @@ extern "C" {
* EOS.IO organizes data according to the following broad structure:
*
* - **scope** - an account where the data is stored
* - **code** - the account name which has write permission
* - **code** - the account name which has write permission
* - **table** - a name for the table that is being stored
* - **record** - a row in the table
*
* Every transaction specifies the set of valid scopes that may be read and/or written
* to. The code that is running determines what can be written to; therefore, write operations
* do not allow you to specify/configure the code.
* do not allow you to specify/configure the code.
*
* @note Attempts to read and/or write outside the valid scope and/or code sections will
* @note Attempts to read and/or write outside the valid scope and/or code sections will
* cause your transaction to fail.
*
*
* @section tabletypes table Types
* There are several supported table types identified by the number and
* size of the index.
* size of the index.
*
* 1. @ref dbi64
* 1. @ref dbi64
* 2. @ref dbi128i128
*
* The database APIs assume that the first bytes of each record represent
...
...
@@ -264,7 +264,7 @@ int32_t remove_i64( account_name scope, table_name table, void* data );
*
*/
int32_t
store_str
(
account_name
scope
,
table_name
table
,
account_name
bta
,
char
*
key
,
uint32_t
keylen
,
char
*
value
,
uint32_t
valuelen
);
/**
* @param scope - the account scope that will be read, must exist in the transaction scopes list
* @param table - the ID/name of the table within the current scope/code context to modify
...
...
@@ -286,7 +286,7 @@ int32_t store_str( account_name scope, table_name table, account_name bta, char*
*
*/
int32_t
update_str
(
account_name
scope
,
table_name
table
,
account_name
bta
,
char
*
key
,
uint32_t
keylen
,
char
*
value
,
uint32_t
valuelen
);
/**
* @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
...
...
@@ -294,7 +294,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param key - location of the record key
* @param keylen - length of the record key
* @param value - location to copy the record value
* @param valuelen - maximum length of the record value to read
* @param valuelen - maximum length of the record value to read
*
* @return the number of bytes read or -1 if key was not found
*/
...
...
@@ -305,7 +305,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param code - identifies the code that controls write-access to the data
* @param table - the ID/name of the table within the scope/code context to query
* @param value - location to copy the front record value
* @param valuelen - maximum length of the record value to read
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
*/
int32_t
front_str
(
account_name
code
,
account_name
scope
,
table_name
table
,
char
*
value
,
uint32_t
valuelen
);
...
...
@@ -315,7 +315,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param code - identifies the code that controls write-access to the data
* @param table - the ID/name of the table within the scope/code context to query
* @param value - location to copy the back record value
* @param valuelen - maximum length of the record value to read
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
*/
int32_t
back_str
(
account_name
code
,
account_name
scope
,
table_name
table
,
char
*
value
,
uint32_t
valuelen
);
...
...
@@ -327,7 +327,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param key - location of the record key
* @param keylen - length of the record key
* @param value - location to copy the next record value
* @param valuelen - maximum length of the record value to read
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
*/
int32_t
next_str
(
account_name
code
,
account_name
scope
,
table_name
table
,
char
*
key
,
uint32_t
keylen
,
char
*
value
,
uint32_t
valuelen
);
...
...
@@ -339,7 +339,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @param key - location of the record key
* @param keylen - length of the record key
* @param value - location to copy the previous record value
* @param valuelen - maximum length of the record value to read
* @param valuelen - maximum length of the record value to read
* @return the number of bytes read or -1 if key was not found
*/
int32_t
previous_str
(
account_name
code
,
account_name
scope
,
table_name
table
,
char
*
key
,
uint32_t
keylen
,
char
*
value
,
uint32_t
valuelen
);
...
...
@@ -367,7 +367,7 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @return the number of bytes read or -1 if key was not found
*/
int32_t
upper_bound_str
(
account_name
code
,
account_name
scope
,
table_name
table
,
char
*
key
,
uint32_t
keylen
,
char
*
value
,
uint32_t
valuelen
);
/**
* @param key - location of the record key
* @param keylen - length of the record key
...
...
@@ -375,22 +375,22 @@ int32_t update_str( account_name scope, table_name table, account_name bta, char
* @return 1 if a record was removed, and 0 if no record with key was found
*/
int32_t
remove_str
(
account_name
scope
,
table_name
table
,
char
*
key
,
uint32_t
keylen
);
///@} dbstr
/**
* @defgroup dbi128i128 Dual 128 bit Index table
* @brief Interface to a database table with 128 bit primary and secondary keys and arbitary binary data value.
* @ingroup databaseC
* @ingroup databaseC
*
* @param scope - the account where table data will be found
* @param code - the code which owns the table
* @param table - the name of the table where record is stored
* @param data - a pointer to memory that is at least 32 bytes long
* @param data - a pointer to memory that is at least 32 bytes long
* @param len - the length of data, must be greater than or equal to 32 bytes
*
* @return the total number of bytes read or -1 for "not found" or "end" where bytes
* read includes 32 bytes of the key
* @return the total number of bytes read or -1 for "not found" or "end" where bytes
* read includes 32 bytes of the key
*
* These methods assume a database table with records of the form:
*
...
...
@@ -671,16 +671,16 @@ int32_t update_i128i128( account_name scope, table_name table, account_name bta,
/**
* @defgroup dbi64i64i64 Triple 64 bit Index table
* @brief Interface to a database table with 64 bit primary, secondary and tertiary keys and arbitrary binary data value.
* @ingroup databaseC
* @ingroup databaseC
*
* @param scope - the account where table data will be found
* @param code - the code which owns the table
* @param table - the name of the table where record is stored
* @param data - a pointer to memory that is at least 32 bytes long
* @param data - a pointer to memory that is at least 32 bytes long
* @param len - the length of data, must be greater than or equal to 32 bytes
*
* @return the total number of bytes read or -1 for "not found" or "end" where bytes
* read includes 24 bytes of the key
* @return the total number of bytes read or -1 for "not found" or "end" where bytes
* read includes 24 bytes of the key
*
* These methods assume a database table with records of the form:
*
...
...
@@ -1023,7 +1023,7 @@ int32_t store_i64i64i64( account_name scope, table_name table, account_name bta,
* @return 1 if the record was updated, 0 if no record with key was found
*/
int32_t
update_i64i64i64
(
account_name
scope
,
table_name
table
,
account_name
bta
,
const
void
*
data
,
uint32_t
len
);
///@} dbi64i64i64
///@} dbi64i64i64
int32_t
db_store_i64
(
account_name
scope
,
table_name
table
,
account_name
payer
,
uint64_t
id
,
const
void
*
data
,
uint32_t
len
);
void
db_update_i64
(
int32_t
iterator
,
account_name
payer
,
const
void
*
data
,
uint32_t
len
);
...
...
@@ -1032,8 +1032,9 @@ int32_t db_get_i64(int32_t iterator, const void* data, uint32_t len);
int32_t
db_next_i64
(
int32_t
iterator
,
uint64_t
*
primary
);
int32_t
db_previous_i64
(
int32_t
iterator
,
uint64_t
*
primary
);
int32_t
db_find_i64
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
id
);
int32_t
db_lowerbound_i64
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
id
);
int32_t
db_upperbound_i64
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
id
);
int32_t
db_lowerbound_i64
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
id
);
int32_t
db_upperbound_i64
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
id
);
int32_t
db_end_i64
(
account_name
code
,
account_name
scope
,
table_name
table
);
int32_t
db_idx64_store
(
account_name
scope
,
table_name
table
,
account_name
payer
,
uint64_t
id
,
const
uint64_t
*
secondary
);
void
db_idx64_update
(
int32_t
iterator
,
account_name
payer
,
const
uint64_t
*
secondary
);
...
...
@@ -1044,6 +1045,7 @@ int32_t db_idx64_find_primary(account_name code, account_name scope, table_name
int32_t
db_idx64_find_secondary
(
account_name
code
,
account_name
scope
,
table_name
table
,
const
uint64_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx64_lowerbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx64_upperbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint64_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx64_end
(
account_name
code
,
account_name
scope
,
table_name
table
);
int32_t
db_idx128_store
(
account_name
scope
,
table_name
table
,
account_name
payer
,
uint64_t
id
,
const
uint128_t
*
secondary
);
void
db_idx128_update
(
int32_t
iterator
,
account_name
payer
,
const
uint128_t
*
secondary
);
...
...
@@ -1054,5 +1056,17 @@ int32_t db_idx128_find_primary(account_name code, account_name scope, table_name
int32_t
db_idx128_find_secondary
(
account_name
code
,
account_name
scope
,
table_name
table
,
const
uint128_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx128_lowerbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint128_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx128_upperbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
uint128_t
*
secondary
,
uint64_t
*
primary
);
int32_t
db_idx128_end
(
account_name
code
,
account_name
scope
,
table_name
table
);
int32_t
db_idx256_store
(
account_name
scope
,
table_name
table
,
account_name
payer
,
uint64_t
id
,
const
void
*
data
,
uint32_t
data_len
);
void
db_idx256_update
(
int32_t
iterator
,
account_name
payer
,
const
void
*
data
,
uint32_t
data_len
);
void
db_idx256_remove
(
int32_t
iterator
);
int32_t
db_idx256_next
(
int32_t
iterator
,
uint64_t
*
primary
);
int32_t
db_idx256_previous
(
int32_t
iterator
,
uint64_t
*
primary
);
int32_t
db_idx256_find_primary
(
account_name
code
,
account_name
scope
,
table_name
table
,
void
*
data
,
uint32_t
data_len
,
uint64_t
primary
);
int32_t
db_idx256_find_secondary
(
account_name
code
,
account_name
scope
,
table_name
table
,
const
void
*
data
,
uint32_t
data_len
,
uint64_t
*
primary
);
int32_t
db_idx256_lowerbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
void
*
data
,
uint32_t
data_len
,
uint64_t
*
primary
);
int32_t
db_idx256_upperbound
(
account_name
code
,
account_name
scope
,
table_name
table
,
void
*
data
,
uint32_t
data_len
,
uint64_t
*
primary
);
int32_t
db_idx256_end
(
account_name
code
,
account_name
scope
,
table_name
table
);
}
contracts/eosiolib/fixed_key.hpp
0 → 100644
浏览文件 @
fee30e1c
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <array>
#include <algorithm>
#include <type_traits>
#include <eosiolib/system.h>
namespace
eosio
{
template
<
size_t
Size
>
class
fixed_key
;
template
<
size_t
Size
>
bool
operator
==
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
!=
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
<
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
/**
* @defgroup fixed_key fixed size key sorted lexicographically
* @ingroup types
* @{
*/
template
<
size_t
Size
>
class
fixed_key
{
private:
template
<
bool
...>
struct
bool_pack
;
template
<
bool
...
bs
>
using
all_true
=
std
::
is_same
<
bool_pack
<
bs
...,
true
>
,
bool_pack
<
true
,
bs
...
>
>
;
public:
typedef
uint128_t
word_t
;
static
constexpr
size_t
num_words
()
{
return
(
Size
+
sizeof
(
word_t
)
-
1
)
/
sizeof
(
word_t
);
}
static
constexpr
size_t
padded_bytes
()
{
return
num_words
()
*
sizeof
(
word_t
)
-
Size
;
}
/**
* @brief Default constructor to fixed_key object
*
* @details Default constructor to fixed_key object which initializes all bytes to zero
*/
fixed_key
()
:
_data
()
{}
/**
* @brief Constructor to fixed_key object from array of num_words() words
*
* @details Constructor to fixed_key object from array of num_words() words
* @param arr data
*/
fixed_key
(
const
word_t
(
&
arr
)[
num_words
()])
{
std
::
copy
(
arr
,
arr
+
num_words
(),
_data
.
begin
());
}
/**
* @brief Constructor to fixed_key object from std::array of num_words() words
*
* @details Constructor to fixed_key object from std::array of num_words() words
* @param arr data
*/
fixed_key
(
const
std
::
array
<
word_t
,
num_words
()
>&
arr
)
{
std
::
copy
(
arr
.
begin
(),
arr
.
end
(),
_data
.
begin
());
}
template
<
typename
FirstWord
,
typename
...
Rest
>
static
fixed_key
<
Size
>
make_from_word_sequence
(
typename
std
::
enable_if
<
std
::
is_integral
<
FirstWord
>::
value
&&
!
std
::
is_same
<
FirstWord
,
bool
>::
value
&&
sizeof
(
FirstWord
)
<=
sizeof
(
word_t
)
&&
all_true
<
(
std
::
is_same
<
FirstWord
,
Rest
>::
value
)...
>::
value
,
FirstWord
>::
type
first_word
,
Rest
...
rest
)
{
static_assert
(
sizeof
(
word_t
)
==
(
sizeof
(
word_t
)
/
sizeof
(
FirstWord
))
*
sizeof
(
FirstWord
),
"size of the backing word size is not divisble by the size of the words supplied as arguments"
);
static_assert
(
sizeof
(
FirstWord
)
*
(
1
+
sizeof
...(
Rest
))
<=
Size
,
"too many words supplied to fixed_key constructor"
);
fixed_key
<
Size
>
key
;
auto
itr
=
key
.
_data
.
begin
();
word_t
temp_word
=
0
;
const
size_t
sub_word_shift
=
8
*
sizeof
(
FirstWord
);
const
size_t
num_sub_words
=
sizeof
(
word_t
)
/
sizeof
(
FirstWord
);
auto
sub_words_left
=
num_sub_words
;
for
(
auto
&&
w
:
{
first_word
,
rest
...
}
)
{
if
(
sub_words_left
>
1
)
{
temp_word
|=
static_cast
<
word_t
>
(
w
);
temp_word
<<=
sub_word_shift
;
--
sub_words_left
;
continue
;
}
eosio_assert
(
sub_words_left
==
1
,
"unexpected error in fixed_key constructor"
);
temp_word
|=
static_cast
<
word_t
>
(
w
);
sub_words_left
=
num_sub_words
;
*
itr
=
temp_word
;
temp_word
=
0
;
++
itr
;
}
if
(
sub_words_left
!=
num_sub_words
)
{
if
(
sub_words_left
>
1
)
temp_word
<<=
8
*
(
sub_words_left
-
1
);
*
itr
=
temp_word
;
}
return
key
;
}
const
auto
&
get_array
()
const
{
return
_data
;
}
auto
data
()
{
return
_data
.
data
();
}
auto
data
()
const
{
return
_data
.
data
();
}
auto
size
()
const
{
return
_data
.
size
();
}
std
::
array
<
uint8_t
,
Size
>
extract_as_byte_array
()
const
{
std
::
array
<
uint8_t
,
Size
>
arr
;
const
size_t
num_sub_words
=
sizeof
(
word_t
);
auto
arr_itr
=
arr
.
begin
();
auto
data_itr
=
_data
.
begin
();
for
(
size_t
counter
=
_data
.
size
();
counter
>
0
;
--
counter
,
++
data_itr
)
{
size_t
sub_words_left
=
num_sub_words
;
if
(
counter
==
1
)
{
// If last word in _data array...
sub_words_left
-=
padded_bytes
();
}
auto
temp_word
=
*
data_itr
;
for
(
;
sub_words_left
>
0
;
--
sub_words_left
)
{
*
(
arr_itr
+
sub_words_left
-
1
)
=
static_cast
<
uint8_t
>
(
temp_word
&
0xFF
);
temp_word
>>=
8
;
}
arr_itr
+=
num_sub_words
;
}
return
arr
;
}
// Comparison operators
friend
bool
operator
==
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
!=
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
>
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
<
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
private:
std
::
array
<
word_t
,
num_words
()
>
_data
;
};
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 == c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
==
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
==
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 != c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
!=
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
!=
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 > c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
>
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 < c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
<
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
<
c2
.
_data
;
}
/// @} fixed_key
typedef
fixed_key
<
32
>
key256
;
}
contracts/eosiolib/generic_currency.hpp
浏览文件 @
fee30e1c
#pragma once
#include <eosiolib/
table
.hpp>
#include <eosiolib/
multi_index
.hpp>
#include <eosiolib/token.hpp>
#include <eosiolib/asset.hpp>
#include <eosiolib/dispatcher.hpp>
...
...
@@ -61,6 +61,8 @@ namespace eosio {
uint64_t
symbol
=
token_type
::
symbol
;
token_type
balance
;
auto
primary_key
()
const
{
return
symbol
;
}
EOSLIB_SERIALIZE
(
account
,
(
symbol
)(
balance
)
)
};
...
...
@@ -68,6 +70,8 @@ namespace eosio {
uint64_t
symbol
=
token_type
::
symbol
;
token_type
supply
;
auto
primary_key
()
const
{
return
symbol
;
}
EOSLIB_SERIALIZE
(
currency_stats
,
(
symbol
)(
supply
)
)
};
...
...
@@ -75,25 +79,41 @@ namespace eosio {
* Each user stores their balance in the singleton table under the
* scope of their account name.
*/
typedef
table64
<
code
,
accounts_table_name
,
code
,
account
>
accounts
;
typedef
table64
<
code
,
stats_table_name
,
code
,
currency_stats
>
stats
;
typedef
eosio
::
multi_index
<
accounts_table_name
,
account
>
accounts
;
typedef
eosio
::
multi_index
<
stats_table_name
,
currency_stats
>
stats
;
static
token_type
get_balance
(
account_name
owner
)
{
return
accounts
::
get_or_create
(
token_type
::
symbol
,
owner
).
balance
;
accounts
t
(
code
,
owner
);
auto
ptr
=
t
.
find
(
symbol
);
return
ptr
?
ptr
->
balance
:
token_type
(
asset
(
0
,
symbol
)
);
}
static
void
set_balance
(
account_name
owner
,
token_type
balance
)
{
accounts
::
set
(
account
{
token_type
::
symbol
,
balance
},
owner
);
static
void
set_balance
(
account_name
owner
,
token_type
balance
,
account_name
create_bill_to
,
account_name
update_bill_to
)
{
accounts
t
(
code
,
owner
);
auto
f
=
[
&
](
account
&
acc
)
{
acc
.
symbol
=
symbol
;
acc
.
balance
=
balance
;
};
auto
ptr
=
t
.
find
(
symbol
);
if
(
ptr
)
{
t
.
update
(
*
ptr
,
update_bill_to
,
f
);
}
else
{
t
.
emplace
(
create_bill_to
,
f
);
}
}
static
void
on
(
const
issue
&
act
)
{
require_auth
(
code
);
auto
s
=
stats
::
get_or_create
(
token_type
::
symbol
);
s
.
supply
+=
act
.
quantity
;
stats
::
set
(
s
);
stats
t
(
code
,
code
);
auto
ptr
=
t
.
find
(
symbol
);
if
(
ptr
)
{
t
.
update
(
*
ptr
,
0
,
[
&
](
currency_stats
&
s
)
{
s
.
supply
+=
act
.
quantity
;
});
}
else
{
t
.
emplace
(
code
,
[
&
](
currency_stats
&
s
)
{
s
.
supply
=
act
.
quantity
;
});
}
set_balance
(
code
,
get_balance
(
code
)
+
act
.
quantity
);
set_balance
(
code
,
get_balance
(
code
)
+
act
.
quantity
,
code
,
0
);
inline_transfer
(
code
,
act
.
to
,
act
.
quantity
);
}
...
...
@@ -103,8 +123,8 @@ namespace eosio {
require_auth
(
act
.
from
);
require_recipient
(
act
.
to
,
act
.
from
);
set_balance
(
act
.
from
,
get_balance
(
act
.
from
)
-
act
.
quantity
);
set_balance
(
act
.
to
,
get_balance
(
act
.
to
)
+
act
.
quantity
);
set_balance
(
act
.
from
,
get_balance
(
act
.
from
)
-
act
.
quantity
,
act
.
from
,
act
.
from
);
set_balance
(
act
.
to
,
get_balance
(
act
.
to
)
+
act
.
quantity
,
act
.
from
,
0
);
}
static
void
inline_transfer
(
account_name
from
,
account_name
to
,
token_type
quantity
,
...
...
contracts/eosiolib/multi_index.hpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
contracts/eosiolib/print.h
浏览文件 @
fee30e1c
...
...
@@ -100,7 +100,7 @@ extern "C" {
/**
*/
void
printhex
(
void
*
data
,
uint32_t
datalen
);
void
printhex
(
const
void
*
data
,
uint32_t
datalen
);
/// @}
#ifdef __cplusplus
...
...
contracts/eosiolib/print.hpp
浏览文件 @
fee30e1c
...
...
@@ -6,6 +6,8 @@
#include <eosiolib/print.h>
#include <eosiolib/types.hpp>
#include <eosiolib/math.hpp>
#include <eosiolib/fixed_key.hpp>
#include <utility>
namespace
eosio
{
...
...
@@ -47,6 +49,10 @@ namespace eosio {
printi
(
uint64_t
(
num
));
}
inline
void
print
(
long
num
)
{
printi
(
num
);
}
/**
* Prints unsigned integer as a 64 bit unsigned integer
* @brief Prints unsigned integer
...
...
@@ -71,7 +77,20 @@ namespace eosio {
* @param num to be printed
*/
inline
void
print
(
uint128_t
num
)
{
printi128
((
uint128_t
*
)
&
num
);
printi128
(
&
num
);
}
/**
* Prints fixed_key as a hexidecimal string
* @brief Prints fixed_key as a hexidecimal string
* @param val to be printed
*/
template
<
size_t
Size
>
inline
void
print
(
const
fixed_key
<
Size
>&
val
)
{
auto
arr
=
val
.
extract_as_byte_array
();
prints
(
"0x"
);
printhex
(
static_cast
<
const
void
*>
(
arr
.
data
()),
arr
.
size
());
}
/**
...
...
@@ -96,7 +115,7 @@ namespace eosio {
inline
void
print_f
(
const
char
*
s
)
{
prints
(
s
);
}
template
<
typename
Arg
,
typename
...
Args
>
inline
void
print_f
(
const
char
*
s
,
Arg
val
,
Args
...
rest
)
{
while
(
*
s
!=
'\0'
)
{
...
...
@@ -151,9 +170,9 @@ namespace eosio {
* @endcode
*/
template
<
typename
Arg
,
typename
...
Args
>
void
print
(
Arg
a
,
Args
...
args
)
{
print
(
a
);
print
(
args
...);
void
print
(
Arg
&&
a
,
Args
&&
...
args
)
{
print
(
std
::
forward
<
Arg
>
(
a
)
);
print
(
std
::
forward
<
Args
>
(
args
)
...);
}
/**
...
...
contracts/eosiolib/singleton.hpp
浏览文件 @
fee30e1c
#pragma once
#include <eosiolib/
db
.hpp>
#include <eosiolib/
datastream.hpp
>
#include <eosiolib/
multi_index
.hpp>
#include <eosiolib/
system.h
>
namespace
eosio
{
/**
* This wrapper uses a single table to store named objects various types.
* This wrapper uses a single table to store named objects various types.
*
* @tparam Code - the name of the code which has write permission
* @tparam SingletonName - the name of this singlton variable
* @tparam T - the type of the singleton
* @tparam T - the type of the singleton
*/
template
<
account_name
Code
,
uint64_t
SingletonName
,
account_name
BillToAccount
,
typename
T
>
class
singleton
{
constexpr
static
uint64_t
pk_value
=
SingletonName
;
struct
row
{
T
value
;
uint64_t
primary_key
()
const
{
return
pk_value
;
}
EOSLIB_SERIALIZE
(
row
,
(
value
)
);
};
typedef
eosio
::
multi_index
<
SingletonName
,
row
>
table
;
public:
//static const uint64_t singleton_table_name = N(singleton);
static
bool
exists
(
scope_name
scope
=
Code
)
{
uint64_t
key
=
SingletonName
;
auto
read
=
load_i64
(
Code
,
scope
,
key
,
(
char
*
)
&
key
,
sizeof
(
key
)
);
return
read
>
0
;
table
t
(
Code
,
scope
);
return
t
.
find
(
pk_value
);
}
static
T
get
(
scope_name
scope
=
Code
)
{
char
temp
[
1024
+
8
];
*
reinterpret_cast
<
uint64_t
*>
(
temp
)
=
SingletonName
;
auto
read
=
load_i64
(
Code
,
scope
,
SingletonName
,
temp
,
sizeof
(
temp
)
);
eosio_assert
(
read
>
0
,
"singleton does not exist"
);
return
unpack
<
T
>
(
temp
+
sizeof
(
SingletonName
),
read
);
table
t
(
Code
,
scope
);
auto
ptr
=
t
.
find
(
pk_value
);
eosio_assert
(
bool
(
ptr
),
"singleton does not exist"
);
return
ptr
->
value
;
}
static
T
get_or_default
(
scope_name
scope
=
Code
,
const
T
&
def
=
T
()
)
{
char
temp
[
1024
+
8
];
*
reinterpret_cast
<
uint64_t
*>
(
temp
)
=
SingletonName
;
auto
read
=
load_i64
(
Code
,
scope
,
SingletonName
,
temp
,
sizeof
(
temp
)
);
if
(
read
<
0
)
{
return
def
;
}
return
unpack
<
T
>
(
temp
+
sizeof
(
SingletonName
),
size_t
(
read
)
);
table
t
(
Code
,
scope
);
auto
ptr
=
t
.
find
(
pk_value
);
return
ptr
?
ptr
->
value
:
def
;
}
static
T
get_or_create
(
scope_name
scope
=
Code
,
const
T
&
def
=
T
()
)
{
char
temp
[
1024
+
8
];
*
reinterpret_cast
<
uint64_t
*>
(
temp
)
=
SingletonName
;
auto
read
=
load_i64
(
Code
,
scope
,
SingletonName
,
temp
,
sizeof
(
temp
)
);
if
(
read
<
0
)
{
set
(
def
,
scope
);
return
def
;
}
return
unpack
<
T
>
(
temp
+
sizeof
(
SingletonName
),
read
);
table
t
(
Code
,
scope
);
auto
ptr
=
t
.
find
(
pk_value
);
return
ptr
?
ptr
->
value
:
t
.
emplace
(
BillToAccount
,
[
&
](
row
&
r
)
{
r
.
value
=
def
;
});
}
static
void
set
(
const
T
&
value
=
T
(),
scope_name
scope
=
Code
,
account_name
b
=
BillToAccount
)
{
auto
size
=
pack_size
(
value
);
char
buf
[
size
+
sizeof
(
SingletonName
)];
eosio_assert
(
sizeof
(
buf
)
<=
1024
+
8
,
"singleton too big to store"
);
datastream
<
char
*>
ds
(
buf
,
size
+
sizeof
(
SingletonName
)
);
ds
<<
SingletonName
;
ds
<<
value
;
store_i64
(
scope
,
SingletonName
,
b
,
buf
,
sizeof
(
buf
)
);
table
t
(
Code
,
scope
);
auto
ptr
=
t
.
find
(
pk_value
);
if
(
ptr
)
{
t
.
update
(
*
ptr
,
b
,
[
&
](
row
&
r
)
{
r
.
value
=
value
;
});
}
else
{
t
.
emplace
(
b
,
[
&
](
row
&
r
)
{
r
.
value
=
value
;
});
}
}
static
void
remove
(
scope_name
scope
=
Code
)
{
uint64_t
key
=
SingletonName
;
remove_i64
(
scope
,
SingletonName
,
&
key
);
table
t
(
Code
,
scope
);
auto
ptr
=
t
.
find
(
pk_value
);
if
(
ptr
)
{
t
.
remove
(
*
ptr
);
}
}
};
...
...
contracts/eosiolib/types.h
浏览文件 @
fee30e1c
...
...
@@ -23,10 +23,6 @@ extern "C" {
* @{
*/
struct
uint256
{
uint64_t
words
[
4
];
};
typedef
uint64_t
account_name
;
typedef
uint64_t
permission_name
;
typedef
uint64_t
token_name
;
...
...
contracts/eosiolib/types.hpp
浏览文件 @
fee30e1c
...
...
@@ -23,7 +23,7 @@ namespace eosio {
/**
* @brief Converts a base32 string to a uint64_t.
* @brief Converts a base32 string to a uint64_t.
*
* @details Converts a base32 string to a uint64_t. This is a constexpr so that
* this method can be used in template arguments as well.
...
...
@@ -87,7 +87,6 @@ namespace eosio {
return
ds
>>
v
.
value
;
}
};
/// @}
}
// namespace eos
contracts/identity/identity.abi
浏览文件 @
fee30e1c
...
...
@@ -66,7 +66,6 @@
"name": "accountrow",
"base": "",
"fields": [
{"name":"singleton_name", "type":"uint64"},
{"name":"identity", "type":"uint64"}
]
}
...
...
contracts/identity/identity.hpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
contracts/identity/test/identity_test.cpp
浏览文件 @
fee30e1c
...
...
@@ -25,28 +25,14 @@ namespace identity_test {
{
uint64_t
identity
;
template
<
typename
DataStream
>
friend
DataStream
&
operator
<<
(
DataStream
&
ds
,
const
get_owner_for_identity
&
c
){
return
ds
<<
c
.
identity
;
}
template
<
typename
DataStream
>
friend
DataStream
&
operator
>>
(
DataStream
&
ds
,
get_owner_for_identity
&
c
){
return
ds
>>
c
.
identity
;
}
EOSLIB_SERIALIZE
(
get_owner_for_identity
,
(
identity
)
);
};
struct
get_identity_for_account
:
public
action_meta
<
code
,
N
(
getidentity
)
>
{
account_name
account
;
template
<
typename
DataStream
>
friend
DataStream
&
operator
<<
(
DataStream
&
ds
,
const
get_identity_for_account
&
c
){
return
ds
<<
c
.
account
;
}
template
<
typename
DataStream
>
friend
DataStream
&
operator
>>
(
DataStream
&
ds
,
get_identity_for_account
&
c
){
return
ds
>>
c
.
account
;
}
EOSLIB_SERIALIZE
(
get_identity_for_account
,
(
account
)
);
};
typedef
singleton
<
code
,
N
(
result
),
code
,
uint64_t
>
result_table
;
...
...
contracts/multi_index_test/multi_index_test.abi
浏览文件 @
fee30e1c
{
"types": [{
"new_type_name": "my_account_name",
"type": "name"
}
],
"types": [],
"structs": [{
"name": "
message
",
"name": "
trigger
",
"base": "",
"fields": [
{"name":"from", "type":"my_account_name"},
{"name":"to", "type":"my_account_name"},
{"name": "message", "type":"string" }
{"name": "what", "type": "uint32" }
]
},{
"name": "messages_count",
"base": "",
"fields": [
{"name": "user", "type": "my_account_name"},
{"name": "count", "type": "uint32"}
]
}
}
],
"actions": [{
"name": "
message
",
"type": "
message
"
"name": "
trigger
",
"type": "
trigger
"
}
],
"tables": [{
"name": "msgsent",
"type": "messages_count",
"index_type": "i64",
"key_names" : ["user"],
"key_types" : ["my_account_name"]
},{
"name": "msgreceived",
"type": "messages_count",
"index_type": "i64",
"key_names" : ["user"],
"key_types" : ["my_account_name"]
}
]
}
\ No newline at end of file
"tables": []
}
contracts/multi_index_test/multi_index_test.cpp
浏览文件 @
fee30e1c
#include <eosiolib/eosio.hpp>
#include <eosiolib/dispatcher.hpp>
#include <eosiolib/multi_index.hpp>
using
namespace
eosio
;
namespace
multi_index_test
{
struct
limit_order
{
uint64_t
id
;
...
...
@@ -10,47 +13,166 @@ struct limit_order {
uint64_t
expiration
;
account_name
owner
;
auto
primary_key
()
const
{
return
id
;
}
uint64_t
get_expiration
()
const
{
return
expiration
;
}
uint128_t
get_price
()
const
{
return
price
;
}
auto
primary_key
()
const
{
return
id
;
}
uint64_t
get_expiration
()
const
{
return
expiration
;
}
uint128_t
get_price
()
const
{
return
price
;
}
EOSLIB_SERIALIZE
(
limit_order
,
(
id
)(
price
)(
expiration
)(
owner
)
)
};
EOSLIB_SERIALIZE
(
limit_order
,
(
id
)(
price
)(
expiration
)(
owner
)
)
};
extern
"C"
{
/// The apply method implements the dispatch of events to this contract
void
apply
(
uint64_t
code
,
uint64_t
action
)
{
eosio
::
multi_index
<
N
(
orders
),
limit_order
,
indexed_by
<
N
(
byexp
),
const_mem_fun
<
limit_order
,
uint64_t
,
&
limit_order
::
get_expiration
>
>
,
indexed_by
<
N
(
byprice
),
const_mem_fun
<
limit_order
,
uint128_t
,
&
limit_order
::
get_price
>
>
>
orders
(
N
(
exchange
),
N
(
exchange
)
);
struct
test_k256
{
uint64_t
id
;
key256
val
;
auto
payer
=
code
;
const
auto
&
order
=
orders
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
1
;
o
.
expiration
=
3
;
o
.
owner
=
N
(
dan
);
});
auto
primary_key
()
const
{
return
id
;
}
key256
get_val
()
const
{
return
val
;
}
orders
.
update
(
order
,
payer
,
[
&
](
auto
&
o
)
{
o
.
expiration
=
4
;
});
EOSLIB_SERIALIZE
(
test_k256
,
(
id
)(
val
)
)
};
const
auto
*
o
=
orders
.
find
(
1
);
class
multi_index_test
{
public:
orders
.
remove
(
order
);
ACTION
(
N
(
multitest
),
trigger
)
{
trigger
()
:
what
(
0
)
{}
trigger
(
uint32_t
w
)
:
what
(
w
)
{}
auto
expidx
=
orders
.
get_index
<
N
(
byexp
)
>
()
;
uint32_t
what
;
for
(
const
auto
&
item
:
orders
)
{
(
void
)
item
.
id
;
}
EOSLIB_SERIALIZE
(
trigger
,
(
what
))
};
for
(
const
auto
&
item
:
expidx
)
{
(
void
)
item
.
id
;
}
static
void
on
(
const
trigger
&
act
)
{
auto
payer
=
act
.
get_account
();
print
(
"Acting on trigger action.
\n
"
);
switch
(
act
.
what
)
{
case
0
:
{
print
(
"Testing uint128_t secondary index.
\n
"
);
eosio
::
multi_index
<
N
(
orders
),
limit_order
,
indexed_by
<
N
(
byexp
),
const_mem_fun
<
limit_order
,
uint64_t
,
&
limit_order
::
get_expiration
>
>
,
indexed_by
<
N
(
byprice
),
const_mem_fun
<
limit_order
,
uint128_t
,
&
limit_order
::
get_price
>
>
>
orders
(
N
(
multitest
),
N
(
multitest
)
);
const
auto
&
order1
=
orders
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
1
;
o
.
expiration
=
300
;
o
.
owner
=
N
(
dan
);
});
const
auto
&
order2
=
orders
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
2
;
o
.
expiration
=
200
;
o
.
owner
=
N
(
alice
);
});
print
(
"Items sorted by primary key:
\n
"
);
for
(
const
auto
&
item
:
orders
)
{
print
(
" ID="
,
item
.
id
,
", expiration="
,
item
.
expiration
,
", owner="
,
name
(
item
.
owner
),
"
\n
"
);
}
auto
expidx
=
orders
.
get_index
<
N
(
byexp
)
>
();
print
(
"Items sorted by expiration:
\n
"
);
for
(
const
auto
&
item
:
expidx
)
{
print
(
" ID="
,
item
.
id
,
", expiration="
,
item
.
expiration
,
", owner="
,
name
(
item
.
owner
),
"
\n
"
);
}
print
(
"Updating expiration of order with ID=2 to 400.
\n
"
);
orders
.
update
(
order2
,
payer
,
[
&
](
auto
&
o
)
{
o
.
expiration
=
400
;
});
print
(
"Items sorted by expiration:
\n
"
);
for
(
const
auto
&
item
:
expidx
)
{
print
(
" ID="
,
item
.
id
,
", expiration="
,
item
.
expiration
,
", owner="
,
name
(
item
.
owner
),
"
\n
"
);
}
auto
lower
=
expidx
.
lower_bound
(
100
);
print
(
"First order with an expiration of at least 100 has ID="
,
lower
->
id
,
" and expiration="
,
lower
->
get_expiration
(),
"
\n
"
);
}
break
;
case
1
:
// Test key265 secondary index
{
print
(
"Testing key256 secondary index.
\n
"
);
eosio
::
multi_index
<
N
(
test1
),
test_k256
,
indexed_by
<
N
(
byval
),
const_mem_fun
<
test_k256
,
key256
,
&
test_k256
::
get_val
>
>
>
testtable
(
N
(
multitest
),
N
(
exchange
)
);
// Code must be same as the receiver? Scope doesn't have to be.
const
auto
&
entry1
=
testtable
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
1
;
o
.
val
=
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
42ULL
);
});
const
auto
&
entry2
=
testtable
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
2
;
o
.
val
=
key256
::
make_from_word_sequence
<
uint64_t
>
(
1ULL
,
2ULL
,
3ULL
,
4ULL
);
});
auto
lower
=
expidx
.
lower_bound
(
4
);
const
auto
&
entry3
=
testtable
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
3
;
o
.
val
=
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
42ULL
);
});
const
auto
*
e
=
testtable
.
find
(
2
);
print
(
"Items sorted by primary key:
\n
"
);
for
(
const
auto
&
item
:
testtable
)
{
print
(
" ID="
,
item
.
primary_key
(),
", val="
,
item
.
val
,
"
\n
"
);
}
auto
validx
=
testtable
.
get_index
<
N
(
byval
)
>
();
auto
lower1
=
validx
.
lower_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
40ULL
));
print
(
"First entry with a val of at least 40 has ID="
,
lower1
->
id
,
".
\n
"
);
auto
lower2
=
validx
.
lower_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
50ULL
));
print
(
"First entry with a val of at least 50 has ID="
,
lower2
->
id
,
".
\n
"
);
if
(
&*
lower2
==
e
)
{
print
(
"Previously found entry is the same as the one found earlier with a primary key value of 2.
\n
"
);
}
print
(
"Items sorted by val (secondary key):
\n
"
);
for
(
const
auto
&
item
:
validx
)
{
print
(
" ID="
,
item
.
primary_key
(),
", val="
);
cout
<<
item
.
val
<<
"
\n
"
;
}
auto
upper
=
validx
.
upper_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
42ULL
));
print
(
"First entry with a val greater than 42 has ID="
,
upper
->
id
,
".
\n
"
);
print
(
"Removed entry with ID="
,
lower1
->
id
,
".
\n
"
);
testtable
.
remove
(
*
lower1
);
print
(
"Items sorted by primary key:
\n
"
);
for
(
const
auto
&
item
:
testtable
)
{
print
(
" ID="
,
item
.
primary_key
(),
", val="
);
cout
<<
item
.
val
<<
"
\n
"
;
}
}
break
;
default:
eosio_assert
(
0
,
"Given what code is not supported."
);
break
;
}
}
};
}
/// multi_index_test
namespace
multi_index_test
{
extern
"C"
{
/// The apply method implements the dispatch of events to this contract
void
apply
(
uint64_t
code
,
uint64_t
action
)
{
eosio_assert
(
eosio
::
dispatch
<
multi_index_test
,
multi_index_test
::
trigger
>
(
code
,
action
),
"Could not dispatch"
);
}
}
}
contracts/proxy/proxy.cpp
浏览文件 @
fee30e1c
...
...
@@ -11,16 +11,25 @@ namespace proxy {
using
namespace
eosio
;
namespace
configs
{
bool
get
(
config
&
out
,
const
account_name
&
self
)
{
auto
read
=
load_i64
(
self
,
self
,
N
(
config
),
(
char
*
)
&
out
,
sizeof
(
config
));
if
(
read
<
0
)
{
auto
it
=
db_find_i64
(
self
,
self
,
N
(
config
),
config
::
key
);
if
(
it
!=
-
1
)
{
auto
size
=
db_get_i64
(
it
,
(
char
*
)
&
out
,
sizeof
(
config
));
eosio_assert
(
size
==
sizeof
(
config
),
"Wrong record size"
);
return
true
;
}
else
{
return
false
;
}
return
true
;
}
void
store
(
const
config
&
in
,
const
account_name
&
self
)
{
store_i64
(
self
,
N
(
config
),
self
,
(
const
char
*
)
&
in
,
sizeof
(
config
));
auto
it
=
db_find_i64
(
self
,
self
,
N
(
config
),
config
::
key
);
if
(
it
!=
-
1
)
{
db_update_i64
(
it
,
self
,
(
const
char
*
)
&
in
,
sizeof
(
config
));
}
else
{
db_store_i64
(
self
,
N
(
config
),
self
,
config
::
key
,
(
const
char
*
)
&
in
,
sizeof
(
config
));
}
}
};
...
...
contracts/proxy/proxy.hpp
浏览文件 @
fee30e1c
...
...
@@ -15,7 +15,7 @@ namespace proxy {
//@abi table
struct
config
{
config
(){}
const
uint64_t
key
=
N
(
config
);
const
expr
static
uint64_t
key
=
N
(
config
);
account_name
owner
=
0
;
uint32_t
delay
=
0
;
uint32_t
next_id
=
0
;
...
...
contracts/simpledb/simpledb.cpp
浏览文件 @
fee30e1c
...
...
@@ -12,7 +12,7 @@
using
namespace
eosio
;
namespace
simpledb
{
template
<
uint64_t
Val
>
struct
dispatchable
{
constexpr
static
uint64_t
action_name
=
Val
;
...
...
@@ -20,22 +20,22 @@ namespace simpledb {
//@abi table
struct
record1
{
uint64_t
key
;
uint256
u256
;
//
uint256 u256;
uint128_t
u128
;
uint64_t
u64
;
uint32_t
u32
;
uint16_t
u16
;
uint16_t
u16
;
uint8_t
u8
;
int64_t
i64
;
int32_t
i32
;
int16_t
i16
;
int8_t
i8
;
EOSLIB_SERIALIZE
(
record1
,
(
key
)(
u
256
)(
u
128
)(
u64
)(
u32
)(
u16
)(
u8
)(
i64
)(
i32
)(
i16
)(
i8
)
);
EOSLIB_SERIALIZE
(
record1
,
(
key
)(
u128
)(
u64
)(
u32
)(
u16
)(
u8
)(
i64
)(
i32
)(
i16
)(
i8
)
);
};
//@abi action insert1
...
...
@@ -223,4 +223,4 @@ extern "C" {
}
}
}
\ No newline at end of file
}
contracts/test_api/test_api.hpp
浏览文件 @
fee30e1c
...
...
@@ -24,7 +24,7 @@ static constexpr u64 WASM_TEST_ACTION(const char* cls, const char* method)
CLASS::METHOD(); \
return; \
}
#pragma pack(push, 1)
struct
dummy_action
{
char
a
;
//1
...
...
@@ -123,7 +123,7 @@ struct test_db {
static
void
key_i64i64i64_under_limit
();
static
void
key_i64i64i64_available_space_exceed_limit
();
static
void
key_i64i64i64_another_under_limit
();
static
void
primary_i64_general
();
static
void
primary_i64_lowerbound
();
static
void
primary_i64_upperbound
();
...
...
@@ -133,6 +133,16 @@ struct test_db {
static
void
idx64_upperbound
();
};
struct
test_multi_index
{
static
void
idx64_general
();
static
void
idx64_store_only
();
static
void
idx64_check_without_storing
();
static
void
idx128_autoincrement_test
();
static
void
idx128_autoincrement_test_part1
();
static
void
idx128_autoincrement_test_part2
();
static
void
idx256_general
();
};
struct
test_crypto
{
static
void
test_recover_key
();
static
void
test_recover_key_assert_true
();
...
...
@@ -233,4 +243,3 @@ struct test_checktime {
static
void
checktime_pass
();
static
void
checktime_failure
();
};
contracts/test_api/test_types.cpp
浏览文件 @
fee30e1c
...
...
@@ -7,7 +7,7 @@
#include "test_api.hpp"
void
test_types
::
types_size
()
{
eosio_assert
(
sizeof
(
int64_t
)
==
8
,
"int64_t size != 8"
);
eosio_assert
(
sizeof
(
uint64_t
)
==
8
,
"uint64_t size != 8"
);
eosio_assert
(
sizeof
(
uint32_t
)
==
4
,
"uint32_t size != 4"
);
...
...
@@ -20,11 +20,11 @@ void test_types::types_size() {
eosio_assert
(
sizeof
(
token_name
)
==
8
,
"token_name size != 8"
);
eosio_assert
(
sizeof
(
table_name
)
==
8
,
"table_name size != 8"
);
eosio_assert
(
sizeof
(
time
)
==
4
,
"time size != 4"
);
eosio_assert
(
sizeof
(
uint256
)
==
32
,
"uint256
!= 32"
);
eosio_assert
(
sizeof
(
key256
)
==
32
,
"key256 size
!= 32"
);
}
void
test_types
::
char_to_symbol
()
{
eosio_assert
(
eosio
::
char_to_symbol
(
'1'
)
==
1
,
"eosio::char_to_symbol('1') != 1"
);
eosio_assert
(
eosio
::
char_to_symbol
(
'2'
)
==
2
,
"eosio::char_to_symbol('2') != 2"
);
eosio_assert
(
eosio
::
char_to_symbol
(
'3'
)
==
3
,
"eosio::char_to_symbol('3') != 3"
);
...
...
@@ -56,7 +56,7 @@ void test_types::char_to_symbol() {
eosio_assert
(
eosio
::
char_to_symbol
(
'x'
)
==
29
,
"eosio::char_to_symbol('x') != 29"
);
eosio_assert
(
eosio
::
char_to_symbol
(
'y'
)
==
30
,
"eosio::char_to_symbol('y') != 30"
);
eosio_assert
(
eosio
::
char_to_symbol
(
'z'
)
==
31
,
"eosio::char_to_symbol('z') != 31"
);
for
(
unsigned
char
i
=
0
;
i
<
255
;
i
++
)
{
if
((
i
>=
'a'
&&
i
<=
'z'
)
||
(
i
>=
'1'
||
i
<=
'5'
))
continue
;
eosio_assert
(
eosio
::
char_to_symbol
(
i
)
==
0
,
"eosio::char_to_symbol() != 0"
);
...
...
contracts/test_api_db/test_db.cpp
浏览文件 @
fee30e1c
...
...
@@ -89,7 +89,7 @@ void test_db::key_str_table() {
const char* atr[] = { "atr", "atr", "atr", "atr" };
const char* ztr[] = { "ztr", "ztr", "ztr", "ztr" };
eosio::var_table<N(tester), N(tester), N(atr), char*> StringTableAtr;
eosio::var_table<N(tester), N(tester), N(ztr), char*> StringTableZtr;
eosio::var_table<N(tester), N(tester), N(str), char*> StringTableStr;
...
...
@@ -100,13 +100,13 @@ void test_db::key_str_table() {
for( int ii = 0; ii < 4; ++ii ) {
res = StringTableAtr.store( (char*)keys[ii], STRLEN(keys[ii]), (char*)atr[ii], STRLEN(atr[ii]) );
eosio_assert( res != 0, "atr" );
res = StringTableZtr.store( (char*)keys[ii], STRLEN(keys[ii]), (char*)ztr[ii], STRLEN(ztr[ii]) );
eosio_assert(res != 0, "ztr" );
}
char tmp[64];
res = StringTableStr.store ((char *)keys[0], STRLEN(keys[0]), (char *)vals[0], STRLEN(vals[0]));
eosio_assert(res != 0, "store alice" );
...
...
@@ -307,7 +307,7 @@ void test_db::key_i64_general() {
res = previous_i64( current_receiver(), current_receiver(), N(test_table), &tmp, sizeof(test_model) );
eosio_assert(res == sizeof(test_model) && tmp.name == N(carol) && tmp.age == 30 && tmp.phone == 545342453, "carol previous");
res = previous_i64( current_receiver(), current_receiver(), N(test_table), &tmp, sizeof(test_model) );
eosio_assert(res == sizeof(test_model) && tmp.name == N(bob) && tmp.age == 15 && tmp.phone == 11932435, "bob previous");
...
...
@@ -340,13 +340,13 @@ void test_db::key_i64_general() {
alice.age = 21;
alice.phone = 1234;
res = store_i64(current_receiver(), N(test_table), &alice, sizeof(test_model));
eosio_assert(res == 0, "store alice 2" );
my_memset(&alice, 0, sizeof(test_model));
alice.name = N(alice);
res = load_i64(current_receiver(), current_receiver(), N(test_table), &alice, sizeof(test_model));
eosio_assert(res == sizeof(test_model) && alice.age == 21 && alice.phone == 1234, "alice error 2");
...
...
@@ -426,7 +426,7 @@ void test_db::key_i64_general() {
res = load_i64(current_receiver(), current_receiver(), N(test_table), &tmp2, sizeof(test_model_v3));
eosio_assert(res == sizeof(test_model_v2) &&
tmp2.age == 21 &&
tmp2.age == 21 &&
tmp2.phone == 1234 &&
tmp2.new_field == 66655444,
"load4update");
...
...
@@ -437,7 +437,7 @@ void test_db::key_i64_general() {
res = load_i64(current_receiver(), current_receiver(), N(test_table), &tmp2, sizeof(test_model_v3));
eosio_assert(res == sizeof(test_model_v3) &&
tmp2.age == 21 &&
tmp2.age == 21 &&
tmp2.phone == 1234 &&
tmp2.new_field == 66655444 &&
tmp2.another_field == 221122,
...
...
@@ -449,7 +449,7 @@ void test_db::key_i64_general() {
res = load_i64(current_receiver(), current_receiver(), N(test_table), &tmp2, sizeof(test_model_v3));
eosio_assert(res == sizeof(test_model_v3) &&
tmp2.age == 11 &&
tmp2.age == 11 &&
tmp2.phone == 1234 &&
tmp2.new_field == 66655444 &&
tmp2.another_field == 221122,
...
...
@@ -466,22 +466,22 @@ void test_db::key_i64_general() {
}
void test_db::key_i64_remove_all() {
uint32_t res = 0;
uint64_t key;
key = N(alice);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 1, "remove alice");
key = N(bob);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 1, "remove bob");
key = N(carol);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 1, "remove carol");
key = N(dave);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 1, "remove dave");
...
...
@@ -492,19 +492,19 @@ void test_db::key_i64_remove_all() {
res = back_i64( current_receiver(), current_receiver(), N(test_table), &tmp, sizeof(test_model) );
eosio_assert(res == 0, "back_i64_i64 remove");
key = N(alice);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 0, "remove alice 1");
key = N(bob);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 0, "remove bob 1");
key = N(carol);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 0, "remove carol 1");
key = N(dave);
res = remove_i64(current_receiver(), N(test_table), &key);
eosio_assert(res == 0, "remove dave 1");
...
...
@@ -546,7 +546,7 @@ void test_db::key_i64_not_found() {
}
void test_db::key_i64_front_back() {
uint32_t res = 0;
test_model dave { N(dave), 46, 6535354};
...
...
@@ -598,7 +598,7 @@ void test_db::key_i64_front_back() {
key = N(dave);
remove_i64(current_receiver(), N(b), &key);
res = front_i64( current_receiver(), current_receiver(), N(b), &tmp, sizeof(test_model) );
eosio_assert(res == 0, "key_i64_front 9");
res = back_i64( current_receiver(), current_receiver(), N(b), &tmp, sizeof(test_model) );
...
...
@@ -628,7 +628,7 @@ uint32_t store_set_in_table(uint64_t table_name)
{
uint32_t res = 0;
TestModel128x2 alice0{0, 500, N(alice0), table_name};
TestModel128x2 alice1{1, 400, N(alice1), table_name};
TestModel128x2 alice2{2, 300, N(alice2), table_name};
...
...
@@ -714,7 +714,7 @@ void store_set_in_table(TestModel3xi64* records, int len, uint64_t table_name) {
//TODO fix things
#if 0
void test_db::key_i64i64i64_general() {
uint32_t res = 0;
TestModel3xi64 records[] = {
...
...
@@ -784,7 +784,7 @@ void test_db::key_i64i64i64_general() {
V={4}; LOAD_OK(primary, i64i64i64, N(table2), 7, "i64x3 LOAD primary 4");
V={5}; LOAD_OK(primary, i64i64i64, N(table2), 9, "i64x3 LOAD primary 5");
V={6}; LOAD_ER(primary, i64i64i64, N(table2), "i64x3 LOAD primary fail 6");
V={11,0}; LOAD_OK(secondary, i64i64i64, N(table2), 7, "i64x3 LOAD secondary 0");
V={11,1}; LOAD_OK(secondary, i64i64i64, N(table2), 0, "i64x3 LOAD secondary 1");
V={11,2}; LOAD_OK(secondary, i64i64i64, N(table2),10, "i64x3 LOAD secondary 2");
...
...
@@ -886,7 +886,7 @@ void test_db::key_i64i64i64_general() {
v2.new_field = 555;
res = update_i64i64i64(current_receiver(), N(table2), &v2, sizeof(TestModel3xi64_V2));
eosio_assert(res == 1, "store v2");
eosio_assert(res == 1, "store v2");
res = LOAD(primary, i64i64i64, N(table2), v2);
eosio_assert(res == sizeof(TestModel3xi64_V2), "load v2 updated");
...
...
@@ -899,7 +899,7 @@ void test_db::key_i64i64i64_general() {
return 0;
}
#endif
#endif
void test_db::key_i128i128_general() {
uint32_t res = 0;
...
...
@@ -928,7 +928,7 @@ return;
my_memset(&tmp, 0, sizeof(TestModel128x2));
tmp.price = 4;
res = load_secondary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert( res == sizeof(TestModel128x2) &&
tmp.number == 13 &&
...
...
@@ -944,7 +944,7 @@ return;
tmp.extra == N(alice0) &&
tmp.table_name == N(table5),
"front primary load");
res = previous_primary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert(res == -1, "previous primary fail");
...
...
@@ -963,7 +963,7 @@ return;
tmp.extra == N(bob0) &&
tmp.table_name == N(table5),
"front secondary ok");
res = previous_secondary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert(res == -1, "previous secondary fail");
...
...
@@ -982,7 +982,7 @@ return;
tmp.extra == N(dave3) &&
tmp.table_name == N(table5),
"back primary ok");
res = next_primary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert(res == -1, "next primary fail");
...
...
@@ -1001,12 +1001,12 @@ return;
tmp.extra == N(carol0) &&
tmp.table_name == N(table5),
"back secondary ok");
res = next_secondary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert(res == -1, "next secondary fail");
res = previous_secondary_i128i128( current_receiver(), current_receiver(), N(table5), &tmp, sizeof(TestModel128x2) );
eosio_assert( res == sizeof(TestModel128x2) &&
tmp.number == 21 &&
tmp.price == 800 &&
...
...
@@ -1052,7 +1052,7 @@ return;
tmp2.extra == N(carol0) &&
tmp2.table_name == N(table5),
"ub secondary ok");
tmp2.new_field = 123456;
res = update_i128i128(current_receiver(), N(table5), &tmp2, sizeof(TestModel128x2_V2));
eosio_assert( res == 1, "update_i128i128 ok");
...
...
@@ -1526,7 +1526,7 @@ void test_db::primary_i64_general()
// nothing after charlie
uint64_t
prim
=
0
;
int
end_itr
=
db_next_i64
(
charlie_itr
,
&
prim
);
eosio_assert
(
end_itr
==
-
1
,
"primary_i64_general - db_next_i64"
);
eosio_assert
(
end_itr
<
0
,
"primary_i64_general - db_next_i64"
);
// prim didn't change
eosio_assert
(
prim
==
0
,
"primary_i64_general - db_next_i64"
);
}
...
...
@@ -1548,23 +1548,22 @@ void test_db::primary_i64_general()
eosio_assert
(
itr_prev
==
itr_prev_expected
&&
prim
==
N
(
alice
),
"primary_i64_general - db_previous_i64"
);
itr_prev
=
db_previous_i64
(
itr_prev
,
&
prim
);
itr_prev_expected
=
-
1
;
eosio_assert
(
itr_prev
==
itr_prev_expected
&&
prim
==
N
(
alice
),
"primary_i64_general - db_previous_i64"
);
eosio_assert
(
itr_prev
<
0
&&
prim
==
N
(
alice
),
"primary_i64_general - db_previous_i64"
);
}
// remove
{
int
itr
=
db_find_i64
(
current_receiver
(),
current_receiver
(),
table1
,
N
(
alice
));
eosio_assert
(
itr
!=
-
1
,
"primary_i64_general - db_find_i64"
);
eosio_assert
(
itr
>=
0
,
"primary_i64_general - db_find_i64"
);
db_remove_i64
(
itr
);
itr
=
db_find_i64
(
current_receiver
(),
current_receiver
(),
table1
,
N
(
alice
));
eosio_assert
(
itr
==
-
1
,
"primary_i64_general - db_find_i64"
);
eosio_assert
(
itr
<
0
,
"primary_i64_general - db_find_i64"
);
}
// get
{
int
itr
=
db_find_i64
(
current_receiver
(),
current_receiver
(),
table1
,
N
(
bob
));
eosio_assert
(
itr
!=
-
1
,
""
);
eosio_assert
(
itr
>=
0
,
""
);
int
buffer_len
=
5
;
char
value
[
50
];
auto
len
=
db_get_i64
(
itr
,
value
,
buffer_len
);
...
...
@@ -1572,7 +1571,7 @@ void test_db::primary_i64_general()
std
::
string
s
(
value
);
eosio_assert
(
len
==
strlen
(
"bob's info"
),
"primary_i64_general - db_get_i64"
);
eosio_assert
(
s
==
"bob's"
,
"primary_i64_general - db_get_i64"
);
buffer_len
=
20
;
db_get_i64
(
itr
,
value
,
buffer_len
);
value
[
buffer_len
]
=
'\0'
;
...
...
@@ -1583,9 +1582,9 @@ void test_db::primary_i64_general()
// update
{
int
itr
=
db_find_i64
(
current_receiver
(),
current_receiver
(),
table1
,
N
(
bob
));
eosio_assert
(
itr
!=
-
1
,
""
);
eosio_assert
(
itr
>=
0
,
""
);
const
char
*
new_value
=
"bob's new info"
;
int
new_value_len
=
strlen
(
new_value
);
int
new_value_len
=
strlen
(
new_value
);
db_update_i64
(
itr
,
current_receiver
(),
new_value
,
new_value_len
);
char
ret_value
[
50
];
auto
len
=
db_get_i64
(
itr
,
ret_value
,
new_value_len
);
...
...
@@ -1625,7 +1624,7 @@ void test_db::primary_i64_lowerbound()
}
{
int
lb
=
db_lowerbound_i64
(
current_receiver
(),
current_receiver
(),
table
,
N
(
kevin
));
eosio_assert
(
lb
==
-
1
,
err
.
c_str
());
eosio_assert
(
lb
<
0
,
err
.
c_str
());
}
}
...
...
@@ -1647,11 +1646,11 @@ void test_db::primary_i64_upperbound()
}
{
int
ub
=
db_upperbound_i64
(
current_receiver
(),
current_receiver
(),
table
,
N
(
joe
));
eosio_assert
(
ub
==
-
1
,
err
.
c_str
());
eosio_assert
(
ub
<
0
,
err
.
c_str
());
}
{
int
ub
=
db_upperbound_i64
(
current_receiver
(),
current_receiver
(),
table
,
N
(
kevin
));
eosio_assert
(
ub
==
-
1
,
err
.
c_str
());
eosio_assert
(
ub
<
0
,
err
.
c_str
());
}
}
...
...
@@ -1683,62 +1682,62 @@ void test_db::idx64_general()
{
secondary_type
sec
=
0
;
int
itr
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
999
);
eosio_assert
(
itr
==
-
1
&&
sec
==
0
,
"idx64_general - db_idx64_find_primary"
);
eosio_assert
(
itr
<
0
&&
sec
==
0
,
"idx64_general - db_idx64_find_primary"
);
itr
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
110
);
eosio_assert
(
itr
!=
-
1
&&
sec
==
N
(
joe
),
"idx64_general - db_idx64_find_primary"
);
eosio_assert
(
itr
>=
0
&&
sec
==
N
(
joe
),
"idx64_general - db_idx64_find_primary"
);
uint64_t
prim_next
=
0
;
int
itr_next
=
db_idx64_next
(
itr
,
&
prim_next
);
eosio_assert
(
itr_next
==
-
1
&&
prim_next
==
0
,
"idx64_general - db_idx64_find_primary"
);
eosio_assert
(
itr_next
<
0
&&
prim_next
==
0
,
"idx64_general - db_idx64_find_primary"
);
}
// iterate forward starting with charlie
{
secondary_type
sec
=
0
;
int
itr
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
234
);
eosio_assert
(
itr
!=
-
1
&&
sec
==
N
(
charlie
),
"idx64_general - db_idx64_find_primary"
);
eosio_assert
(
itr
>=
0
&&
sec
==
N
(
charlie
),
"idx64_general - db_idx64_find_primary"
);
uint64_t
prim_next
=
0
;
int
itr_next
=
db_idx64_next
(
itr
,
&
prim_next
);
eosio_assert
(
itr_next
!=
-
1
&&
prim_next
==
976
,
"idx64_general - db_idx64_next"
);
eosio_assert
(
itr_next
>=
0
&&
prim_next
==
976
,
"idx64_general - db_idx64_next"
);
secondary_type
sec_next
=
0
;
int
itr_next_expected
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec_next
,
prim_next
);
eosio_assert
(
itr_next
==
itr_next_expected
&&
sec_next
==
N
(
emily
),
"idx64_general - db_idx64_next"
);
itr_next
=
db_idx64_next
(
itr_next
,
&
prim_next
);
eosio_assert
(
itr_next
!=
-
1
&&
prim_next
==
110
,
"idx64_general - db_idx64_next"
);
eosio_assert
(
itr_next
>=
0
&&
prim_next
==
110
,
"idx64_general - db_idx64_next"
);
itr_next_expected
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec_next
,
prim_next
);
eosio_assert
(
itr_next
==
itr_next_expected
&&
sec_next
==
N
(
joe
),
"idx64_general - db_idx64_next"
);
itr_next
=
db_idx64_next
(
itr_next
,
&
prim_next
);
eosio_assert
(
itr_next
==
-
1
&&
prim_next
==
110
,
"idx64_general - db_idx64_next"
);
eosio_assert
(
itr_next
<
0
&&
prim_next
==
110
,
"idx64_general - db_idx64_next"
);
}
// iterate backward staring with second bob
{
secondary_type
sec
=
0
;
int
itr
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
781
);
eosio_assert
(
itr
!=
-
1
&&
sec
==
N
(
bob
),
"idx64_general - db_idx64_find_primary"
);
eosio_assert
(
itr
>=
0
&&
sec
==
N
(
bob
),
"idx64_general - db_idx64_find_primary"
);
uint64_t
prim_prev
=
0
;
int
itr_prev
=
db_idx64_previous
(
itr
,
&
prim_prev
);
eosio_assert
(
itr_prev
!=
-
1
&&
prim_prev
==
540
,
"idx64_general - db_idx64_previous"
);
eosio_assert
(
itr_prev
>=
0
&&
prim_prev
==
540
,
"idx64_general - db_idx64_previous"
);
secondary_type
sec_prev
=
0
;
int
itr_prev_expected
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec_prev
,
prim_prev
);
eosio_assert
(
itr_prev
==
itr_prev_expected
&&
sec_prev
==
N
(
bob
),
"idx64_general - db_idx64_previous"
);
itr_prev
=
db_idx64_previous
(
itr_prev
,
&
prim_prev
);
eosio_assert
(
itr_prev
!=
-
1
&&
prim_prev
==
650
,
"idx64_general - db_idx64_previous"
);
eosio_assert
(
itr_prev
>=
0
&&
prim_prev
==
650
,
"idx64_general - db_idx64_previous"
);
itr_prev_expected
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec_prev
,
prim_prev
);
eosio_assert
(
itr_prev
==
itr_prev_expected
&&
sec_prev
==
N
(
allyson
),
"idx64_general - db_idx64_previous"
);
itr_prev
=
db_idx64_previous
(
itr_prev
,
&
prim_prev
);
eosio_assert
(
itr_prev
!=
-
1
&&
prim_prev
==
265
,
"idx64_general - db_idx64_previous"
);
eosio_assert
(
itr_prev
>=
0
&&
prim_prev
==
265
,
"idx64_general - db_idx64_previous"
);
itr_prev_expected
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec_prev
,
prim_prev
);
eosio_assert
(
itr_prev
==
itr_prev_expected
&&
sec_prev
==
N
(
alice
),
"idx64_general - db_idx64_previous"
);
itr_prev
=
db_idx64_previous
(
itr_prev
,
&
prim_prev
);
eosio_assert
(
itr_prev
==
-
1
&&
prim_prev
==
265
,
"idx64_general - db_idx64_previous"
);
eosio_assert
(
itr_prev
<
0
&&
prim_prev
==
265
,
"idx64_general - db_idx64_previous"
);
}
// find_secondary
...
...
@@ -1746,15 +1745,15 @@ void test_db::idx64_general()
uint64_t
prim
=
0
;
auto
sec
=
N
(
bob
);
int
itr
=
db_idx64_find_secondary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
&
prim
);
eosio_assert
(
itr
!=
-
1
&&
prim
==
540
,
"idx64_general - db_idx64_find_secondary"
);
eosio_assert
(
itr
>=
0
&&
prim
==
540
,
"idx64_general - db_idx64_find_secondary"
);
sec
=
N
(
emily
);
itr
=
db_idx64_find_secondary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
&
prim
);
eosio_assert
(
itr
!=
-
1
&&
prim
==
976
,
"idx64_general - db_idx64_find_secondary"
);
eosio_assert
(
itr
>=
0
&&
prim
==
976
,
"idx64_general - db_idx64_find_secondary"
);
sec
=
N
(
frank
);
itr
=
db_idx64_find_secondary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
&
prim
);
eosio_assert
(
itr
==
-
1
&&
prim
==
976
,
"idx64_general - db_idx64_find_secondary"
);
eosio_assert
(
itr
<
0
&&
prim
==
976
,
"idx64_general - db_idx64_find_secondary"
);
}
// update and remove
...
...
@@ -1769,7 +1768,7 @@ void test_db::idx64_general()
eosio_assert
(
sec_itr
==
itr
&&
sec
==
new_name
,
"idx64_general - db_idx64_update"
);
db_idx64_remove
(
itr
);
int
itrf
=
db_idx64_find_primary
(
current_receiver
(),
current_receiver
(),
table
,
&
sec
,
ssn
);
eosio_assert
(
itrf
==
-
1
,
"idx64_general - db_idx64_remove"
);
eosio_assert
(
itrf
<
0
,
"idx64_general - db_idx64_remove"
);
}
}
...
...
@@ -1807,7 +1806,7 @@ void test_db::idx64_lowerbound()
uint64_t
lb_prim
=
0
;
int
lb
=
db_idx64_lowerbound
(
current_receiver
(),
current_receiver
(),
table
,
&
lb_sec
,
&
lb_prim
);
eosio_assert
(
lb_prim
==
0
&&
lb_sec
==
N
(
kevin
),
err
.
c_str
());
eosio_assert
(
lb
==
-
1
,
""
);
eosio_assert
(
lb
<
0
,
""
);
}
}
...
...
@@ -1838,14 +1837,13 @@ void test_db::idx64_upperbound()
const
uint64_t
ssn
=
110
;
int
ub
=
db_idx64_upperbound
(
current_receiver
(),
current_receiver
(),
table
,
&
ub_sec
,
&
ub_prim
);
eosio_assert
(
ub_prim
==
0
&&
ub_sec
==
N
(
joe
),
err
.
c_str
());
eosio_assert
(
ub
==
-
1
,
err
.
c_str
());
eosio_assert
(
ub
<
0
,
err
.
c_str
());
}
{
secondary_type
ub_sec
=
N
(
kevin
);
uint64_t
ub_prim
=
0
;
int
ub
=
db_idx64_upperbound
(
current_receiver
(),
current_receiver
(),
table
,
&
ub_sec
,
&
ub_prim
);
eosio_assert
(
ub_prim
==
0
&&
ub_sec
==
N
(
kevin
),
err
.
c_str
());
eosio_assert
(
ub
==
-
1
,
err
.
c_str
());
eosio_assert
(
ub
<
0
,
err
.
c_str
());
}
}
contracts/test_api_multi_index/CMakeLists.txt
0 → 100644
浏览文件 @
fee30e1c
add_wast_executable
(
TARGET test_api_multi_index
INCLUDE_FOLDERS
"
${
STANDARD_INCLUDE_FOLDERS
}
"
LIBRARIES libc++ libc eosiolib
DESTINATION_FOLDER
${
CMAKE_CURRENT_BINARY_DIR
}
)
contracts/test_api_multi_index/test_api_multi_index.cpp
0 → 100644
浏览文件 @
fee30e1c
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosiolib/eosio.hpp>
#include "../test_api/test_api.hpp"
#include "test_multi_index.cpp"
extern
"C"
{
void
init
()
{
}
void
apply
(
unsigned
long
long
code
,
unsigned
long
long
action
)
{
WASM_TEST_HANDLER
(
test_multi_index
,
idx64_general
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx64_store_only
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx64_check_without_storing
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx128_autoincrement_test
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx128_autoincrement_test_part1
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx128_autoincrement_test_part2
);
WASM_TEST_HANDLER
(
test_multi_index
,
idx256_general
);
//unhandled test call
eosio_assert
(
false
,
"Unknown Test"
);
}
}
contracts/test_api_multi_index/test_multi_index.cpp
0 → 100644
浏览文件 @
fee30e1c
#include <eosiolib/multi_index.hpp>
#include "../test_api/test_api.hpp"
#include <eosiolib/print.hpp>
namespace
_test_multi_index
{
using
eosio
::
key256
;
struct
record_idx64
{
uint64_t
id
;
uint64_t
sec
;
auto
primary_key
()
const
{
return
id
;
}
uint64_t
get_secondary
()
const
{
return
sec
;
}
EOSLIB_SERIALIZE
(
record_idx64
,
(
id
)(
sec
)
)
};
struct
record_idx128
{
uint64_t
id
;
uint128_t
sec
;
auto
primary_key
()
const
{
return
id
;
}
uint128_t
get_secondary
()
const
{
return
sec
;
}
EOSLIB_SERIALIZE
(
record_idx128
,
(
id
)(
sec
)
)
};
struct
record_idx256
{
uint64_t
id
;
key256
sec
;
auto
primary_key
()
const
{
return
id
;
}
const
key256
&
get_secondary
()
const
{
return
sec
;
}
EOSLIB_SERIALIZE
(
record_idx256
,
(
id
)(
sec
)
)
};
template
<
uint64_t
TableName
>
void
idx64_store_only
()
{
using
namespace
eosio
;
typedef
record_idx64
record
;
record
records
[]
=
{{
265
,
N
(
alice
)},
{
781
,
N
(
bob
)},
{
234
,
N
(
charlie
)},
{
650
,
N
(
allyson
)},
{
540
,
N
(
bob
)},
{
976
,
N
(
emily
)},
{
110
,
N
(
joe
)}
};
size_t
num_records
=
sizeof
(
records
)
/
sizeof
(
records
[
0
]);
// Construct and fill table using multi_index
multi_index
<
TableName
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint64_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
auto
payer
=
current_receiver
();
for
(
size_t
i
=
0
;
i
<
num_records
;
++
i
)
{
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
records
[
i
].
id
;
r
.
sec
=
records
[
i
].
sec
;
});
}
}
template
<
uint64_t
TableName
>
void
idx64_check_without_storing
()
{
using
namespace
eosio
;
typedef
record_idx64
record
;
// Load table using multi_index
multi_index
<
TableName
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint64_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
auto
payer
=
current_receiver
();
auto
secondary_index
=
table
.
template
get_index
<
N
(
bysecondary
)>();
// find by primary key
{
auto
ptr
=
table
.
find
(
999
);
eosio_assert
(
ptr
==
nullptr
,
"idx64_general - table.find() of non-existing primary key"
);
ptr
=
table
.
find
(
976
);
eosio_assert
(
ptr
!=
nullptr
&&
ptr
->
sec
==
N
(
emily
),
"idx64_general - table.find() of existing primary key"
);
// Workaround: would prefer to instead receive iterator (rather than pointer) from find().
auto
itr
=
table
.
lower_bound
(
976
);
eosio_assert
(
itr
!=
table
.
end
()
&&
itr
->
id
==
976
&&
itr
->
sec
==
N
(
emily
),
"idx64_general - iterator to existing object in primary index"
);
++
itr
;
eosio_assert
(
itr
==
table
.
end
(),
"idx64_general - increment primary iterator to end"
);
}
// iterate forward starting with charlie
{
auto
itr
=
secondary_index
.
lower_bound
(
N
(
charlie
));
eosio_assert
(
itr
!=
secondary_index
.
end
()
&&
itr
->
sec
==
N
(
charlie
),
"idx64_general - secondary_index.lower_bound()"
);
++
itr
;
eosio_assert
(
itr
!=
secondary_index
.
end
()
&&
itr
->
id
==
976
&&
itr
->
sec
==
N
(
emily
),
"idx64_general - increment secondary iterator"
);
++
itr
;
eosio_assert
(
itr
!=
secondary_index
.
end
()
&&
itr
->
id
==
110
&&
itr
->
sec
==
N
(
joe
),
"idx64_general - increment secondary iterator again"
);
++
itr
;
eosio_assert
(
itr
==
secondary_index
.
end
(),
"idx64_general - increment secondary iterator to end"
);
}
// iterate backward staring with second bob
{
auto
ptr
=
table
.
find
(
781
);
eosio_assert
(
ptr
!=
nullptr
&&
ptr
->
sec
==
N
(
bob
),
"idx64_general - table.find() of existing primary key"
);
// Workaround: need to add find_primary wrapper support in secondary indices of multi_index
auto
itr
=
secondary_index
.
upper_bound
(
ptr
->
sec
);
--
itr
;
eosio_assert
(
itr
->
id
==
781
&&
itr
->
sec
==
N
(
bob
),
"idx64_general - iterator to existing object in secondary index"
);
--
itr
;
eosio_assert
(
itr
!=
secondary_index
.
end
()
&&
itr
->
id
==
540
&&
itr
->
sec
==
N
(
bob
),
"idx64_general - decrement secondary iterator"
);
--
itr
;
eosio_assert
(
itr
!=
secondary_index
.
end
()
&&
itr
->
id
==
650
&&
itr
->
sec
==
N
(
allyson
),
"idx64_general - decrement secondary iterator again"
);
--
itr
;
eosio_assert
(
itr
==
secondary_index
.
begin
()
&&
itr
->
id
==
265
&&
itr
->
sec
==
N
(
alice
),
"idx64_general - decrement secondary iterator to beginning"
);
}
// update and remove
{
const
uint64_t
ssn
=
421
;
const
auto
&
new_person
=
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
ssn
;
r
.
sec
=
N
(
bob
);
});
table
.
update
(
new_person
,
payer
,
[
&
](
auto
&
r
)
{
r
.
sec
=
N
(
billy
);
});
auto
ptr
=
table
.
find
(
ssn
);
eosio_assert
(
ptr
!=
nullptr
&&
ptr
->
sec
==
N
(
billy
),
"idx64_general - table.update()"
);
table
.
remove
(
*
ptr
);
auto
ptr2
=
table
.
find
(
ssn
);
eosio_assert
(
ptr2
==
nullptr
,
"idx64_general - table.remove()"
);
}
}
}
/// _test_multi_index
void
test_multi_index
::
idx64_store_only
()
{
_test_multi_index
::
idx64_store_only
<
N
(
indextable1
)
>
();
}
void
test_multi_index
::
idx64_check_without_storing
()
{
_test_multi_index
::
idx64_check_without_storing
<
N
(
indextable1
)
>
();
}
void
test_multi_index
::
idx64_general
()
{
_test_multi_index
::
idx64_store_only
<
N
(
indextable2
)
>
();
_test_multi_index
::
idx64_check_without_storing
<
N
(
indextable2
)
>
();
}
void
test_multi_index
::
idx128_autoincrement_test
()
{
using
namespace
eosio
;
using
namespace
_test_multi_index
;
typedef
record_idx128
record
;
const
uint64_t
table_name
=
N
(
indextable3
);
auto
payer
=
current_receiver
();
multi_index
<
table_name
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint128_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
table
.
available_primary_key
();
r
.
sec
=
1000
-
static_cast
<
uint128_t
>
(
r
.
id
);
});
}
uint64_t
expected_key
=
4
;
for
(
const
auto
&
r
:
table
.
get_index
<
N
(
bysecondary
)
>
()
)
{
eosio_assert
(
r
.
primary_key
()
==
expected_key
,
"idx128_autoincrement_test - unexpected primary key"
);
--
expected_key
;
}
auto
ptr
=
table
.
find
(
3
);
eosio_assert
(
ptr
!=
nullptr
,
"idx128_autoincrement_test - could not find object with primary key of 3"
);
table
.
update
(
*
ptr
,
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
100
;
});
eosio_assert
(
table
.
available_primary_key
()
==
101
,
"idx128_autoincrement_test - next_primary_key was not correct after record update"
);
}
void
test_multi_index
::
idx128_autoincrement_test_part1
()
{
using
namespace
eosio
;
using
namespace
_test_multi_index
;
typedef
record_idx128
record
;
const
uint64_t
table_name
=
N
(
indextable4
);
auto
payer
=
current_receiver
();
multi_index
<
table_name
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint128_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
table
.
available_primary_key
();
r
.
sec
=
1000
-
static_cast
<
uint128_t
>
(
r
.
id
);
});
}
table
.
remove
(
table
.
get
(
0
));
uint64_t
expected_key
=
2
;
for
(
const
auto
&
r
:
table
.
get_index
<
N
(
bysecondary
)
>
()
)
{
eosio_assert
(
r
.
primary_key
()
==
expected_key
,
"idx128_autoincrement_test_part1 - unexpected primary key"
);
--
expected_key
;
}
}
void
test_multi_index
::
idx128_autoincrement_test_part2
()
{
using
namespace
eosio
;
using
namespace
_test_multi_index
;
typedef
record_idx128
record
;
const
uint64_t
table_name
=
N
(
indextable4
);
auto
payer
=
current_receiver
();
{
multi_index
<
table_name
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint128_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
eosio_assert
(
table
.
available_primary_key
()
==
3
,
"idx128_autoincrement_test_part2 - did not recover expected next primary key"
);
}
multi_index
<
table_name
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
uint128_t
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
0
;
r
.
sec
=
1000
;
});
// Done this way to make sure that table._next_primary_key is not incorrectly set to 1.
for
(
int
i
=
3
;
i
<
5
;
++
i
)
{
table
.
emplace
(
payer
,
[
&
](
auto
&
r
)
{
auto
itr
=
table
.
available_primary_key
();
print
(
itr
,
"
\n
"
);
r
.
id
=
itr
;
r
.
sec
=
1000
-
static_cast
<
uint128_t
>
(
r
.
id
);
});
}
uint64_t
expected_key
=
4
;
for
(
const
auto
&
r
:
table
.
get_index
<
N
(
bysecondary
)
>
()
)
{
eosio_assert
(
r
.
primary_key
()
==
expected_key
,
"idx128_autoincrement_test_part2 - unexpected primary key"
);
--
expected_key
;
}
auto
ptr
=
table
.
find
(
3
);
eosio_assert
(
ptr
!=
nullptr
,
"idx128_autoincrement_test_part2 - could not find object with primary key of 3"
);
table
.
update
(
*
ptr
,
payer
,
[
&
](
auto
&
r
)
{
r
.
id
=
100
;
});
eosio_assert
(
table
.
available_primary_key
()
==
101
,
"idx128_autoincrement_test_part2 - next_primary_key was not correct after record update"
);
}
void
test_multi_index
::
idx256_general
()
{
using
namespace
eosio
;
using
namespace
_test_multi_index
;
typedef
record_idx256
record
;
const
uint64_t
table_name
=
N
(
indextable5
);
auto
payer
=
current_receiver
();
print
(
"Testing key256 secondary index.
\n
"
);
multi_index
<
table_name
,
record
,
indexed_by
<
N
(
bysecondary
),
const_mem_fun
<
record
,
const
key256
&
,
&
record
::
get_secondary
>
>
>
table
(
current_receiver
(),
current_receiver
()
);
auto
fourtytwo
=
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
42ULL
);
auto
onetwothreefour
=
key256
::
make_from_word_sequence
<
uint64_t
>
(
1ULL
,
2ULL
,
3ULL
,
4ULL
);
const
auto
&
entry1
=
table
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
1
;
o
.
sec
=
fourtytwo
;
});
const
auto
&
entry2
=
table
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
2
;
o
.
sec
=
onetwothreefour
;
});
const
auto
&
entry3
=
table
.
emplace
(
payer
,
[
&
](
auto
&
o
)
{
o
.
id
=
3
;
o
.
sec
=
fourtytwo
;
});
const
auto
*
e
=
table
.
find
(
2
);
print
(
"Items sorted by primary key:
\n
"
);
for
(
const
auto
&
item
:
table
)
{
print
(
" ID="
,
item
.
primary_key
(),
", secondary="
,
item
.
sec
,
"
\n
"
);
}
{
auto
itr
=
table
.
begin
();
eosio_assert
(
itr
->
primary_key
()
==
1
&&
itr
->
get_secondary
()
==
fourtytwo
,
"idx256_general - primary key sort"
);
++
itr
;
eosio_assert
(
itr
->
primary_key
()
==
2
&&
itr
->
get_secondary
()
==
onetwothreefour
,
"idx256_general - primary key sort"
);
++
itr
;
eosio_assert
(
itr
->
primary_key
()
==
3
&&
itr
->
get_secondary
()
==
fourtytwo
,
"idx256_general - primary key sort"
);
++
itr
;
eosio_assert
(
itr
==
table
.
end
(),
"idx256_general - primary key sort"
);
}
auto
secidx
=
table
.
get_index
<
N
(
bysecondary
)
>
();
auto
lower1
=
secidx
.
lower_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
40ULL
));
print
(
"First entry with a secondary key of at least 40 has ID="
,
lower1
->
id
,
".
\n
"
);
eosio_assert
(
lower1
->
id
==
1
,
"idx256_general - lower_bound"
);
auto
lower2
=
secidx
.
lower_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
50ULL
));
print
(
"First entry with a secondary key of at least 50 has ID="
,
lower2
->
id
,
".
\n
"
);
eosio_assert
(
lower2
->
id
==
2
,
"idx256_general - lower_bound"
);
if
(
&*
lower2
==
e
)
{
print
(
"Previously found entry is the same as the one found earlier with a primary key value of 2.
\n
"
);
}
print
(
"Items sorted by secondary key (key256):
\n
"
);
for
(
const
auto
&
item
:
secidx
)
{
print
(
" ID="
,
item
.
primary_key
(),
", secondary="
);
cout
<<
item
.
sec
<<
"
\n
"
;
}
{
auto
itr
=
secidx
.
begin
();
eosio_assert
(
itr
->
primary_key
()
==
1
,
"idx256_general - secondary key sort"
);
++
itr
;
eosio_assert
(
itr
->
primary_key
()
==
3
,
"idx256_general - secondary key sort"
);
++
itr
;
eosio_assert
(
itr
->
primary_key
()
==
2
,
"idx256_general - secondary key sort"
);
++
itr
;
eosio_assert
(
itr
==
secidx
.
end
(),
"idx256_general - secondary key sort"
);
}
auto
upper
=
secidx
.
upper_bound
(
key256
::
make_from_word_sequence
<
uint64_t
>
(
0ULL
,
0ULL
,
0ULL
,
42ULL
));
print
(
"First entry with a secondary key greater than 42 has ID="
,
upper
->
id
,
".
\n
"
);
eosio_assert
(
upper
->
id
==
2
,
"idx256_general - upper_bound"
);
print
(
"Removed entry with ID="
,
lower1
->
id
,
".
\n
"
);
table
.
remove
(
*
lower1
);
print
(
"Items sorted by primary key:
\n
"
);
for
(
const
auto
&
item
:
table
)
{
print
(
" ID="
,
item
.
primary_key
(),
", secondary="
,
item
.
sec
,
"
\n
"
);
}
{
auto
itr
=
table
.
begin
();
eosio_assert
(
itr
->
primary_key
()
==
2
&&
itr
->
get_secondary
()
==
onetwothreefour
,
"idx256_general - primary key sort after remove"
);
++
itr
;
eosio_assert
(
itr
->
primary_key
()
==
3
&&
itr
->
get_secondary
()
==
fourtytwo
,
"idx256_general - primary key sort after remove"
);
++
itr
;
eosio_assert
(
itr
==
table
.
end
(),
"idx256_general - primary key sort after remove"
);
}
}
libraries/chain/apply_context.cpp
浏览文件 @
fee30e1c
...
...
@@ -118,13 +118,13 @@ void apply_context::require_authorization( const account_name& account )const {
wdump
((
act
));
EOS_ASSERT
(
false
,
tx_missing_auth
,
"missing authority of ${account}"
,
(
"account"
,
account
));
}
void
apply_context
::
require_authorization
(
const
account_name
&
account
,
void
apply_context
::
require_authorization
(
const
account_name
&
account
,
const
permission_name
&
permission
)
const
{
for
(
const
auto
&
auth
:
act
.
authorization
)
if
(
auth
.
actor
==
account
)
{
if
(
auth
.
permission
==
permission
)
return
;
}
EOS_ASSERT
(
false
,
tx_missing_auth
,
"missing authority of ${account}/${permission}"
,
EOS_ASSERT
(
false
,
tx_missing_auth
,
"missing authority of ${account}/${permission}"
,
(
"account"
,
account
)(
"permission"
,
permission
)
);
}
...
...
@@ -162,7 +162,7 @@ void apply_context::require_read_lock(const account_name& account, const scope_n
bool
apply_context
::
has_recipient
(
account_name
code
)
const
{
for
(
auto
a
:
_notified
)
if
(
a
==
code
)
if
(
a
==
code
)
return
true
;
return
false
;
}
...
...
@@ -304,17 +304,17 @@ void apply_context::update_db_usage( const account_name& payer, int64_t delta )
}
int
apply_context
::
get_action
(
uint32_t
type
,
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
int
apply_context
::
get_action
(
uint32_t
type
,
uint32_t
index
,
char
*
buffer
,
size_t
buffer_size
)
const
{
const
transaction
&
trx
=
trx_meta
.
trx
();
const
action
*
act
=
nullptr
;
if
(
type
==
0
)
{
if
(
index
>=
trx
.
context_free_actions
.
size
()
)
if
(
index
>=
trx
.
context_free_actions
.
size
()
)
return
-
1
;
act
=
&
trx
.
context_free_actions
[
index
];
}
else
if
(
type
==
1
)
{
if
(
index
>=
trx
.
actions
.
size
()
)
if
(
index
>=
trx
.
actions
.
size
()
)
return
-
1
;
act
=
&
trx
.
actions
[
index
];
}
...
...
@@ -336,7 +336,7 @@ int apply_context::get_context_free_data( uint32_t index, char* buffer, size_t b
if
(
buffer_size
<
s
)
memcpy
(
buffer
,
trx_meta
.
context_free_data
.
data
(),
buffer_size
);
else
else
memcpy
(
buffer
,
trx_meta
.
context_free_data
.
data
(),
s
);
return
s
;
...
...
@@ -379,7 +379,7 @@ void apply_context::db_update_i64( int iterator, account_name payer, const char*
if
(
payer
==
account_name
()
)
payer
=
obj
.
payer
;
if
(
account_name
(
obj
.
payer
)
==
payer
)
{
update_db_usage
(
obj
.
payer
,
buffer_size
+
200
-
old_size
);
update_db_usage
(
obj
.
payer
,
buffer_size
-
old_size
);
}
else
{
update_db_usage
(
obj
.
payer
,
-
(
old_size
+
200
)
);
update_db_usage
(
payer
,
(
buffer_size
+
200
)
);
...
...
@@ -404,94 +404,122 @@ void apply_context::db_remove_i64( int iterator ) {
});
mutable_db
.
remove
(
obj
);
keyval_cache
.
remove
(
iterator
,
obj
);
keyval_cache
.
remove
(
iterator
);
}
int
apply_context
::
db_get_i64
(
int
iterator
,
char
*
buffer
,
size_t
buffer_size
)
{
const
key_value_object
&
obj
=
keyval_cache
.
get
(
iterator
);
memcpy
(
buffer
,
obj
.
value
.
data
(),
std
::
min
(
obj
.
value
.
size
(),
buffer_size
)
);
return
obj
.
value
.
size
();
}
int
apply_context
::
db_next_i64
(
int
iterator
,
uint64_t
&
primary
)
{
const
auto
&
obj
=
keyval_cache
.
get
(
iterator
);
if
(
iterator
<
-
1
)
return
-
1
;
// cannot increment past end iterator of table
const
auto
&
obj
=
keyval_cache
.
get
(
iterator
);
// Check for iterator != -1 happens in this call
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
iterator_to
(
obj
);
++
itr
;
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
obj
.
t_id
)
return
-
1
;
if
(
itr
==
idx
.
end
()
||
itr
->
t_id
!=
obj
.
t_id
)
return
keyval_cache
.
get_end_iterator_by_table_id
(
obj
.
t_id
);
primary
=
itr
->
primary_key
;
return
keyval_cache
.
add
(
*
itr
);
}
int
apply_context
::
db_previous_i64
(
int
iterator
,
uint64_t
&
primary
)
{
const
auto
&
obj
=
keyval_cache
.
get
(
iterator
);
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
if
(
iterator
<
-
1
)
// is end iterator
{
auto
tab
=
keyval_cache
.
find_table_by_end_iterator
(
iterator
);
FC_ASSERT
(
tab
,
"not a valid end iterator"
);
auto
itr
=
idx
.
upper_bound
(
tab
->
id
);
if
(
itr
==
idx
.
begin
()
)
return
-
1
;
// Empty table
--
itr
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
-
1
;
// Empty table
primary
=
itr
->
primary_key
;
return
keyval_cache
.
add
(
*
itr
);
}
const
auto
&
obj
=
keyval_cache
.
get
(
iterator
);
auto
itr
=
idx
.
iterator_to
(
obj
);
if
(
itr
==
idx
.
end
()
||
itr
==
idx
.
begin
())
return
-
1
;
if
(
itr
==
idx
.
begin
()
)
return
-
1
;
// cannot decrement past beginning iterator of table
--
itr
;
if
(
itr
->
t_id
!=
obj
.
t_id
)
return
-
1
;
if
(
itr
->
t_id
!=
obj
.
t_id
)
return
-
1
;
// cannot decrement past beginning iterator of table
primary
=
itr
->
primary_key
;
return
keyval_cache
.
add
(
*
itr
);
}
int
apply_context
::
db_find_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
require_read_lock
(
code
,
scope
);
// redundant?
const
auto
*
tab
=
find_table
(
code
,
scope
,
table
);
if
(
!
tab
)
return
-
1
;
validate_table_key
(
*
tab
,
contracts
::
table_key_type
::
type_i64
);
auto
table_end_itr
=
keyval_cache
.
cache_table
(
*
tab
);
const
key_value_object
*
obj
=
db
.
find
<
key_value_object
,
contracts
::
by_scope_primary
>
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
!
obj
)
return
-
1
;
if
(
!
obj
)
return
table_end_itr
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
obj
);
}
int
apply_context
::
db_lowerbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
require_read_lock
(
code
,
scope
);
// redundant?
const
auto
*
tab
=
find_table
(
code
,
scope
,
table
);
if
(
!
tab
)
return
-
1
;
validate_table_key
(
*
tab
,
contracts
::
table_key_type
::
type_i64
);
auto
table_end_itr
=
keyval_cache
.
cache_table
(
*
tab
);
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
lower_bound
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
-
1
;
if
(
itr
==
idx
.
end
()
)
return
table_end_itr
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
table_end_itr
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
itr
);
}
int
apply_context
::
db_upperbound_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
,
uint64_t
id
)
{
require_read_lock
(
code
,
scope
);
require_read_lock
(
code
,
scope
);
// redundant?
const
auto
*
tab
=
find_table
(
code
,
scope
,
table
);
if
(
!
tab
)
return
-
1
;
validate_table_key
(
*
tab
,
contracts
::
table_key_type
::
type_i64
);
auto
table_end_itr
=
keyval_cache
.
cache_table
(
*
tab
);
const
auto
&
idx
=
db
.
get_index
<
contracts
::
key_value_index
,
contracts
::
by_scope_primary
>
();
auto
itr
=
idx
.
upper_bound
(
boost
::
make_tuple
(
tab
->
id
,
id
)
);
if
(
itr
==
idx
.
end
()
)
return
-
1
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
-
1
;
if
(
itr
==
idx
.
end
()
)
return
table_end_itr
;
if
(
itr
->
t_id
!=
tab
->
id
)
return
table_end_itr
;
keyval_cache
.
cache_table
(
*
tab
);
return
keyval_cache
.
add
(
*
itr
);
}
int
apply_context
::
db_end_i64
(
uint64_t
code
,
uint64_t
scope
,
uint64_t
table
)
{
require_read_lock
(
code
,
scope
);
// redundant?
const
auto
*
tab
=
find_table
(
code
,
scope
,
table
);
if
(
!
tab
)
return
-
1
;
validate_table_key
(
*
tab
,
contracts
::
table_key_type
::
type_i64
);
return
keyval_cache
.
cache_table
(
*
tab
);
}
template
<
>
contracts
::
table_key_type
apply_context
::
get_key_type
<
contracts
::
key_value_object
>
()
{
return
contracts
::
table_key_type
::
type_i64
;
...
...
libraries/chain/chain_controller.cpp
浏览文件 @
fee30e1c
...
...
@@ -1048,6 +1048,7 @@ void chain_controller::_initialize_indexes() {
_db
.
add_index
<
contracts
::
key_value_index
>
();
_db
.
add_index
<
contracts
::
index64_index
>
();
_db
.
add_index
<
contracts
::
index128_index
>
();
_db
.
add_index
<
contracts
::
index256_index
>
();
_db
.
add_index
<
contracts
::
keystr_value_index
>
();
...
...
libraries/chain/include/eosio/chain/apply_context.hpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
libraries/chain/include/eosio/chain/contracts/contract_table_objects.hpp
浏览文件 @
fee30e1c
...
...
@@ -9,6 +9,9 @@
#include <chainbase/chainbase.hpp>
#include <array>
#include <type_traits>
namespace
eosio
{
namespace
chain
{
namespace
contracts
{
enum
table_key_type
{
...
...
@@ -58,7 +61,7 @@ namespace eosio { namespace chain { namespace contracts {
struct
by_scope_secondary
;
struct
by_scope_tertiary
;
struct
key_value_object
:
public
chainbase
::
object
<
key_value_object_type
,
key_value_object
>
{
OBJECT_CTOR
(
key_value_object
,
(
value
))
...
...
@@ -126,12 +129,39 @@ namespace eosio { namespace chain { namespace contracts {
>
index_index
;
};
/*
template <typename T, typename = void>
struct _is_array : std::false_type {};
template <typename T>
struct _is_array<T, std::enable_if<std::is_same<size_t, decltype(SecondaryKey::arr_size)>::type> : std::true_type {};
template<SecondaryKey>
inline
typename std::enable_if<_is_array<SecondaryKey>::value, size_t>::type
get_key_memory_usage() {
return SecondaryKey::arr_size;
}
*/
template
<
typename
SecondaryKey
>
inline
//typename std::enable_if<!_is_array<SecondaryKey>::value, size_t>::type
size_t
get_key_memory_usage
()
{
return
sizeof
(
SecondaryKey
);
}
typedef
secondary_index
<
uint64_t
,
index64_object_type
>::
index_object
index64_object
;
typedef
secondary_index
<
uint64_t
,
index64_object_type
>::
index_index
index64_index
;
typedef
secondary_index
<
uint128_t
,
index128_object_type
>::
index_object
index128_object
;
typedef
secondary_index
<
uint128_t
,
index128_object_type
>::
index_index
index128_index
;
typedef
std
::
array
<
uint128_t
,
2
>
key256_t
;
typedef
secondary_index
<
key256_t
,
index256_object_type
>::
index_object
index256_object
;
typedef
secondary_index
<
key256_t
,
index256_object_type
>::
index_index
index256_index
;
/*
struct index64_object : public chainbase::object<index64_object_type, index64_object> {
OBJECT_CTOR(index64_object)
...
...
@@ -353,6 +383,7 @@ CHAINBASE_SET_INDEX_TYPE(eosio::chain::contracts::key64x64x64_value_object, eosi
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
index64_object
,
eosio
::
chain
::
contracts
::
index64_index
)
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
index128_object
,
eosio
::
chain
::
contracts
::
index128_index
)
CHAINBASE_SET_INDEX_TYPE
(
eosio
::
chain
::
contracts
::
index256_object
,
eosio
::
chain
::
contracts
::
index256_index
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
table_id_object
,
(
id
)(
code
)(
scope
)(
table
)(
key_type
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
key_value_object
,
(
id
)(
t_id
)(
primary_key
)(
value
)(
payer
)
)
...
...
libraries/chain/include/eosio/chain/contracts/types.hpp
浏览文件 @
fee30e1c
...
...
@@ -28,7 +28,6 @@ using field_name = fixed_string16;
using
table_name
=
name
;
using
action_name
=
eosio
::
chain
::
action_name
;
struct
type_def
{
type_def
()
=
default
;
type_def
(
const
type_name
&
new_type_name
,
const
type_name
&
type
)
...
...
@@ -44,7 +43,7 @@ struct field_def {
field_def
(
const
field_name
&
name
,
const
type_name
&
type
)
:
name
(
name
),
type
(
type
)
{}
field_name
name
;
type_name
type
;
...
...
@@ -291,4 +290,3 @@ FC_REFLECT( eosio::chain::contracts::unlinkauth , (account
FC_REFLECT
(
eosio
::
chain
::
contracts
::
postrecovery
,
(
account
)(
data
)(
memo
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
passrecovery
,
(
account
)
)
FC_REFLECT
(
eosio
::
chain
::
contracts
::
vetorecovery
,
(
account
)
)
libraries/chain/include/eosio/chain/fixed_key.hpp
0 → 100644
浏览文件 @
fee30e1c
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <array>
#include <algorithm>
#include <type_traits>
#include <fc/exception/exception.hpp>
namespace
eosio
{
template
<
size_t
Size
>
class
fixed_key
;
template
<
size_t
Size
>
bool
operator
==
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
!=
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
template
<
size_t
Size
>
bool
operator
<
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
/**
* @defgroup fixed_key fixed size key sorted lexicographically
* @ingroup types
* @{
*/
template
<
size_t
Size
>
class
fixed_key
{
private:
template
<
bool
...>
struct
bool_pack
;
template
<
bool
...
bs
>
using
all_true
=
std
::
is_same
<
bool_pack
<
bs
...,
true
>
,
bool_pack
<
true
,
bs
...
>
>
;
public:
typedef
uint128_t
word_t
;
static
constexpr
size_t
num_words
()
{
return
(
Size
+
sizeof
(
word_t
)
-
1
)
/
sizeof
(
word_t
);
}
static
constexpr
size_t
padded_bytes
()
{
return
num_words
()
*
sizeof
(
word_t
)
-
Size
;
}
/**
* @brief Default constructor to fixed_key object
*
* @details Default constructor to fixed_key object which initializes all bytes to zero
*/
fixed_key
()
:
_data
()
{}
/**
* @brief Constructor to fixed_key object from array of num_words() words
*
* @details Constructor to fixed_key object from array of num_words() words
* @param arr data
*/
fixed_key
(
const
word_t
(
&
arr
)[
num_words
()])
{
std
::
copy
(
arr
,
arr
+
num_words
(),
_data
.
begin
());
}
/**
* @brief Constructor to fixed_key object from std::array of num_words() words
*
* @details Constructor to fixed_key object from std::array of num_words() words
* @param arr data
*/
fixed_key
(
const
std
::
array
<
word_t
,
num_words
()
>&
arr
)
{
std
::
copy
(
arr
.
begin
(),
arr
.
end
(),
_data
.
begin
());
}
#if 0
// Cannot infer constructor template arguments in C++ versions prior to C++17
/**
* @brief Constructor to fixed_key object from sequence of words supplied as arguments
*
* @details Constructor to fixed_key object from sequence of words (of small sizes allowed) supplied as arguments
*/
template<typename FirstWord, typename... Rest>
fixed_key(typename std::enable_if<std::is_integral<FirstWord>::value &&
!std::is_same<FirstWord, bool>::value &&
sizeof(FirstWord) <= sizeof(word_t) &&
all_true<(std::is_same<FirstWord, Rest>::value)...>::value,
FirstWord>::type first_word,
Rest... rest)
{
static_assert( sizeof(word_t) == (sizeof(word_t)/sizeof(FirstWord)) * sizeof(FirstWord),
"size of the backing word size is not divisble by the size of the words supplied as arguments" );
static_assert( sizeof(FirstWord) * (1 + sizeof...(Rest)) <= Size, "too many words supplied to fixed_key constructor" );
auto itr = _data.begin();
word_t temp_word = 0;
const size_t sub_word_shift = 8 * sizeof(FirstWord);
const size_t num_sub_words = sizeof(word_t) / sizeof(FirstWord);
auto sub_words_left = num_sub_words;
for( auto&& w : { first_word, rest... } ) {
if( sub_words_left > 1 ) {
temp_word |= static_cast<word_t>(w);
temp_word <<= sub_word_shift;
--sub_words_left;
continue;
}
FC_ASSERT( sub_words_left == 1, "unexpected error in fixed_key constructor" );
temp_word |= static_cast<word_t>(w);
sub_words_left = num_sub_words;
*itr = temp_word;
temp_word = 0;
++itr;
}
if( sub_words_left != num_sub_words ) {
if( sub_words_left > 1 )
temp_word <<= 8 * (sub_words_left-1);
*itr = temp_word;
}
}
#endif
template
<
typename
FirstWord
,
typename
...
Rest
>
static
fixed_key
<
Size
>
make_from_word_sequence
(
typename
std
::
enable_if
<
std
::
is_integral
<
FirstWord
>::
value
&&
!
std
::
is_same
<
FirstWord
,
bool
>::
value
&&
sizeof
(
FirstWord
)
<=
sizeof
(
word_t
)
&&
all_true
<
(
std
::
is_same
<
FirstWord
,
Rest
>::
value
)...
>::
value
,
FirstWord
>::
type
first_word
,
Rest
...
rest
)
{
static_assert
(
sizeof
(
word_t
)
==
(
sizeof
(
word_t
)
/
sizeof
(
FirstWord
))
*
sizeof
(
FirstWord
),
"size of the backing word size is not divisble by the size of the words supplied as arguments"
);
static_assert
(
sizeof
(
FirstWord
)
*
(
1
+
sizeof
...(
Rest
))
<=
Size
,
"too many words supplied to fixed_key constructor"
);
fixed_key
<
Size
>
key
;
auto
itr
=
key
.
_data
.
begin
();
word_t
temp_word
=
0
;
const
size_t
sub_word_shift
=
8
*
sizeof
(
FirstWord
);
const
size_t
num_sub_words
=
sizeof
(
word_t
)
/
sizeof
(
FirstWord
);
auto
sub_words_left
=
num_sub_words
;
for
(
auto
&&
w
:
{
first_word
,
rest
...
}
)
{
if
(
sub_words_left
>
1
)
{
temp_word
|=
static_cast
<
word_t
>
(
w
);
temp_word
<<=
sub_word_shift
;
--
sub_words_left
;
continue
;
}
FC_ASSERT
(
sub_words_left
==
1
,
"unexpected error in fixed_key constructor"
);
temp_word
|=
static_cast
<
word_t
>
(
w
);
sub_words_left
=
num_sub_words
;
*
itr
=
temp_word
;
temp_word
=
0
;
++
itr
;
}
if
(
sub_words_left
!=
num_sub_words
)
{
if
(
sub_words_left
>
1
)
temp_word
<<=
8
*
(
sub_words_left
-
1
);
*
itr
=
temp_word
;
}
return
key
;
}
const
auto
&
get_array
()
const
{
return
_data
;
}
auto
data
()
{
return
_data
.
data
();
}
auto
data
()
const
{
return
_data
.
data
();
}
auto
size
()
const
{
return
_data
.
size
();
}
std
::
array
<
uint8_t
,
Size
>
extract_as_byte_array
()
const
{
std
::
array
<
uint8_t
,
Size
>
arr
;
const
size_t
num_sub_words
=
sizeof
(
word_t
);
auto
arr_itr
=
arr
.
begin
();
auto
data_itr
=
_data
.
begin
();
for
(
size_t
counter
=
_data
.
size
();
counter
>
0
;
--
counter
,
++
data_itr
)
{
size_t
sub_words_left
=
num_sub_words
;
if
(
counter
==
1
)
{
// If last word in _data array...
sub_words_left
-=
padded_bytes
();
}
auto
temp_word
=
*
data_itr
;
for
(
;
sub_words_left
>
0
;
--
sub_words_left
)
{
*
(
arr_itr
+
sub_words_left
-
1
)
=
static_cast
<
uint8_t
>
(
temp_word
&
0xFF
);
temp_word
>>=
8
;
}
arr_itr
+=
num_sub_words
;
}
return
arr
;
}
// Comparison operators
friend
bool
operator
==
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
!=
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
>
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
friend
bool
operator
<
<>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
);
private:
std
::
array
<
word_t
,
num_words
()
>
_data
;
};
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 == c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
==
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
==
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 != c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
!=
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
!=
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 > c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
>
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
>
c2
.
_data
;
}
/**
* @brief Compares two fixed_key variables c1 and c2
*
* @details Lexicographically compares two fixed_key variables c1 and c2
* @return if c1 < c2, return true, otherwise false
*/
template
<
size_t
Size
>
bool
operator
<
(
const
fixed_key
<
Size
>
&
c1
,
const
fixed_key
<
Size
>
&
c2
)
{
return
c1
.
_data
<
c2
.
_data
;
}
/// @} fixed_key
typedef
fixed_key
<
32
>
key256
;
}
libraries/chain/include/eosio/chain/types.hpp
浏览文件 @
fee30e1c
...
...
@@ -122,6 +122,7 @@ namespace eosio { namespace chain {
key64x64_value_object_type
,
index64_object_type
,
index128_object_type
,
index256_object_type
,
action_permission_object_type
,
global_property_object_type
,
dynamic_global_property_object_type
,
...
...
@@ -164,7 +165,7 @@ namespace eosio { namespace chain {
using
uint128_t
=
__uint128_t
;
using
bytes
=
vector
<
char
>
;
}
}
// eosio::chain
...
...
@@ -180,6 +181,7 @@ FC_REFLECT_ENUM(eosio::chain::object_type,
(
key64x64_value_object_type
)
(
index64_object_type
)
(
index128_object_type
)
(
index256_object_type
)
(
action_permission_object_type
)
(
global_property_object_type
)
(
dynamic_global_property_object_type
)
...
...
libraries/chain/wasm_interface.cpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
libraries/fc/include/fc/crypto/sha256.hpp
浏览文件 @
fee30e1c
...
...
@@ -107,6 +107,7 @@ class sha256
uint64_t
hash64
(
const
char
*
buf
,
size_t
len
);
}
// fc
namespace
std
{
template
<
>
...
...
@@ -117,6 +118,7 @@ namespace std
return
*
((
size_t
*
)
&
s
);
}
};
}
namespace
boost
...
...
libraries/testing/tester.cpp
浏览文件 @
fee30e1c
...
...
@@ -318,7 +318,8 @@ namespace eosio { namespace testing {
if
(
tbl
)
{
const
auto
*
obj
=
db
.
find
<
contracts
::
key_value_object
,
contracts
::
by_scope_primary
>
(
boost
::
make_tuple
(
tbl
->
id
,
asset_symbol
.
value
()));
if
(
obj
)
{
fc
::
datastream
<
const
char
*>
ds
(
obj
->
value
.
data
(),
obj
->
value
.
size
());
//balance is the second field after symbol, so skip the symbol
fc
::
datastream
<
const
char
*>
ds
(
obj
->
value
.
data
()
+
sizeof
(
symbol
),
obj
->
value
.
size
()
-
sizeof
(
symbol
));
fc
::
raw
::
unpack
(
ds
,
result
);
}
}
...
...
plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
tests/api_tests/api_tests.cpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
tests/tests/abi_tests.cpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
tests/wasm_tests/identity_tests.cpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
tests/wasm_tests/multi_index_tests.cpp
浏览文件 @
fee30e1c
此差异已折叠。
点击以展开。
tests/wasm_tests/wasm_tests.cpp
浏览文件 @
fee30e1c
...
...
@@ -21,6 +21,9 @@
#include "test_wasts.hpp"
#include <array>
#include <utility>
using
namespace
eosio
;
using
namespace
eosio
::
chain
;
using
namespace
eosio
::
chain
::
contracts
;
...
...
@@ -430,7 +433,7 @@ BOOST_FIXTURE_TEST_CASE( lotso_globals, tester ) try {
//add a few immutable ones for good measure
for
(
unsigned
int
i
=
0
;
i
<
10
;
++
i
)
ss
<<
"(global $g"
<<
i
+
200
<<
" i32 (i32.const 0))"
;
set_code
(
N
(
globals
),
string
(
ss
.
str
()
+
")"
)
.
c_str
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录