diff --git a/.gitignore b/.gitignore index d7aee3188e4..d013a76b483 100644 --- a/.gitignore +++ b/.gitignore @@ -58,8 +58,6 @@ programs/enunode/enunode scripts/tn_init.sh tests/plugin_test -tests/config.hpp -unittests/config.hpp unittests/unit_test doxygen diff --git a/Docker/Dockerfile b/Docker/Dockerfile index 54eb4a9f4bb..bd39a9a06e2 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -5,7 +5,7 @@ RUN git clone -b $branch https://github.com/enumivo/enumivo.git --recursive \ && cd eos && echo "$branch:$(git rev-parse HEAD)" > /etc/eosio-version \ && cmake -H. -B"/tmp/build" -GNinja -DCMAKE_BUILD_TYPE=Release -DWASM_ROOT=/opt/wasm -DCMAKE_CXX_COMPILER=clang++ \ -DCMAKE_C_COMPILER=clang -DCMAKE_INSTALL_PREFIX=/tmp/build -DSecp256k1_ROOT_DIR=/usr/local -DBUILD_MONGO_DB_PLUGIN=true \ - && cmake --build /tmp/build --target install + && cmake --build /tmp/build --target install && rm /tmp/build/bin/eosiocpp FROM ubuntu:18.04 diff --git a/Docker/README.md b/Docker/README.md index 2de9aea53d5..cb4c1861b25 100644 --- a/Docker/README.md +++ b/Docker/README.md @@ -15,7 +15,7 @@ Simple and fast setup of Enumivo on Docker is also available. ## Build eos image ```bash -git clone https://github.com/enumivo/enumivo.git --recursive +git clone https://github.com/enumivo/enumivo.git --recursive --depth 1 cd eos/Docker docker build . -t enumivo/eos ``` @@ -67,7 +67,7 @@ After `docker-compose up -d`, two services named `nodeosd` and `enuwallet` will You can run the `enucli` commands via a bash alias. ```bash -alias enucli='docker-compose exec enuwallet /opt/enumivo/bin/enucli -u http://nodeosd:8888' +alias enucli='docker-compose exec enuwallet /opt/enumivo/bin/enucli -u http://nodeosd:8888 --wallet-url http://localhost:8888' enucli get info enucli get account inita ``` @@ -86,29 +86,15 @@ docker-compose stop enuwallet ### Develop/Build custom contracts -Due to the fact that the enumivo/eos image does not contain the required dependencies for contract development (this is by design, to keep the image size small), you will need to utilize enumivo/builder. However, enumivo/builder does not contain enumivocpp. As such, you will need to run enumivo/builder interactively, and clone, build and install Enumivo. Once this is complete, you can then utilize enumivocpp to compile your contracts. +Due to the fact that the enumivo/eos image does not contain the required dependencies for contract development (this is by design, to keep the image size small), you will need to utilize the enumivo/eos-dev image. This image contains both the required binaries and dependencies to build contracts using enumivocpp. -You can also create a Dockerfile that will do this for you. - -``` -FROM enumivo/builder - -RUN git clone -b master --depth 1 https://github.com/enumivo/enumivo.git --recursive \ - && cd eos \ - && cmake -H. -B"/tmp/build" -GNinja -DCMAKE_BUILD_TYPE=Release -DWASM_ROOT=/opt/wasm -DCMAKE_CXX_COMPILER=clang++ \ - -DCMAKE_C_COMPILER=clang -DSecp256k1_ROOT_DIR=/usr/local -DBUILD_MONGO_DB_PLUGIN=true \ - && cmake --build /tmp/build --target install && rm -rf /tmp/build /eos -``` - -Then, from the same directory as the Dockerfile, simply run: +You can either use the image available on [Docker Hub](https://hub.docker.com/r/enumivo/eos-dev/) or navigate into the dev folder and build the image manually. ```bash -docker build -t enumivo/contracts . -docker run -it -v /path/to/custom/contracts:/contracts enumivo/contracts /bin/bash +cd dev +docker build -t enumivo/eos-dev . ``` -At this time you should be at a bash shell. You can navigate into the /contracts directory and use enumivocpp to compile your custom contracts. - ### Change default configuration You can use docker compose override file to change the default configurations. For example, create an alternate config file `config2.ini` and a `docker-compose.override.yml` with the following content. diff --git a/Docker/dev/Dockerfile b/Docker/dev/Dockerfile new file mode 100644 index 00000000000..82f200ee1f0 --- /dev/null +++ b/Docker/dev/Dockerfile @@ -0,0 +1,17 @@ +FROM eosio/builder +ARG branch=master + +RUN git clone -b $branch https://github.com/EOSIO/eos.git --recursive \ + && cd eos && echo "$branch:$(git rev-parse HEAD)" > /etc/eosio-version \ + && cmake -H. -B"/opt/eosio" -GNinja -DCMAKE_BUILD_TYPE=Release -DWASM_ROOT=/opt/wasm -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_C_COMPILER=clang -DCMAKE_INSTALL_PREFIX=/opt/eosio -DSecp256k1_ROOT_DIR=/usr/local -DBUILD_MONGO_DB_PLUGIN=true \ + && cmake --build /opt/eosio --target install \ + && mv /eos/Docker/config.ini / && mv /opt/eosio/contracts /contracts && mv /eos/Docker/nodeosd.sh /opt/eosio/bin/nodeosd.sh \ + && rm -rf /eos + +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install openssl && rm -rf /var/lib/apt/lists/* +ENV EOSIO_ROOT=/opt/eosio +RUN chmod +x /opt/eosio/bin/nodeosd.sh +ENV LD_LIBRARY_PATH /usr/local/lib +VOLUME /opt/eosio/bin/data-dir +ENV PATH /opt/eosio/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin diff --git a/contracts/asserter/asserter.abi b/contracts/asserter/asserter.abi index d42fc9e0960..dc429d4da8f 100644 --- a/contracts/asserter/asserter.abi +++ b/contracts/asserter/asserter.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [], "structs": [ { @@ -31,5 +32,6 @@ } ], "tables": [], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/dice/dice.abi b/contracts/dice/dice.abi index 6e1758a1291..92320d34395 100644 --- a/contracts/dice/dice.abi +++ b/contracts/dice/dice.abi @@ -1,6 +1,9 @@ { - "____comment": "This file was generated by enugenabi. DO NOT EDIT - 2018-03-29T02:09:11", - "types": [], + "version": "enumivo::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + }], "structs": [{ "name": "offer", "base": "", @@ -213,5 +216,6 @@ "type": "account" } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/enumivo.bios/enumivo.bios.abi b/contracts/enumivo.bios/enumivo.bios.abi index 7d0d17b6e16..c04eca7f326 100644 --- a/contracts/enumivo.bios/enumivo.bios.abi +++ b/contracts/enumivo.bios/enumivo.bios.abi @@ -1,6 +1,131 @@ { - "types": [], - "structs": [{ + "version": "enumivo::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ "name": "set_account_limits", "base": "", "fields": [ @@ -42,7 +167,43 @@ {"name":"from", "type":"account_name"} ] }], - "actions": [{ + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ "name": "setalimits", "type": "set_account_limits", "ricardian_contract": "" @@ -63,7 +224,8 @@ "type": "require_auth", "ricardian_contract": "" } - ], - "tables": [], - "ricardian_clauses": [] + ], + "tables": [], + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/enumivo.coin/enumivo.coin.abi b/contracts/enumivo.coin/enumivo.coin.abi index 260bc50de94..02f273be3e7 100644 --- a/contracts/enumivo.coin/enumivo.coin.abi +++ b/contracts/enumivo.coin/enumivo.coin.abi @@ -1,5 +1,9 @@ { - "types": [], + "version": "enumivo::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + }], "structs": [{ "name": "transfer", "base": "", @@ -69,5 +73,6 @@ "key_types" : ["uint64"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/enumivo.msig/enumivo.msig.abi b/contracts/enumivo.msig/enumivo.msig.abi index d9fa69f7399..62ffd8010b0 100644 --- a/contracts/enumivo.msig/enumivo.msig.abi +++ b/contracts/enumivo.msig/enumivo.msig.abi @@ -1,9 +1,15 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "account_name", "type": "name" - } - ], + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], "structs": [{ "name": "permission_level", "base": "", @@ -139,7 +145,8 @@ "index_type": "i64", "key_names" : ["proposal_name"], "key_types" : ["name"] - } + } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/enumivo.system/enumivo.system.abi b/contracts/enumivo.system/enumivo.system.abi index d4df888b580..ea25080fb5d 100644 --- a/contracts/enumivo.system/enumivo.system.abi +++ b/contracts/enumivo.system/enumivo.system.abi @@ -1,6 +1,131 @@ { - "types": [], - "structs": [{ + "version": "enumivo::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ "name": "buyrambytes", "base": "", "fields": [ @@ -202,70 +327,104 @@ {"name":"owner", "type":"account_name"} ] },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - } - ], - "actions": [ - { + "name": "setpriv", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"is_priv", "type":"int8"} + ] + } + ], + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ "name": "buyrambytes", "type": "buyrambytes", "ricardian_contract": "" - },{ + },{ "name": "buyram", "type": "buyram", "ricardian_contract": "" - },{ + },{ "name": "sellram", "type": "sellram", "ricardian_contract": "" - },{ + },{ "name": "delegatebw", "type": "delegatebw", "ricardian_contract": "" - },{ + },{ "name": "undelegatebw", "type": "undelegatebw", "ricardian_contract": "" - },{ + },{ "name": "refund", "type": "refund", "ricardian_contract": "" - },{ + },{ "name": "regproducer", "type": "regproducer", "ricardian_contract": "" - },{ + },{ "name": "setram", "type": "setram", "ricardian_contract": "" - },{ + },{ "name": "unregprod", "type": "unregprod", "ricardian_contract": "" - },{ + },{ "name": "regproxy", "type": "regproxy", "ricardian_contract": "" - },{ + },{ "name": "voteproducer", "type": "voteproducer", "ricardian_contract": "" - },{ + },{ "name": "claimrewards", "type": "claimrewards", "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - } - ], - "tables": [{ + },{ + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" + }], + "tables": [{ "name": "producers", "type": "producer_info", "index_type": "i64", @@ -308,6 +467,7 @@ "key_names" : ["owner"], "key_types" : ["uint64"] } - ], - "ricardian_clauses": [] + ], + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/enumivo.system/producer_pay.cpp b/contracts/enumivo.system/producer_pay.cpp index 7286ddd1a2f..d71a6a99228 100644 --- a/contracts/enumivo.system/producer_pay.cpp +++ b/contracts/enumivo.system/producer_pay.cpp @@ -4,8 +4,8 @@ namespace enumivosystem { - const int64_t min_daily_tokens = 100; - + const int64_t min_daily_tokens = 100; + const int64_t min_activated_stake = 150'000'000'0000; const double continuous_rate = 0.04879; // 5% annual rate const double perblock_rate = 0.0025; // 0.25% const double standby_rate = 0.0075; // 0.75% @@ -23,7 +23,7 @@ namespace enumivosystem { require_auth(N(enumivo)); /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 150'000'000'0000 ) + if( _gstate.total_activated_stake < min_activated_stake ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses @@ -55,6 +55,8 @@ namespace enumivosystem { const auto& prod = _producers.get( owner ); enumivo_assert( prod.active(), "producer does not have an active key" ); + + enumivo_assert( _gstate.total_activated_stake >= min_activated_stake, "not enough has been staked for producers to claim rewards" ); auto ct = current_time(); @@ -81,8 +83,14 @@ namespace enumivosystem { _gstate.last_pervote_bucket_fill = ct; } - int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; - int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + int64_t producer_per_block_pay = 0; + if( _gstate.total_unpaid_blocks > 0 ) { + producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; + } + int64_t producer_per_vote_pay = 0; + if( _gstate.total_producer_vote_weight > 0 ) { + producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + } if( producer_per_vote_pay < 100'0000 ) { producer_per_vote_pay = 0; } diff --git a/contracts/enumivolib/types.h b/contracts/enumivolib/types.h index c50d2c84300..9218e39f7ad 100644 --- a/contracts/enumivolib/types.h +++ b/contracts/enumivolib/types.h @@ -26,13 +26,12 @@ typedef uint64_t table_name; typedef uint32_t time; typedef uint64_t scope_name; typedef uint64_t action_name; -typedef uint16_t region_id; typedef uint64_t asset_symbol; typedef int64_t share_type; typedef uint16_t weight_type; -/* macro to align/overalign a type to ensure calls to intrinsics with pointers/references are properly aligned */ +/* macro to align/overalign a type to ensure calls to intrinsics with pointers/references are properly aligned */ #define ALIGNED(X) __attribute__ ((aligned (16))) X struct public_key { @@ -55,23 +54,9 @@ struct ALIGNED(checksum512) { uint8_t hash[64]; }; -struct fixed_string16 { - uint8_t len; - char str[16]; -}; - typedef struct checksum256 transaction_id_type; typedef struct checksum256 block_id_type; -typedef struct fixed_string16 field_name; - -struct fixed_string32 { - uint8_t len; - char str[32]; -}; - -typedef struct fixed_string32 type_name; - struct account_permission { account_name account; permission_name permission; diff --git a/contracts/exchange/exchange.abi b/contracts/exchange/exchange.abi index 5481c8cef70..88c7d40228a 100644 --- a/contracts/exchange/exchange.abi +++ b/contracts/exchange/exchange.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "account_name", "type": "name" @@ -160,5 +161,6 @@ "key_types" : ["uint64"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/identity/identity.abi b/contracts/identity/identity.abi index c9e1605efd3..aec51f05d06 100644 --- a/contracts/identity/identity.abi +++ b/contracts/identity/identity.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "account_name", "type": "name" @@ -112,5 +113,6 @@ "key_types": [ "account_name" ] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/multi_index_test/multi_index_test.abi b/contracts/multi_index_test/multi_index_test.abi index 3eafc1c1cd1..d1657892ed0 100644 --- a/contracts/multi_index_test/multi_index_test.abi +++ b/contracts/multi_index_test/multi_index_test.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [], "structs": [{ "name": "trigger", @@ -15,5 +16,6 @@ } ], "tables": [], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/noop/noop.abi b/contracts/noop/noop.abi index 323cc24ab0b..716ea4991ba 100644 --- a/contracts/noop/noop.abi +++ b/contracts/noop/noop.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "account_name", "type": "name" @@ -21,5 +22,6 @@ } ], "tables": [], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/proxy/proxy.abi b/contracts/proxy/proxy.abi index 0449aaf852d..132fffaa212 100644 --- a/contracts/proxy/proxy.abi +++ b/contracts/proxy/proxy.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "account_name", "type": "name" @@ -35,5 +36,6 @@ "key_types" : ["name"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/stltest/stltest.abi b/contracts/stltest/stltest.abi index 69f33e29c71..31b6b89791a 100644 --- a/contracts/stltest/stltest.abi +++ b/contracts/stltest/stltest.abi @@ -1,4 +1,5 @@ { + "version": "enumivo::abi/1.0", "types": [{ "new_type_name": "my_account_name", "type": "name" @@ -41,5 +42,6 @@ "key_types" : ["my_account_name"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/contracts/tic_tac_toe/tic_tac_toe.abi b/contracts/tic_tac_toe/tic_tac_toe.abi index 6f2bb8ec17d..c9bcc3f4ded 100644 --- a/contracts/tic_tac_toe/tic_tac_toe.abi +++ b/contracts/tic_tac_toe/tic_tac_toe.abi @@ -1,5 +1,9 @@ { - "types": [], + "version": "enumivo::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + }], "structs": [{ "name": "game", "base": "", @@ -76,5 +80,6 @@ "key_types" : ["account_name"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } diff --git a/libraries/abi_generator/abi_generator.cpp b/libraries/abi_generator/abi_generator.cpp index 6103dc6f1f3..0749ee98899 100644 --- a/libraries/abi_generator/abi_generator.cpp +++ b/libraries/abi_generator/abi_generator.cpp @@ -9,7 +9,7 @@ void abi_generator::set_target_contract(const string& contract, const vectorcompiler_instance = &compiler_instance; } -void abi_generator::handle_tagdecl_definition(TagDecl* tag_decl) { +void abi_generator::handle_tagdecl_definition(TagDecl* tag_decl) { ast_context = &tag_decl->getASTContext(); auto decl_location = tag_decl->getLocation().printToString(ast_context->getSourceManager()); - try { + try { handle_decl(tag_decl); } FC_CAPTURE_AND_RETHROW((decl_location)) } @@ -71,7 +71,7 @@ string abi_generator::translate_type(const string& type_name) { string built_in_type = type_name; if (type_name == "unsigned __int128" || type_name == "uint128_t") built_in_type = "uint128"; - else if (type_name == "__int128" || type_name == "int128_t") built_in_type = "unt128"; + else if (type_name == "__int128" || type_name == "int128_t") built_in_type = "int128"; else if (type_name == "unsigned long long" || type_name == "uint64_t") built_in_type = "uint64"; else if (type_name == "unsigned long" || type_name == "uint32_t") built_in_type = "uint32"; @@ -118,7 +118,7 @@ bool abi_generator::inspect_type_methods_for_actions(const Decl* decl) { try { string field_type_name = add_type(qt); field_def struct_field{field_name, field_type_name}; - ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) + ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) || find_struct(get_vector_element_type(struct_field.type)) || find_type(get_vector_element_type(struct_field.type)) , "Unknown type ${type} [${abi}]",("type",struct_field.type)("abi",*output)); @@ -228,7 +228,7 @@ void abi_generator::handle_decl(const Decl* decl) { try { auto qt = action_decl->getTypeForDecl()->getCanonicalTypeInternal(); auto type_name = add_struct(qt); - ABI_ASSERT(!is_builtin_type(type_name), + ABI_ASSERT(!is_builtin_type(type_name), "A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name)); if(params.size()==0) { @@ -236,7 +236,7 @@ void abi_generator::handle_decl(const Decl* decl) { try { } for(const auto& action : params) { - const auto* ac = find_action(action); + const auto* ac = find_action(action); if( ac ) { ABI_ASSERT(ac->type == type_name, "Same action name with different type ${action}",("action",action)); continue; @@ -252,7 +252,7 @@ void abi_generator::handle_decl(const Decl* decl) { try { auto qt = table_decl->getTypeForDecl()->getCanonicalTypeInternal(); auto type_name = add_struct(qt); - ABI_ASSERT(!is_builtin_type(type_name), + ABI_ASSERT(!is_builtin_type(type_name), "A built-in type with the same name exists, try using another name: ${type_name}", ("type_name",type_name)); const auto* s = find_struct(type_name); @@ -279,7 +279,7 @@ void abi_generator::handle_decl(const Decl* decl) { try { //TODO: assert that we are adding the same table const auto* ta = find_table(table.name); if(!ta) { - output->tables.push_back(table); + output->tables.push_back(table); } } } @@ -354,7 +354,7 @@ void abi_generator::guess_key_names(table_def& table, const struct_def s) { vector fields; get_all_fields(s, fields); - if( table.index_type == "i64i64i64" || table.index_type == "i128i128" + if( table.index_type == "i64i64i64" || table.index_type == "i128i128" || table.index_type == "i64") { table.key_names.clear(); @@ -448,7 +448,7 @@ bool abi_generator::is_typedef(const clang::QualType& qt) { } bool abi_generator::is_elaborated(const clang::QualType& qt) { - return isa(qt.getTypePtr()); + return isa(qt.getTypePtr()); } bool abi_generator::is_vector(const clang::QualType& vqt) { @@ -480,7 +480,7 @@ clang::QualType abi_generator::get_vector_element_type(const clang::QualType& qt const auto* tst = clang::dyn_cast(qt.getTypePtr()); ABI_ASSERT(tst != nullptr); const clang::TemplateArgument& arg0 = tst->getArg(0); - return arg0.getAsType(); + return arg0.getAsType(); } string abi_generator::get_vector_element_type(const string& type_name) { @@ -491,7 +491,7 @@ string abi_generator::get_vector_element_type(const string& type_name) { string abi_generator::get_type_name(const clang::QualType& qt, bool with_namespace=false) { auto name = clang::TypeName::getFullyQualifiedName(qt, *ast_context); - if(!with_namespace) + if(!with_namespace) name = remove_namespace(name); return name; } @@ -571,7 +571,7 @@ string abi_generator::add_vector(const clang::QualType& vqt) { auto vector_element_type_str = translate_type(get_type_name(vector_element_type)); vector_element_type_str += "[]"; - return vector_element_type_str; + return vector_element_type_str; } string abi_generator::add_type(const clang::QualType& tqt) { @@ -658,7 +658,7 @@ string abi_generator::add_struct(const clang::QualType& sqt, string full_name) { string field_type_name = add_type(qt); field_def struct_field{field_name, field_type_name}; - ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) + ABI_ASSERT(is_builtin_type(get_vector_element_type(struct_field.type)) || find_struct(get_vector_element_type(struct_field.type)) || find_type(get_vector_element_type(struct_field.type)) , "Unknown type ${type} [${abi}]",("type",struct_field.type)("abi",*output)); diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index c8ba50aaebc..32b53389680 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include using namespace boost; @@ -54,55 +53,46 @@ namespace enumivo { namespace chain { } void abi_serializer::configure_built_in_types() { - //public_key.hpp - built_in_types.emplace("public_key", pack_unpack()); - - //symbol.hpp - built_in_types.emplace("symbol", pack_unpack()); - built_in_types.emplace("symbol_code", pack_unpack()); - - //asset.hpp - built_in_types.emplace("asset", pack_unpack()); - built_in_types.emplace("extended_asset", pack_unpack()); - //native.hpp - built_in_types.emplace("string", pack_unpack()); - built_in_types.emplace("clause_pair", pack_unpack()); - built_in_types.emplace("time_point", pack_unpack()); - built_in_types.emplace("time_point_sec", pack_unpack()); - built_in_types.emplace("block_timestamp_type", pack_unpack()); - built_in_types.emplace("signature", pack_unpack()); - built_in_types.emplace("checksum160", pack_unpack()); - built_in_types.emplace("checksum256", pack_unpack()); - built_in_types.emplace("checksum512", pack_unpack()); - built_in_types.emplace("transaction_id_type", pack_unpack()); - built_in_types.emplace("field_name", pack_unpack()); - built_in_types.emplace("fixed_string32", pack_unpack()); - built_in_types.emplace("fixed_string16", pack_unpack()); - built_in_types.emplace("type_name", pack_unpack()); - built_in_types.emplace("bytes", pack_unpack()); - built_in_types.emplace("uint128", pack_unpack()); - built_in_types.emplace("uint256", pack_unpack()); - built_in_types.emplace("varuint32", pack_unpack()); built_in_types.emplace("bool", pack_unpack()); built_in_types.emplace("int8", pack_unpack()); - built_in_types.emplace("int16", pack_unpack()); - built_in_types.emplace("int32", pack_unpack()); - built_in_types.emplace("int64", pack_unpack()); built_in_types.emplace("uint8", pack_unpack()); + built_in_types.emplace("int16", pack_unpack()); built_in_types.emplace("uint16", pack_unpack()); + built_in_types.emplace("int32", pack_unpack()); built_in_types.emplace("uint32", pack_unpack()); + built_in_types.emplace("int64", pack_unpack()); built_in_types.emplace("uint64", pack_unpack()); + built_in_types.emplace("int128", pack_unpack()); + built_in_types.emplace("uint128", pack_unpack()); built_in_types.emplace("varint32", pack_unpack()); + built_in_types.emplace("varuint32", pack_unpack()); + + // TODO: Add proper support for floating point types. For now this is good enough. + built_in_types.emplace("float32", pack_unpack()); built_in_types.emplace("float64", pack_unpack()); + built_in_types.emplace("float128", pack_unpack()); + + built_in_types.emplace("time_point", pack_unpack()); + built_in_types.emplace("time_point_sec", pack_unpack()); + built_in_types.emplace("block_timestamp_type", pack_unpack()); + built_in_types.emplace("name", pack_unpack()); - built_in_types.emplace("account_name", pack_unpack()); - built_in_types.emplace("permission_name", pack_unpack()); - built_in_types.emplace("action_name", pack_unpack()); - built_in_types.emplace("scope_name", pack_unpack()); - built_in_types.emplace("permission_level", pack_unpack()); - built_in_types.emplace("producer_schedule", pack_unpack()); - built_in_types.emplace("newaccount", pack_unpack()); + + built_in_types.emplace("bytes", pack_unpack()); + built_in_types.emplace("string", pack_unpack()); + + built_in_types.emplace("checksum160", pack_unpack()); + built_in_types.emplace("checksum256", pack_unpack()); + built_in_types.emplace("checksum512", pack_unpack()); + + built_in_types.emplace("public_key", pack_unpack()); + built_in_types.emplace("signature", pack_unpack()); + + built_in_types.emplace("symbol", pack_unpack()); + built_in_types.emplace("symbol_code", pack_unpack()); + built_in_types.emplace("asset", pack_unpack()); + built_in_types.emplace("extended_asset", pack_unpack()); } void abi_serializer::set_abi(const abi_def& abi) { diff --git a/libraries/chain/asset.cpp b/libraries/chain/asset.cpp index 7afde564e80..0b38e9dd3c1 100644 --- a/libraries/chain/asset.cpp +++ b/libraries/chain/asset.cpp @@ -4,11 +4,9 @@ */ #include #include -#include #include namespace enumivo { namespace chain { -typedef boost::multiprecision::int128_t int128_t; uint8_t asset::decimals()const { return sym.decimals(); diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 26eec707f09..9cd0eb004e5 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ struct pending_state { struct controller_impl { controller& self; chainbase::database db; + chainbase::database unconfirmed_blocks; ///< a special database to persist blocks that have successfully been applied but are still reversible block_log blog; optional pending; block_state_ptr head; @@ -69,10 +71,17 @@ struct controller_impl { void pop_block() { auto prev = fork_db.get_block( head->header.previous ); FC_ASSERT( prev, "attempt to pop beyond last irreversible block" ); + + if( const auto* b = unconfirmed_blocks.find(head->block_num) ) + { + unconfirmed_blocks.remove( *b ); + } + for( const auto& t : head->trxs ) unapplied_transactions[t->signed_id] = t; head = prev; db.undo(); + } @@ -85,6 +94,9 @@ struct controller_impl { db( cfg.shared_memory_dir, cfg.read_only ? database::read_only : database::read_write, cfg.shared_memory_size ), + unconfirmed_blocks( cfg.block_log_dir/"unconfirmed", + cfg.read_only ? database::read_only : database::read_write, + cfg.unconfirmed_cache_size ), blog( cfg.block_log_dir ), fork_db( cfg.shared_memory_dir ), wasmif( cfg.wasm_runtime ), @@ -130,8 +142,10 @@ struct controller_impl { void emit( const Signal& s, Arg&& a ) { try { s(std::forward(a)); + } catch ( fc::exception& e ) { + wlog( "${details}", ("details", e.to_detail_string()) ); } catch ( ... ) { - elog( "signal handler threw exception" ); + wlog( "signal handler threw exception" ); } } @@ -143,18 +157,25 @@ struct controller_impl { FC_ASSERT( log_head ); auto lh_block_num = log_head->block_num(); - if( s->block_num - 1 == lh_block_num ) { - FC_ASSERT( s->block->previous == log_head->id(), "irreversible doesn't link to block log head" ); - blog.append( s->block ); - } else if( s->block_num -1 > lh_block_num ) { - wlog( "skipped blocks..." ); - edump((s->block_num)(log_head->block_num())); - if( s->block_num == log_head->block_num() ) { - FC_ASSERT( s->id == log_head->id(), "", ("s->id",s->id)("hid",log_head->id()) ); - } + if( s->block_num <= lh_block_num ) { +// edump((s->block_num)("double call to on_irr")); +// edump((s->block_num)(s->block->previous)(log_head->id())); + return; } + + FC_ASSERT( s->block_num - 1 == lh_block_num, "unlinkable block", ("s->block_num",s->block_num)("lh_block_num", lh_block_num) ); + FC_ASSERT( s->block->previous == log_head->id(), "irreversible doesn't link to block log head" ); + blog.append(s->block); + emit( self.irreversible_block, s ); db.commit( s->block_num ); + + const auto& ubi = unconfirmed_blocks.get_index(); + auto objitr = ubi.begin(); + while( objitr != ubi.end() && objitr->blocknum <= s->block_num ) { + unconfirmed_blocks.remove( *objitr ); + objitr = ubi.begin(); + } } void init() { @@ -174,17 +195,20 @@ struct controller_impl { db.undo(); } + uint32_t unconf_blocknum = 1; + const auto& ubi = unconfirmed_blocks.get_index(); + auto objitr = ubi.rbegin(); + if( objitr != ubi.rend() ) { + unconf_blocknum = objitr->blocknum; + } + FC_ASSERT( db.revision() == head->block_num, "fork database is inconsistent with shared memory", - ("db",db.revision())("head",head->block_num) ); + ("db",db.revision())("head",head->block_num)("unconfimed",unconf_blocknum) ); + + edump((unconf_blocknum)); + FC_ASSERT( head->block_num == unconf_blocknum, "unconfirmed block database out of sync", + ("db",db.revision())("head",head->block_num)("unconfimed",unconf_blocknum) ); - /** - * The undoable state contains state transitions from blocks - * in the fork database that could be reversed. Because this - * is a new startup and the fork database is empty, we must - * unwind that pending state. This state will be regenerated - * when we catch up to the head block later. - */ - //clear_all_undo(); } ~controller_impl() { @@ -194,9 +218,12 @@ struct controller_impl { edump((db.revision())(head->block_num)(blog.read_head()->block_num())); db.flush(); + unconfirmed_blocks.flush(); } void add_indices() { + unconfirmed_blocks.add_index(); + db.add_index(); db.add_index(); @@ -265,9 +292,19 @@ struct controller_impl { std::cerr << std::setw(10) << next->block_num() << " of " << end->block_num() <<"\r"; } } + + int unconf = 0; + while( auto obj = unconfirmed_blocks.find(head->block_num+1) ) { + ++unconf; + self.push_block( obj->get_block(), true ); + } + std::cerr<< "\n"; + ilog( "${n} unconfirmed blocks replayed", ("n",unconf) ); auto end = fc::time_point::now(); - ilog( "replayed blocks in ${n} seconds, ${spb} spb", ("n", (end-start).count()/1000000.0)("spb", ((end-start).count()/1000000.0)/head->block_num) ); + ilog( "replayed blocks in ${n} seconds, ${spb} spb", + ("n", head->block_num)("spb", ((end-start).count()/1000000.0)/head->block_num) ); + std::cerr<< "\n"; replaying = false; } else if( !end ) { @@ -354,14 +391,22 @@ struct controller_impl { emit( self.accepted_block_header, pending->_pending_block_state ); head = fork_db.head(); FC_ASSERT( new_bsp == head, "committed block did not become the new head in fork database" ); + } // ilog((fc::json::to_pretty_string(*pending->_pending_block_state->block))); emit( self.accepted_block, pending->_pending_block_state ); + + if( !replaying ) { + unconfirmed_blocks.create( [&]( auto& ubo ) { + ubo.blocknum = pending->_pending_block_state->block_num; + ubo.set_block( pending->_pending_block_state->block ); + }); + } + pending->push(); pending.reset(); - self.log_irreversible_blocks(); } // The returned scoped_exit should not exceed the lifetime of the pending which existed when make_block_restore_point was called. @@ -1059,7 +1104,6 @@ void controller::abort_block() { void controller::push_block( const signed_block_ptr& b, bool trust ) { my->push_block( b, trust ); - log_irreversible_blocks(); } void controller::push_confirmation( const header_confirmation& c ) { @@ -1125,47 +1169,6 @@ const global_property_object& controller::get_global_properties()const { return my->db.get(); } -/** - * This method reads the current dpos_irreverible block number, if it is higher - * than the last block number of the log, it grabs the next block from the - * fork database, saves it to disk, then removes the block from the fork database. - * - * Any forks built off of a different block with the same number are also pruned. - */ -void controller::log_irreversible_blocks() { - /* - if( !my->blog.head() ) - my->blog.read_head(); - - const auto& log_head = my->blog.head(); - auto lib = my->head->dpos_irreversible_blocknum; - - - if( lib > 2 ) { - if( log_head && log_head->block_num() > lib ) { - auto blk = my->fork_db.get_block_in_current_chain_by_num( lib - 1 ); - FC_ASSERT( blk, "unable to find block state", ("block_num",lib-1)); - my->fork_db.prune( blk ); - my->db.commit( lib -1 ); - return; - } - - while( log_head && (log_head->block_num()+1) < lib ) { - auto lhead = log_head->block_num(); - auto blk = my->fork_db.get_block_in_current_chain_by_num( lhead + 1 ); - FC_ASSERT( blk, "unable to find block state", ("block_num",lhead+1)); - irreversible_block( blk ); - - if( !my->replaying ) { - my->blog.append( blk->block ); - } - - my->fork_db.prune( blk ); - my->db.commit( lhead ); - } - } - */ -} signed_block_ptr controller::fetch_block_by_id( block_id_type id )const { auto state = my->fork_db.get_block(id); if( state ) return state->block; diff --git a/libraries/chain/enumivo_contract.cpp b/libraries/chain/enumivo_contract.cpp index 586ef3a6543..7d8fbbd980e 100644 --- a/libraries/chain/enumivo_contract.cpp +++ b/libraries/chain/enumivo_contract.cpp @@ -146,17 +146,18 @@ void apply_enumivo_setcode(apply_context& context) { db.modify( account, [&]( auto& a ) { /** TODO: consider whether a microsecond level local timestamp is sufficient to detect code version changes*/ #warning TODO: update setcode message to include the hash, then validate it in validate + a.last_code_update = context.control.pending_block_time(); a.code_version = code_id; a.code.resize( code_size ); - a.last_code_update = context.control.pending_block_time(); - memcpy( a.code.data(), act.code.data(), code_size ); + if( code_size > 0 ) + memcpy( a.code.data(), act.code.data(), code_size ); }); const auto& account_sequence = db.get(act.account); db.modify( account_sequence, [&]( auto& aso ) { aso.code_sequence += 1; - }); + }); if (new_size != old_size) { context.trx_context.add_ram_usage( act.account, new_size - old_size ); @@ -169,29 +170,23 @@ void apply_enumivo_setabi(apply_context& context) { context.require_authorization(act.account); - // if system account append native abi - if ( act.account == enumivo::chain::config::system_account_name ) { - act.abi = enumivo_contract_abi(act.abi); - } - /// if an ABI is specified make sure it is well formed and doesn't - /// reference any undefined types - abi_serializer(act.abi).validate(); - // todo: figure out abi serialization location - const auto& account = db.get(act.account); - int64_t old_size = (int64_t)account.abi.size(); - int64_t new_size = (int64_t)fc::raw::pack_size(act.abi); + int64_t abi_size = act.abi.size(); + int64_t old_size = (int64_t)account.abi.size(); + int64_t new_size = abi_size; db.modify( account, [&]( auto& a ) { - a.set_abi( act.abi ); + a.abi.resize( abi_size ); + if( abi_size > 0 ) + memcpy( a.abi.data(), act.abi.data(), abi_size ); }); const auto& account_sequence = db.get(act.account); db.modify( account_sequence, [&]( auto& aso ) { aso.abi_sequence += 1; - }); + }); if (new_size != old_size) { context.trx_context.add_ram_usage( act.account, new_size - old_size ); @@ -359,16 +354,6 @@ void apply_enumivo_unlinkauth(apply_context& context) { db.remove(*link); } -static const abi_serializer& get_abi_serializer() { - static optional _abi_serializer; - if (!_abi_serializer) { - _abi_serializer.emplace(enumivo_contract_abi(abi_def())); - } - - return *_abi_serializer; -} - - void apply_enumivo_canceldelay(apply_context& context) { auto cancel = context.act.data_as(); context.require_authorization(cancel.canceling_auth.actor); // only here to mark the single authority on this action as used diff --git a/libraries/chain/enumivo_contract_abi.cpp b/libraries/chain/enumivo_contract_abi.cpp index 14b65e48313..90dae9c5584 100644 --- a/libraries/chain/enumivo_contract_abi.cpp +++ b/libraries/chain/enumivo_contract_abi.cpp @@ -1,159 +1,24 @@ -#include +#include namespace enumivo { namespace chain { abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi) { abi_def eos_abi(enumivo_system_abi); - eos_abi.types.push_back( type_def{"account_name","name"} ); - eos_abi.types.push_back( type_def{"table_name","name"} ); - eos_abi.types.push_back( type_def{"share_type","int64"} ); - eos_abi.types.push_back( type_def{"context_free_type","bytes"} ); - eos_abi.types.push_back( type_def{"weight_type","uint16"} ); - eos_abi.types.push_back( type_def{"fields","field[]"} ); - // TODO add ricardian contracts - eos_abi.actions.push_back( action_def{name("setcode"), "setcode",""} ); - eos_abi.actions.push_back( action_def{name("setabi"), "setabi",""} ); - eos_abi.actions.push_back( action_def{name("linkauth"), "linkauth",""} ); - eos_abi.actions.push_back( action_def{name("unlinkauth"), "unlinkauth",""} ); - eos_abi.actions.push_back( action_def{name("updateauth"), "updateauth",""} ); - eos_abi.actions.push_back( action_def{name("deleteauth"), "deleteauth",""} ); - eos_abi.actions.push_back( action_def{name("newaccount"), "newaccount",""} ); - eos_abi.actions.push_back( action_def{name("postrecovery"), "postrecovery",""} ); - eos_abi.actions.push_back( action_def{name("passrecovery"), "passrecovery",""} ); - eos_abi.actions.push_back( action_def{name("vetorecovery"), "vetorecovery",""} ); - eos_abi.actions.push_back( action_def{name("onerror"), "onerror",""} ); - eos_abi.actions.push_back( action_def{name("onblock"), "onblock",""} ); - eos_abi.actions.push_back( action_def{name("canceldelay"), "canceldelay",""} ); - - // TODO add any ricardian_clauses - // - // ACTION PAYLOADS - - - eos_abi.structs.emplace_back( struct_def { - "setcode", "", { - {"account", "account_name"}, - {"vmtype", "uint8"}, - {"vmversion", "uint8"}, - {"code", "bytes"} - } - }); - - eos_abi.structs.emplace_back( struct_def { - "setabi", "", { - {"account", "account_name"}, - {"abi", "abi_def"} - } - }); - - eos_abi.structs.emplace_back( struct_def { - "updateauth", "", { - {"account", "account_name"}, - {"permission", "permission_name"}, - {"parent", "permission_name"}, - {"auth", "authority"} - } - }); - - eos_abi.structs.emplace_back( struct_def { - "linkauth", "", { - {"account", "account_name"}, - {"code", "account_name"}, - {"type", "action_name"}, - {"requirement", "permission_name"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "unlinkauth", "", { - {"account", "account_name"}, - {"code", "account_name"}, - {"type", "action_name"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "deleteauth", "", { - {"account", "account_name"}, - {"permission", "permission_name"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "newaccount", "", { - {"creator", "account_name"}, - {"name", "account_name"}, - {"owner", "authority"}, - {"active", "authority"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "postrecovery", "", { - {"account", "account_name"}, - {"auth", "authority"}, - {"memo", "string"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "passrecovery", "", { - {"account", "account_name"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "vetorecovery", "", { - {"account", "account_name"}, - } - }); - - eos_abi.structs.emplace_back( struct_def { - "canceldelay", "", { - {"canceling_auth", "permission_level"}, - {"trx_id", "transaction_id_type"}, - } - }); - - // DATABASE RECORDS - - eos_abi.structs.emplace_back( struct_def { - "pending_recovery", "", { - {"account", "name"}, - {"request_id", "uint128"}, - {"update", "updateauth"}, - {"memo", "string"} - } - }); + if( eos_abi.version.size() == 0 ) { + eos_abi.version = "enumivo::abi/1.0"; + } - eos_abi.tables.emplace_back( table_def { - "recovery", "i64", { - "account", - }, { - "name" - }, - "pending_recovery" - }); - - // abi_def fields - - eos_abi.structs.emplace_back( struct_def { - "field", "", { - {"name", "field_name"}, - {"type", "type_name"} - } - }); - - eos_abi.structs.emplace_back( struct_def { - "struct_def", "", { - {"name", "type_name"}, - {"base", "type_name"}, - {"fields", "fields"} - } - }); + eos_abi.types.push_back( type_def{"account_name", "name"} ); + eos_abi.types.push_back( type_def{"permission_name", "name"} ); + eos_abi.types.push_back( type_def{"action_name", "name"} ); + eos_abi.types.push_back( type_def{"table_name", "name"} ); + eos_abi.types.push_back( type_def{"transaction_id_type", "checksum256"} ); + eos_abi.types.push_back( type_def{"block_id_type", "checksum256"} ); + eos_abi.types.push_back( type_def{"weight_type", "uint16"} ); + // transaction eos_abi.structs.emplace_back( struct_def { "permission_level", "", { {"actor", "account_name"}, @@ -170,6 +35,13 @@ abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi) } }); + eos_abi.structs.emplace_back( struct_def { + "extension", "", { + {"type", "uint16"}, + {"data", "bytes"} + } + }); + eos_abi.structs.emplace_back( struct_def { "transaction_header", "", { {"expiration", "time_point_sec"}, @@ -184,17 +56,42 @@ abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi) eos_abi.structs.emplace_back( struct_def { "transaction", "transaction_header", { {"context_free_actions", "action[]"}, - {"actions", "action[]"} + {"actions", "action[]"}, + {"transaction_extensions", "extension[]"} + } + }); + + // block_header + + eos_abi.structs.emplace_back( struct_def { + "producer_key", "", { + {"producer_name", "account_name"}, + {"block_signing_key", "public_key"} + } + }); + + eos_abi.structs.emplace_back( struct_def { + "producer_schedule", "", { + {"version", "uint32"}, + {"producers", "producer_key[]"} } }); eos_abi.structs.emplace_back( struct_def { - "signed_transaction", "transaction", { - {"signatures", "signature[]"}, - {"context_free_data", "bytes[]"} + "block_header", "", { + {"timestamp", "uint32"}, + {"producer", "account_name"}, + {"confirmed", "uint16"}, + {"previous", "block_id_type"}, + {"transaction_mroot", "checksum256"}, + {"action_mroot", "checksum256"}, + {"schedule_version", "uint32"}, + {"new_producers", "producer_schedule?"}, + {"header_extensions", "extension[]"} } }); + // authority eos_abi.structs.emplace_back( struct_def { "key_weight", "", { {"key", "public_key"}, @@ -225,63 +122,72 @@ abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi) } }); + // TODO add any ricardian_clauses + // + // ACTION PAYLOADS + eos_abi.structs.emplace_back( struct_def { - "clause_pair", "", { - {"id", "string"}, - {"body", "string"} - } + "newaccount", "", { + {"creator", "account_name"}, + {"name", "account_name"}, + {"owner", "authority"}, + {"active", "authority"}, + } }); + eos_abi.structs.emplace_back( struct_def { - "type_def", "", { - {"new_type_name", "type_name"}, - {"type", "type_name"} + "setcode", "", { + {"account", "account_name"}, + {"vmtype", "uint8"}, + {"vmversion", "uint8"}, + {"code", "bytes"} } }); eos_abi.structs.emplace_back( struct_def { - "action_def", "", { - {"name", "action_name"}, - {"type", "type_name"}, - {"ricardian_contract", "string"} + "setabi", "", { + {"account", "account_name"}, + {"abi", "bytes"} + } + }); + + eos_abi.structs.emplace_back( struct_def { + "updateauth", "", { + {"account", "account_name"}, + {"permission", "permission_name"}, + {"parent", "permission_name"}, + {"auth", "authority"} } }); eos_abi.structs.emplace_back( struct_def { - "table_def", "", { - {"name", "table_name"}, - {"index_type", "type_name"}, - {"key_names", "field_name[]"}, - {"key_types", "type_name[]"}, - {"type", "type_name"} + "deleteauth", "", { + {"account", "account_name"}, + {"permission", "permission_name"}, } }); eos_abi.structs.emplace_back( struct_def { - "abi_def", "", { - {"types", "type_def[]"}, - {"structs", "struct_def[]"}, - {"actions", "action_def[]"}, - {"tables", "table_def[]"}, - {"ricardian_clauses", "clause_pair[]"} + "linkauth", "", { + {"account", "account_name"}, + {"code", "account_name"}, + {"type", "action_name"}, + {"requirement", "permission_name"}, } }); eos_abi.structs.emplace_back( struct_def { - "block_header", "", { - {"previous", "checksum256"}, - {"timestamp", "uint32"}, - {"transaction_mroot", "checksum256"}, - {"action_mroot", "checksum256"}, - {"block_mroot", "checksum256"}, - {"producer", "account_name"}, - {"schedule_version", "uint32"}, - {"new_producers", "producer_schedule?"} + "unlinkauth", "", { + {"account", "account_name"}, + {"code", "account_name"}, + {"type", "action_name"}, } }); eos_abi.structs.emplace_back( struct_def { - "onblock", "", { - {"header", "block_header"} + "canceldelay", "", { + {"canceling_auth", "permission_level"}, + {"trx_id", "transaction_id_type"}, } }); @@ -292,6 +198,25 @@ abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi) } }); + eos_abi.structs.emplace_back( struct_def { + "onblock", "", { + {"header", "block_header"} + } + }); + + // TODO add ricardian contracts + eos_abi.actions.push_back( action_def{name("newaccount"), "newaccount",""} ); + eos_abi.actions.push_back( action_def{name("setcode"), "setcode",""} ); + eos_abi.actions.push_back( action_def{name("setabi"), "setabi",""} ); + eos_abi.actions.push_back( action_def{name("updateauth"), "updateauth",""} ); + eos_abi.actions.push_back( action_def{name("deleteauth"), "deleteauth",""} ); + eos_abi.actions.push_back( action_def{name("linkauth"), "linkauth",""} ); + eos_abi.actions.push_back( action_def{name("unlinkauth"), "unlinkauth",""} ); + eos_abi.actions.push_back( action_def{name("canceldelay"), "canceldelay",""} ); + eos_abi.actions.push_back( action_def{name("onerror"), "onerror",""} ); + eos_abi.actions.push_back( action_def{name("onblock"), "onblock",""} ); + return eos_abi; } + } } /// enumivo::chain diff --git a/libraries/chain/include/enumivo/chain/abi_def.hpp b/libraries/chain/include/enumivo/chain/abi_def.hpp new file mode 100644 index 00000000000..25cfad96d65 --- /dev/null +++ b/libraries/chain/include/enumivo/chain/abi_def.hpp @@ -0,0 +1,112 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include + +namespace enumivo { namespace chain { + +using type_name = string; +using field_name = string; + +struct type_def { + type_def() = default; + type_def(const type_name& new_type_name, const type_name& type) + :new_type_name(new_type_name), type(type) + {} + + type_name new_type_name; + type_name type; +}; + +struct field_def { + field_def() = default; + field_def(const field_name& name, const type_name& type) + :name(name), type(type) + {} + + field_name name; + type_name type; + + bool operator==(const field_def& other) const { + return std::tie(name, type) == std::tie(other.name, other.type); + } +}; + +struct struct_def { + struct_def() = default; + struct_def(const type_name& name, const type_name& base, const vector& fields) + :name(name), base(base), fields(fields) + {} + + type_name name; + type_name base; + vector fields; + + bool operator==(const struct_def& other) const { + return std::tie(name, base, fields) == std::tie(other.name, other.base, other.fields); + } +}; + +struct action_def { + action_def() = default; + action_def(const action_name& name, const type_name& type, const string& ricardian_contract) + :name(name), type(type), ricardian_contract(ricardian_contract) + {} + + action_name name; + type_name type; + string ricardian_contract; +}; + +struct table_def { + table_def() = default; + table_def(const table_name& name, const type_name& index_type, const vector& key_names, const vector& key_types, const type_name& type) + :name(name), index_type(index_type), key_names(key_names), key_types(key_types), type(type) + {} + + table_name name; // the name of the table + type_name index_type; // the kind of index, i64, i128i128, etc + vector key_names; // names for the keys defined by key_types + vector key_types; // the type of key parameters + type_name type; // type of binary data stored in this table +}; + +struct clause_pair { + clause_pair() = default; + clause_pair( const string& id, const string& body ) + : id(id), body(body) + {} + + string id; + string body; +}; + +struct abi_def { + abi_def() = default; + abi_def(const vector& types, const vector& structs, const vector& actions, const vector& tables, const vector& clauses) + :version("enumivo::abi/1.0"), types(types), structs(structs), actions(actions), tables(tables), ricardian_clauses(clauses) + {} + + string version; + vector types; + vector structs; + vector actions; + vector tables; + vector ricardian_clauses; + extensions_type abi_extensions; +}; + +abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi); + +} } /// namespace enumivo::chain + +FC_REFLECT( enumivo::chain::type_def , (new_type_name)(type) ) +FC_REFLECT( enumivo::chain::field_def , (name)(type) ) +FC_REFLECT( enumivo::chain::struct_def , (name)(base)(fields) ) +FC_REFLECT( enumivo::chain::action_def , (name)(type)(ricardian_contract) ) +FC_REFLECT( enumivo::chain::clause_pair , (id)(body) ) +FC_REFLECT( enumivo::chain::table_def , (name)(index_type)(key_names)(key_types)(type) ) +FC_REFLECT( enumivo::chain::abi_def , (version)(types)(structs)(actions)(tables)(ricardian_clauses)(abi_extensions) ) diff --git a/libraries/chain/include/enumivo/chain/abi_serializer.hpp b/libraries/chain/include/enumivo/chain/abi_serializer.hpp index 365ef421b0d..a0fd11746a2 100644 --- a/libraries/chain/include/enumivo/chain/abi_serializer.hpp +++ b/libraries/chain/include/enumivo/chain/abi_serializer.hpp @@ -3,7 +3,7 @@ * @copyright defined in enumivo/LICENSE.txt */ #pragma once -#include +#include #include #include #include diff --git a/libraries/chain/include/enumivo/chain/account_object.hpp b/libraries/chain/include/enumivo/chain/account_object.hpp index f2469f362a1..5d0519a816f 100644 --- a/libraries/chain/include/enumivo/chain/account_object.hpp +++ b/libraries/chain/include/enumivo/chain/account_object.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include "multi_index_includes.hpp" diff --git a/libraries/chain/include/enumivo/chain/config.hpp b/libraries/chain/include/enumivo/chain/config.hpp index 42c6d01324a..fa89ca3259b 100644 --- a/libraries/chain/include/enumivo/chain/config.hpp +++ b/libraries/chain/include/enumivo/chain/config.hpp @@ -15,6 +15,7 @@ typedef __uint128_t uint128_t; const static auto default_block_log_dir = "block_log"; const static auto default_shared_memory_dir = "shared_mem"; const static auto default_shared_memory_size = 1*1024*1024*1024ll; +const static auto default_unconfirmed_cache_size = 320*1024*1024ll;/// 1MB * 340 blocks based on 21 producer BFT delay const static uint64_t system_account_name = N(enumivo); const static uint64_t null_account_name = N(enumivo.null); diff --git a/libraries/chain/include/enumivo/chain/contract_types.hpp b/libraries/chain/include/enumivo/chain/contract_types.hpp index 069a9defe21..90a9212d108 100644 --- a/libraries/chain/include/enumivo/chain/contract_types.hpp +++ b/libraries/chain/include/enumivo/chain/contract_types.hpp @@ -5,103 +5,10 @@ #include #include -#include - namespace enumivo { namespace chain { -using fixed_string32 = fc::fixed_string>; -using fixed_string16 = fc::fixed_string<>; -using type_name = string; -using field_name = string; -using table_name = name; using action_name = enumivo::chain::action_name; -struct type_def { - type_def() = default; - type_def(const type_name& new_type_name, const type_name& type) - :new_type_name(new_type_name), type(type) - {} - - type_name new_type_name; - type_name type; -}; - -struct field_def { - field_def() = default; - field_def(const field_name& name, const type_name& type) - :name(name), type(type) - {} - - field_name name; - type_name type; - - bool operator==(const field_def& other) const { - return std::tie(name, type) == std::tie(other.name, other.type); - } -}; - -struct struct_def { - struct_def() = default; - struct_def(const type_name& name, const type_name& base, const vector& fields) - :name(name), base(base), fields(fields) - {} - - type_name name; - type_name base; - vector fields; - - bool operator==(const struct_def& other) const { - return std::tie(name, base, fields) == std::tie(other.name, other.base, other.fields); - } -}; - -struct action_def { - action_def() = default; - action_def(const action_name& name, const type_name& type, const string& ricardian_contract) - :name(name), type(type), ricardian_contract(ricardian_contract) - {} - - action_name name; - type_name type; - string ricardian_contract; -}; - -struct table_def { - table_def() = default; - table_def(const table_name& name, const type_name& index_type, const vector& key_names, const vector& key_types, const type_name& type) - :name(name), index_type(index_type), key_names(key_names), key_types(key_types), type(type) - {} - - table_name name; // the name of the table - type_name index_type; // the kind of index, i64, i128i128, etc - vector key_names; // names for the keys defined by key_types - vector key_types; // the type of key parameters - type_name type; // type of binary data stored in this table -}; - -struct clause_pair { - clause_pair() = default; - clause_pair( const string& id, const string& body ) - : id(id), body(body) - {} - - string id; - string body; -}; - -struct abi_def { - abi_def() = default; - abi_def(const vector& types, const vector& structs, const vector& actions, const vector& tables, const vector& clauses) - :types(types), structs(structs), actions(actions), tables(tables), ricardian_clauses(clauses) - {} - - vector types; - vector structs; - vector actions; - vector tables; - vector ricardian_clauses; -}; - struct newaccount { account_name creator; account_name name; @@ -134,7 +41,7 @@ struct setcode { struct setabi { account_name account; - abi_def abi; + bytes abi; static account_name get_account() { return config::system_account_name; @@ -218,52 +125,43 @@ struct unlinkauth { } }; -struct onerror { - uint128_t sender_id; - bytes sent_trx; - - onerror( uint128_t sid, const char* data, size_t len ) - :sender_id(sid),sent_trx(data,data+len){} +struct canceldelay { + permission_level canceling_auth; + transaction_id_type trx_id; static account_name get_account() { return config::system_account_name; } static action_name get_name() { - return N(onerror); + return N(canceldelay); } }; +struct onerror { + uint128_t sender_id; + bytes sent_trx; -struct canceldelay { - permission_level canceling_auth; - transaction_id_type trx_id; + onerror( uint128_t sid, const char* data, size_t len ) + :sender_id(sid),sent_trx(data,data+len){} static account_name get_account() { return config::system_account_name; } static action_name get_name() { - return N(canceldelay); + return N(onerror); } }; } } /// namespace enumivo::chain -FC_REFLECT( enumivo::chain::type_def , (new_type_name)(type) ) -FC_REFLECT( enumivo::chain::field_def , (name)(type) ) -FC_REFLECT( enumivo::chain::struct_def , (name)(base)(fields) ) -FC_REFLECT( enumivo::chain::action_def , (name)(type)(ricardian_contract) ) -FC_REFLECT( enumivo::chain::clause_pair , (id)(body) ) -FC_REFLECT( enumivo::chain::table_def , (name)(index_type)(key_names)(key_types)(type) ) -FC_REFLECT( enumivo::chain::abi_def , (types)(structs)(actions)(tables)(ricardian_clauses) ) - FC_REFLECT( enumivo::chain::newaccount , (creator)(name)(owner)(active) ) -FC_REFLECT( enumivo::chain::setcode , (account)(vmtype)(vmversion)(code) ) +FC_REFLECT( enumivo::chain::setcode , (account)(vmtype)(vmversion)(code) ) FC_REFLECT( enumivo::chain::setabi , (account)(abi) ) FC_REFLECT( enumivo::chain::updateauth , (account)(permission)(parent)(auth) ) FC_REFLECT( enumivo::chain::deleteauth , (account)(permission) ) FC_REFLECT( enumivo::chain::linkauth , (account)(code)(type)(requirement) ) FC_REFLECT( enumivo::chain::unlinkauth , (account)(code)(type) ) FC_REFLECT( enumivo::chain::canceldelay , (canceling_auth)(trx_id) ) -FC_REFLECT( enumivo::chain::onerror, (sender_id)(sent_trx) ) +FC_REFLECT( enumivo::chain::onerror , (sender_id)(sent_trx) ) diff --git a/libraries/chain/include/enumivo/chain/controller.hpp b/libraries/chain/include/enumivo/chain/controller.hpp index 0ba42c5655e..656ecf1195b 100644 --- a/libraries/chain/include/enumivo/chain/controller.hpp +++ b/libraries/chain/include/enumivo/chain/controller.hpp @@ -36,7 +36,8 @@ namespace enumivo { namespace chain { class controller { public: struct config { - path block_log_dir = chain::config::default_block_log_dir; + path block_log_dir = chain::config::default_block_log_dir; + uint64_t unconfirmed_cache_size = chain::config::default_unconfirmed_cache_size;; path shared_memory_dir = chain::config::default_shared_memory_dir; uint64_t shared_memory_size = chain::config::default_shared_memory_size; bool read_only = false; @@ -96,7 +97,6 @@ namespace enumivo { namespace chain { void finalize_block(); void sign_block( const std::function& signer_callback ); void commit_block(); - void log_irreversible_blocks(); void pop_block(); void push_block( const signed_block_ptr& b, bool trust = false /* does the caller trust the block*/ ); @@ -201,6 +201,7 @@ namespace enumivo { namespace chain { FC_REFLECT( enumivo::chain::controller::config, (block_log_dir) + (unconfirmed_cache_size) (shared_memory_dir)(shared_memory_size)(read_only) (genesis) (wasm_runtime) diff --git a/libraries/chain/include/enumivo/chain/enumivo_contract.hpp b/libraries/chain/include/enumivo/chain/enumivo_contract.hpp index 389e68e9a92..5bf355a25f1 100644 --- a/libraries/chain/include/enumivo/chain/enumivo_contract.hpp +++ b/libraries/chain/include/enumivo/chain/enumivo_contract.hpp @@ -7,7 +7,7 @@ #include #include -namespace enumivo { namespace chain { +namespace enumivo { namespace chain { class apply_context; @@ -32,7 +32,5 @@ namespace enumivo { namespace chain { void apply_enumivo_canceldelay(apply_context&); ///@} end action handlers - - abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi); } } /// namespace enumivo::chain diff --git a/libraries/chain/include/enumivo/chain/eosio_contract.hpp b/libraries/chain/include/enumivo/chain/eosio_contract.hpp deleted file mode 100644 index 389e68e9a92..00000000000 --- a/libraries/chain/include/enumivo/chain/eosio_contract.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @file - * @copyright defined in enumivo/LICENSE.txt - */ -#pragma once - -#include -#include - -namespace enumivo { namespace chain { - - class apply_context; - - /** - * @defgroup native_action_handlers Native Action Handlers - */ - ///@{ - void apply_enumivo_newaccount(apply_context&); - void apply_enumivo_updateauth(apply_context&); - void apply_enumivo_deleteauth(apply_context&); - void apply_enumivo_linkauth(apply_context&); - void apply_enumivo_unlinkauth(apply_context&); - - /* - void apply_enumivo_postrecovery(apply_context&); - void apply_enumivo_passrecovery(apply_context&); - void apply_enumivo_vetorecovery(apply_context&); - */ - - void apply_enumivo_setcode(apply_context&); - void apply_enumivo_setabi(apply_context&); - - void apply_enumivo_canceldelay(apply_context&); - ///@} end action handlers - - abi_def enumivo_contract_abi(const abi_def& enumivo_system_abi); - -} } /// namespace enumivo::chain diff --git a/libraries/chain/include/enumivo/chain/types.hpp b/libraries/chain/include/enumivo/chain/types.hpp index f1e42b8f07b..7e310fcc9a2 100644 --- a/libraries/chain/include/enumivo/chain/types.hpp +++ b/libraries/chain/include/enumivo/chain/types.hpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -102,6 +101,7 @@ namespace enumivo { namespace chain { using scope_name = name; using account_name = name; using permission_name = name; + using table_name = name; /** @@ -150,6 +150,7 @@ namespace enumivo { namespace chain { resource_limits_config_object_type, account_history_object_type, action_history_object_type, + unconfirmed_block_object_type, OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types }; @@ -166,12 +167,13 @@ namespace enumivo { namespace chain { using weight_type = uint16_t; using block_num_type = uint32_t; using share_type = int64_t; - using uint128_t = __uint128_t; + using int128_t = __int128; + using uint128_t = unsigned __int128; using bytes = vector; /** - * Extentions are prefixed with type and are a buffer that can be + * Extentions are prefixed with type and are a buffer that can be * interpreted by code that is aware and ignored by unaware code. */ typedef vector>> extensions_type; @@ -218,6 +220,7 @@ FC_REFLECT_ENUM(enumivo::chain::object_type, (resource_limits_config_object_type) (account_history_object_type) (action_history_object_type) + (unconfirmed_block_object_type) (OBJECT_TYPE_COUNT) ) FC_REFLECT( enumivo::chain::void_t, ) diff --git a/libraries/chain/include/enumivo/chain/unconfirmed_block_object.hpp b/libraries/chain/include/enumivo/chain/unconfirmed_block_object.hpp new file mode 100644 index 00000000000..388eebdcc41 --- /dev/null +++ b/libraries/chain/include/enumivo/chain/unconfirmed_block_object.hpp @@ -0,0 +1,49 @@ + +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once +#include +#include +#include +#include + +#include "multi_index_includes.hpp" + +namespace enumivo { namespace chain { + + class unconfirmed_block_object : public chainbase::object { + OBJECT_CTOR(unconfirmed_block_object,(packedblock) ) + + id_type id; + uint32_t blocknum = 0; + shared_string packedblock; + + void set_block( const signed_block_ptr& b ) { + packedblock.resize( fc::raw::pack_size( *b ) ); + fc::datastream ds( packedblock.data(), packedblock.size() ); + fc::raw::pack( ds, *b ); + } + + signed_block_ptr get_block()const { + fc::datastream ds( packedblock.data(), packedblock.size() ); + auto result = std::make_shared(); + fc::raw::unpack( ds, *result ); + return result; + } + }; + + struct by_num; + using unconfirmed_block_index = chainbase::shared_multi_index_container< + unconfirmed_block_object, + indexed_by< + ordered_unique, member>, + ordered_unique, member> + > + >; + +} } // enumivo::chain + +CHAINBASE_SET_INDEX_TYPE(enumivo::chain::unconfirmed_block_object, enumivo::chain::unconfirmed_block_index) + diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 5e37d81dd9a..49780815b06 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include diff --git a/libraries/fc/include/fc/io/datastream.hpp b/libraries/fc/include/fc/io/datastream.hpp index 07c2da72be7..1ac171e1eb7 100644 --- a/libraries/fc/include/fc/io/datastream.hpp +++ b/libraries/fc/include/fc/io/datastream.hpp @@ -7,7 +7,7 @@ namespace fc { -namespace detail +namespace detail { NO_RETURN void throw_datastream_range_error( const char* file, size_t len, int64_t over ); } @@ -16,7 +16,7 @@ namespace detail * The purpose of this datastream is to provide a fast, effecient, means * of calculating the amount of data "about to be written" and then * writing it. This means having two modes of operation, "test run" where - * you call the entire pack sequence calculating the size, and then + * you call the entire pack sequence calculating the size, and then * actually packing it after doing a single allocation. */ template @@ -24,8 +24,8 @@ class datastream { public: datastream( T start, size_t s ) :_start(start),_pos(start),_end(start+s){}; - - + + inline void skip( size_t s ){ _pos += s; } inline bool read( char* d, size_t s ) { if( size_t(_end - _pos) >= (size_t)s ) { @@ -35,7 +35,7 @@ class datastream { } detail::throw_datastream_range_error( "read", _end-_start, int64_t(-((_end-_pos) - 1))); } - + inline bool write( const char* d, size_t s ) { if( _end - _pos >= (int32_t)s ) { memcpy( _pos, d, s ); @@ -44,27 +44,27 @@ class datastream { } detail::throw_datastream_range_error( "write", _end-_start, int64_t(-((_end-_pos) - 1))); } - - inline bool put(char c) { + + inline bool put(char c) { if( _pos < _end ) { - *_pos = c; - ++_pos; + *_pos = c; + ++_pos; return true; } detail::throw_datastream_range_error( "put", _end-_start, int64_t(-((_end-_pos) - 1))); } - + inline bool get( unsigned char& c ) { return get( *(char*)&c ); } - inline bool get( char& c ) + inline bool get( char& c ) { if( _pos < _end ) { c = *_pos; - ++_pos; + ++_pos; return true; } detail::throw_datastream_range_error( "get", _end-_start, int64_t(-((_end-_pos) - 1))); } - + T pos()const { return _pos; } inline bool valid()const { return _pos <= _end && _pos >= _start; } inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; } @@ -92,26 +92,29 @@ class datastream { }; template -inline datastream& operator<<(datastream& ds, const int32_t& d) { +inline datastream& operator<<(datastream& ds, const __int128& d) { ds.write( (const char*)&d, sizeof(d) ); return ds; } + template -inline datastream& operator>>(datastream& ds, int32_t& d) { +inline datastream& operator>>(datastream& ds, __int128& d) { ds.read((char*)&d, sizeof(d) ); return ds; } + template -inline datastream& operator<<(datastream& ds, const uint32_t& d) { +inline datastream& operator<<(datastream& ds, const unsigned __int128& d) { ds.write( (const char*)&d, sizeof(d) ); return ds; } template -inline datastream& operator>>(datastream& ds, uint32_t& d) { +inline datastream& operator>>(datastream& ds, unsigned __int128& d) { ds.read((char*)&d, sizeof(d) ); return ds; } + template inline datastream& operator<<(datastream& ds, const int64_t& d) { ds.write( (const char*)&d, sizeof(d) ); @@ -123,6 +126,7 @@ inline datastream& operator>>(datastream& ds, int64_t& d) { ds.read((char*)&d, sizeof(d) ); return ds; } + template inline datastream& operator<<(datastream& ds, const uint64_t& d) { ds.write( (const char*)&d, sizeof(d) ); @@ -134,6 +138,31 @@ inline datastream& operator>>(datastream& ds, uint64_t& d) { ds.read((char*)&d, sizeof(d) ); return ds; } + +template +inline datastream& operator<<(datastream& ds, const int32_t& d) { + ds.write( (const char*)&d, sizeof(d) ); + return ds; +} + +template +inline datastream& operator>>(datastream& ds, int32_t& d) { + ds.read((char*)&d, sizeof(d) ); + return ds; +} + +template +inline datastream& operator<<(datastream& ds, const uint32_t& d) { + ds.write( (const char*)&d, sizeof(d) ); + return ds; +} + +template +inline datastream& operator>>(datastream& ds, uint32_t& d) { + ds.read((char*)&d, sizeof(d) ); + return ds; +} + template inline datastream& operator<<(datastream& ds, const int16_t& d) { ds.write( (const char*)&d, sizeof(d) ); @@ -145,6 +174,7 @@ inline datastream& operator>>(datastream& ds, int16_t& d) { ds.read((char*)&d, sizeof(d) ); return ds; } + template inline datastream& operator<<(datastream& ds, const uint16_t& d) { ds.write( (const char*)&d, sizeof(d) ); @@ -179,14 +209,14 @@ inline datastream& operator>>(datastream& ds, uint8_t& d) { return ds; } /* -template +template inline datastream& operator<<(datastream& ds, const boost::multiprecision::number& n) { unsigned char data[(std::numeric_limits::digits+1)/8]; ds.read( (char*)data, sizeof(data) ); boost::multiprecision::import_bits( n, data, data + sizeof(data), 1 ); } -template +template inline datastream& operator>>(datastream& ds, boost::multiprecision::number& n) { unsigned char data[(std::numeric_limits::digits+1)/8]; boost::multiprecision::export_bits( n, data, 1 ); @@ -196,4 +226,3 @@ inline datastream& operator>>(datastream& ds, boost::multiprecision::num } // namespace fc - diff --git a/libraries/fc/include/fc/reflect/typename.hpp b/libraries/fc/include/fc/reflect/typename.hpp index 5cd55c9ccc1..d96cfd9b248 100644 --- a/libraries/fc/include/fc/reflect/typename.hpp +++ b/libraries/fc/include/fc/reflect/typename.hpp @@ -16,14 +16,17 @@ namespace fc { namespace ip { class address; } template struct get_typename; - template<> struct get_typename { static const char* name() { return "int32_t"; } }; - template<> struct get_typename { static const char* name() { return "int64_t"; } }; - template<> struct get_typename { static const char* name() { return "int16_t"; } }; template<> struct get_typename { static const char* name() { return "int8_t"; } }; + template<> struct get_typename { static const char* name() { return "uint8_t"; } }; + template<> struct get_typename { static const char* name() { return "int16_t"; } }; + template<> struct get_typename { static const char* name() { return "uint16_t"; } }; + template<> struct get_typename { static const char* name() { return "int32_t"; } }; template<> struct get_typename { static const char* name() { return "uint32_t"; } }; + template<> struct get_typename { static const char* name() { return "int64_t"; } }; template<> struct get_typename { static const char* name() { return "uint64_t"; } }; - template<> struct get_typename { static const char* name() { return "uint16_t"; } }; - template<> struct get_typename { static const char* name() { return "uint8_t"; } }; + template<> struct get_typename<__int128> { static const char* name() { return "int128_t"; } }; + template<> struct get_typename { static const char* name() { return "uint128_t"; } }; + template<> struct get_typename { static const char* name() { return "double"; } }; template<> struct get_typename { static const char* name() { return "float"; } }; template<> struct get_typename { static const char* name() { return "bool"; } }; @@ -33,41 +36,41 @@ namespace fc { template<> struct get_typename { static const char* name() { return "value"; } }; template<> struct get_typename { static const char* name() { return "fc::exception"; } }; template<> struct get_typename> { static const char* name() { return "std::vector"; } }; - template struct get_typename> - { - static const char* name() { - static std::string n = std::string("std::vector<") + get_typename::name() + ">"; - return n.c_str(); - } + template struct get_typename> + { + static const char* name() { + static std::string n = std::string("std::vector<") + get_typename::name() + ">"; + return n.c_str(); + } }; - template struct get_typename> - { - static const char* name() { - static std::string n = std::string("flat_set<") + get_typename::name() + ">"; - return n.c_str(); - } + template struct get_typename> + { + static const char* name() { + static std::string n = std::string("flat_set<") + get_typename::name() + ">"; + return n.c_str(); + } }; template struct get_typename< std::deque > { static const char* name() { - static std::string n = std::string("std::deque<") + get_typename::name() + ">"; - return n.c_str(); + static std::string n = std::string("std::deque<") + get_typename::name() + ">"; + return n.c_str(); } }; - template struct get_typename> - { - static const char* name() { - static std::string n = std::string("optional<") + get_typename::name() + ">"; - return n.c_str(); - } + template struct get_typename> + { + static const char* name() { + static std::string n = std::string("optional<") + get_typename::name() + ">"; + return n.c_str(); + } }; - template struct get_typename> - { - static const char* name() { - static std::string n = std::string("std::map<") + get_typename::name() + ","+get_typename::name()+">"; - return n.c_str(); - } + template struct get_typename> + { + static const char* name() { + static std::string n = std::string("std::map<") + get_typename::name() + ","+get_typename::name()+">"; + return n.c_str(); + } }; struct signed_int; diff --git a/libraries/fc/include/fc/uint128.hpp b/libraries/fc/include/fc/uint128.hpp index 4ab9c7de53d..52607aab9aa 100644 --- a/libraries/fc/include/fc/uint128.hpp +++ b/libraries/fc/include/fc/uint128.hpp @@ -129,8 +129,8 @@ namespace fc void to_variant( const uint128& var, variant& vo ); void from_variant( const variant& var, uint128& vo ); - void to_variant( const unsigned __int128& var, variant& vo ); - void from_variant( const variant& var, unsigned __int128& vo ); +// void to_variant( const unsigned __int128& var, variant& vo ); +// void from_variant( const variant& var, unsigned __int128& vo ); namespace raw { diff --git a/libraries/fc/include/fc/variant.hpp b/libraries/fc/include/fc/variant.hpp index 1bce1ae83af..e2679e94315 100644 --- a/libraries/fc/include/fc/variant.hpp +++ b/libraries/fc/include/fc/variant.hpp @@ -58,19 +58,19 @@ namespace fc using UInt = number >; template using Int = number >; - + void to_variant( const UInt<8>& n, variant& v ); void from_variant( const variant& v, UInt<8>& n ); - + void to_variant( const UInt<16>& n, variant& v ); void from_variant( const variant& v, UInt<16>& n ); - + void to_variant( const UInt<32>& n, variant& v ); void from_variant( const variant& v, UInt<32>& n ); - + void to_variant( const UInt<64>& n, variant& v ); void from_variant( const variant& v, UInt<64>& n ); - + template void to_variant( const boost::multiprecision::number& n, variant& v ); template void from_variant( const variant& v, boost::multiprecision::number& n ); @@ -99,6 +99,11 @@ namespace fc void to_variant( const int32_t& var, variant& vo ); void from_variant( const variant& var, int32_t& vo ); + void to_variant( const unsigned __int128& var, variant& vo ); + void from_variant( const variant& var, unsigned __int128& vo ); + void to_variant( const __int128& var, variant& vo ); + void from_variant( const variant& var, __int128& vo ); + void to_variant( const variant_object& var, variant& vo ); void from_variant( const variant& var, variant_object& vo ); void to_variant( const mutable_variant_object& var, variant& vo ); diff --git a/libraries/fc/src/uint128.cpp b/libraries/fc/src/uint128.cpp index ec9fc4300a5..c5b26a1eb3f 100644 --- a/libraries/fc/src/uint128.cpp +++ b/libraries/fc/src/uint128.cpp @@ -6,12 +6,12 @@ #include #include "byteswap.hpp" -namespace fc +namespace fc { typedef boost::multiprecision::uint128_t m128; template - static void divide(const T &numerator, const T &denominator, T "ient, T &remainder) + static void divide(const T &numerator, const T &denominator, T "ient, T &remainder) { static const int bits = sizeof(T) * 8;//CHAR_BIT; @@ -44,8 +44,8 @@ namespace fc } } - uint128::uint128(const std::string &sz) - :hi(0), lo(0) + uint128::uint128(const std::string &sz) + :hi(0), lo(0) { // do we have at least one character? if(!sz.empty()) { @@ -151,33 +151,33 @@ namespace fc } - uint128& uint128::operator<<=(const uint128& rhs) + uint128& uint128::operator<<=(const uint128& rhs) { - if(rhs >= 128) + if(rhs >= 128) { hi = 0; lo = 0; - } - else + } + else { unsigned int n = rhs.to_integer(); const unsigned int halfsize = 128 / 2; - + if(n >= halfsize){ n -= halfsize; hi = lo; lo = 0; } - + if(n != 0) { // shift high half hi <<= n; - + const uint64_t mask(~(uint64_t(-1) >> n)); - + // and add them to high half hi |= (lo & mask) >> (halfsize - n); - + // and finally shift also low half lo <<= n; } @@ -186,7 +186,7 @@ namespace fc return *this; } - uint128 & uint128::operator>>=(const uint128& rhs) + uint128 & uint128::operator>>=(const uint128& rhs) { if(rhs >= 128) { @@ -197,23 +197,23 @@ namespace fc { unsigned int n = rhs.to_integer(); const unsigned int halfsize = 128 / 2; - + if(n >= halfsize) { n -= halfsize; lo = hi; hi = 0; } - + if(n != 0) { // shift low half lo >>= n; - + // get lower N bits of high half const uint64_t mask(~(uint64_t(-1) << n)); - + // and add them to low qword lo |= (hi & mask) << (halfsize - n); - + // and finally shift also high half hi >>= n; } @@ -221,7 +221,7 @@ namespace fc return *this; } - uint128& uint128::operator/=(const uint128 &b) + uint128& uint128::operator/=(const uint128 &b) { auto self = (m128(hi) << 64) + m128(lo); auto other = (m128(b.hi) << 64) + m128(b.lo); @@ -238,7 +238,7 @@ namespace fc exit(1); } */ - + /* const auto& b128 = std::reinterpret_cast(b); auto& this128 = std::reinterpret_cast(*this); @@ -247,14 +247,14 @@ namespace fc return *this; } - uint128& uint128::operator%=(const uint128 &b) + uint128& uint128::operator%=(const uint128 &b) { uint128 quotient; divide(*this, b, quotient, *this); return *this; } - uint128& uint128::operator*=(const uint128 &b) + uint128& uint128::operator*=(const uint128 &b) { uint64_t a0 = (uint32_t) (this->lo ); uint64_t a1 = (uint32_t) (this->lo >> 0x20); @@ -275,7 +275,7 @@ namespace fc // (a3 * b0 + a2 * b1 + a1 * b2 + a0 * b3) << 0x60 // // all other cross terms are << 0x80 or higher, thus do not appear in result - + this->hi = 0; this->lo = a3*b0; (*this) += a2*b1; @@ -293,7 +293,7 @@ namespace fc return *this; } - + void uint128::full_product( const uint128& a, const uint128& b, uint128& result_hi, uint128& result_lo ) { // (ah * 2**64 + al) * (bh * 2**64 + bl) @@ -304,7 +304,7 @@ namespace fc // + Rh * 2**128 + Rl * 2**64 // + Sh * 2**64 + Sl // - + uint64_t ah = a.hi; uint64_t al = a.lo; uint64_t bh = b.hi; @@ -318,7 +318,7 @@ namespace fc q *= bh; uint128 p = ah; p *= bh; - + uint64_t sl = s.lo; uint64_t sh = s.hi; uint64_t rl = r.lo; @@ -330,7 +330,7 @@ namespace fc uint64_t y[4]; // final result y[0] = sl; - + uint128_t acc = sh; acc += ql; acc += rl; @@ -341,10 +341,10 @@ namespace fc acc += pl; y[2] = acc.lo; y[3] = acc.hi + ph; - + result_hi = uint128( y[3], y[2] ); result_lo = uint128( y[1], y[0] ); - + return; } @@ -376,13 +376,14 @@ namespace fc void to_variant( const uint128& var, variant& vo ) { vo = std::string(var); } void from_variant( const variant& var, uint128& vo ){ vo = uint128(var.as_string()); } +/* void to_variant( const unsigned __int128& var, variant& vo ) { to_variant( uint128(var), vo); } void from_variant( const variant& var, unsigned __int128& vo ) { uint128 tmp; from_variant( var, tmp ); vo = (unsigned __int128)tmp; } - +*/ } // namespace fc @@ -402,4 +403,3 @@ namespace fc * suitability this software for any purpose. It is provided "as is" * without express or implied warranty. */ - diff --git a/libraries/fc/src/variant.cpp b/libraries/fc/src/variant.cpp index 4ed6c758289..d571735243a 100644 --- a/libraries/fc/src/variant.cpp +++ b/libraries/fc/src/variant.cpp @@ -159,9 +159,9 @@ variant::variant( variants arr ) } -typedef const variant_object* const_variant_object_ptr; -typedef const variants* const_variants_ptr; -typedef const blob* const_blob_ptr; +typedef const variant_object* const_variant_object_ptr; +typedef const variants* const_variants_ptr; +typedef const blob* const_blob_ptr; typedef const string* const_string_ptr; void variant::clear() @@ -188,17 +188,17 @@ variant::variant( const variant& v ) switch( v.get_type() ) { case object_type: - *reinterpret_cast(this) = + *reinterpret_cast(this) = new variant_object(**reinterpret_cast(&v)); set_variant_type( this, object_type ); return; case array_type: - *reinterpret_cast(this) = + *reinterpret_cast(this) = new variants(**reinterpret_cast(&v)); set_variant_type( this, array_type ); return; case string_type: - *reinterpret_cast(this) = + *reinterpret_cast(this) = new string(**reinterpret_cast(&v) ); set_variant_type( this, string_type ); return; @@ -223,24 +223,24 @@ variant& variant::operator=( variant&& v ) if( this == &v ) return *this; clear(); memcpy( (char*)this, (char*)&v, sizeof(v) ); - set_variant_type( &v, null_type ); + set_variant_type( &v, null_type ); return *this; } variant& variant::operator=( const variant& v ) { - if( this == &v ) + if( this == &v ) return *this; clear(); switch( v.get_type() ) { case object_type: - *reinterpret_cast(this) = + *reinterpret_cast(this) = new variant_object((**reinterpret_cast(&v))); break; case array_type: - *reinterpret_cast(this) = + *reinterpret_cast(this) = new variants((**reinterpret_cast(&v))); break; case string_type: @@ -365,7 +365,7 @@ int64_t variant::as_int64()const switch( get_type() ) { case string_type: - return to_int64(**reinterpret_cast(this)); + return to_int64(**reinterpret_cast(this)); case double_type: return int64_t(*reinterpret_cast(this)); case int64_type: @@ -386,7 +386,7 @@ uint64_t variant::as_uint64()const switch( get_type() ) { case string_type: - return to_uint64(**reinterpret_cast(this)); + return to_uint64(**reinterpret_cast(this)); case double_type: return static_cast(*reinterpret_cast(this)); case int64_type: @@ -408,7 +408,7 @@ double variant::as_double()const switch( get_type() ) { case string_type: - return to_double(**reinterpret_cast(this)); + return to_double(**reinterpret_cast(this)); case double_type: return *reinterpret_cast(this); case int64_type: @@ -457,13 +457,13 @@ string variant::as_string()const switch( get_type() ) { case string_type: - return **reinterpret_cast(this); + return **reinterpret_cast(this); case double_type: - return to_string(*reinterpret_cast(this)); + return to_string(*reinterpret_cast(this)); case int64_type: - return to_string(*reinterpret_cast(this)); + return to_string(*reinterpret_cast(this)); case uint64_type: - return to_string(*reinterpret_cast(this)); + return to_string(*reinterpret_cast(this)); case bool_type: return *reinterpret_cast(this) ? "true" : "false"; case blob_type: @@ -477,27 +477,27 @@ string variant::as_string()const } } - + /// @throw if get_type() != array_type | null_type variants& variant::get_array() { if( get_type() == array_type ) return **reinterpret_cast(this); - + FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from ${type} to Array", ("type",get_type()) ); } blob& variant::get_blob() { if( get_type() == blob_type ) return **reinterpret_cast(this); - + FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from ${type} to Blob", ("type",get_type()) ); } const blob& variant::get_blob()const { if( get_type() == blob_type ) return **reinterpret_cast(this); - + FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from ${type} to Blob", ("type",get_type()) ); } @@ -527,7 +527,7 @@ blob variant::as_blob()const } -/// @throw if get_type() != array_type +/// @throw if get_type() != array_type const variants& variant::get_array()const { if( get_type() == array_type ) @@ -565,7 +565,7 @@ const string& variant::get_string()const FC_THROW_EXCEPTION( bad_cast_exception, "Invalid cast from type '${type}' to string", ("type",get_type()) ); } -/// @throw if get_type() != object_type +/// @throw if get_type() != object_type const variant_object& variant::get_object()const { if( get_type() == object_type ) @@ -607,12 +607,80 @@ void from_variant( const variant& var, uint32_t& vo ) vo = static_cast(var.as_uint64()); } -void to_variant( const int32_t& var, variant& vo ) { vo = int64_t(var); } +void to_variant( const int32_t& var, variant& vo ) { + vo = int64_t(var); +} + void from_variant( const variant& var, int32_t& vo ) { vo = static_cast(var.as_int64()); } +void to_variant( const unsigned __int128& var, variant& vo ) { + /* + if( var <= static_cast( std::numeric_limits::max() ) ) + { // uint32_t rather than uint64_t so that the number can be represented in JavaScript + vo = static_cast(var); + return; + } + */ + std::string s = "0x"; + s.append( to_hex( reinterpret_cast(&var), sizeof(var) ) ); + vo = s; + // Assumes platform is little endian since it should write out the hex representation of 128-bit integer in little endian order. +} + +void from_variant( const variant& var, unsigned __int128& vo ) +{ + if( var.is_uint64() ) { + vo = var.as_uint64(); + } else if( var.is_string() ) { + unsigned __int128 temp = 0; + auto s = var.as_string(); + FC_ASSERT( s.size() == 2 + 2 * sizeof(temp) && s.find("0x") == 0, + "Failure in converting hex data into a uint128_t" ); + auto sz = from_hex( s.substr(2), reinterpret_cast(&temp), sizeof(temp) ); + // Assumes platform is little endian and hex representation of 128-bit integer is in little endian order. + FC_ASSERT( sz == sizeof(temp), "Failure in converting hex data into a uint128_t" ); + vo = temp; + } else { + FC_THROW_EXCEPTION( bad_cast_exception, "Cannot convert variant of type '${type}' into a uint128_t", ("type", var.get_type()) ); + } +} + +void to_variant( const __int128& var, variant& vo ) { + /* + if( static_cast<__int128>( std::numeric_limits::lowest() ) <= var + && var <= static_cast<__int128>( std::numeric_limits::max() ) ) + { // int32_t rather than int64_t so that the number can be represented in JavaScript + vo = static_cast(var); + return; + } + */ + std::string s = "0x"; + s.append( to_hex( reinterpret_cast(&var), sizeof(var) ) ); + vo = s; + // Assumes platform is little endian since it should write out the hex representation of 128-bit integer in little endian order. +} + +void from_variant( const variant& var, __int128& vo ) +{ + if( var.is_int64() ) { + vo = var.as_int64(); + } else if( var.is_string() ) { + __int128 temp = 0; + auto s = var.as_string(); + FC_ASSERT( s.size() == 2 + 2 * sizeof(temp) && s.find("0x") == 0, + "Failure in converting hex data into a int128_t" ); + auto sz = from_hex( s.substr(2), reinterpret_cast(&temp), sizeof(temp) ); + // Assumes platform is little endian and hex representation of 128-bit integer is in little endian order. + FC_ASSERT( sz == sizeof(temp), "Failure in converting hex data into a int128_t" ); + vo = temp; + } else { + FC_THROW_EXCEPTION( bad_cast_exception, "Cannot convert variant of type '${type}' into a int128_t", ("type", var.get_type()) ); + } +} + void from_variant( const variant& var, int64_t& vo ) { vo = var.as_int64(); @@ -687,23 +755,23 @@ string format_string( const string& format, const variant_object& args ) std::stringstream ss; size_t prev = 0; auto next = format.find( '$' ); - while( prev != size_t(string::npos) && prev < size_t(format.size()) ) + while( prev != size_t(string::npos) && prev < size_t(format.size()) ) { ss << format.substr( prev, size_t(next-prev) ); - + // if we got to the end, return it. - if( next == size_t(string::npos) ) - return ss.str(); - + if( next == size_t(string::npos) ) + return ss.str(); + // if we are not at the end, then update the start prev = next + 1; - - if( format[prev] == '{' ) - { + + if( format[prev] == '{' ) + { // if the next char is a open, then find close next = format.find( '}', prev ); - // if we found close... - if( next != size_t(string::npos) ) + // if we found close... + if( next != size_t(string::npos) ) { // the key is between prev and next string key = format.substr( prev+1, (next-prev-1) ); @@ -714,26 +782,26 @@ string format_string( const string& format, const variant_object& args ) if( val->value().is_object() || val->value().is_array() ) { ss << json::to_string( val->value() ); - } - else + } + else { ss << val->value().as_string(); } - } - else + } + else { ss << "${"<commit_block(); - control->log_irreversible_blocks(); last_produced_block[control->head_block_state()->header.producer] = control->head_block_state()->id; _start_block( next_time + fc::microseconds(config::block_interval_us)); @@ -632,7 +632,7 @@ namespace enumivo { namespace testing { trx.actions.emplace_back( vector{{account,config::active_name}}, setabi{ .account = account, - .abi = abi + .abi = fc::raw::pack(abi) }); set_transaction_headers(trx); diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index f4e061bd707..22d6a3b1a99 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -403,11 +403,27 @@ static float64_t to_softfloat64( double d ) { return *reinterpret_cast(&d); } +static fc::variant get_global_row( const database& db, const abi_def& abi, const abi_serializer& abis ) { + const auto table_type = get_table_type(abi, N(global)); + ENU_ASSERT(table_type == read_only::KEYi64, chain::contract_table_query_exception, "Invalid table type ${type} for table global", ("type",table_type)); + + const auto* const table_id = db.find(boost::make_tuple(N(enumivo), N(enumivo), N(global))); + ENU_ASSERT(table_id, chain::contract_table_query_exception, "Missing table global"); + + const auto& kv_index = db.get_index(); + const auto it = kv_index.find(boost::make_tuple(table_id->id, N(global))); + ENU_ASSERT(it != kv_index.end(), chain::contract_table_query_exception, "Missing row in table global"); + + vector data; + read_only::copy_inline_row(*it, data); + return abis.binary_to_variant(abis.get_table_type(N(global)), data); +} + read_only::get_producers_result read_only::get_producers( const read_only::get_producers_params& p ) const { const abi_def abi = get_abi(db, N(enumivo)); const auto table_type = get_table_type(abi, N(producers)); const abi_serializer abis{ abi }; - ENU_ASSERT(table_type == KEYi64, chain::contract_table_query_exception, "Invalid table type ${type}", ("type",table_type)); + ENU_ASSERT(table_type == KEYi64, chain::contract_table_query_exception, "Invalid table type ${type} for table producers", ("type",table_type)); const auto& d = db.db(); const auto lower = name{p.lower_bound}; @@ -448,6 +464,7 @@ read_only::get_producers_result read_only::get_producers( const read_only::get_p result.rows.emplace_back(fc::variant(data)); } + result.total_producer_vote_weight = get_global_row(d, abi, abis)["total_producer_vote_weight"].as_double(); return result; } diff --git a/plugins/chain_plugin/include/enumivo/chain_plugin/chain_plugin.hpp b/plugins/chain_plugin/include/enumivo/chain_plugin/chain_plugin.hpp index 6a276a121e6..7c6adbe7d6b 100644 --- a/plugins/chain_plugin/include/enumivo/chain_plugin/chain_plugin.hpp +++ b/plugins/chain_plugin/include/enumivo/chain_plugin/chain_plugin.hpp @@ -216,6 +216,7 @@ class read_only { struct get_producers_result { vector rows; ///< one row per item, either encoded as hex string or JSON object + double total_producer_vote_weight; string more; ///< fill lower_bound with this value to fetch more rows }; @@ -397,7 +398,7 @@ FC_REFLECT( enumivo::chain_apis::read_only::get_currency_stats_params, (code)(sy FC_REFLECT( enumivo::chain_apis::read_only::get_currency_stats_result, (supply)(max_supply)(issuer)); FC_REFLECT( enumivo::chain_apis::read_only::get_producers_params, (json)(lower_bound)(limit) ) -FC_REFLECT( enumivo::chain_apis::read_only::get_producers_result, (rows)(more) ); +FC_REFLECT( enumivo::chain_apis::read_only::get_producers_result, (rows)(total_producer_vote_weight)(more) ); FC_REFLECT( enumivo::chain_apis::read_only::get_account_results, (account_name)(privileged)(last_code_update)(created)(ram_quota)(net_weight)(cpu_weight)(net_limit)(cpu_limit)(ram_usage)(permissions)(total_resources)(delegated_bandwidth)(voter_info) ) FC_REFLECT( enumivo::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) ) diff --git a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp index 80a4cbf969b..8a555bb3819 100644 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -144,7 +144,7 @@ struct txn_test_gen_plugin_impl { { setabi handler; handler.account = newaccountC; - handler.abi = json::from_string(enumivo_coin_abi).as(); + handler.abi = fc::raw::pack(json::from_string(enumivo_coin_abi).as()); trx.actions.emplace_back( vector{{newaccountC,"active"}}, handler); } diff --git a/programs/enucli/main.cpp b/programs/enucli/main.cpp index 6deacf4bd90..28954528d44 100644 --- a/programs/enucli/main.cpp +++ b/programs/enucli/main.cpp @@ -509,7 +509,7 @@ chain::action create_setabi(const name& account, const abi_def& abi) { tx_permission.empty() ? vector{{account,config::active_name}} : get_account_permissions(tx_permission), setabi{ .account = account, - .abi = abi + .abi = fc::raw::pack(abi) } }; } @@ -1031,13 +1031,16 @@ struct list_producers_subcommand { std::cout << "No producers found" << std::endl; return; } - printf("%-13s %-54s %-59s %s\n", "Producer", "Producer key", "Url", "Total votes"); + auto weight = result.total_producer_vote_weight; + if ( !weight ) + weight = 1; + printf("%-13s %-54s %-59s %s\n", "Producer", "Producer key", "Url", "Scaled votes"); for ( auto& row : result.rows ) - printf("%-13.13s %-54.54s %-59.59s %040f\n", + printf("%-13.13s %-54.54s %-59.59s %1.4f\n", row["owner"].as_string().c_str(), row["producer_key"].as_string().c_str(), row["url"].as_string().c_str(), - row["total_votes"].as_double()); + row["total_votes"].as_double() / weight); if ( !result.more.empty() ) std::cout << "-L " << result.more << " for more" << std::endl; }); @@ -1761,7 +1764,7 @@ int main( int argc, char** argv ) { // ->check(CLI::ExistingFile); auto abi = contractSubcommand->add_option("abi-file,-a,--abi", abiPath, localized("The ABI for the contract relative to contract-dir")); // ->check(CLI::ExistingFile); - + std::vector actions; auto set_code_callback = [&]() { std::string wast; diff --git a/unittests/abi_tests.cpp b/unittests/abi_tests.cpp index 5f4df427a77..d5e116e9c20 100644 --- a/unittests/abi_tests.cpp +++ b/unittests/abi_tests.cpp @@ -77,13 +77,145 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const const char* my_abi = R"=====( { - "types": [], - "structs": [{ + "version": "", + "types": [{ + "new_type_name": "type_name", + "type": "string" + },{ + "new_type_name": "field_name", + "type": "string" + },{ + "new_type_name": "fields", + "type": "field_def[]" + },{ + "new_type_name": "scope_name", + "type": "name" + }], + "structs": [{ + "name": "abi_extension", + "base": "", + "fields": [{ + "name": "type", + "type": "uint16" + },{ + "name": "data", + "type": "bytes" + }] + },{ + "name": "type_def", + "base": "", + "fields": [{ + "name": "new_type_name", + "type": "type_name" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "field_def", + "base": "", + "fields": [{ + "name": "name", + "type": "field_name" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "struct_def", + "base": "", + "fields": [{ + "name": "name", + "type": "type_name" + },{ + "name": "base", + "type": "type_name" + }{ + "name": "fields", + "type": "field_def[]" + }] + },{ + "name": "action_def", + "base": "", + "fields": [{ + "name": "name", + "type": "action_name" + },{ + "name": "type", + "type": "type_name" + },{ + "name": "ricardian_contract", + "type": "string" + }] + },{ + "name": "table_def", + "base": "", + "fields": [{ + "name": "name", + "type": "table_name" + },{ + "name": "index_type", + "type": "type_name" + },{ + "name": "key_names", + "type": "field_name[]" + },{ + "name": "key_types", + "type": "type_name[]" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "clause_pair", + "base": "", + "fields": [{ + "name": "id", + "type": "string" + },{ + "name": "body", + "type": "string" + }] + },{ + "name": "abi_def", + "base": "", + "fields": [{ + "name": "version", + "type": "string" + },{ + "name": "types", + "type": "type_def[]" + },{ + "name": "structs", + "type": "struct_def[]" + },{ + "name": "actions", + "type": "action_def[]" + },{ + "name": "tables", + "type": "table_def[]" + },{ + "name": "ricardian_clauses", + "type": "clause_pair[]" + },{ + "name": "abi_extensions", + "type": "abi_extension[]" + }] + },{ "name" : "A", "base" : "PublicKeyTypes", "fields": [] - }, - { + },{ + "name": "signed_transaction", + "base": "transaction", + "fields": [{ + "name": "signatures", + "type": "signature[]" + },{ + "name": "context_free_data", + "type": "bytes[]" + }] + },{ "name": "PublicKeyTypes", "base" : "AssetTypes", "fields": [{ @@ -144,18 +276,6 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const },{ "name": "fieldname_arr", "type": "field_name[]" - },{ - "name": "fixedstring32", - "type": "fixed_string32" - },{ - "name": "fixedstring32_ar", - "type": "fixed_string32[]" - },{ - "name": "fixedstring16", - "type": "fixed_string16" - },{ - "name": "fixedstring16_ar", - "type": "fixed_string16[]" },{ "name": "typename", "type": "type_name" @@ -192,12 +312,6 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const },{ "name": "uint128_arr", "type": "uint128[]" - },{ - "name": "uint256", - "type": "uint256" - },{ - "name": "uint256_arr", - "type": "uint256[]" },{ "name": "int8", "type": "int8" @@ -222,6 +336,12 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const },{ "name": "int64_arr", "type": "int64[]" + },{ + "name": "int128", + "type": "int128" + },{ + "name": "int128_arr", + "type": "int128[]" },{ "name": "name", "type": "name" @@ -230,10 +350,10 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const "type": "name[]" },{ "name": "field", - "type": "field" + "type": "field_def" },{ "name": "field_arr", - "type": "field[]" + "type": "field_def[]" },{ "name": "struct", "type": "struct_def" @@ -342,7 +462,8 @@ fc::variant verify_type_round_trip_conversion( const abi_serializer& abis, const "actions": [], "tables": [], "ricardian_clauses": [{"id":"clause A","body":"clause body A"}, - {"id":"clause B","body":"clause body B"}] + {"id":"clause B","body":"clause body B"}], + "abi_extensions": [] } )====="; @@ -432,7 +553,7 @@ struct abi_gen_helper { ); FC_ASSERT(res == true); - abi_serializer(enumivo_contract_abi(output)).validate(); + abi_serializer(output).validate(); auto abi1 = fc::json::from_string(abi).as(); @@ -471,44 +592,45 @@ BOOST_FIXTURE_TEST_CASE(abigen_all_types, abi_gen_helper) const char* all_types = R"=====( #pragma GCC diagnostic ignored "-Wpointer-bool-conversion" #include + #include #include - #include #include - #include - typedef enumivo::symbol_type symbol; + using namespace enumivo; + + typedef signed_int varint32; + typedef unsigned_int varuint32; + typedef symbol_type symbol; //@abi action struct test_struct { - std::string field1; - enumivo::time_point_sec field2; - signature field3; - checksum256 field4; - field_name field5; - fixed_string32 field6; - fixed_string16 field7; - type_name field8; - uint8_t field9; - uint16_t field10; - uint32_t field11; - uint64_t field12; - uint128_t field13; - int8_t field15; - int16_t field16; - int32_t field17; - int64_t field18; - enumivo::name field19; - account_name field23; - permission_name field24; - action_name field25; - scope_name field26; - enumivo::permission_level field27; - public_key field39; - enumivo::asset field40; - enumivo::extended_asset field41; - symbol field42; - enumivo::time_point field43; - enumivo::block_timestamp_type field44; + bool field1; + int8_t field2; + uint8_t field3; + int16_t field4; + uint16_t field5; + int32_t field6; + uint32_t field7; + int64_t field8; + uint64_t field9; + int128_t field10; + uint128_t field11; + varint32 field12; + varuint32 field13; + time_point field14; + time_point_sec field15; + block_timestamp_type field16; + name field17; + bytes field18; + std::string field19; + checksum160 field20; + checksum256 field21; + checksum512 field22; + public_key field23; + signature field24; + symbol field25; + asset field26; + extended_asset field27; }; )====="; @@ -516,99 +638,92 @@ BOOST_FIXTURE_TEST_CASE(abigen_all_types, abi_gen_helper) { "types": [], "structs": [{ - "name": "test_struct", - "base": "", - "fields": [{ - "name": "field1", - "type": "string" - },{ - "name": "field2", - "type": "time_point_sec" - },{ - "name": "field3", - "type": "signature" - },{ - "name": "field4", - "type": "checksum256" - },{ - "name": "field5", - "type": "field_name" - },{ - "name": "field6", - "type": "fixed_string32" - },{ - "name": "field7", - "type": "fixed_string16" - },{ - "name": "field8", - "type": "type_name" - },{ - "name": "field9", - "type": "uint8" - },{ - "name": "field10", - "type": "uint16" - },{ - "name": "field11", - "type": "uint32" - },{ - "name": "field12", - "type": "uint64" - },{ - "name": "field13", - "type": "uint128" - },{ - "name": "field15", - "type": "int8" - },{ - "name": "field16", - "type": "int16" - },{ - "name": "field17", - "type": "int32" - },{ - "name": "field18", - "type": "int64" - },{ - "name": "field19", - "type": "name" - },{ - "name": "field23", - "type": "account_name" - },{ - "name": "field24", - "type": "permission_name" - },{ - "name": "field25", - "type": "action_name" - },{ - "name": "field26", - "type": "scope_name" - },{ - "name": "field27", - "type": "permission_level" - },{ - "name": "field39", - "type": "public_key" - },{ - "name": "field40", - "type": "asset" - },{ - "name": "field41", - "type": "extended_asset" - },{ - "name": "field42", - "type": "symbol" - },{ - "name": "field43", - "type": "time_point" - },{ - "name": "field44", - "type": "block_timestamp_type" - } - ] - } - ], + "name": "test_struct", + "base": "", + "fields": [{ + "name": "field1", + "type": "bool" + },{ + "name": "field2", + "type": "int8" + },{ + "name": "field3", + "type": "uint8" + },{ + "name": "field4", + "type": "int16" + },{ + "name": "field5", + "type": "uint16" + },{ + "name": "field6", + "type": "int32" + },{ + "name": "field7", + "type": "uint32" + },{ + "name": "field8", + "type": "int64" + },{ + "name": "field9", + "type": "uint64" + },{ + "name": "field10", + "type": "int128" + },{ + "name": "field11", + "type": "uint128" + },{ + "name": "field12", + "type": "varint32" + },{ + "name": "field13", + "type": "varuint32" + },{ + "name": "field14", + "type": "time_point" + },{ + "name": "field15", + "type": "time_point_sec" + },{ + "name": "field16", + "type": "block_timestamp_type" + },{ + "name": "field17", + "type": "name" + },{ + "name": "field18", + "type": "bytes" + },{ + "name": "field19", + "type": "string" + },{ + "name": "field20", + "type": "checksum160" + },{ + "name": "field21", + "type": "checksum256" + },{ + "name": "field22", + "type": "checksum512" + },{ + "name": "field23", + "type": "public_key" + },{ + "name": "field24", + "type": "signature" + },{ + "name": "field25", + "type": "symbol" + },{ + "name": "field26", + "type": "asset" + },{ + "name": "field27", + "type": "extended_asset" + } + ] + }], "actions": [{ "name": "teststruct", "type": "test_struct", @@ -739,8 +854,8 @@ BOOST_FIXTURE_TEST_CASE(abigen_all_indexes, abi_gen_helper) }; struct my_complex_value { - uint64_t a; - account_name b; + uint64_t a; + name b; }; //@abi table @@ -792,7 +907,7 @@ BOOST_FIXTURE_TEST_CASE(abigen_all_indexes, abi_gen_helper) "type" : "uint64" },{ "name" : "b", - "type" : "account_name" + "type" : "name" }] },{ "name" : "table4", @@ -1541,10 +1656,10 @@ BOOST_FIXTURE_TEST_CASE(abigen_vector_multidimension, abi_gen_helper) } FC_LOG_AND_RETHROW() } -BOOST_FIXTURE_TEST_CASE(abgigen_vector_alias, abi_gen_helper) +BOOST_FIXTURE_TEST_CASE(abigen_vector_alias, abi_gen_helper) { try { - const char* abgigen_vector_alias = R"=====( + const char* abigen_vector_alias = R"=====( #include #include #include @@ -1566,7 +1681,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_vector_alias, abi_gen_helper) )====="; - const char* abgigen_vector_alias_abi = R"=====( + const char* abigen_vector_alias_abi = R"=====( { "types": [{ "new_type_name": "array_of_rows", @@ -1605,7 +1720,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_vector_alias, abi_gen_helper) } )====="; - BOOST_TEST( generate_abi(abgigen_vector_alias, abgigen_vector_alias_abi) == true ); + BOOST_TEST( generate_abi(abigen_vector_alias, abigen_vector_alias_abi) == true ); } FC_LOG_AND_RETHROW() } @@ -1627,11 +1742,11 @@ BOOST_FIXTURE_TEST_CASE(abgigen_enumivoabi_macro, abi_gen_helper) public: using contract::contract; - void hi( account_name user ) { + void hi( name user ) { print( "Hello, ", name{user} ); } - void bye( account_name user ) { + void bye( name user ) { print( "Bye, ", name{user} ); } }; @@ -1650,7 +1765,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_enumivoabi_macro, abi_gen_helper) "base": "", "fields": [{ "name": "user", - "type": "account_name" + "type": "name" } ] } @@ -1669,10 +1784,10 @@ BOOST_FIXTURE_TEST_CASE(abgigen_enumivoabi_macro, abi_gen_helper) } FC_LOG_AND_RETHROW() } -BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) +BOOST_FIXTURE_TEST_CASE(abigen_contract_inheritance, abi_gen_helper) { try { - const char* abgigen_contract_inheritance = R"=====( + const char* abigen_contract_inheritance = R"=====( #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpointer-bool-conversion" @@ -1686,7 +1801,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) public: using contract::contract; - void hi( account_name user ) { + void hi( name user ) { print( "Hello, ", name{user} ); } }; @@ -1694,7 +1809,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) struct new_hello : hello { public: new_hello(account_name self) : hello(self) {} - void bye( account_name user ) { + void bye( name user ) { print( "Bye, ", name{user} ); } }; @@ -1704,7 +1819,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) #pragma GCC diagnostic pop )====="; - const char* abgigen_contract_inheritance_abi = R"=====( + const char* abigen_contract_inheritance_abi = R"=====( { "types": [], "structs": [{ @@ -1712,7 +1827,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) "base": "", "fields": [{ "name": "user", - "type": "account_name" + "type": "name" } ] },{ @@ -1720,7 +1835,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) "base": "", "fields": [{ "name": "user", - "type": "account_name" + "type": "name" } ] } @@ -1738,7 +1853,7 @@ BOOST_FIXTURE_TEST_CASE(abgigen_contract_inheritance, abi_gen_helper) } )====="; - BOOST_TEST( generate_abi(abgigen_contract_inheritance, abgigen_contract_inheritance_abi) == true ); + BOOST_TEST( generate_abi(abigen_contract_inheritance, abigen_contract_inheritance_abi) == true ); } FC_LOG_AND_RETHROW() } @@ -1771,10 +1886,6 @@ BOOST_AUTO_TEST_CASE(general) "checksum256_arr" : ["ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad","ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"], "fieldname" : "name1", "fieldname_arr" : ["name1","name2"], - "fixedstring32" : "1234567890abcdef1234567890abcdef", - "fixedstring32_ar" : ["1234567890abcdef1234567890abcdef","1234567890abcdef1234567890abcdea"], - "fixedstring16" : "1234567890abcdef", - "fixedstring16_ar" : ["1234567890abcdef","1234567890abcdea"], "typename" : "name3", "typename_arr" : ["name4","name5"], "bytes" : "010203", @@ -1787,10 +1898,8 @@ BOOST_AUTO_TEST_CASE(general) "uint32_arr" : [32,33], "uint64" : 64, "uint64_arr" : [64,65], - "uint128" : "128", - "uint128_arr" : ["128","129"], - "uint256" : "256", - "uint256_arr" : ["256","257"], + "uint128" : 128, + "uint128_arr" : ["0x00000000000000000000000000000080",129], "int8" : 108, "int8_arr" : [108,109], "int16" : 116, @@ -1799,6 +1908,8 @@ BOOST_AUTO_TEST_CASE(general) "int32_arr" : [132,133], "int64" : 164, "int64_arr" : [164,165], + "int128" : -128, + "int128_arr" : ["0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80",-129], "name" : "xname1", "name_arr" : ["xname2","xname3"], "field" : {"name":"name1", "type":"type1"}, @@ -1829,7 +1940,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"accountname1", "name":"actionname1", "authorization":[{"actor":"acc1","permission":"permname1"}], "data":"445566"}], "max_net_usage_words":15, "max_cpu_usage_ms":43, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] }, "transaction_arr": [{ "ref_block_num":"1", @@ -1839,7 +1951,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"acc1", "name":"actionname1", "authorization":[{"actor":"acc1","permission":"permname1"}], "data":"445566"}], "max_net_usage_words":15, "max_cpu_usage_ms":43, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] },{ "ref_block_num":"2", "ref_block_prefix":"3", @@ -1848,7 +1961,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"acc2", "name":"actionname2", "authorization":[{"actor":"acc2","permission":"permname2"}], "data":""}], "max_net_usage_words":21, "max_cpu_usage_ms":87, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] }], "strx": { "ref_block_num":"1", @@ -1861,7 +1975,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"accountname1", "name":"actionname1", "authorization":[{"actor":"acc1","permission":"permname1"}], "data":"445566"}], "max_net_usage_words":15, "max_cpu_usage_ms":43, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] }, "strx_arr": [{ "ref_block_num":"1", @@ -1874,7 +1989,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"acc1", "name":"actionname1", "authorization":[{"actor":"acc1","permission":"permname1"}], "data":"445566"}], "max_net_usage_words":15, "max_cpu_usage_ms":43, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] },{ "ref_block_num":"2", "ref_block_prefix":"3", @@ -1886,7 +2002,8 @@ BOOST_AUTO_TEST_CASE(general) "actions":[{"account":"acc2", "name":"actionname2", "authorization":[{"actor":"acc2","permission":"permname2"}], "data":""}], "max_net_usage_words":15, "max_cpu_usage_ms":43, - "delay_sec":0 + "delay_sec":0, + "transaction_extensions": [] }], "keyweight": {"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":"100"}, "keyweight_arr": [{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":"100"},{"key":"EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV", "weight":"200"}], @@ -1917,24 +2034,30 @@ BOOST_AUTO_TEST_CASE(general) {"name":"table2","index_type":"indextype2","key_names":["keyname2"],"key_types":["typename2"],"type":"type2"} ], "abidef":{ + "version": "", "types" : [{"new_type_name":"new", "type":"old"}], "structs" : [{"name":"struct1", "base":"base1", "fields": [{"name":"name1", "type": "type1"}, {"name":"name2", "type": "type2"}] }], "actions" : [{"name":"action1","type":"type1", "ricardian_contract":""}], "tables" : [{"name":"table1","index_type":"indextype1","key_names":["keyname1"],"key_types":["typename1"],"type":"type1"}], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] }, "abidef_arr": [{ + "version": "", "types" : [{"new_type_name":"new", "type":"old"}], "structs" : [{"name":"struct1", "base":"base1", "fields": [{"name":"name1", "type": "type1"}, {"name":"name2", "type": "type2"}] }], "actions" : [{"name":"action1","type":"type1", "ricardian_contract":""}], "tables" : [{"name":"table1","index_type":"indextype1","key_names":["keyname1"],"key_types":["typename1"],"type":"type1"}], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] },{ + "version": "", "types" : [{"new_type_name":"new", "type":"old"}], "structs" : [{"name":"struct1", "base":"base1", "fields": [{"name":"name1", "type": "type1"}, {"name":"name2", "type": "type2"}] }], "actions" : [{"name":"action1","type":"type1", "ricardian_contract": ""}], "tables" : [{"name":"table1","index_type":"indextype1","key_names":["keyname1"],"key_types":["typename1"],"type":"type1"}], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] }] } )====="; @@ -2177,14 +2300,16 @@ BOOST_AUTO_TEST_CASE(newaccount_test) "keys" : [ {"key" : "EOS65rXebLhtk2aTTzP4e9x1AQZs7c5NNXJp89W8R3HyaA6Zyd4im", "weight" : 57005}, {"key" : "EOS5eVr9TVnqwnUBNwf9kwMTbrHvX5aPyyEG97dz2b2TNeqWRzbJf", "weight" : 57605} ], "accounts" : [ {"permission" : {"actor" : "prm.acct1", "permission" : "prm.prm1"}, "weight" : 53005 }, - {"permission" : {"actor" : "prm.acct2", "permission" : "prm.prm2"}, "weight" : 53405 }] + {"permission" : {"actor" : "prm.acct2", "permission" : "prm.prm2"}, "weight" : 53405 }], + "waits" : [] }, "active" : { "threshold" : 2146483145, "keys" : [ {"key" : "EOS65rXebLhtk2aTTzP4e9x1AQZs7c5NNXJp89W8R3HyaA6Zyd4im", "weight" : 57005}, {"key" : "EOS5eVr9TVnqwnUBNwf9kwMTbrHvX5aPyyEG97dz2b2TNeqWRzbJf", "weight" : 57605} ], "accounts" : [ {"permission" : {"actor" : "prm.acct1", "permission" : "prm.prm1"}, "weight" : 53005 }, - {"permission" : {"actor" : "prm.acct2", "permission" : "prm.prm2"}, "weight" : 53405 }] + {"permission" : {"actor" : "prm.acct2", "permission" : "prm.prm2"}, "weight" : 53405 }], + "waits" : [] } } )====="; @@ -2306,12 +2431,141 @@ BOOST_AUTO_TEST_CASE(setcode_test) BOOST_AUTO_TEST_CASE(setabi_test) { try { - abi_serializer abis(enumivo_contract_abi(abi_def())); + const char* abi_def_abi = R"=====( + { + "version": "", + "types": [{ + "new_type_name": "type_name", + "type": "string" + },{ + "new_type_name": "field_name", + "type": "string" + }], + "structs": [{ + "name": "abi_extension", + "base": "", + "fields": [{ + "name": "type", + "type": "uint16" + },{ + "name": "data", + "type": "bytes" + }] + },{ + "name": "type_def", + "base": "", + "fields": [{ + "name": "new_type_name", + "type": "type_name" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "field_def", + "base": "", + "fields": [{ + "name": "name", + "type": "field_name" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "struct_def", + "base": "", + "fields": [{ + "name": "name", + "type": "type_name" + },{ + "name": "base", + "type": "type_name" + }{ + "name": "fields", + "type": "field_def[]" + }] + },{ + "name": "action_def", + "base": "", + "fields": [{ + "name": "name", + "type": "action_name" + },{ + "name": "type", + "type": "type_name" + },{ + "name": "ricardian_contract", + "type": "string" + }] + },{ + "name": "table_def", + "base": "", + "fields": [{ + "name": "name", + "type": "table_name" + },{ + "name": "index_type", + "type": "type_name" + },{ + "name": "key_names", + "type": "field_name[]" + },{ + "name": "key_types", + "type": "type_name[]" + },{ + "name": "type", + "type": "type_name" + }] + },{ + "name": "clause_pair", + "base": "", + "fields": [{ + "name": "id", + "type": "string" + },{ + "name": "body", + "type": "string" + }] + },{ + "name": "abi_def", + "base": "", + "fields": [{ + "name": "version", + "type": "string" + },{ + "name": "types", + "type": "type_def[]" + },{ + "name": "structs", + "type": "struct_def[]" + },{ + "name": "actions", + "type": "action_def[]" + },{ + "name": "tables", + "type": "table_def[]" + },{ + "name": "ricardian_clauses", + "type": "clause_pair[]" + },{ + "name": "abi_extensions", + "type": "abi_extension[]" + }] + }], + "actions": [], + "tables": [], + "ricardian_clauses": [], + "abi_extensions": [] + } + )====="; - const char* test_data = R"=====( - { - "account": "setabi.acc", - "abi": { + auto v = fc::json::from_string(abi_def_abi); + + abi_serializer abis(enumivo_contract_abi(v.as())); + + const char* abi_string = R"=====( + { + "version": "", "types": [{ "new_type_name": "account_name", "type": "name" @@ -2363,110 +2617,104 @@ BOOST_AUTO_TEST_CASE(setabi_test) "key_types" : ["name"] } ], - "ricardian_clauses": [] + "ricardian_clauses": [], + "abi_extensions": [] } - } )====="; - auto var = fc::json::from_string(test_data); - - auto set_abi = var.as(); - BOOST_TEST("setabi.acc" == set_abi.account); - - BOOST_TEST_REQUIRE(1 == set_abi.abi.types.size()); - - BOOST_TEST("account_name" == set_abi.abi.types[0].new_type_name); - BOOST_TEST("name" == set_abi.abi.types[0].type); - - BOOST_TEST_REQUIRE(3 == set_abi.abi.structs.size()); - - BOOST_TEST("transfer_base" == set_abi.abi.structs[0].name); - BOOST_TEST("" == set_abi.abi.structs[0].base); - BOOST_TEST_REQUIRE(1 == set_abi.abi.structs[0].fields.size()); - BOOST_TEST("memo" == set_abi.abi.structs[0].fields[0].name); - BOOST_TEST("string" == set_abi.abi.structs[0].fields[0].type); - - BOOST_TEST("transfer" == set_abi.abi.structs[1].name); - BOOST_TEST("transfer_base" == set_abi.abi.structs[1].base); - BOOST_TEST_REQUIRE(3 == set_abi.abi.structs[1].fields.size()); - BOOST_TEST("from" == set_abi.abi.structs[1].fields[0].name); - BOOST_TEST("account_name" == set_abi.abi.structs[1].fields[0].type); - BOOST_TEST("to" == set_abi.abi.structs[1].fields[1].name); - BOOST_TEST("account_name" == set_abi.abi.structs[1].fields[1].type); - BOOST_TEST("amount" == set_abi.abi.structs[1].fields[2].name); - BOOST_TEST("uint64" == set_abi.abi.structs[1].fields[2].type); - - BOOST_TEST("account" == set_abi.abi.structs[2].name); - BOOST_TEST("" == set_abi.abi.structs[2].base); - BOOST_TEST_REQUIRE(2 == set_abi.abi.structs[2].fields.size()); - BOOST_TEST("account" == set_abi.abi.structs[2].fields[0].name); - BOOST_TEST("name" == set_abi.abi.structs[2].fields[0].type); - BOOST_TEST("balance" == set_abi.abi.structs[2].fields[1].name); - BOOST_TEST("uint64" == set_abi.abi.structs[2].fields[1].type); - - BOOST_TEST_REQUIRE(1 == set_abi.abi.actions.size()); - BOOST_TEST("transfer" == set_abi.abi.actions[0].name); - BOOST_TEST("transfer" == set_abi.abi.actions[0].type); - - BOOST_TEST_REQUIRE(1 == set_abi.abi.tables.size()); - BOOST_TEST("account" == set_abi.abi.tables[0].name); - BOOST_TEST("account" == set_abi.abi.tables[0].type); - BOOST_TEST("i64" == set_abi.abi.tables[0].index_type); - BOOST_TEST_REQUIRE(1 == set_abi.abi.tables[0].key_names.size()); - BOOST_TEST("account" == set_abi.abi.tables[0].key_names[0]); - BOOST_TEST_REQUIRE(1 == set_abi.abi.tables[0].key_types.size()); - BOOST_TEST("name" == set_abi.abi.tables[0].key_types[0]); - - auto var2 = verify_byte_round_trip_conversion( abis, "setabi", var ); - auto setabi2 = var2.as(); - - BOOST_TEST(set_abi.account == setabi2.account); - - BOOST_TEST_REQUIRE(set_abi.abi.types.size() == setabi2.abi.types.size()); - - BOOST_TEST(set_abi.abi.types[0].new_type_name == setabi2.abi.types[0].new_type_name); - BOOST_TEST(set_abi.abi.types[0].type == setabi2.abi.types[0].type); - - BOOST_TEST_REQUIRE(set_abi.abi.structs.size() == setabi2.abi.structs.size()); - - BOOST_TEST(set_abi.abi.structs[0].name == setabi2.abi.structs[0].name); - BOOST_TEST(set_abi.abi.structs[0].base == setabi2.abi.structs[0].base); - BOOST_TEST_REQUIRE(set_abi.abi.structs[0].fields.size() == setabi2.abi.structs[0].fields.size()); - BOOST_TEST(set_abi.abi.structs[0].fields[0].name == setabi2.abi.structs[0].fields[0].name); - BOOST_TEST(set_abi.abi.structs[0].fields[0].type == setabi2.abi.structs[0].fields[0].type); - - BOOST_TEST(set_abi.abi.structs[1].name == setabi2.abi.structs[1].name); - BOOST_TEST(set_abi.abi.structs[1].base == setabi2.abi.structs[1].base); - BOOST_TEST_REQUIRE(set_abi.abi.structs[1].fields.size() == setabi2.abi.structs[1].fields.size()); - BOOST_TEST(set_abi.abi.structs[1].fields[0].name == setabi2.abi.structs[1].fields[0].name); - BOOST_TEST(set_abi.abi.structs[1].fields[0].type == setabi2.abi.structs[1].fields[0].type); - BOOST_TEST(set_abi.abi.structs[1].fields[1].name == setabi2.abi.structs[1].fields[1].name); - BOOST_TEST(set_abi.abi.structs[1].fields[1].type == setabi2.abi.structs[1].fields[1].type); - BOOST_TEST(set_abi.abi.structs[1].fields[2].name == setabi2.abi.structs[1].fields[2].name); - BOOST_TEST(set_abi.abi.structs[1].fields[2].type == setabi2.abi.structs[1].fields[2].type); - - BOOST_TEST(set_abi.abi.structs[2].name == setabi2.abi.structs[2].name); - BOOST_TEST(set_abi.abi.structs[2].base == setabi2.abi.structs[2].base); - BOOST_TEST_REQUIRE(set_abi.abi.structs[2].fields.size() == setabi2.abi.structs[2].fields.size()); - BOOST_TEST(set_abi.abi.structs[2].fields[0].name == setabi2.abi.structs[2].fields[0].name); - BOOST_TEST(set_abi.abi.structs[2].fields[0].type == setabi2.abi.structs[2].fields[0].type); - BOOST_TEST(set_abi.abi.structs[2].fields[1].name == setabi2.abi.structs[2].fields[1].name); - BOOST_TEST(set_abi.abi.structs[2].fields[1].type == setabi2.abi.structs[2].fields[1].type); - - BOOST_TEST_REQUIRE(set_abi.abi.actions.size() == setabi2.abi.actions.size()); - BOOST_TEST(set_abi.abi.actions[0].name == setabi2.abi.actions[0].name); - BOOST_TEST(set_abi.abi.actions[0].type == setabi2.abi.actions[0].type); - - BOOST_TEST_REQUIRE(set_abi.abi.tables.size() == setabi2.abi.tables.size()); - BOOST_TEST(set_abi.abi.tables[0].name == setabi2.abi.tables[0].name); - BOOST_TEST(set_abi.abi.tables[0].type == setabi2.abi.tables[0].type); - BOOST_TEST(set_abi.abi.tables[0].index_type == setabi2.abi.tables[0].index_type); - BOOST_TEST_REQUIRE(set_abi.abi.tables[0].key_names.size() == setabi2.abi.tables[0].key_names.size()); - BOOST_TEST(set_abi.abi.tables[0].key_names[0] == setabi2.abi.tables[0].key_names[0]); - BOOST_TEST_REQUIRE(set_abi.abi.tables[0].key_types.size() == setabi2.abi.tables[0].key_types.size()); - BOOST_TEST(set_abi.abi.tables[0].key_types[0] == setabi2.abi.tables[0].key_types[0]); - - verify_type_round_trip_conversion( abis, "setabi", var); + auto var = fc::json::from_string(abi_string); + auto abi = var.as(); + + BOOST_TEST_REQUIRE(1 == abi.types.size()); + + BOOST_TEST("account_name" == abi.types[0].new_type_name); + BOOST_TEST("name" == abi.types[0].type); + + BOOST_TEST_REQUIRE(3 == abi.structs.size()); + + BOOST_TEST("transfer_base" == abi.structs[0].name); + BOOST_TEST("" == abi.structs[0].base); + BOOST_TEST_REQUIRE(1 == abi.structs[0].fields.size()); + BOOST_TEST("memo" == abi.structs[0].fields[0].name); + BOOST_TEST("string" == abi.structs[0].fields[0].type); + + BOOST_TEST("transfer" == abi.structs[1].name); + BOOST_TEST("transfer_base" == abi.structs[1].base); + BOOST_TEST_REQUIRE(3 == abi.structs[1].fields.size()); + BOOST_TEST("from" == abi.structs[1].fields[0].name); + BOOST_TEST("account_name" == abi.structs[1].fields[0].type); + BOOST_TEST("to" == abi.structs[1].fields[1].name); + BOOST_TEST("account_name" == abi.structs[1].fields[1].type); + BOOST_TEST("amount" == abi.structs[1].fields[2].name); + BOOST_TEST("uint64" == abi.structs[1].fields[2].type); + + BOOST_TEST("account" == abi.structs[2].name); + BOOST_TEST("" == abi.structs[2].base); + BOOST_TEST_REQUIRE(2 == abi.structs[2].fields.size()); + BOOST_TEST("account" == abi.structs[2].fields[0].name); + BOOST_TEST("name" == abi.structs[2].fields[0].type); + BOOST_TEST("balance" == abi.structs[2].fields[1].name); + BOOST_TEST("uint64" == abi.structs[2].fields[1].type); + + BOOST_TEST_REQUIRE(1 == abi.actions.size()); + BOOST_TEST("transfer" == abi.actions[0].name); + BOOST_TEST("transfer" == abi.actions[0].type); + + BOOST_TEST_REQUIRE(1 == abi.tables.size()); + BOOST_TEST("account" == abi.tables[0].name); + BOOST_TEST("account" == abi.tables[0].type); + BOOST_TEST("i64" == abi.tables[0].index_type); + BOOST_TEST_REQUIRE(1 == abi.tables[0].key_names.size()); + BOOST_TEST("account" == abi.tables[0].key_names[0]); + BOOST_TEST_REQUIRE(1 == abi.tables[0].key_types.size()); + BOOST_TEST("name" == abi.tables[0].key_types[0]); + + auto var2 = verify_byte_round_trip_conversion( abis, "abi_def", var ); + auto abi2 = var2.as(); + + BOOST_TEST_REQUIRE(abi.types.size() == abi2.types.size()); + + BOOST_TEST(abi.types[0].new_type_name == abi2.types[0].new_type_name); + BOOST_TEST(abi.types[0].type == abi2.types[0].type); + + BOOST_TEST_REQUIRE(abi.structs.size() == abi2.structs.size()); + + BOOST_TEST(abi.structs[0].name == abi2.structs[0].name); + BOOST_TEST(abi.structs[0].base == abi2.structs[0].base); + BOOST_TEST_REQUIRE(abi.structs[0].fields.size() == abi2.structs[0].fields.size()); + BOOST_TEST(abi.structs[0].fields[0].name == abi2.structs[0].fields[0].name); + BOOST_TEST(abi.structs[0].fields[0].type == abi2.structs[0].fields[0].type); + + BOOST_TEST(abi.structs[1].name == abi2.structs[1].name); + BOOST_TEST(abi.structs[1].base == abi2.structs[1].base); + BOOST_TEST_REQUIRE(abi.structs[1].fields.size() == abi2.structs[1].fields.size()); + BOOST_TEST(abi.structs[1].fields[0].name == abi2.structs[1].fields[0].name); + BOOST_TEST(abi.structs[1].fields[0].type == abi2.structs[1].fields[0].type); + BOOST_TEST(abi.structs[1].fields[1].name == abi2.structs[1].fields[1].name); + BOOST_TEST(abi.structs[1].fields[1].type == abi2.structs[1].fields[1].type); + BOOST_TEST(abi.structs[1].fields[2].name == abi2.structs[1].fields[2].name); + BOOST_TEST(abi.structs[1].fields[2].type == abi2.structs[1].fields[2].type); + + BOOST_TEST(abi.structs[2].name == abi2.structs[2].name); + BOOST_TEST(abi.structs[2].base == abi2.structs[2].base); + BOOST_TEST_REQUIRE(abi.structs[2].fields.size() == abi2.structs[2].fields.size()); + BOOST_TEST(abi.structs[2].fields[0].name == abi2.structs[2].fields[0].name); + BOOST_TEST(abi.structs[2].fields[0].type == abi2.structs[2].fields[0].type); + BOOST_TEST(abi.structs[2].fields[1].name == abi2.structs[2].fields[1].name); + BOOST_TEST(abi.structs[2].fields[1].type == abi2.structs[2].fields[1].type); + + BOOST_TEST_REQUIRE(abi.actions.size() == abi2.actions.size()); + BOOST_TEST(abi.actions[0].name == abi2.actions[0].name); + BOOST_TEST(abi.actions[0].type == abi2.actions[0].type); + + BOOST_TEST_REQUIRE(abi.tables.size() == abi2.tables.size()); + BOOST_TEST(abi.tables[0].name == abi2.tables[0].name); + BOOST_TEST(abi.tables[0].type == abi2.tables[0].type); + BOOST_TEST(abi.tables[0].index_type == abi2.tables[0].index_type); + BOOST_TEST_REQUIRE(abi.tables[0].key_names.size() == abi2.tables[0].key_names.size()); + BOOST_TEST(abi.tables[0].key_names[0] == abi2.tables[0].key_names[0]); + BOOST_TEST_REQUIRE(abi.tables[0].key_types.size() == abi2.tables[0].key_types.size()); + BOOST_TEST(abi.tables[0].key_types[0] == abi2.tables[0].key_types[0]); } FC_LOG_AND_RETHROW() } diff --git a/unittests/bootseq_tests.cpp b/unittests/bootseq_tests.cpp index eac6c52fd3b..847aaaee0c1 100644 --- a/unittests/bootseq_tests.cpp +++ b/unittests/bootseq_tests.cpp @@ -79,12 +79,12 @@ class bootseq_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "enumivo_global_state", data ); } - + auto buyram( name payer, name receiver, asset ram ) { auto r = base_tester::push_action(N(enumivo), N(buyram), payer, mvo() ("payer", payer) ("receiver", receiver) - ("quant", ram) + ("quant", ram) ); produce_block(); return r; @@ -94,9 +94,9 @@ class bootseq_tester : public TESTER { auto r = base_tester::push_action(N(enumivo), N(delegatebw), from, mvo() ("from", "enumivo" ) ("receiver", receiver) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu) - ("transfer", transfer) + ("stake_net_quantity", net) + ("stake_cpu_quantity", cpu) + ("transfer", transfer) ); produce_block(); return r; @@ -142,16 +142,16 @@ class bootseq_tester : public TESTER { produce_block(); return r; } - + auto undelegate_bandwidth( name from, name receiver, asset net, asset cpu ) { auto r = base_tester::push_action(N(enumivo), N(undelegatebw), from, mvo() ("from", from ) ("receiver", receiver) - ("unstake_net_quantity", net) - ("unstake_cpu_quantity", cpu) + ("unstake_net_quantity", net) + ("unstake_cpu_quantity", cpu) ); produce_block(); - return r; + return r; } asset get_balance( const account_name& act ) { @@ -218,7 +218,7 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { // Set enumivo.system to enumivo set_code_abi(N(enumivo), enumivo_system_wast, enumivo_system_abi); - // Buy ram and stake cpu and net for each genesis accounts + // Buy ram and stake cpu and net for each genesis accounts for( const auto& a : test_genesis ) { auto ib = a.initial_balance; auto ram = 1000; @@ -235,7 +235,7 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { auto producer_candidates = { N(proda), N(prodb), N(prodc), N(prodd), N(prode), N(prodf), N(prodg), N(prodh), N(prodi), N(prodj), N(prodk), N(prodl), N(prodm), N(prodn), - N(prodo), N(prodp), N(prodq), N(prodr), N(prods), N(prodt), N(produ), + N(prodo), N(prodp), N(prodq), N(prodr), N(prods), N(prodt), N(produ), N(runnerup1), N(runnerup2), N(runnerup3) }; @@ -250,7 +250,7 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { base_tester::push_action(N(enumivo), N(voteproducer), voter, mvo() ("voter", name(voter)) ("proxy", name(0) ) - ("producers", producers) + ("producers", producers) ); }; votepro( N(b1), { N(proda), N(prodb), N(prodc), N(prodd), N(prode), N(prodf), N(prodg), @@ -272,7 +272,7 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { // Since the total activated stake is less than 150,000,000, reward should remain zero produce_min_num_of_blocks_to_spend_time_wo_inactive_prod(fc::seconds(30 * 24 * 3600)); // 30 days // #warning TODO: now claiming rewards when the pool is empty will throw div by 0 error, fix this as separate issue - // claim_rewards(N(runnerup1)); + // claim_rewards(N(runnerup1)); produce_block(); BOOST_TEST(get_balance(N(runnerup1)).amount == 0); @@ -312,14 +312,14 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { claim_rewards(N(runnerup1)); produce_block(); BOOST_TEST(get_balance(N(runnerup1)).amount > 0); - + const auto first_june_2018 = fc::seconds(1527811200); // 2018-06-01 const auto first_june_2028 = fc::seconds(1843430400); // 2028-06-01 // Ensure that now is yet 10 years after 2018-06-01 yet BOOST_REQUIRE(control->head_block_time().time_since_epoch() < first_june_2028); // This should thrown an error, since block one can only unstake all his stake after 10 years - BOOST_REQUIRE_THROW(undelegate_bandwidth(N(b1), N(b1), asset::from_string("49999500.0000 EOS"), asset::from_string("49999500.0000 EOS")), assert_exception); + BOOST_REQUIRE_THROW(undelegate_bandwidth(N(b1), N(b1), asset::from_string("49999500.0000 EOS"), asset::from_string("49999500.0000 EOS")), assert_exception); // Skip 10 years produce_block(first_june_2028 - control->head_block_time().time_since_epoch()); @@ -329,7 +329,7 @@ BOOST_FIXTURE_TEST_CASE( bootseq_test, bootseq_tester ) { } // Block one should be able to unstake all his stake now undelegate_bandwidth(N(b1), N(b1), asset::from_string("49999500.0000 EOS"), asset::from_string("49999500.0000 EOS")); - + return; produce_blocks(7000); /// produce blocks until virutal bandwidth can acomadate a small user wlog("minow" ); diff --git a/unittests/enumivo.system_tests.cpp b/unittests/enumivo.system_tests.cpp index a1e8f500133..a3dfbe5b6b0 100644 --- a/unittests/enumivo.system_tests.cpp +++ b/unittests/enumivo.system_tests.cpp @@ -2120,6 +2120,16 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, enumivo_system_tester) try { BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); } + { + BOOST_CHECK_EQUAL(0, get_global_state()["total_unpaid_blocks"].as()); + BOOST_REQUIRE_EQUAL(error("condition: assertion failed: not enough has been staked for producers to claim rewards"), + push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); + BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.front()).amount); + BOOST_REQUIRE_EQUAL(error("condition: assertion failed: not enough has been staked for producers to claim rewards"), + push_action(producer_names.back(), N(claimrewards), mvo()("owner", producer_names.back()))); + BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.back()).amount); + } + // stake across 15% boundary transfer(config::system_account_name, "producvoterb", "100000000.0000 EOS", config::system_account_name); BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", "4000000.0000 EOS", "4000000.0000 EOS")); @@ -2157,6 +2167,9 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, enumivo_system_tester) try { } BOOST_REQUIRE_EQUAL(true, all_21_produced); BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); + BOOST_REQUIRE_EQUAL(success(), + push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); + BOOST_REQUIRE(0 < get_balance(producer_names.front()).amount); } } FC_LOG_AND_RETHROW()