Merge Beatrice to Master (#408)

* Skip auth check when pushing self-generated blocks

* Extract public keys before pushing a transaction

* Dereference chain_database shared_ptr

* Updated transaction::signees to mutable

and
* updated get_signature_keys() to return a const reference,
* get_signature_keys() will update signees on first call,
* modified test cases and wallet.cpp accordingly,
* no longer construct a new signed_transaction object before pushing

* Added get_asset_count API

* No longer extract public keys before pushing a trx

and removed unused new added constructor and _get_signature_keys() function from signed_transaction struct

* changes to withdraw_vesting feature(for both cdd and GPOS)

* Comments update

* update to GPOS hardfork ref

* Remove leftover comment from merge

* fix for get_vesting_balance API call

* braces update

* Allow sufficient space for new undo_session

* Throw for deep nesting

* node.cpp: Check the attacker/buggy client before updating items ids

The peer is an attacker or buggy, which means the item_hashes_received is
not correct.

Move the check before updating items ids to save some time in this case.

* Create .gitlab-ci.yml

* Added cli_test to CI

* fixing build errors (#150)

* fixing build errors

vest type correction

* fixing build errors

vest type correction

* fixes 

new Dockerfile

* vesting_balance_type correction

vesting_balance_type changed to normal

* gcc5 support to Dockerfile

gcc5 support to Dockerfile

* use random port numbers in app_test (#154)

* Changes to compiple with GCC 7(Ubuntu 18.04)

* proposal fail_reason bug fixed (#157)

* Added Sonarcloud code_quality to CI (#159)

* Added sonarcloud analysis (#158)

* changes to have separate methods and single withdrawl fee for multiple vest objects

* 163-fix, Return only non-zero vesting balances

* Support/gitlab develop (#168)

* Added code_quality to CI

* Update .gitlab-ci.yml

* Point to PBSA/peerplays-fc commit f13d063 (#167)

* [GRPH-3] Additional cli tests (#155)

* Additional cli tests

* Compatible with latest fc changes

* Fixed Spacing issues

* [GRPH-106] Added voting tests (#136)

* Added more voting tests

* Added additional option

* Adjust p2p log level (#180)

* Added submodule sync to peerplays compile process

* merge gpos to develop (#186)

* issue - 154: Don't allow to vote when vesting balance is 0

* changes to withdraw_vesting feature(for both cdd and GPOS)

* Comments update

* update to GPOS hardfork ref

* fix for get_vesting_balance API call

* braces update

* Create .gitlab-ci.yml

* fixing build errors (#150)

* fixing build errors

vest type correction

* fixing build errors

vest type correction

* fixes 

new Dockerfile

* vesting_balance_type correction

vesting_balance_type changed to normal

* gcc5 support to Dockerfile

gcc5 support to Dockerfile

* Changes to compiple with GCC 7(Ubuntu 18.04)

* changes to have separate methods and single withdrawl fee for multiple vest objects

* 163-fix, Return only non-zero vesting balances

* Revert "Revert "GPOS protocol""

This reverts commit 67616417b7.

* add new line needed to gpos hardfork file

* comment temporally cli_vote_for_2_witnesses until refactor or delete

* fix gpos tests

* fix gitlab-ci conflict

* Fixed few error messages

* error message corrections at other places

* Updated FC repository to peerplays-network/peerplays-fc (#189)

Point to fc commit hash 6096e94 [latest-fc branch]

* Project name update in Doxyfile (#146)

* changes to allow user to vote in each sub-period

* Fixed GPOS vesting factor issue when proxy is set

* Added unit test for proxy voting

* Review changes

* changes to update last voting time

* resolve merge conflict

* unit test changes and also separated GPOS test suite

* delete unused variables

* removed witness check

* eliminate time gap between two consecutive vesting periods

* deleted GPOS specific test suite and updated gpos tests

* updated GPOS hf

* Fixed dividend distribution issue and added test case

* fix flag

* clean newlines gpos_tests

* adapt gpos_tests to changed flag

* Fix to roll in GPOS rules, carry votes from 6th sub-period

* check was already modified

* comments updated

* updated comments to the benefit of reviewer

* Added token symbol name in error messages

* Added token symbol name in error messages (#204)

* case 1: Fixed last voting time issue

* get_account bug fixed

* Fixed flag issue

* Fixed spelling issue

* remove non needed gcc5 changes to dockerfile

* GRPH134- High CPU Issue, websocket changes (#213)

* update submodule branch to refer to the latest commit on latest-fc branch (#214)

* Improve account maintenance performance (#130)

* Improve account maintenance performance

* merge fixes

* Fixed merge issue

* Fixed indentations and extra ';'

* Update CI for syncing gitmodules (#216)

* Added logging for the old update_expired_feeds bug

The old bug is https://github.com/cryptonomex/graphene/issues/615 .

Due to the bug, `update_median_feeds()` and `check_call_orders()`
will be called when a feed is not actually expired, normally this
should not affect consensus since calling them should not change
any data in the state.

However, the logging indicates that `check_call_orders()` did
change some data under certain circumstances, specifically, when
multiple limit order matching issue (#453) occurred at same block.
* https://github.com/bitshares/bitshares-core/issues/453

* Minor performance improvement for price::is_null()

* Use static refs in db_getter for immutable objects

* Minor performance improvement for db_maint

* Minor code updates for asset_evaluator.cpp

* changed an `assert()` to `FC_ASSERT()`
* replaced one `db.get(asset_id_type())` with `db.get_core_asset()`
* capture only required variables for lambda

* Improve update_expired_feeds performance #1093

* Change static refs to member pointers of db class

* Added getter for witness schedule object

* Added getter for core dynamic data object

* Use getters

* Removed unused variable

* Add comments for update_expired_feeds in db_block

* Minor refactory asset_create_evaluator::do_apply()

* Added FC_ASSERT for dynamic data id of core asset

* Added header inclusions in db_management.cpp

* fix global objects usage during replay

* Logging config parsing issue

* added new files

* compilation fix

* Simplified code in database::pay_workers()

* issue with withdrawl

* Added unit test for empty account history

* set extensions default values

* Update GPOS hardfork date and don't allow GPOS features before hardfork time

* refer to latest commit of latest-fc branch (#224)

* account name or id support in all database api

* asset id or name support in all asset APIs

* Fixed compilation issues

* Fixed alignment issues

* check witness signature before adding block to fork db

* Externalized some API templates

* Externalize serialization of blocks, tx, ops

* Externalized db objects

* Externalized genesis serialization

* Externalized serialization in protocol library

* Undo superfluous change

* remove default value for extension parameter

* Replace verify_no_send_in_progress with no_parallel_execution_guard

* fix compilation issues

* fixed cli_wallet log issue

* Port plugin sanitization code

* GRPH-46-Quit_command_cliwallet

* removed multiple function definition

* Fixed chainparameter update proposal issue

* Move GPOS withdraw logic to have single transaction(also single fee) and update API

* Added log for authorization failure of proposal operations

* Votes consideration on GPOS activation

* bump fc version

* fix gpos tests

* Bump fc version

* Updated gpos/voting_tests

* avoid directly overwriting wallet file

* Fixed withdraw vesting bug

* Added unit test

* Update hardfork date for TESTNET, sync fc module and update logs

* avoid wlog as it filling up space

* Beatrice hot fix(sync issue fix)

* gpos tests fix

* Set hardfork date to Jan5th on TESTNET

* Implemented "plugins" config variable

* allow plugin to have descriptions

* Merge pull request #444 from oxarbitrage/elasticsearch

Elasticsearch plugin

* Merge pull request #500 from oxarbitrage/elasticsearch-extras

es_objects plugin

* Merge pull request #873 from pmconrad/585_fix_history_ids

Fix history ids

* Merge pull request #1201 from oxarbitrage/elasticsearch_tests2

Elasticsearch refactor

* Merge pull request #1271 from oxarbitrage/es_objects

refine es_objects plugin

* Merge pull request #1429 from oxarbitrage/es_objects_templates

Add an adaptor to es_objects and template function to reduce code

* Merge pull request #1458 from oxarbitrage/issue1455

add option elasticsearch-start-es-after-block to es plugin

* Merge pull request #1541 from oxarbitrage/es_objects_start_after_block

add es-objects-start-es-after-block option

* explicitly cleanup external library facilities

* Merge pull request #1717 from oxarbitrage/issue1652

add genesis data to es_objects

* Merge pull request #1073 from xiangxn/merge-impacted

merge impacted into db_notify

* Merge pull request #1725 from oxarbitrage/issue1682

elasticsearch history api #1682

* change ES index prefixes to Peerplays-specific

* sync develop with beatrice

* fix the data writing to ES during sync issues

* fix CLI tests

* brought updates from mainnet branch (#285)

* Fix unit test failures (#289)

* fixed unit test failures from the recent merges

* fixed unit test failures from the recent merges

* enable snapshot plugin (#288)

* sync fc branch(build optimization changes)

* update to es plugin

* fix verify witness signature method (#295)

* enable mandatory plugins to have smooth transition for next release

* updated tests to keep in-line with plugin changes

* Merge Elasticplugin, snapshot plugin and graphene updates to beatrice (#304)

* check witness signature before adding block to fork db

* Replace verify_no_send_in_progress with no_parallel_execution_guard

* fixed cli_wallet log issue

* Port plugin sanitization code

* avoid directly overwriting wallet file

* Implemented "plugins" config variable

* allow plugin to have descriptions

* Merge pull request #444 from oxarbitrage/elasticsearch

Elasticsearch plugin

* Merge pull request #500 from oxarbitrage/elasticsearch-extras

es_objects plugin

* Merge pull request #873 from pmconrad/585_fix_history_ids

Fix history ids

* Merge pull request #1201 from oxarbitrage/elasticsearch_tests2

Elasticsearch refactor

* Merge pull request #1271 from oxarbitrage/es_objects

refine es_objects plugin

* Merge pull request #1429 from oxarbitrage/es_objects_templates

Add an adaptor to es_objects and template function to reduce code

* Merge pull request #1458 from oxarbitrage/issue1455

add option elasticsearch-start-es-after-block to es plugin

* Merge pull request #1541 from oxarbitrage/es_objects_start_after_block

add es-objects-start-es-after-block option

* explicitly cleanup external library facilities

* Merge pull request #1717 from oxarbitrage/issue1652

add genesis data to es_objects

* Merge pull request #1073 from xiangxn/merge-impacted

merge impacted into db_notify

* Merge pull request #1725 from oxarbitrage/issue1682

elasticsearch history api #1682

* change ES index prefixes to Peerplays-specific

* sync develop with beatrice

* fix the data writing to ES during sync issues

* fix CLI tests

* brought updates from mainnet branch (#285)

* Fix unit test failures (#289)

* fixed unit test failures from the recent merges

* fixed unit test failures from the recent merges

* enable snapshot plugin (#288)

* sync fc branch(build optimization changes)

* update to es plugin

* fix verify witness signature method (#295)

* enable mandatory plugins to have smooth transition for next release

* updated tests to keep in-line with plugin changes

Co-authored-by: Sandip Patel <sandip@knackroot.com>
Co-authored-by: Peter Conrad <conrad@quisquis.de>
Co-authored-by: Alfredo <oxarbitrage@gmail.com>
Co-authored-by: Abit <abitmore@users.noreply.github.com>
Co-authored-by: crypto-ape <43807588+crypto-ape@users.noreply.github.com>
Co-authored-by: gladcow <s.gladkov@pbsa.info>

* sync latest fc commit on beatrice

* nh5050:winner ticket id changes

* update HF check

* update HF-check

* code improvement with edge case handling

* update HF check

* changes to fetch operations based on lottery asset

* update HF date 16th April 2020

* update variable type to uint64

* update HF to 15th April

* ci: update .gitlab-ci.yml

* NFT Marketplace HRP Beatrice Merge (#371)

* private-key option update

* ppy marketplace 1 - add evaluators and objects

* NFT object and basic operations

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* NFT evaluators and basic tests, no evaluator checks

* Evaluator checks in place

* ppy marketplace 2 - batch sale, offer_object escrow

* Database API

* Wallet API

* NFT metadata implemented

* Fix NFT tests

* Database API for NFT metadata and enumerables

* ppy marketplace 4 - Add tests NFT+Marketplace

* ppy marketplace 5 - Add revenue split

* ppy marketplace 6 - Remove unnecessary files

* ppy marketplace 7 - Add db, wallet changes and some NFT fixes

* ppy marketplace 8 - Add pagination for list APIs

* ci: update .gitlab-ci.yml

* New DB API, list all NFTs, list NFTs by owner

* Marketplace + NFT + RBAC (#368)

* rbac1 - evaluators and op validators added
* rbac2 - op_type hf checks
* rbac3 - tx auth verify changes
* Update .gitlab-ci.yml
* rbac4 - basic op tests
* rbac5 - clear expired and deleted permission linked auths
* rbac6 - more tests
* rbac7 - more tests
* rbac8 - more tests
* rbac9 - wallet and db api changes
* rbac10 - db api changes for required signature fetch
* rbac11 - add db_api tests
* rbac12 - add missing code for key auths

Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>

* Fix nft_get_token_uri returning empty string

* Fix nft_mint_evaluator to save token_uri

* Fix cli_wallet to properly pass metadata id for nft_create

* ppy marketplace 9 - FC_REFLECT offer create op

* Add stricter checks to NFTs

* GPOS2 HF - Handle rolling period on missing blocks (#369)

* Mainnet chain halt 5050 Issue (#370)

* Unlisting offers, add result in offer history object

* Reverting genesis.json wrong commit

* Add non-transferable non-sellable properties to NFTs

* Review comments - change variable names, use scoped enums

* nft_metadata_update changes

* NFT HF checks and op fee addition changes

* NFT make revenue_split integer from double

* revenue_split condition check allow zero or above

* Peerplays Marketplace + NFT (#367)

* ppy marketplace 1 - add evaluators and objects

* NFT object and basic operations

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* NFT evaluators and basic tests, no evaluator checks

* Evaluator checks in place

* ppy marketplace 2 - batch sale, offer_object escrow

* Database API

* Wallet API

* NFT metadata implemented

* Fix NFT tests

* Database API for NFT metadata and enumerables

* ppy marketplace 4 - Add tests NFT+Marketplace

* ppy marketplace 5 - Add revenue split

* ppy marketplace 6 - Remove unnecessary files

* ppy marketplace 7 - Add db, wallet changes and some NFT fixes

* ppy marketplace 8 - Add pagination for list APIs

* New DB API, list all NFTs, list NFTs by owner

* Marketplace + NFT + RBAC (#368)

* rbac1 - evaluators and op validators added
* rbac2 - op_type hf checks
* rbac3 - tx auth verify changes
* Update .gitlab-ci.yml
* rbac4 - basic op tests
* rbac5 - clear expired and deleted permission linked auths
* rbac6 - more tests
* rbac7 - more tests
* rbac8 - more tests
* rbac9 - wallet and db api changes
* rbac10 - db api changes for required signature fetch
* rbac11 - add db_api tests
* rbac12 - add missing code for key auths

Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>

* Fix nft_get_token_uri returning empty string

* Fix nft_mint_evaluator to save token_uri

* Fix cli_wallet to properly pass metadata id for nft_create

* ppy marketplace 9 - FC_REFLECT offer create op

* Add stricter checks to NFTs

* Unlisting offers, add result in offer history object

* Reverting genesis.json wrong commit

* Add non-transferable non-sellable properties to NFTs

* Review comments - change variable names, use scoped enums

* nft_metadata_update changes

* NFT HF checks and op fee addition changes

* NFT make revenue_split integer from double

* revenue_split condition check allow zero or above

Co-authored-by: Srdjan Obucina <obucinac@gmail.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>

* Beatrice NFT HF

Co-authored-by: pbattu123 <43043205+pbattu123@users.noreply.github.com>
Co-authored-by: pbattu123 <p.battu@pbsa.info>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>

* ci: added additional security scanning for gitlab

* Merge develop into beatrice (#386)

* Fix building on Ubuntu 18.04 with GCC 7

* Peerplays SON plugin skeleton (#122)

* Peerplays SON plugin skeleton
* SON tests skeleton

* Part two of SON-83 - plugins option in command line and config file (#126)

- Empty SON plugin is INACTIVE by default
- To enable it, add peerplays_sidechain to plugins section in
  config file, or use --plugins command line option
- Plugin can work with or without witness

* SON11 - Add chain extension parameter to set SON count

* [SON-107] Merge develop branch to SONs-base (#166)

* fix rng and get_winner_numbers implemented

* coipied code for bitshares fixing 429 and 433 isuues

* ticket_purchase_operation implemented. added lottery_options to asset

* lottery end implemented

* minor logic changes. added db_api and cli_wallet methods

* fix reindex on peerplays network

* fix some tests. add gitlab-ci.yml

* add pull to gitlab-ci

* fix

* fix and comment some tests

* added owner to lottery_asset_options. commented async call in on_applied_block callback

* added get_account_lotteries method to db_api and cli, lottery end_date and ticket_price verification

* merge get_account_lotteries branch. fix create_witness test

* fix test genesis and end_date verification

* fixed indices sorting and lottery end checking by date

* update db_version for replay and removed duplicate include files

* Added ntp and upgraded boost version

* Revert "GPOS protocol"

* need to remove backup files

* virtual-op-fix for deterministic virtual_op number

* Merged beatrice into 5050

* Updated gitmodules, changes to allow voting on lottery fee

* Removed submodule libraries/fc

* Added libraries/fc

* added missing , in types.hpp

* Added sweeps parameters to parameter_extension

* added missing comma in operations.hpp, small changes to config.hpp

* fixed returntype in chain_parameters.hpp

* removed sweeps_parameter_extensions

* Changed fc library

* fixed asset_object

* Changed peerplays-fc submodule

* Changed fc submodule to ubuntu 18.04 upgrade

* Removed submodule libraries/fc

* Added fc library back

* fix casting in overloaded function

* Removed blind_sign and unblind_signature functions

* Added new lottery_asset_create_operation

* Changed sweeps hardfork time

* Removed redundant if from asset_evaluator and fixed db_notify

* fixed duplicate code in fee_tests

* removed redundant tgenesis file

* Enable building on Ubuntu 18.04 using GCC 7 compiler

* fix: is_benefactor_reward had the default value of true when not set

* Docker file for Ubuntu 18.04

Base image updated to Unbuntu 18.04
Prerequisite list updated
Basic configuration updated

* Quick fix: Added missing package pkg-config

* Docker file updates

* 5050 fee update and compilation error fix

* Dockerfile, set system locale

Prevents locale::facet::_S_create_c_locale name error

* Update README.md

Fix typo

* Update README.md

* Changed hardfork time for SWEEPS and Core-429

* revert master changes that were brought in previous commit

* Fixed error when account_history_object with id 0 doesnt exist

* Fixed error while loading object database

* test for zero id object in account history

* Reorder operations in Dockerfile, to make image creation faster

- Reorder prevents unnecessary building of Boost libraries

* Fix for irrelevant signature included issue

* fix copyrigth messages order

* remove double empty lines

* Backport fix for `get_account_history` from https://github.com/bitshares/bitshares-core/pull/628 and add additional account history test case

* NTP client back

* GRPH-53-Log_format_error

* Merge pull request #1036 from jmjatlanta/issue_730

Add fail_reason to proposal_object

* Unit test case fixes and prepared SONs base

* Use offsetof instead of custom macro

* Hide some compiler warnings

* Make all the tests compile

* Add nullptr check in api.cpp for easier testing

* Add test case for broadcast_trx_with_callback API

* Unit test case fixes and prepared SONs base

* Merge pull request #714 from pmconrad/json_fix

JSON fix

* Increase max depth for trx confirmation callback

* Adapt to variant API with `max_depth` argument

* Update fc submodule

* Created unit test for #325

* remove needless find()

* GRPH-4-CliWallet_crash_ctrlD

* fix copyright message

* Make all the tests compile

* increase delay for node connection

* Increase block creation timeout to 2500ms

* remove cache from cli get_account

* add cli tests framework

* Adjust newly merged code to new API

* Improved resilience of block database against corruption

* Merged changes from Bitshares PR 1036

* GRPH-76 - Short-cut long sequences of missed blocks

Fixes database::update_global_dynamic_data to speed up counting missed blocks.
(This also fixes a minor issue with counting - the previous algorithm would skip missed blocks for the witness who signed the first block after the gap.)

* Moved reindex logic into database / chain_database, make use of additional blocks in block_database

Fixed tests wrt db.open

* Enable undo + fork database for final blocks in a replay

Dont remove blocks from block db when popping blocks, handle edge case in replay wrt fork_db, adapted unit tests

* Log starting block number of replay

* Prevent unsigned integer underflow

* Fixed lock detection

* Dont leave _data_dir empty if db is locked

* Writing the object_database is now almost atomic

* Improved consistency check for block_log

* Cut back block_log index file if inconsistent

* Fixed undo_database

* Added test case for broken merge on empty undo_db

* Merge pull request #938 from bitshares/fix-block-storing

Store correct block ID when switching forks

* exclude second undo_db.enable() call in some cases

* Add missing change

* change bitshares to core in message

* Fixed integer overflow issue

* Fix for for history ID mismatch ( Bitshares PR #875 )

* Update the FC submodule with the changes for GRPH-4

* Fix #436 object_database created outside of witness data directory

* supplement more comments on database::_opened variable

* prevent segfault when destructing application obj

* Fixed duplicate ops returned from get_account_history

* minor performance improvement

* Added comment

* Merged Bitshares PR #1462 and compilation fixes

* Support/gitlab (#123)

* Updated gitlab process

* Fix undefined references in cli test

* Fixed test failures and compilation issue

* Fixed account_history_pagination test

* Fix compilation in debug mode

* Removed unrelated comment

* Skip auth check when pushing self-generated blocks

* Extract public keys before pushing a transaction

* Dereference chain_database shared_ptr

* Updated transaction::signees to mutable

and
* updated get_signature_keys() to return a const reference,
* get_signature_keys() will update signees on first call,
* modified test cases and wallet.cpp accordingly,
* no longer construct a new signed_transaction object before pushing

* Added get_asset_count API

* Allow sufficient space for new undo_session

* Throw for deep nesting

* No longer extract public keys before pushing a trx

and removed unused new added constructor and _get_signature_keys() function from signed_transaction struct

* Added cli_test to CI

* use random port numbers in app_test (#154)

* proposal fail_reason bug fixed (#157)

* Added Sonarcloud code_quality to CI (#159)

* Added sonarcloud analysis (#158)

* fix for lottery end

* fix declarations

* fix declarations

* fix boost integer

* fix compilation

* fix chain tests

* fix app_test

* try to fix cli test

* fix incorrect max_depth param

* working cli test

* correct fc version

* Revert "[SON-107] Merge develop branch to SONs-base (#166)"

This reverts commit 499e318199.

* Fix build error, add missing GRAPHENE_MAX_NESTED_OBJECTS parameter

* Plugin description added, SON plugin params example

* fix for cli test

* SON object, operations, cli_wallet commands and RPC (#160)

- create_son, update_son, delete_son, list_sons
- get_sons, get_son_by_account, lookup_son_accounts, get_son_count
- vote_for_son, update_son_votes
- claim_registered_son
- get_son in cli_wallet
- Updating global_property_object
- Decrease SON hardfork time for test purposes
- CLI Wallet tests imported from develop branch

* fix affiliate tests

* SON-108 - Add cli wallet tests for create_son (#174)

* SON-108 - Add cli wallet tests for create_son

* Add info message at the beginning and end of the SON CLI tests

* Minor output message change

* Enable Boost test messages in unit tests

* [SON-110] get_son cli test (#173)

* get_son cli test

* update_son cli test

* Add cli wallet tests for vote_for_son (#175)

* fix insert object processing in indexes, son_delete is working

* Fix segfault when using delete_son from cli_wallet (#177)

* Fix segfault when using list_sons from cli_wallet (#178)

* Add son_delete cli tests (#182)

* Add son_delete cli tests

* add son vesting config options

* add vesting balance type support

* add dormant vesting policy for son

* add precision to son vesting amount

* SON118-Add Budget for SON (#165)

* SON118-Add Budget for SON

* SON118 - Compilation errors fix

* SON118 - Proper commenting around pay_sons function

* SON118 - Comment correction, SON statistics object implementation type correction

* SON118 - Add missing index init and reflect enums

* SON118 - Correcting the indentation

* SON118 SON144 - Add unit test, code fixes and resolve failures for existing tests

* SON118 SON144 - Removing extra spaces added

* abstraction of dormant vesting policy

* force son create vesting balance to have dormant policy

* remove not needed code from wallet son commands, add delete son test to cli (#181)

* Active SONs, list up to 15, order by votes, add test (#185)

* Add test for selecting 15 SONs with highest votes
* Display up to 15 active SONs, SON ordering by total_votes

* fix build error (#191)

* fix build error

* adapt son_pay_test to dormant vesting policy

* [SON-113] Unit test for cli `update_son_votes` (#179)

* refactor cli tests

* update_son_votes tests

* list_sons test

* test changes in get_global_properties() result

* fix generate_block failure

* fix update_son_votes test

* improve update_son cli test

* fix linking errors

* refactor select_top_fifteen_sons test

* refactor other son cli tests to use son_test_helper

* create_vesting call in wallet_api

* test fix

* fix create_son in wallet_api and cli tests

* SON126 - Witness Proposals to deregister SONs (#192)

* SON126 - Witness Proposals to deregister SONs

* SON126 - Approval by witness, removal of son_proposal_object, commenting

* SON126 - Witness proposal tests and related fixes

* SON126 - Proper commenting

* fix son_delete_operation reflection

* [SON-160] Fix create_vesting wallet_api call (#206)

* Fix create_vesting wallet_api call

* change type for vesting_type in create_vesting_balance

* [SON-113] Fix several issues in update_son_votes call in wallet_api  (#208)

* do not allow update votes with both empty lists

* fix error messages

* check number of sons against votes number in account_object

* Update error message

* list_active_sons api call implementation

* unit test for list_active_sons

* fix code style

* use assert instead of checking condition with low possibility

* Fixed betting tests (#217)

* Fixed betting tests

* Removed comments

* removed unrelated parameter description from delete_son

* Add Bitcoin network listener to a SON plugin (#196)

* Add Bitcoin network listener to a SON plugin
* Add default parameters for Peerplays Bitcoin test node
* Add Bitcoin block processing
* Update source code to last designs
* Set default parameters for peerplays_sidechain plugin to Bitcoin test server
* WIP: Some Bitcoin transaction processing

* [SON-199] Fix unit tests (#233)

* fix app_test

* fix son_delete_test

* Add peerplays account for a SON in a config/command line options (#231)

* SON193-SON200- SON Heartbeats and maintenance mode changes (#241)

* SON193-SON200- SON Heartbeats and maintenance mode changes

* SON193-SON200- SON Heartbeats and maintenance tests

* User sidechain address mappings (#240)

* WIP: Sidechain objects
* Revert "WIP: Sidechain objects"
This reverts commit 8676940a28.
* WIP: User sidechain address mappings
* Fix reflection problem
* Reflect missing members of sidechain_address_update_operation
* Add sidechain address operation tests
* Enable RPC calls
* Fix build errors due to merge conflict
* Fix RPC, add CLI wallet commands for sidechain addresses
* Improved peerplays_sidechain_plugin_impl
* Remove short param for son-id
* Fix crashing errors on bitcoin event received
* Code review changes

* SON207 - Introduce scheduling for SONs similar to witnesses (#251)

* Extend SON objects to contain sidechain public keys (#254)

* SON194-SON195 - Report SON Down, addition of SON Account for sidechain consensus (#244)

* SON194-SON195 - Addition of SON BTC Account and report son down changes

* SON194-SON195 - SON BTC Account errors rectification

* SON194-SON195 - Adding Tests

* User sidechain address mappings (#240)

* WIP: Sidechain objects
* Revert "WIP: Sidechain objects"
This reverts commit 8676940a28.
* WIP: User sidechain address mappings
* Fix reflection problem
* Reflect missing members of sidechain_address_update_operation
* Add sidechain address operation tests
* Enable RPC calls
* Fix build errors due to merge conflict
* Fix RPC, add CLI wallet commands for sidechain addresses
* Improved peerplays_sidechain_plugin_impl
* Remove short param for son-id
* Fix crashing errors on bitcoin event received
* Code review changes

* SON207 - Introduce scheduling for SONs similar to witnesses (#251)

* Extend SON objects to contain sidechain public keys (#254)

Co-authored-by: obucinac <obucinac@users.noreply.github.com>

* SON206 - Plugin SON Heartbeat changes (#250)

* SON206 - Plugin SON Heartbeat changes

* SON206 - Plugin SON Heartbeat changes, comment removal

* SON206 - Plugin SON Heartbeat changes, stub testing and changes

* SON206 - Plugin SON Heartbeat changes, removing debugs prints

* Wallet recreation on new set of SONs voted in (#256)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* Fix build errors

* SON212-SON213 - Add Sidechain Plugin Code to report and approve SON Down proposal (#260)

* SON212 - Add Sidechain Plugin Code to report SON Down

* SON212-SON213 - Add Sidechain Plugin Code to report SON Down, Approve proposal from sidechain plugin

* SON212-SON213 - Fix Build Error (#262)

* SON212-SON213 - Fix Build Error

* SON212-SON213 - Fix Build Error Add smart_ref definition for linking

* Updated gitlab CI to sync submodules (#265)

* SON217 - SON Maintenance,Heartbeat state transition changes (#264)

* SON217 - SON Maintenance,Heartbeat state transition changes

* SON217 - SON Maintenance,Heartbeat state transition changes

* [SON-202] Implement cli_wallet commands for maintenance mode (#261)

* Add stop_son_maintenance CLI call

* fix bug with SON activation

* son_maintenance_operation

* son_maintenance_operation tests

* cli test for son maintenance state

* start_son_maintenance CLI call

* keep maintenance state during active SON set changes

* Quick fix for list_active_sons

* SON199 - Fix Unit Test Failure (#268)

* Quickfix for update_sidechain_address and delete_sidechain_address cli commands

* SON206_Plugin_CrashFix_Reorg - Plugin Changes (#272)

* SON206_Plugin_CrashFix_Reorg - Plugin Changes

* SON206_Plugin_CrashFix_Reorg - add owner auths to consensus account

* SON165 - Keys mapping missing from wallet data (#274)

* SON232 - Avoid duplicate proposals from sidechain plugin (#275)

* SON233 - Provide correct downtime metrics to user (#278)

* son_wallet_object operations and multisig wallet recreation by RPC (#263)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object
* son_wallet_object operations
* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
* son_wallet_object API and cli wallet commands
* Send RPC command to bitcoin node to recreate multisig wallet
* Updating wallet info through operation instead through database.modify() for persistance
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
* Refactor primary wallet recreation
* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
* Quickfix for checking payer in evaluator
* Fix failing son_wallet_tests
- Check for son_btc_account is temporarely disabled
* Remove redundant file
Co-authored-by: gladcow <jahr@yandex.ru>

* SON214 - Request maintenance wallet commands (#280)

* SON wallet transfer object and operations (#279)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add is_active_son guards for sidechain events processing

Co-authored-by: gladcow <jahr@yandex.ru>

* Support multiple SON nodes per software instance (#282)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Temoprary disable account history tests for tracking accounts

Co-authored-by: gladcow <jahr@yandex.ru>

* [SON-209] Create P2SH address with custom redeemScript (#271)

* Create redeem script for SONs primary wallet

* Add importaddress call

Allows to watch for related transactions without private keys import

* Get UTXO set for watched addresses

* createrawtransaction call

* signing PW spending transaction

* unit test for btc tx serialization

* sending PW transfer in test

* BIP143 tx signing

* use bech32 address format

* use single sha256 for lock script

* Digest fix

* working signing

* separate signing

* test partially signed PW transfer

* add ability to gather signatures before signing (#290)

* [SON-242] fix list_active_sons call after deleting an active son (#292)

* test to reproduce error in list_active_sons after delete_son

* prevent exception in list_active_list

* [SON-260] Sidechain Token withdrawal (#286)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Skeleton of sidechain_net_handler_peerplays

* Skeleton of Peerplays network listener

* Temoprary disable account history tests for tracking accounts

* Full Peerplays listener, use GRAPHENE_SON_ACCOUNT instead son_btc_account

* Renaming son_wallet_transfer* to son_wallet_deposit*, introducing son_wallet_withdrawal*

* Extend sidechain_address_object to contain withdrawal addresses
- Withdrawal address is the address where system will send sidechain currencies

* Rename son_wallet_withdrawal* to son_wallet_withdraw*

* Some refactoring

* Withdrawal refactoring

* Withdrawal refactoring

Co-authored-by: gladcow <jahr@yandex.ru>

* SON261 - Bitcoin deposit, withdrawal, PW transfer (#287)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Skeleton of sidechain_net_handler_peerplays

* Skeleton of Peerplays network listener

* SON261 - Deposit transfer ( user address -> PW ) and Withdrawal transfer ( PW -> user address ) for m-of-n multisig

* Temoprary disable account history tests for tracking accounts

* Full Peerplays listener, use GRAPHENE_SON_ACCOUNT instead son_btc_account

* Renaming son_wallet_transfer* to son_wallet_deposit*, introducing son_wallet_withdrawal*

* Extend sidechain_address_object to contain withdrawal addresses
- Withdrawal address is the address where system will send sidechain currencies

* Rename son_wallet_withdrawal* to son_wallet_withdraw*

* Some refactoring

* SON261 - Withdrawal transfer ( PW -> user address ), addition of bitcoin public private key to config.ini for multiple sons mode

* Withdrawal refactoring

* Withdrawal refactoring

* SON261 - Fix prepare_tx

* SON261 - Add PW->PW Transfer and Code reorg

* Fix file permissions

Co-authored-by: obucinac <obucinac@users.noreply.github.com>
Co-authored-by: gladcow <jahr@yandex.ru>

* [SON-264] Integrating deposit/withdrawals with bitcoin transactions (feature/SON-260 + SON261 branches) (#291)

* Partial integration done, some Bitcoin RPC refactoring
* CLang Format config file
* CLang Format config file v2.0
* Fix repeating tasks that should be executed by scheduled SON only
* Fix withdrawal
* Integrate PW wallet fund moving
* Resolve conflicts

Co-authored-by: gladcow <jahr@yandex.ru>
Co-authored-by: satyakoneru <satyakoneru.iiith@gmail.com>

* SON200 - SON Down proposal broken after latest merges (#294)

* SON200 - SON Down proposal broken after latest merges

* Add the owner weight threshold similar to witnesses and committee accounts

* SON269 - Move SON deregistration to Plugin from witness (#298)

* SON200 - SON Down proposal broken after latest merges

* Add the owner weight threshold similar to witnesses and committee accounts

* SON269 - Move SON deregistration to Plugin from witness

* Various SON improvements (#297)

* Refactor SON processing
* Better exposure of sidechain private keys in sidechain handlers
* Support non default Bitcoin wallets
* Fix crash on config file recreation
* clang-format formatting
* New Bitcoin wallet related RPC calls
* Add missing create_son_deregister_proposals calls
* Add missing create_son_deregister_proposals calls
* Add loading/unlocking/locking of non-default bitcoin wallet
* Bitcon RFC logs improved, proposal aprovement improved
* Move signal connection after handlers are created

* Merge develop into SONS

* SON118 - Add tx sign metrics for SON rewards (#302)

* resolved compilation issues and other conflicts

* SON202 - Maintenance improvements (#303)

* Quickfix, remove dead code, return result from wallet withdraw do_evaluate

* SON275 - ZMQ Crash on application exit (#306)

* SON275 - ZMQ Crash on application exit

* SON275 - Fix Indentation

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* need to assign both name and id to stats id

* fix unit test case failures(add gpos vesting before voting)

* SON276 - Fix SON proposal exceptions - I (#307)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Add SON statistic for tracking reported sidechain transactions (#308)

- Deposit and Withdrawal object extended to contain expected
  and received transaction reports from SON network
- SON statistic object extended to contain total number of
  sidechain transactions reported by SON network when SON was
  active and number of transactions reported by single SON when
  he was active
- Code formatting

* Allow voting for son, only if GPOS vesting balance available

* notifications of SONS should get restrict to sons functionality

* update GPOS hardfork date to sons branch

* SON127 - Add son parameter extensions to genesis, push proposal fix (#310)

* SON276 - Fix SON proposal exceptions - I

* SON127 - Add son parameter extensions to genesis, push proposal fix

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* update GPOS HF to fall in before SONS HF, remove check

* updated unit test cases to reflect GPOS vesting and update account id's according to sons-account

* [SON-24] - SON Rewards missing serialisations and end to end testing (#313)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Revert "Merge develop branch changes(GPOS+graphene updates) into SONs branch"

* [SON-122] - SON Statistics improvements and consensus account creation (#318)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Replace raw with psbt transactions to support parital tx signing (#311)

* RPC calls for PSBT, raw transactions replaced with PSBT
* Fix estimatesmartfeerate, extensive RPC calls logging for debugging purposes
* Remove dead code
* Partial signing functional for deposit and withdrawal
* Fix sidechain_type declarations
* Depositing Peerplays asset refactored
* Partial signing functional for primary wallet funds moving
* Prettier logs
* Refactor multiple SON support processing
* Serialize field complete from sidechain_transaction_sign_operation
* Refactor transaction signing in particular order, BTC only (maybe) need it
* Add number of required signatures parameter for addmultisigaddress
* Change default bitcoin node parameters
* Transaction signing only by scheduled son
* Removed scheduling log
* Prevent PW funds moving to the same address
* Refactor sidechain_transaction_object processing, code cleanup
* Remove obsolete tests
* Decrease logging
* Code readability
* When updated, import son wallet bitcoin address to bitcoin wallet
* When updated, recreate son wallet bitcoin address on each node
* Refactor on_changed_objects, move it into task
* Add check to prevent deposit/withdrawal double processing
* Improved check for sidechain transaction object creation
* Single sidechain transaction signature per block allowed only
* Unlock wallet on addmultisigaddress
* Import both address and redeem script on primary wallet change, fix some compiler warnings
* Fix invalid list of signers for PW funds transfer

* [SON-312] Refactor create_son to assign owner account public key as a signing_key

remove key derivation from create son (#323)
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>

* [SON-271] Merge recent develop branch changes(both GPOS and graphene updates) into SONs branch (#322)

* Parallelizing sidechain transaction signing (#319)

* [SON-321, SON-323] Deposit/Withdraw object creation refactoring (#320)

* Remove proposals for creating deposit and withdrawal objects, strenghten evaluator checks
* Only active SON can create the object
* Only expected SON can confirm the transaction
* Transaction must be initiated (paid) by SON account owner (SON account given in operation)
* Transaction confirmation must contain exactly the same data as existing object
* Mirror SON owner account weights from son-account.active.account_auths to active SONs
* Fix duplicated typedef, peerplays_sidechain::sidechain_type to chain::sidechain_type
* Add missing serialized field

* [SON-318_SON-319] - Add approval checks for son down, deregister proposals (#321)

* [SON-318_SON-319] - Add approval checks for son down and deregister proposals

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>

* [SON-311] Add try_create_son call without explicit deposit params (#324)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - Fix build error

* Quickfix - change GPOS and SON hardfork times

* [SON-332] Check gitlab building process for dirty build (#327)

* Fix failing son test, fix data types and check condition
* Very clean build on Gitlab

* update son-account parameters (#328)

* [SON-329] Hotfix - Enable test test_update_dividend_interval

* [SON-313] - Limit SON functionality when min no. of sons are not present (#329)

* [SON-313] - Limit SON functionality when min no. of sons are not present

* Revert SON HF related checks and tests

* Remove the capability to process proposals in plugin

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-307] Create PBTC asset  (#326)

* SON-297_SON-336 - SON vesting functionality broken after graphene merge (#331)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Hotfix - add initialization values to extension params, remove trailing spaces

* [SON-305, SON-308, SON-310] Use BTC asset in bitcoin deposits and withdraws (#332)

* [SON-339] - SON Schedule crash (#334)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-291,SON-328] - SON Configuration invalid, PW creation issues (#335)

* [SON-291,SON-328] - SON Configuration invalid, PW creation issues

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-322, SON-324] Approval checks for processing deposit/withdrawal (#330)

* Refactor proposal processing
* Added check for approving son_wallet_deposit_process_operation
* Added check for approving son_wallet_withdraw_process_operation
* Calculating exchange rates fixed
* Fix depositing Peerplays assets

* [SON-320] Added check for approving son_wallet_update_operation (#336)

* [SON-325] Added check for approving sidechain_transaction_create_operation (#337)

* [SON-341, SON-342] Fix issue with deposits number (#339)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* [SON-344] BTC asset is created with wrong quote asset id, Fixed (#341)

* [SON-344] BTC asset is created with wrong quote asset id, Fixed
* Respond to code review

* [SON-346] Sidechain transaction marked as complete even though current_weight < threshold, Fixed (#342)

* [SON-348] Transaction hash not saved in object after Bitcoin transaction is sent (#343)

- Fixed
- Unused parameters removed

* [SON-337] - Prevent update_son_votes without GPOS vesting (#344)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-353] Refactor PW processing, PW transfer fixed (#347)

* Add proposal checks for deposit and withdrawal
* Refactor proposal approvement
* Fix transaction verification
* Remove logs

* [SON-354] Fix son_info compare function (#350)

* check object's id (#351)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* SON Weighted Multi Signature Signing (#349)

* Bring in the bitcoin utils code into plugin
* Add tx creation, signing and tests
* tx deserialization fix
* add 10-of-14 multisig address test
* Add signing and verification tests and sign_transaction_standalone
* Add send_transaction_standalone function
* Debug logs and additional tests
* Fix for son deletion in the middle
* Extend script_builder
* Witness script for weighted wallet
* btc_weighted_multisig_address implementation
* Fix for bad-txns-nonstandard-inputs
* Weighted multisignature address test
* Create test tx with weighted multisig wallet
* Fix the issues with tx signing
* End to End test weighted multi sig
* 1 or m-of-n deposit address support
* Move network_type enum to the base class
* btc_one_or_weighted_multisig_address implementation
* Simplify redeem script
* Fix error in redeem_script
* btc_one_or_weighted_multisig_address tests
* Refactor sidechain address mapping
* CLANG code format
* CLANG code format sidechain tests
* Integration of deposit and rest of weighted wallets, withdrawal fee fix, whole code refactoring
* Move util functions to Utils file
* Add proper checks for withdraw fee
* Deposit address creation, import deposit/withdraw addresses, some code cleanup

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: gladcow <s.gladkov@pbsa.info>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>

* [SON-349] Delay BTC asset issue/reserve until tx confirmed on sidchain (#348)

* Separate transaction settling from deposit/withdrawal processing
* Handle peerplays deposits with transaction settling
* Remove logs
* All dev features enabled/disabled with single flag
* Deposit/withdraw process and sidechain transaction creation in single proposal

* Hotfix - remove importing sidechain addresses

* Hotfix - remove redundant deposit sidechain address recreation

* private-key option update

* Use decoderawtraction json for proposal approvals (#352)

* Use decoderawtraction json for proposal approvals
* Use default null string to get first vout

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Prevent incorrect signatures to be added to transaction (#354)

* Prevent incorrect signatures to be added to transaction
* Check signers list before signing

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Hotfix - use getrawtransaction for approvals and settling (#355)

* Revert "Use decoderawtraction json for proposal approvals (#352)"
This reverts commit d3385b28cb.
* User getrawtransaction for proposal approvals and settling
* Code cleanup

* [SON-135] Add timelock to user deposit address (#356)

* timelocks
* timelocked deposit address
* test for deposit timelock

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - fix threshold_weight calculation in redeem scripts

* fix broken peerplays_sidechain tests (#357)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - Save deposit address redeem and witness script into sidechain address object

* [SON-359] - Fix Errors processing to-be-refunded deposits (#358)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-363] - Remove son deletion (#359)

* [SON-363] - Remove son deletion

* Fix the tests

* [SON-314] - Weighted Rewards and equal weighted son-account (#360)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Bitcoin network type deduction (#361)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* chore: changed building to debug mode

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* chore: updated Dockerfile with dnsutils

* GPOS2 HF - Handle rolling period on missing blocks (#369)

* Mainnet chain halt 5050 Issue (#370)

* Peerplays Marketplace + NFT (#367)

* ppy marketplace 1 - add evaluators and objects

* NFT object and basic operations

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* NFT evaluators and basic tests, no evaluator checks

* Evaluator checks in place

* ppy marketplace 2 - batch sale, offer_object escrow

* Database API

* Wallet API

* NFT metadata implemented

* Fix NFT tests

* Database API for NFT metadata and enumerables

* ppy marketplace 4 - Add tests NFT+Marketplace

* ppy marketplace 5 - Add revenue split

* ppy marketplace 6 - Remove unnecessary files

* ppy marketplace 7 - Add db, wallet changes and some NFT fixes

* ppy marketplace 8 - Add pagination for list APIs

* New DB API, list all NFTs, list NFTs by owner

* Marketplace + NFT + RBAC (#368)

* rbac1 - evaluators and op validators added
* rbac2 - op_type hf checks
* rbac3 - tx auth verify changes
* Update .gitlab-ci.yml
* rbac4 - basic op tests
* rbac5 - clear expired and deleted permission linked auths
* rbac6 - more tests
* rbac7 - more tests
* rbac8 - more tests
* rbac9 - wallet and db api changes
* rbac10 - db api changes for required signature fetch
* rbac11 - add db_api tests
* rbac12 - add missing code for key auths

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>

* Fix nft_get_token_uri returning empty string

* Fix nft_mint_evaluator to save token_uri

* Fix cli_wallet to properly pass metadata id for nft_create

* ppy marketplace 9 - FC_REFLECT offer create op

* Add stricter checks to NFTs

* Unlisting offers, add result in offer history object

* Reverting genesis.json wrong commit

* Add non-transferable non-sellable properties to NFTs

* Review comments - change variable names, use scoped enums

* nft_metadata_update changes

* NFT HF checks and op fee addition changes

* NFT make revenue_split integer from double

* revenue_split condition check allow zero or above

Co-authored-by: Srdjan Obucina <obucinac@gmail.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: Satyanarayana Koneru <skoneru@SK-GT.local>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>
Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Son deposit address enhancements (#362)

* Deposit address enhancements

* fix tests

Co-authored-by: Koneru Satyanarayana <15652887+satyakoneru@users.noreply.github.com>

* Ws updates

* Fix for custom operation authority checking (BTS Issue #210) (#382)

* Resolve #210: [HF] Check authorities on custom_operation

The required_auths field on custom_operation was being ignored during authority checking. This commit causes it to be checked correctly, and adds a unit test verifying as much.

* Ref #381: Fixes

Build and logic fixes for Pull Request #381

* Ref #381: Fix bad merge

During merge conflict resolution, I accidentally broke custom
authorities. This fixes it.

* compilation fix

Co-authored-by: Nathan Hourt <nathan@followmyvote.com>

* Cleanup changes for pretier diff

* Cleanup changes for prettier diff

* NFT Permissions (#380)

* Account Roles Permission 1 - Working code with tests

* Account Roles Permission 2 - Add marketplace offer/bid tests

* Account Roles Permission 3 - Add Op check

* Account Roles Permission 4 - Add chain params and limits

* Cleanup changes for prettier diff

* Fix failing saving_keys_wallet_test

* Fix failing saving_keys_wallet_test

* Align submodule versions

* Add missing break

* Increase tests log_level, some cleanup

* Decrease log level for tests

* Fix block_tests/maintenance_interval test

* Fix son_operation_tests/son_pay_test test

* Remove base_uri length checks

* Fix HF info

Co-authored-by: S <obucinac@gmail.com>
Co-authored-by: Bobinson K B <bobinson@gmail.com>
Co-authored-by: obucinac <obucinac@users.noreply.github.com>
Co-authored-by: satyakoneru <satyakoneru.iiith@gmail.com>
Co-authored-by: gladcow <jahr@yandex.ru>
Co-authored-by: gladcow <s.gladkov@pbsa.info>
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
Co-authored-by: Sandip Patel <sandip@knackroot.com>
Co-authored-by: Roshan Syed <r.syed@pbsa.info>
Co-authored-by: pbattu123 <p.battu@pbsa.info>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>
Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>
Co-authored-by: pbattu123 <43043205+pbattu123@users.noreply.github.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: Satyanarayana Koneru <skoneru@SK-GT.local>
Co-authored-by: blockc p <pravin.blockc@gmail.com>
Co-authored-by: Nathan Hourt <nathan@followmyvote.com>

* SON hardfork time to Saturday, October 17, 2020 00:00:00 UTC

* hotfix - chain params variable overflow, rbac hf check (#387)

* hotfix - son max count fix

* init variables

* Update SON HF time to October 20th 2020, 00:00:00

* Update SON HF time to October 20th 2020, 00:00:00

* Release build fix, missing includes (#391)

fixes https://github.com/peerplays-network/peerplays/issues/390

* Fix release build on 18.04, fc::smart_ref_* removed (#394)

* Fix building on Ubuntu 18.04 with GCC 7

* Peerplays SON plugin skeleton (#122)

* Peerplays SON plugin skeleton
* SON tests skeleton

* Part two of SON-83 - plugins option in command line and config file (#126)

- Empty SON plugin is INACTIVE by default
- To enable it, add peerplays_sidechain to plugins section in
  config file, or use --plugins command line option
- Plugin can work with or without witness

* SON11 - Add chain extension parameter to set SON count

* [SON-107] Merge develop branch to SONs-base (#166)

* fix rng and get_winner_numbers implemented

* coipied code for bitshares fixing 429 and 433 isuues

* ticket_purchase_operation implemented. added lottery_options to asset

* lottery end implemented

* minor logic changes. added db_api and cli_wallet methods

* fix reindex on peerplays network

* fix some tests. add gitlab-ci.yml

* add pull to gitlab-ci

* fix

* fix and comment some tests

* added owner to lottery_asset_options. commented async call in on_applied_block callback

* added get_account_lotteries method to db_api and cli, lottery end_date and ticket_price verification

* merge get_account_lotteries branch. fix create_witness test

* fix test genesis and end_date verification

* fixed indices sorting and lottery end checking by date

* update db_version for replay and removed duplicate include files

* Added ntp and upgraded boost version

* Revert "GPOS protocol"

* need to remove backup files

* virtual-op-fix for deterministic virtual_op number

* Merged beatrice into 5050

* Updated gitmodules, changes to allow voting on lottery fee

* Removed submodule libraries/fc

* Added libraries/fc

* added missing , in types.hpp

* Added sweeps parameters to parameter_extension

* added missing comma in operations.hpp, small changes to config.hpp

* fixed returntype in chain_parameters.hpp

* removed sweeps_parameter_extensions

* Changed fc library

* fixed asset_object

* Changed peerplays-fc submodule

* Changed fc submodule to ubuntu 18.04 upgrade

* Removed submodule libraries/fc

* Added fc library back

* fix casting in overloaded function

* Removed blind_sign and unblind_signature functions

* Added new lottery_asset_create_operation

* Changed sweeps hardfork time

* Removed redundant if from asset_evaluator and fixed db_notify

* fixed duplicate code in fee_tests

* removed redundant tgenesis file

* Enable building on Ubuntu 18.04 using GCC 7 compiler

* fix: is_benefactor_reward had the default value of true when not set

* Docker file for Ubuntu 18.04

Base image updated to Unbuntu 18.04
Prerequisite list updated
Basic configuration updated

* Quick fix: Added missing package pkg-config

* Docker file updates

* 5050 fee update and compilation error fix

* Dockerfile, set system locale

Prevents locale::facet::_S_create_c_locale name error

* Update README.md

Fix typo

* Update README.md

* Changed hardfork time for SWEEPS and Core-429

* revert master changes that were brought in previous commit

* Fixed error when account_history_object with id 0 doesnt exist

* Fixed error while loading object database

* test for zero id object in account history

* Reorder operations in Dockerfile, to make image creation faster

- Reorder prevents unnecessary building of Boost libraries

* Fix for irrelevant signature included issue

* fix copyrigth messages order

* remove double empty lines

* Backport fix for `get_account_history` from https://github.com/bitshares/bitshares-core/pull/628 and add additional account history test case

* NTP client back

* GRPH-53-Log_format_error

* Merge pull request #1036 from jmjatlanta/issue_730

Add fail_reason to proposal_object

* Unit test case fixes and prepared SONs base

* Use offsetof instead of custom macro

* Hide some compiler warnings

* Make all the tests compile

* Add nullptr check in api.cpp for easier testing

* Add test case for broadcast_trx_with_callback API

* Unit test case fixes and prepared SONs base

* Merge pull request #714 from pmconrad/json_fix

JSON fix

* Increase max depth for trx confirmation callback

* Adapt to variant API with `max_depth` argument

* Update fc submodule

* Created unit test for #325

* remove needless find()

* GRPH-4-CliWallet_crash_ctrlD

* fix copyright message

* Make all the tests compile

* increase delay for node connection

* Increase block creation timeout to 2500ms

* remove cache from cli get_account

* add cli tests framework

* Adjust newly merged code to new API

* Improved resilience of block database against corruption

* Merged changes from Bitshares PR 1036

* GRPH-76 - Short-cut long sequences of missed blocks

Fixes database::update_global_dynamic_data to speed up counting missed blocks.
(This also fixes a minor issue with counting - the previous algorithm would skip missed blocks for the witness who signed the first block after the gap.)

* Moved reindex logic into database / chain_database, make use of additional blocks in block_database

Fixed tests wrt db.open

* Enable undo + fork database for final blocks in a replay

Dont remove blocks from block db when popping blocks, handle edge case in replay wrt fork_db, adapted unit tests

* Log starting block number of replay

* Prevent unsigned integer underflow

* Fixed lock detection

* Dont leave _data_dir empty if db is locked

* Writing the object_database is now almost atomic

* Improved consistency check for block_log

* Cut back block_log index file if inconsistent

* Fixed undo_database

* Added test case for broken merge on empty undo_db

* Merge pull request #938 from bitshares/fix-block-storing

Store correct block ID when switching forks

* exclude second undo_db.enable() call in some cases

* Add missing change

* change bitshares to core in message

* Fixed integer overflow issue

* Fix for for history ID mismatch ( Bitshares PR #875 )

* Update the FC submodule with the changes for GRPH-4

* Fix #436 object_database created outside of witness data directory

* supplement more comments on database::_opened variable

* prevent segfault when destructing application obj

* Fixed duplicate ops returned from get_account_history

* minor performance improvement

* Added comment

* Merged Bitshares PR #1462 and compilation fixes

* Support/gitlab (#123)

* Updated gitlab process

* Fix undefined references in cli test

* Fixed test failures and compilation issue

* Fixed account_history_pagination test

* Fix compilation in debug mode

* Removed unrelated comment

* Skip auth check when pushing self-generated blocks

* Extract public keys before pushing a transaction

* Dereference chain_database shared_ptr

* Updated transaction::signees to mutable

and
* updated get_signature_keys() to return a const reference,
* get_signature_keys() will update signees on first call,
* modified test cases and wallet.cpp accordingly,
* no longer construct a new signed_transaction object before pushing

* Added get_asset_count API

* Allow sufficient space for new undo_session

* Throw for deep nesting

* No longer extract public keys before pushing a trx

and removed unused new added constructor and _get_signature_keys() function from signed_transaction struct

* Added cli_test to CI

* use random port numbers in app_test (#154)

* proposal fail_reason bug fixed (#157)

* Added Sonarcloud code_quality to CI (#159)

* Added sonarcloud analysis (#158)

* fix for lottery end

* fix declarations

* fix declarations

* fix boost integer

* fix compilation

* fix chain tests

* fix app_test

* try to fix cli test

* fix incorrect max_depth param

* working cli test

* correct fc version

* Revert "[SON-107] Merge develop branch to SONs-base (#166)"

This reverts commit 499e318199.

* Fix build error, add missing GRAPHENE_MAX_NESTED_OBJECTS parameter

* Plugin description added, SON plugin params example

* fix for cli test

* SON object, operations, cli_wallet commands and RPC (#160)

- create_son, update_son, delete_son, list_sons
- get_sons, get_son_by_account, lookup_son_accounts, get_son_count
- vote_for_son, update_son_votes
- claim_registered_son
- get_son in cli_wallet
- Updating global_property_object
- Decrease SON hardfork time for test purposes
- CLI Wallet tests imported from develop branch

* fix affiliate tests

* SON-108 - Add cli wallet tests for create_son (#174)

* SON-108 - Add cli wallet tests for create_son

* Add info message at the beginning and end of the SON CLI tests

* Minor output message change

* Enable Boost test messages in unit tests

* [SON-110] get_son cli test (#173)

* get_son cli test

* update_son cli test

* Add cli wallet tests for vote_for_son (#175)

* fix insert object processing in indexes, son_delete is working

* Fix segfault when using delete_son from cli_wallet (#177)

* Fix segfault when using list_sons from cli_wallet (#178)

* Add son_delete cli tests (#182)

* Add son_delete cli tests

* add son vesting config options

* add vesting balance type support

* add dormant vesting policy for son

* add precision to son vesting amount

* SON118-Add Budget for SON (#165)

* SON118-Add Budget for SON

* SON118 - Compilation errors fix

* SON118 - Proper commenting around pay_sons function

* SON118 - Comment correction, SON statistics object implementation type correction

* SON118 - Add missing index init and reflect enums

* SON118 - Correcting the indentation

* SON118 SON144 - Add unit test, code fixes and resolve failures for existing tests

* SON118 SON144 - Removing extra spaces added

* abstraction of dormant vesting policy

* force son create vesting balance to have dormant policy

* remove not needed code from wallet son commands, add delete son test to cli (#181)

* Active SONs, list up to 15, order by votes, add test (#185)

* Add test for selecting 15 SONs with highest votes
* Display up to 15 active SONs, SON ordering by total_votes

* fix build error (#191)

* fix build error

* adapt son_pay_test to dormant vesting policy

* [SON-113] Unit test for cli `update_son_votes` (#179)

* refactor cli tests

* update_son_votes tests

* list_sons test

* test changes in get_global_properties() result

* fix generate_block failure

* fix update_son_votes test

* improve update_son cli test

* fix linking errors

* refactor select_top_fifteen_sons test

* refactor other son cli tests to use son_test_helper

* create_vesting call in wallet_api

* test fix

* fix create_son in wallet_api and cli tests

* SON126 - Witness Proposals to deregister SONs (#192)

* SON126 - Witness Proposals to deregister SONs

* SON126 - Approval by witness, removal of son_proposal_object, commenting

* SON126 - Witness proposal tests and related fixes

* SON126 - Proper commenting

* fix son_delete_operation reflection

* [SON-160] Fix create_vesting wallet_api call (#206)

* Fix create_vesting wallet_api call

* change type for vesting_type in create_vesting_balance

* [SON-113] Fix several issues in update_son_votes call in wallet_api  (#208)

* do not allow update votes with both empty lists

* fix error messages

* check number of sons against votes number in account_object

* Update error message

* list_active_sons api call implementation

* unit test for list_active_sons

* fix code style

* use assert instead of checking condition with low possibility

* Fixed betting tests (#217)

* Fixed betting tests

* Removed comments

* removed unrelated parameter description from delete_son

* Add Bitcoin network listener to a SON plugin (#196)

* Add Bitcoin network listener to a SON plugin
* Add default parameters for Peerplays Bitcoin test node
* Add Bitcoin block processing
* Update source code to last designs
* Set default parameters for peerplays_sidechain plugin to Bitcoin test server
* WIP: Some Bitcoin transaction processing

* [SON-199] Fix unit tests (#233)

* fix app_test

* fix son_delete_test

* Add peerplays account for a SON in a config/command line options (#231)

* SON193-SON200- SON Heartbeats and maintenance mode changes (#241)

* SON193-SON200- SON Heartbeats and maintenance mode changes

* SON193-SON200- SON Heartbeats and maintenance tests

* User sidechain address mappings (#240)

* WIP: Sidechain objects
* Revert "WIP: Sidechain objects"
This reverts commit 8676940a28.
* WIP: User sidechain address mappings
* Fix reflection problem
* Reflect missing members of sidechain_address_update_operation
* Add sidechain address operation tests
* Enable RPC calls
* Fix build errors due to merge conflict
* Fix RPC, add CLI wallet commands for sidechain addresses
* Improved peerplays_sidechain_plugin_impl
* Remove short param for son-id
* Fix crashing errors on bitcoin event received
* Code review changes

* SON207 - Introduce scheduling for SONs similar to witnesses (#251)

* Extend SON objects to contain sidechain public keys (#254)

* SON194-SON195 - Report SON Down, addition of SON Account for sidechain consensus (#244)

* SON194-SON195 - Addition of SON BTC Account and report son down changes

* SON194-SON195 - SON BTC Account errors rectification

* SON194-SON195 - Adding Tests

* User sidechain address mappings (#240)

* WIP: Sidechain objects
* Revert "WIP: Sidechain objects"
This reverts commit 8676940a28.
* WIP: User sidechain address mappings
* Fix reflection problem
* Reflect missing members of sidechain_address_update_operation
* Add sidechain address operation tests
* Enable RPC calls
* Fix build errors due to merge conflict
* Fix RPC, add CLI wallet commands for sidechain addresses
* Improved peerplays_sidechain_plugin_impl
* Remove short param for son-id
* Fix crashing errors on bitcoin event received
* Code review changes

* SON207 - Introduce scheduling for SONs similar to witnesses (#251)

* Extend SON objects to contain sidechain public keys (#254)

Co-authored-by: obucinac <obucinac@users.noreply.github.com>

* SON206 - Plugin SON Heartbeat changes (#250)

* SON206 - Plugin SON Heartbeat changes

* SON206 - Plugin SON Heartbeat changes, comment removal

* SON206 - Plugin SON Heartbeat changes, stub testing and changes

* SON206 - Plugin SON Heartbeat changes, removing debugs prints

* Wallet recreation on new set of SONs voted in (#256)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* Fix build errors

* SON212-SON213 - Add Sidechain Plugin Code to report and approve SON Down proposal (#260)

* SON212 - Add Sidechain Plugin Code to report SON Down

* SON212-SON213 - Add Sidechain Plugin Code to report SON Down, Approve proposal from sidechain plugin

* SON212-SON213 - Fix Build Error (#262)

* SON212-SON213 - Fix Build Error

* SON212-SON213 - Fix Build Error Add smart_ref definition for linking

* Updated gitlab CI to sync submodules (#265)

* SON217 - SON Maintenance,Heartbeat state transition changes (#264)

* SON217 - SON Maintenance,Heartbeat state transition changes

* SON217 - SON Maintenance,Heartbeat state transition changes

* [SON-202] Implement cli_wallet commands for maintenance mode (#261)

* Add stop_son_maintenance CLI call

* fix bug with SON activation

* son_maintenance_operation

* son_maintenance_operation tests

* cli test for son maintenance state

* start_son_maintenance CLI call

* keep maintenance state during active SON set changes

* Quick fix for list_active_sons

* SON199 - Fix Unit Test Failure (#268)

* Quickfix for update_sidechain_address and delete_sidechain_address cli commands

* SON206_Plugin_CrashFix_Reorg - Plugin Changes (#272)

* SON206_Plugin_CrashFix_Reorg - Plugin Changes

* SON206_Plugin_CrashFix_Reorg - add owner auths to consensus account

* SON165 - Keys mapping missing from wallet data (#274)

* SON232 - Avoid duplicate proposals from sidechain plugin (#275)

* SON233 - Provide correct downtime metrics to user (#278)

* son_wallet_object operations and multisig wallet recreation by RPC (#263)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object
* son_wallet_object operations
* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
* son_wallet_object API and cli wallet commands
* Send RPC command to bitcoin node to recreate multisig wallet
* Updating wallet info through operation instead through database.modify() for persistance
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
* Refactor primary wallet recreation
* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
* Quickfix for checking payer in evaluator
* Fix failing son_wallet_tests
- Check for son_btc_account is temporarely disabled
* Remove redundant file
Co-authored-by: gladcow <jahr@yandex.ru>

* SON214 - Request maintenance wallet commands (#280)

* SON wallet transfer object and operations (#279)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add is_active_son guards for sidechain events processing

Co-authored-by: gladcow <jahr@yandex.ru>

* Support multiple SON nodes per software instance (#282)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Temoprary disable account history tests for tracking accounts

Co-authored-by: gladcow <jahr@yandex.ru>

* [SON-209] Create P2SH address with custom redeemScript (#271)

* Create redeem script for SONs primary wallet

* Add importaddress call

Allows to watch for related transactions without private keys import

* Get UTXO set for watched addresses

* createrawtransaction call

* signing PW spending transaction

* unit test for btc tx serialization

* sending PW transfer in test

* BIP143 tx signing

* use bech32 address format

* use single sha256 for lock script

* Digest fix

* working signing

* separate signing

* test partially signed PW transfer

* add ability to gather signatures before signing (#290)

* [SON-242] fix list_active_sons call after deleting an active son (#292)

* test to reproduce error in list_active_sons after delete_son

* prevent exception in list_active_list

* [SON-260] Sidechain Token withdrawal (#286)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Skeleton of sidechain_net_handler_peerplays

* Skeleton of Peerplays network listener

* Temoprary disable account history tests for tracking accounts

* Full Peerplays listener, use GRAPHENE_SON_ACCOUNT instead son_btc_account

* Renaming son_wallet_transfer* to son_wallet_deposit*, introducing son_wallet_withdrawal*

* Extend sidechain_address_object to contain withdrawal addresses
- Withdrawal address is the address where system will send sidechain currencies

* Rename son_wallet_withdrawal* to son_wallet_withdraw*

* Some refactoring

* Withdrawal refactoring

* Withdrawal refactoring

Co-authored-by: gladcow <jahr@yandex.ru>

* SON261 - Bitcoin deposit, withdrawal, PW transfer (#287)

* Extend GPO.active_sons to contain votes and all public keys

* Introduce son_wallet_object

* son_wallet_object operations

* son_wallet_object operations

* son_wallet_object operations completed, basic tests added

* Create son_wallet_object on new set of SONs, to initiate primary wallet recreation

* son_wallet_object API and cli wallet commands

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Send RPC command to bitcoin node to recreate multisig wallet

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Wallet recreation by scheduled SON only, some cosmetic refactoring

* Updating wallet info through operation instead through database.modify() for persistance

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp

Co-Authored-By: gladcow <jahr@yandex.ru>

* Fix #include <graphene/chain/son_wallet_transfer_object.hpp>

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* SON wallet transfer object and operations, for tracking assets deposit/withdrawal

* Refactor primary wallet recreation

* Refactor primary wallet recreation

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal

* Quickfix for checking payer in evaluator

* Quickfix for checking payer in evaluator

* Fix failing son_wallet_tests

- Check for son_btc_account is temporarely disabled

* Remove redundant file

* Squashed commit of the following:

commit a688bb93ed
Author: obucinac <obucinac@users.noreply.github.com>
Date:   Tue Feb 4 19:31:45 2020 +0100

    son_wallet_object operations and multisig wallet recreation by RPC (#263)

    * Extend GPO.active_sons to contain votes and all public keys

    * Introduce son_wallet_object
    * son_wallet_object operations
    * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation
    * son_wallet_object API and cli wallet commands
    * Send RPC command to bitcoin node to recreate multisig wallet
    * Updating wallet info through operation instead through database.modify() for persistance
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp
    * Fix #include <graphene/chain/son_wallet_transfer_object.hpp>
    * Refactor primary wallet recreation
    * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal
    * Quickfix for checking payer in evaluator
    * Fix failing son_wallet_tests
    - Check for son_btc_account is temporarely disabled
    * Remove redundant file
    Co-authored-by: gladcow <jahr@yandex.ru>

commit 6e61d6b055
Author: satyakoneru <satyakoneru.iiith@gmail.com>
Date:   Tue Feb 4 00:14:39 2020 +1100

    SON233 - Provide correct downtime metrics to user (#278)

* Remove duplicated item in CMakeLists.txt

* Issue tokens to the user who deposited Bitcoin, WIP...

* Add son_wallet_transfer_process_operation

* Issue tokens to the user who deposited Bitcoin, WIP...

* Support multiple SON nodes per software instance

* Add is_active_son guards for sidechain events processing

* Add is_active_son guards, fix sending proposals and aprovals

* Managing GRAPHENE_SON_ACCOUNT and issuing assets on Bitcoin deposit

* Fix bad param

* Fix aprovals on already approved or invalid proposals

* Move transfer inside son_wallet_transfer_process_operation

* Fix merging issue

* Add cmake command line option SUPPORT_MULTIPLE_SONS

* Skeleton of sidechain_net_handler_peerplays

* Skeleton of Peerplays network listener

* SON261 - Deposit transfer ( user address -> PW ) and Withdrawal transfer ( PW -> user address ) for m-of-n multisig

* Temoprary disable account history tests for tracking accounts

* Full Peerplays listener, use GRAPHENE_SON_ACCOUNT instead son_btc_account

* Renaming son_wallet_transfer* to son_wallet_deposit*, introducing son_wallet_withdrawal*

* Extend sidechain_address_object to contain withdrawal addresses
- Withdrawal address is the address where system will send sidechain currencies

* Rename son_wallet_withdrawal* to son_wallet_withdraw*

* Some refactoring

* SON261 - Withdrawal transfer ( PW -> user address ), addition of bitcoin public private key to config.ini for multiple sons mode

* Withdrawal refactoring

* Withdrawal refactoring

* SON261 - Fix prepare_tx

* SON261 - Add PW->PW Transfer and Code reorg

* Fix file permissions

Co-authored-by: obucinac <obucinac@users.noreply.github.com>
Co-authored-by: gladcow <jahr@yandex.ru>

* [SON-264] Integrating deposit/withdrawals with bitcoin transactions (feature/SON-260 + SON261 branches) (#291)

* Partial integration done, some Bitcoin RPC refactoring
* CLang Format config file
* CLang Format config file v2.0
* Fix repeating tasks that should be executed by scheduled SON only
* Fix withdrawal
* Integrate PW wallet fund moving
* Resolve conflicts

Co-authored-by: gladcow <jahr@yandex.ru>
Co-authored-by: satyakoneru <satyakoneru.iiith@gmail.com>

* SON200 - SON Down proposal broken after latest merges (#294)

* SON200 - SON Down proposal broken after latest merges

* Add the owner weight threshold similar to witnesses and committee accounts

* SON269 - Move SON deregistration to Plugin from witness (#298)

* SON200 - SON Down proposal broken after latest merges

* Add the owner weight threshold similar to witnesses and committee accounts

* SON269 - Move SON deregistration to Plugin from witness

* Various SON improvements (#297)

* Refactor SON processing
* Better exposure of sidechain private keys in sidechain handlers
* Support non default Bitcoin wallets
* Fix crash on config file recreation
* clang-format formatting
* New Bitcoin wallet related RPC calls
* Add missing create_son_deregister_proposals calls
* Add missing create_son_deregister_proposals calls
* Add loading/unlocking/locking of non-default bitcoin wallet
* Bitcon RFC logs improved, proposal aprovement improved
* Move signal connection after handlers are created

* Merge develop into SONS

* SON118 - Add tx sign metrics for SON rewards (#302)

* resolved compilation issues and other conflicts

* SON202 - Maintenance improvements (#303)

* Quickfix, remove dead code, return result from wallet withdraw do_evaluate

* SON275 - ZMQ Crash on application exit (#306)

* SON275 - ZMQ Crash on application exit

* SON275 - Fix Indentation

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* need to assign both name and id to stats id

* fix unit test case failures(add gpos vesting before voting)

* SON276 - Fix SON proposal exceptions - I (#307)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Add SON statistic for tracking reported sidechain transactions (#308)

- Deposit and Withdrawal object extended to contain expected
  and received transaction reports from SON network
- SON statistic object extended to contain total number of
  sidechain transactions reported by SON network when SON was
  active and number of transactions reported by single SON when
  he was active
- Code formatting

* Allow voting for son, only if GPOS vesting balance available

* notifications of SONS should get restrict to sons functionality

* update GPOS hardfork date to sons branch

* SON127 - Add son parameter extensions to genesis, push proposal fix (#310)

* SON276 - Fix SON proposal exceptions - I

* SON127 - Add son parameter extensions to genesis, push proposal fix

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* update GPOS HF to fall in before SONS HF, remove check

* updated unit test cases to reflect GPOS vesting and update account id's according to sons-account

* [SON-24] - SON Rewards missing serialisations and end to end testing (#313)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Revert "Merge develop branch changes(GPOS+graphene updates) into SONs branch"

* [SON-122] - SON Statistics improvements and consensus account creation (#318)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Replace raw with psbt transactions to support parital tx signing (#311)

* RPC calls for PSBT, raw transactions replaced with PSBT
* Fix estimatesmartfeerate, extensive RPC calls logging for debugging purposes
* Remove dead code
* Partial signing functional for deposit and withdrawal
* Fix sidechain_type declarations
* Depositing Peerplays asset refactored
* Partial signing functional for primary wallet funds moving
* Prettier logs
* Refactor multiple SON support processing
* Serialize field complete from sidechain_transaction_sign_operation
* Refactor transaction signing in particular order, BTC only (maybe) need it
* Add number of required signatures parameter for addmultisigaddress
* Change default bitcoin node parameters
* Transaction signing only by scheduled son
* Removed scheduling log
* Prevent PW funds moving to the same address
* Refactor sidechain_transaction_object processing, code cleanup
* Remove obsolete tests
* Decrease logging
* Code readability
* When updated, import son wallet bitcoin address to bitcoin wallet
* When updated, recreate son wallet bitcoin address on each node
* Refactor on_changed_objects, move it into task
* Add check to prevent deposit/withdrawal double processing
* Improved check for sidechain transaction object creation
* Single sidechain transaction signature per block allowed only
* Unlock wallet on addmultisigaddress
* Import both address and redeem script on primary wallet change, fix some compiler warnings
* Fix invalid list of signers for PW funds transfer

* [SON-312] Refactor create_son to assign owner account public key as a signing_key

remove key derivation from create son (#323)
Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>

* [SON-271] Merge recent develop branch changes(both GPOS and graphene updates) into SONs branch (#322)

* Parallelizing sidechain transaction signing (#319)

* [SON-321, SON-323] Deposit/Withdraw object creation refactoring (#320)

* Remove proposals for creating deposit and withdrawal objects, strenghten evaluator checks
* Only active SON can create the object
* Only expected SON can confirm the transaction
* Transaction must be initiated (paid) by SON account owner (SON account given in operation)
* Transaction confirmation must contain exactly the same data as existing object
* Mirror SON owner account weights from son-account.active.account_auths to active SONs
* Fix duplicated typedef, peerplays_sidechain::sidechain_type to chain::sidechain_type
* Add missing serialized field

* [SON-318_SON-319] - Add approval checks for son down, deregister proposals (#321)

* [SON-318_SON-319] - Add approval checks for son down and deregister proposals

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>

* [SON-311] Add try_create_son call without explicit deposit params (#324)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - Fix build error

* Quickfix - change GPOS and SON hardfork times

* [SON-332] Check gitlab building process for dirty build (#327)

* Fix failing son test, fix data types and check condition
* Very clean build on Gitlab

* update son-account parameters (#328)

* [SON-329] Hotfix - Enable test test_update_dividend_interval

* [SON-313] - Limit SON functionality when min no. of sons are not present (#329)

* [SON-313] - Limit SON functionality when min no. of sons are not present

* Revert SON HF related checks and tests

* Remove the capability to process proposals in plugin

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-307] Create PBTC asset  (#326)

* SON-297_SON-336 - SON vesting functionality broken after graphene merge (#331)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Hotfix - add initialization values to extension params, remove trailing spaces

* [SON-305, SON-308, SON-310] Use BTC asset in bitcoin deposits and withdraws (#332)

* [SON-339] - SON Schedule crash (#334)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-291,SON-328] - SON Configuration invalid, PW creation issues (#335)

* [SON-291,SON-328] - SON Configuration invalid, PW creation issues

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-322, SON-324] Approval checks for processing deposit/withdrawal (#330)

* Refactor proposal processing
* Added check for approving son_wallet_deposit_process_operation
* Added check for approving son_wallet_withdraw_process_operation
* Calculating exchange rates fixed
* Fix depositing Peerplays assets

* [SON-320] Added check for approving son_wallet_update_operation (#336)

* [SON-325] Added check for approving sidechain_transaction_create_operation (#337)

* [SON-341, SON-342] Fix issue with deposits number (#339)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* [SON-344] BTC asset is created with wrong quote asset id, Fixed (#341)

* [SON-344] BTC asset is created with wrong quote asset id, Fixed
* Respond to code review

* [SON-346] Sidechain transaction marked as complete even though current_weight < threshold, Fixed (#342)

* [SON-348] Transaction hash not saved in object after Bitcoin transaction is sent (#343)

- Fixed
- Unused parameters removed

* [SON-337] - Prevent update_son_votes without GPOS vesting (#344)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-353] Refactor PW processing, PW transfer fixed (#347)

* Add proposal checks for deposit and withdrawal
* Refactor proposal approvement
* Fix transaction verification
* Remove logs

* [SON-354] Fix son_info compare function (#350)

* check object's id (#351)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* SON Weighted Multi Signature Signing (#349)

* Bring in the bitcoin utils code into plugin
* Add tx creation, signing and tests
* tx deserialization fix
* add 10-of-14 multisig address test
* Add signing and verification tests and sign_transaction_standalone
* Add send_transaction_standalone function
* Debug logs and additional tests
* Fix for son deletion in the middle
* Extend script_builder
* Witness script for weighted wallet
* btc_weighted_multisig_address implementation
* Fix for bad-txns-nonstandard-inputs
* Weighted multisignature address test
* Create test tx with weighted multisig wallet
* Fix the issues with tx signing
* End to End test weighted multi sig
* 1 or m-of-n deposit address support
* Move network_type enum to the base class
* btc_one_or_weighted_multisig_address implementation
* Simplify redeem script
* Fix error in redeem_script
* btc_one_or_weighted_multisig_address tests
* Refactor sidechain address mapping
* CLANG code format
* CLANG code format sidechain tests
* Integration of deposit and rest of weighted wallets, withdrawal fee fix, whole code refactoring
* Move util functions to Utils file
* Add proper checks for withdraw fee
* Deposit address creation, import deposit/withdraw addresses, some code cleanup

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: gladcow <s.gladkov@pbsa.info>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>

* [SON-349] Delay BTC asset issue/reserve until tx confirmed on sidchain (#348)

* Separate transaction settling from deposit/withdrawal processing
* Handle peerplays deposits with transaction settling
* Remove logs
* All dev features enabled/disabled with single flag
* Deposit/withdraw process and sidechain transaction creation in single proposal

* Hotfix - remove importing sidechain addresses

* Hotfix - remove redundant deposit sidechain address recreation

* private-key option update

* Use decoderawtraction json for proposal approvals (#352)

* Use decoderawtraction json for proposal approvals
* Use default null string to get first vout

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Prevent incorrect signatures to be added to transaction (#354)

* Prevent incorrect signatures to be added to transaction
* Check signers list before signing

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Hotfix - use getrawtransaction for approvals and settling (#355)

* Revert "Use decoderawtraction json for proposal approvals (#352)"
This reverts commit d3385b28cb.
* User getrawtransaction for proposal approvals and settling
* Code cleanup

* [SON-135] Add timelock to user deposit address (#356)

* timelocks
* timelocked deposit address
* test for deposit timelock

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - fix threshold_weight calculation in redeem scripts

* fix broken peerplays_sidechain tests (#357)

Co-authored-by: gladcow <s.gladkov@pbsa.info>

* Hotfix - Save deposit address redeem and witness script into sidechain address object

* [SON-359] - Fix Errors processing to-be-refunded deposits (#358)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* [SON-363] - Remove son deletion (#359)

* [SON-363] - Remove son deletion

* Fix the tests

* [SON-314] - Weighted Rewards and equal weighted son-account (#360)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Bitcoin network type deduction (#361)

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* chore: changed building to debug mode

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* chore: updated Dockerfile with dnsutils

* GPOS2 HF - Handle rolling period on missing blocks (#369)

* Mainnet chain halt 5050 Issue (#370)

* Peerplays Marketplace + NFT (#367)

* ppy marketplace 1 - add evaluators and objects

* NFT object and basic operations

* ci: update .gitlab-ci.yml

* ci: update .gitlab-ci.yml

* NFT evaluators and basic tests, no evaluator checks

* Evaluator checks in place

* ppy marketplace 2 - batch sale, offer_object escrow

* Database API

* Wallet API

* NFT metadata implemented

* Fix NFT tests

* Database API for NFT metadata and enumerables

* ppy marketplace 4 - Add tests NFT+Marketplace

* ppy marketplace 5 - Add revenue split

* ppy marketplace 6 - Remove unnecessary files

* ppy marketplace 7 - Add db, wallet changes and some NFT fixes

* ppy marketplace 8 - Add pagination for list APIs

* New DB API, list all NFTs, list NFTs by owner

* Marketplace + NFT + RBAC (#368)

* rbac1 - evaluators and op validators added
* rbac2 - op_type hf checks
* rbac3 - tx auth verify changes
* Update .gitlab-ci.yml
* rbac4 - basic op tests
* rbac5 - clear expired and deleted permission linked auths
* rbac6 - more tests
* rbac7 - more tests
* rbac8 - more tests
* rbac9 - wallet and db api changes
* rbac10 - db api changes for required signature fetch
* rbac11 - add db_api tests
* rbac12 - add missing code for key auths

Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>

* Fix nft_get_token_uri returning empty string

* Fix nft_mint_evaluator to save token_uri

* Fix cli_wallet to properly pass metadata id for nft_create

* ppy marketplace 9 - FC_REFLECT offer create op

* Add stricter checks to NFTs

* Unlisting offers, add result in offer history object

* Reverting genesis.json wrong commit

* Add non-transferable non-sellable properties to NFTs

* Review comments - change variable names, use scoped enums

* nft_metadata_update changes

* NFT HF checks and op fee addition changes

* NFT make revenue_split integer from double

* revenue_split condition check allow zero or above

Co-authored-by: Srdjan Obucina <obucinac@gmail.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: Satyanarayana Koneru <skoneru@SK-GT.local>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>
Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>

* Son deposit address enhancements (#362)

* Deposit address enhancements

* fix tests

Co-authored-by: Koneru Satyanarayana <15652887+satyakoneru@users.noreply.github.com>

* Ws updates

* Fix for custom operation authority checking (BTS Issue #210) (#382)

* Resolve #210: [HF] Check authorities on custom_operation

The required_auths field on custom_operation was being ignored during authority checking. This commit causes it to be checked correctly, and adds a unit test verifying as much.

* Ref #381: Fixes

Build and logic fixes for Pull Request #381

* Ref #381: Fix bad merge

During merge conflict resolution, I accidentally broke custom
authorities. This fixes it.

* compilation fix

Co-authored-by: Nathan Hourt <nathan@followmyvote.com>

* Cleanup changes for pretier diff

* Cleanup changes for prettier diff

* NFT Permissions (#380)

* Account Roles Permission 1 - Working code with tests

* Account Roles Permission 2 - Add marketplace offer/bid tests

* Account Roles Permission 3 - Add Op check

* Account Roles Permission 4 - Add chain params and limits

* Cleanup changes for prettier diff

* Fix failing saving_keys_wallet_test

* Fix failing saving_keys_wallet_test

* Align submodule versions

* Add missing break

* Increase tests log_level, some cleanup

* Decrease log level for tests

* Fix block_tests/maintenance_interval test

* Fix son_operation_tests/son_pay_test test

* Remove base_uri length checks

* Fix HF info

* hotfix - chain params variable overflow, rbac hf check (#387)

* hotfix - son max count fix (#389)

* hotfix - son max count fix

* init variables

* Release build fix, missing includes

* Fix release build on 18.04, fc::smart_ref_* removed

* Gitlab will build Debug and Release versions

* Revert "Gitlab will build Debug and Release versions"

This reverts commit 7a721f8094.

* Gitlab will build Release version only

* Hotfix/remove smart ref (#396)

* Merge develop into beatrice (#386)

* Fix building on Ubuntu 18.04 with GCC 7

* Peerplays SON plugin skeleton (#122)

* Peerplays SON plugin skeleton
* SON tests skeleton

* Part two of SON-83 - plugins option in command line and config file (#126)

- Empty SON plugin is INACTIVE by default
- To enable it, add peerplays_sidechain to plugins section in
  config file, or use --plugins command line option
- Plugin can work with or without witness

* SON11 - Add chain extension parameter to set SON count

* [SON-107] Merge develop branch to SONs-base (#166)

* fix rng and get_winner_numbers implemented

* coipied code for bitshares fixing 429 and 433 isuues

* ticket_purchase_operation implemented. added lottery_options to asset

* lottery end implemented

* minor logic changes. added db_api and cli_wallet methods

* fix reindex on peerplays network

* fix some tests. add gitlab-ci.yml

* add pull to gitlab-ci

* fix

* fix and comment some tests

* added owner to lottery_asset_options. commented async call in on_applied_block callback

* added get_account_lotteries method to db_api and cli, lottery end_date and ticket_price verification

* merge get_account_lotteries branch. fix create_witness test

* fix test genesis and end_date verification

* fixed indices sorting and lottery end checking by date

* update db_version for replay and removed duplicate include files

* Added ntp and upgraded boost version

* Revert "GPOS protocol"

* need to remove backup files

* virtual-op-fix for deterministic virtual_op number

* Merged beatrice into 5050

* Updated gitmodules, changes to allow voting on lottery fee

* Removed submodule libraries/fc

* Added libraries/fc

* added missing , in types.hpp

* Added sweeps parameters to parameter_extension

* added missing comma in operations.hpp, small changes to config.hpp

* fixed returntype in chain_parameters.hpp

* removed sweeps_parameter_extensions

* Changed fc library

* fixed asset_object

* Changed peerplays-fc submodule

* Changed fc submodule to ubuntu 18.04 upgrade

* Removed submodule libraries/fc

* Added fc library back

* fix casting in overloaded function

* Removed blind_sign and unblind_signature functions

* Added new lottery_asset_create_operation

* Changed sweeps hardfork time

* Removed redundant if from asset_evaluator and fixed db_notify

* fixed duplicate code in fee_tests

* removed redundant tgenesis file

* Enable building on Ubuntu 18.04 using GCC 7 compiler

* fix: is_benefactor_reward had the default value of true when not set

* Docker file for Ubuntu 18.04

Base image updated to Unbuntu 18.04
Prerequisite list updated
Basic configuration updated

* Quick fix: Added missing package pkg-config

* Docker file updates

* 5050 fee update and compilation error fix

* Dockerfile, set system locale

Prevents locale::facet::_S_create_c_locale name error

* Update README.md

Fix typo

* Update README.md

* Changed hardfork time for SWEEPS and Core-429

* revert master changes that were brought in previous commit

* Fixed error when account_history_object with id 0 doesnt exist

* Fixed error while loading object database

* test for zero id object in account history

* Reorder operations in Dockerfile, to make image creation faster

- Reorder prevents unnecessary building of Boost libraries

* Fix for irrelevant signature included issue

* fix copyrigth messages order

* remove double empty lines

* Backport fix for `get_account_history` from https://github.com/bitshares/bitshares-core/pull/628 and add additional account history test case

* NTP client back

* GRPH-53-Log_format_error

* Merge pull request #1036 from jmjatlanta/issue_730

Add fail_reason to proposal_object

* Unit test case fixes and prepared SONs base

* Use offsetof instead of custom macro

* Hide some compiler warnings

* Make all the tests compile

* Add nullptr check in api.cpp for easier testing

* Add test case for broadcast_trx_with_callback API

* Unit test case fixes and prepared SONs base

* Merge pull request #714 from pmconrad/json_fix

JSON fix

* Increase max depth for trx confirmation callback

* Adapt to variant API with `max_depth` argument

* Update fc submodule

* Created unit test for #325

* remove needless find()

* GRPH-4-CliWallet_crash_ctrlD

* fix copyright message

* Make all the tests compile

* increase delay for node connection

* Increase block creation timeout to 2500ms

* remove cache from cli get_account

* add cli tests framework

* Adjust newly merged code to new API

* Improved resilience of block database against corruption

* Merged changes from Bitshares PR 1036

* GRPH-76 - Short-cut long sequences of missed blocks

Fixes database::update_global_dynamic_data to speed up counting missed blocks.
(This also fixes a minor issue with counting - the previous algorithm would skip missed blocks for the witness who signed the first block after the gap.)

* Moved reindex logic into database / chain_database, make use of additional blocks in block_database

Fixed tests wrt db.open

* Enable undo + fork database for final blocks in a replay

Dont remove blocks from block db when popping blocks, handle edge case in replay wrt fork_db, adapted unit tests

* Log starting block number of replay

* Prevent unsigned integer underflow

* Fixed lock detection

* Dont leave _data_dir empty if db is locked

* Writing the object_database is now almost atomic

* Improved consistency check for block_log

* Cut back block_log index file if inconsistent

* Fixed undo_database

* Added test case for broken merge on empty undo_db

* Merge pull request #938 from bitshares/fix-block-storing

Store correct block ID when switching forks

* exclude second undo_db.enable() call in some cases

* Add missing change

* change bitshares to core in message

* Fixed integer overflow issue

* Fix for for history ID mismatch ( Bitshares PR #875 )

* Update the FC submodule with the changes for GRPH-4

* Fix #436 object_database created outside of witness data directory

* supplement more comments on database::_opened variable

* prevent segfault when destructing application obj

* Fixed duplicate ops returned from get_account_history

* minor performance improvement

* Added comment

* Merged Bitshares PR #1462 and compilation fixes

* Support/gitlab (#123)

* Updated gitlab process

* Fix undefined references in cli test

* Fixed test failures and compilation issue

* Fixed account_history_pagination test

* Fix compilation in debug mode

* Removed unrelated comment

* Skip auth check when pushing self-generated blocks

* Extract public keys before pushing a transaction

* Dereference chain_database shared_ptr

* Updated transaction::signees to mutable

and
* updated get_signature_keys() to return a const reference,
* get_signature_keys() will update signees on first call,
* modified test cases and wallet.cpp accordingly,
* no longer construct a new signed_transaction object before pushing

* Added get_asset_count API

* Allow sufficient space for new undo_session

* Throw for deep nesting

* No longer extract public keys before pushing a trx

and removed unused new added constructor and _get_signature_keys() function from signed_transaction struct

* Added cli_test to CI

* use random port numbers in app_test (#154)

* proposal fail_reason bug fixed (#157)

* Added Sonarcloud code_quality to CI (#159)

* Added sonarcloud analysis (#158)

* fix for lottery end

* fix declarations

* fix declarations

* fix boost integer

* fix compilation

* fix chain tests

* fix app_test

* try to fix cli test

* fix incorrect max_depth param

* working cli test

* correct fc version

* Revert "[SON-107] Merge develop branch to SONs-base (#166)"

This reverts commit 499e318199.

* Fix build error, add missing GRAPHENE_MAX_NESTED_OBJECTS parameter

* Plugin description added, SON plugin params example

* fix for cli test

* SON object, operations, cli_wallet commands and RPC (#160)

- create_son, update_son, delete_son, list_sons
- get_sons, get_son_by_account, lookup_son_accounts, get_son_count
- vote_for_son, update_son_votes
- claim_registered_son
- get_son in cli_wallet
- Updating global_property_object
- Decrease SON hardfork time for test purposes
- CLI Wallet tests imported from develop branch

* fix affiliate tests

* SON-108 - Add cli wallet tests for create_son (#174)

* SON-108 - Add cli wallet tests for create_son

* Add info message at the beginning and end of the SON CLI tests

* Minor output message change

* Enable Boost test messages in unit tests

* [SON-110] get_son cli test (#173)

* get_son cli test

* update_son cli test

* Add cli wallet tests for vote_for_son (#175)

* fix insert object processing in indexes, son_delete is working

* Fix segfault when using delete_son from cli_wallet (#177)

* Fix segfault when using list_sons from cli_wallet (#178)

* Add son_delete cli tests (#182)

* Add son_delete cli tests

* add son vesting config options

* add vesting balance type support

* add dormant vesting policy for son

* add precision to son vesting amount

* SON118-Add Budget for SON (#165)

* SON118-Add Budget for SON

* SON118 - Compilation errors fix

* SON118 - Proper commenting around pay_sons function

* SON118 - Comment correction, SON statistics object implementation type correction

* SON118 - Add missing index init and reflect enums

* SON118 - Correcting the indentation

* SON118 SON144 - Add unit test, code fixes and resolve failures for existing tests

* SON118 SON144 - Removing extra spaces added

* abstraction of dormant vesting policy

* force son create vesting balance to have dormant policy

* remove not needed code from wallet son commands, add delete son test to cli (#181)

* Active SONs, list up to 15, order by votes, add test (#185)

* Add test for selecting 15 SONs with highest votes
* Display up to 15 active SONs, SON ordering by total_votes

* fix build error (#191)

* fix build error

* adapt son_pay_test to dormant vesting policy

* [SON-113] Unit test for cli `update_son_votes` (#179)

* refactor cli tests

* update_son_votes tests

* list_sons test

* test changes in get_global_properties() result

* fix generate_block failure

* fix update_son_votes test

* improve update_son cli test

* fix linking errors

* refactor select_top_fifteen_sons test

* refactor other son cli tests to use son_test_helper

* create_vesting call in wallet_api

* test fix

* fix create_son in wallet_api and cli tests

* SON126 - Witness Proposals to deregister SONs (#192)

* SON126 - Witness Proposals to deregister SONs

* SON126 - Approval by witness, removal of son_pro…

* Set SON HF time to October 28, 2020 0:00:00

* Merge Master to Beatrice (#407)

* Fix failing gpos tests

* Fix failing son test

* Fix failing betting test

* Set SON and NFT hardfork date to 2020-12-19 00:00:00 GMT

* Fix failing son_cli tests

* Set SON and NFT hardfork date to 2020-12-21 00:00:00 GMT

Co-authored-by: Alfredo Garcia <oxarbitrage@gmail.com>
Co-authored-by: Bobinson K B <bobinson@gmail.com>
Co-authored-by: abitmore <abitmore@users.noreply.github.com>
Co-authored-by: Sandip Patel <sandip@knackroot.com>
Co-authored-by: pbattu123 <p.battu@pbsa.info>
Co-authored-by: Miha Čančula <miha@noughmad.eu>
Co-authored-by: pbattu123 <43043205+pbattu123@users.noreply.github.com>
Co-authored-by: Peter Conrad <conrad@quisquis.de>
Co-authored-by: Wei Yang <richard.weiyang@gmail.com>
Co-authored-by: Roshan Syed <r.syed@pbsa.info>
Co-authored-by: gladcow <jahr@yandex.ru>
Co-authored-by: satyakoneru <satyakoneru.iiith@gmail.com>
Co-authored-by: gladcow <s.gladkov@pbsa.info>
Co-authored-by: crypto-ape <43807588+crypto-ape@users.noreply.github.com>
Co-authored-by: Roshan Syed <roshan.syed.rs@gmail.com>
Co-authored-by: sierra19XX <15652887+sierra19XX@users.noreply.github.com>
Co-authored-by: Srdjan Obucina <obucinac@gmail.com>
Co-authored-by: obucina <11353193+obucina@users.noreply.github.com>
Co-authored-by: obucinac <obucinac@users.noreply.github.com>
Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com>
Co-authored-by: Satyanarayana Koneru <skoneru@SK-GT.local>
Co-authored-by: blockc p <pravin.blockc@gmail.com>
Co-authored-by: Nathan Hourt <nathan@followmyvote.com>
This commit is contained in:
serkixenos 2020-12-14 15:10:27 +01:00 committed by GitHub
parent e69d35dc82
commit 317093930f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
218 changed files with 23854 additions and 1304 deletions

127
.clang-format Normal file
View file

@ -0,0 +1,127 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -3
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: false
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 6
ContinuationIndentWidth: 6
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 3
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 3
UseTab: Never
...

View file

@ -1,80 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Instructions**
Please include a detailed Title above. Next, please complete the following sections below:
* Bug Description
* Impacts
* Steps To Reproduce
* Expected Behavior
* Screenshots (optional)
* Host Environment (optional)
* Additional Context (optional)
Finally, press the 'Submit new issue' button. The Core Team will evaluate and prioritize your Bug Report for future development.
**Bug Description**
A clear and concise description of what the bug is.
**Porting from Bitshares or other Graphene forks**
Corresponding issues:
- [FILL in issue1]
- [FILL in any other detail]
Corresponding PR:
- [fill in corresponding PR link]
**Impacts**
Describe which portion(s) of Peerplays may be impacted by this bug. Please tick at least one box.
- [ ] API (the application programming interface)
- [ ] Build (the build process or something prior to compiled code)
- [ ] CLI (the command line wallet)
- [ ] Deployment (the deployment process after building such as Docker, Gitlab, etc.)
- [ ] P2P (the peer-to-peer network for transaction/block propagation)
- [ ] Performance (system or user efficiency, etc.)
- [ ] Protocol (the blockchain logic, consensus, validation, etc.)
- [ ] Security (the security of system or user data, etc.)
- [ ] UX (the User Experience)
- [ ] Other (please add below)
**Steps To Reproduce**
Steps to reproduce the behavior (example outlined below):
1. Execute API call '...'
2. Using JSON payload '...'
3. Received response '...'
4. See error in screenshot
**Expected Behavior**
A clear and concise description of what you expected to happen.
**Screenshots (optional)**
If applicable, add screenshots to help explain process flow and behavior.
**Host Environment**
Please provide details about the host environment. Much of this information can be found running: `witness_node --version`.
- Host OS: [e.g. Ubuntu 18.04 LTS]
- Host Physical RAM [e.g. 4GB]
- Peerplays Version
- OpenSSL Version: [e.g. 1.1.0g]
- Boost Version: [e.g. 1.67.0]
**Additional Context (optional)**
Add any other context about the problem here.
## PBSA / Developer tasks
- [ ] Evaluate / Prioritize Bug Report
- [ ] Refine User Stories / Requirements
- [ ] Define Test Cases
- [ ] Design / Develop Solution
- [ ] Perform QA/Testing
- [ ] Update Documentation

View file

@ -1,42 +0,0 @@
---
name: Build Error
about: Create a detailed report about an error encountered during the Peerplays build process.
---
**Instructions**
Please include a detailed Title above. Next, please complete the following sections below:
* Build Error
* Build Environment
* Steps To Reproduce
* Console Logs (optional)
Finally, press the 'Submit new issue' button. The developers/PBSA Team will evaluate and prioritize your Bug Report for future development.
**Build Error Description**
A clear and concise description of what the build error is.
**Build Environment**
Details about the build environment, including the relevant required libraries. Much of this information can be found in the `CMakeFiles/CMakeOutput.log`.
- Host OS: [e.g. Ubuntu 18.04 LTS]
- Host Physical RAM [e.g. 4GB]
- Source Branch/Tag: [e.g. master or 2.0.180425]
- OpenSSL Version: [e.g. 1.1.0g]
- Boost Version: [e.g. 1.65.1]
- C++ Compiler: [e.g. gcc version 4.8.5]
**Steps To Reproduce**
Steps to reproduce the behavior (example outlined below):
1. Using installation guide from this URL...
2. This is my complete build script...
3. It fails at this step with the following output...
4. See the error in the console log below...
**Console Logs (optional)**
Please provide the full console log, including all commands entered and their output. This will allow detailed troubleshooting.
## CORE TEAM TASK LIST
- [ ] Evaluate `Build Error`
- [ ] Provide build guidance
- [ ] <OR> Create `Bug Report`

View file

@ -1,43 +0,0 @@
---
name: Feature Request
about: Suggest an idea for the Peerplays Community & PBSA Team to evaluate and prioritize for development.
---
**Instructions**
Please include a detailed Title above. Next, please complete the following sections below:
* User Story
* Impacts
* Additional Context (optional)
Finally, press the 'Submit new issue' button. The Core Team will evaluate and prioritize your Feature Request for future development.
**User Story**
Please tell us about your feature request using the User Story format:
As a `<persona>` I want `<some functionality>` so that `<some benefit is realized>`.
At minimum, please define the `<who>`, `<what>` and `<why>` for your feature request. The `<who>` may be the system software, a component thereof, the end user, etc.; please be specific describing the context. The `<what>` details the solution your feature will provide; please describe the process flow for the functionality. The `<why>` details the benefits the feature will deliver; consider referencing alternative implementations for context.
**Impacts**
Describe which portion(s) of Peerplays that may be impacted by your request. Please tick at least one box.
- [ ] API (the application programming interface)
- [ ] Build (the build process or something prior to compiled code)
- [ ] CLI (the command line wallet)
- [ ] Deployment (the deployment process after building such as Docker, Gitlab, etc.)
- [ ] P2P (the peer-to-peer network for transaction/block propagation)
- [ ] Performance (system or user efficiency, etc.)
- [ ] Protocol (the blockchain logic, consensus, validation, etc.)
- [ ] Security (the security of system or user data, etc.)
- [ ] UX (the User Experience)
- [ ] Other (please add below)
**Additional Context (optional)**
Add any other context about your request here.
## Community / PBSA check list
- [ ] Evaluate / Prioritize Feature Request
- [ ] Refine User Stories / Requirements
- [ ] Define Test Cases
- [ ] Design / Develop Solution
- [ ] Perform QA/Testing
- [ ] Update Documentation

View file

@ -1,53 +0,0 @@
Please Note:
1. PRs will be reviewed from oldest to newest
2. PRs should use PR template in order to be considered for review.
3. PRs that do not have one of the PR template completely filled out with all declarations satisfied will not be reviewed.
### Purpose
(FILL ME IN) This section describes why this PR is here. Usually it would include a reference
to the tracking task that it is part or all of the solution for.
The Tracking issue is [Create the issue if non existent and fill in]
## Instructions to Verify
**Steps To Reproduce: **
[Provide Steps to reproduce the issue or patterns/regular expression to look for in the CI]
**Expected Behavior**
[Provide Steps to reproduce the issue]
**Tests Added and available in CI**
** Screenshots (optional) **
** Host Environment (optional) **
** Additional Context (optional) **
### Declarations
Check these if you believe they are true
- [ ] The code base is in a better state after this PR
- [ ] Is prepared according to the [Release Management & Versioning](https://github.com/peerplays-network/peerplays/wiki/Release-Management-&-Versioning)
- [ ] The level of testing this PR includes is appropriate
- [ ] All tests pass using the self-service CI/Gitlab.
- [ ] Changes to the API is documented
- [ ] Testing steps for the QA team / community is shared
### Reviewers
(FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR)
(FILL ME IN, optional) Any additional notes to reviewers or testers.
### FYIs
(FILL ME IN, Optional) Names of anyone else you wish to be notified of

1
.gitignore vendored
View file

@ -11,6 +11,7 @@ moc_*
hardfork.hpp hardfork.hpp
build_xc build_xc
data data
CMakeDoxyfile.in
build build

View file

@ -1,5 +1,9 @@
include: include:
- template: Code-Quality.gitlab-ci.yml - template: Code-Quality.gitlab-ci.yml
- template: Dependency-Scanning.gitlab-ci.yml
- template: License-Scanning.gitlab-ci.yml
- template: SAST.gitlab-ci.yml
- template: Secret-Detection.gitlab-ci.yml
stages: stages:
- build - build
@ -8,48 +12,30 @@ stages:
build: build:
stage: build stage: build
script: script:
- rm -rf .git/modules/* ./docs ./libraries/fc
- git submodule sync - git submodule sync
- git submodule update --init --recursive - git submodule update --init --recursive
- cmake . - rm -rf build
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release ..
- make -j$(nproc) - make -j$(nproc)
artifacts: artifacts:
untracked: true untracked: true
paths: paths:
- libraries/ - build/libraries/
- programs/ - build/programs/
- tests/ - build/tests/
tags:
- builder
test:
stage: test
dependencies:
- build
script:
- ./tests/betting_test
- ./tests/chain_test
- ./tests/cli_test
tags: tags:
- builder - builder
code_quality: test:
stage: test stage: test
image: docker:stable dependencies:
variables: - build
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
script: script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') - ./build/tests/betting_test --log_level=message
- docker run - ./build/tests/chain_test --log_level=message
--env SOURCE_CODE="$PWD" - ./build/tests/cli_test --log_level=message
--volume "$PWD":/code tags:
--volume /var/run/docker.sock:/var/run/docker.sock - builder
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [gl-code-quality-report.json]
expire_in: 1 week
except:
variables:
- $CODE_QUALITY_DISABLED

3
.gitmodules vendored
View file

@ -4,5 +4,6 @@
ignore = dirty ignore = dirty
[submodule "libraries/fc"] [submodule "libraries/fc"]
path = libraries/fc path = libraries/fc
url = https://github.com/peerplays-network/peerplays-fc.git url = https://github.com/peerplays-network/peerplays-fc.git
branch = latest-fc
ignore = dirty ignore = dirty

279
CMakeDoxyfile.in Normal file
View file

@ -0,0 +1,279 @@
#
# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE!
#
DOXYFILE_ENCODING = @DOXYGEN_DOXYFILE_ENCODING@
PROJECT_NAME = @DOXYGEN_PROJECT_NAME@
PROJECT_NUMBER = @DOXYGEN_PROJECT_NUMBER@
PROJECT_BRIEF = @DOXYGEN_PROJECT_BRIEF@
PROJECT_LOGO = @DOXYGEN_PROJECT_LOGO@
OUTPUT_DIRECTORY = @DOXYGEN_OUTPUT_DIRECTORY@
CREATE_SUBDIRS = @DOXYGEN_CREATE_SUBDIRS@
ALLOW_UNICODE_NAMES = @DOXYGEN_ALLOW_UNICODE_NAMES@
OUTPUT_LANGUAGE = @DOXYGEN_OUTPUT_LANGUAGE@
OUTPUT_TEXT_DIRECTION = @DOXYGEN_OUTPUT_TEXT_DIRECTION@
BRIEF_MEMBER_DESC = @DOXYGEN_BRIEF_MEMBER_DESC@
REPEAT_BRIEF = @DOXYGEN_REPEAT_BRIEF@
ABBREVIATE_BRIEF = @DOXYGEN_ABBREVIATE_BRIEF@
ALWAYS_DETAILED_SEC = @DOXYGEN_ALWAYS_DETAILED_SEC@
INLINE_INHERITED_MEMB = @DOXYGEN_INLINE_INHERITED_MEMB@
FULL_PATH_NAMES = @DOXYGEN_FULL_PATH_NAMES@
STRIP_FROM_PATH = @DOXYGEN_STRIP_FROM_PATH@
STRIP_FROM_INC_PATH = @DOXYGEN_STRIP_FROM_INC_PATH@
SHORT_NAMES = @DOXYGEN_SHORT_NAMES@
JAVADOC_AUTOBRIEF = @DOXYGEN_JAVADOC_AUTOBRIEF@
JAVADOC_BANNER = @DOXYGEN_JAVADOC_BANNER@
QT_AUTOBRIEF = @DOXYGEN_QT_AUTOBRIEF@
MULTILINE_CPP_IS_BRIEF = @DOXYGEN_MULTILINE_CPP_IS_BRIEF@
INHERIT_DOCS = @DOXYGEN_INHERIT_DOCS@
SEPARATE_MEMBER_PAGES = @DOXYGEN_SEPARATE_MEMBER_PAGES@
TAB_SIZE = @DOXYGEN_TAB_SIZE@
ALIASES = @DOXYGEN_ALIASES@
TCL_SUBST = @DOXYGEN_TCL_SUBST@
OPTIMIZE_OUTPUT_FOR_C = @DOXYGEN_OPTIMIZE_OUTPUT_FOR_C@
OPTIMIZE_OUTPUT_JAVA = @DOXYGEN_OPTIMIZE_OUTPUT_JAVA@
OPTIMIZE_FOR_FORTRAN = @DOXYGEN_OPTIMIZE_FOR_FORTRAN@
OPTIMIZE_OUTPUT_VHDL = @DOXYGEN_OPTIMIZE_OUTPUT_VHDL@
OPTIMIZE_OUTPUT_SLICE = @DOXYGEN_OPTIMIZE_OUTPUT_SLICE@
EXTENSION_MAPPING = @DOXYGEN_EXTENSION_MAPPING@
MARKDOWN_SUPPORT = @DOXYGEN_MARKDOWN_SUPPORT@
TOC_INCLUDE_HEADINGS = @DOXYGEN_TOC_INCLUDE_HEADINGS@
AUTOLINK_SUPPORT = @DOXYGEN_AUTOLINK_SUPPORT@
BUILTIN_STL_SUPPORT = @DOXYGEN_BUILTIN_STL_SUPPORT@
CPP_CLI_SUPPORT = @DOXYGEN_CPP_CLI_SUPPORT@
SIP_SUPPORT = @DOXYGEN_SIP_SUPPORT@
IDL_PROPERTY_SUPPORT = @DOXYGEN_IDL_PROPERTY_SUPPORT@
DISTRIBUTE_GROUP_DOC = @DOXYGEN_DISTRIBUTE_GROUP_DOC@
GROUP_NESTED_COMPOUNDS = @DOXYGEN_GROUP_NESTED_COMPOUNDS@
SUBGROUPING = @DOXYGEN_SUBGROUPING@
INLINE_GROUPED_CLASSES = @DOXYGEN_INLINE_GROUPED_CLASSES@
INLINE_SIMPLE_STRUCTS = @DOXYGEN_INLINE_SIMPLE_STRUCTS@
TYPEDEF_HIDES_STRUCT = @DOXYGEN_TYPEDEF_HIDES_STRUCT@
LOOKUP_CACHE_SIZE = @DOXYGEN_LOOKUP_CACHE_SIZE@
EXTRACT_ALL = @DOXYGEN_EXTRACT_ALL@
EXTRACT_PRIVATE = @DOXYGEN_EXTRACT_PRIVATE@
EXTRACT_PRIV_VIRTUAL = @DOXYGEN_EXTRACT_PRIV_VIRTUAL@
EXTRACT_PACKAGE = @DOXYGEN_EXTRACT_PACKAGE@
EXTRACT_STATIC = @DOXYGEN_EXTRACT_STATIC@
EXTRACT_LOCAL_CLASSES = @DOXYGEN_EXTRACT_LOCAL_CLASSES@
EXTRACT_LOCAL_METHODS = @DOXYGEN_EXTRACT_LOCAL_METHODS@
EXTRACT_ANON_NSPACES = @DOXYGEN_EXTRACT_ANON_NSPACES@
HIDE_UNDOC_MEMBERS = @DOXYGEN_HIDE_UNDOC_MEMBERS@
HIDE_UNDOC_CLASSES = @DOXYGEN_HIDE_UNDOC_CLASSES@
HIDE_FRIEND_COMPOUNDS = @DOXYGEN_HIDE_FRIEND_COMPOUNDS@
HIDE_IN_BODY_DOCS = @DOXYGEN_HIDE_IN_BODY_DOCS@
INTERNAL_DOCS = @DOXYGEN_INTERNAL_DOCS@
CASE_SENSE_NAMES = @DOXYGEN_CASE_SENSE_NAMES@
HIDE_SCOPE_NAMES = @DOXYGEN_HIDE_SCOPE_NAMES@
HIDE_COMPOUND_REFERENCE= @DOXYGEN_HIDE_COMPOUND_REFERENCE@
SHOW_INCLUDE_FILES = @DOXYGEN_SHOW_INCLUDE_FILES@
SHOW_GROUPED_MEMB_INC = @DOXYGEN_SHOW_GROUPED_MEMB_INC@
FORCE_LOCAL_INCLUDES = @DOXYGEN_FORCE_LOCAL_INCLUDES@
INLINE_INFO = @DOXYGEN_INLINE_INFO@
SORT_MEMBER_DOCS = @DOXYGEN_SORT_MEMBER_DOCS@
SORT_BRIEF_DOCS = @DOXYGEN_SORT_BRIEF_DOCS@
SORT_MEMBERS_CTORS_1ST = @DOXYGEN_SORT_MEMBERS_CTORS_1ST@
SORT_GROUP_NAMES = @DOXYGEN_SORT_GROUP_NAMES@
SORT_BY_SCOPE_NAME = @DOXYGEN_SORT_BY_SCOPE_NAME@
STRICT_PROTO_MATCHING = @DOXYGEN_STRICT_PROTO_MATCHING@
GENERATE_TODOLIST = @DOXYGEN_GENERATE_TODOLIST@
GENERATE_TESTLIST = @DOXYGEN_GENERATE_TESTLIST@
GENERATE_BUGLIST = @DOXYGEN_GENERATE_BUGLIST@
GENERATE_DEPRECATEDLIST= @DOXYGEN_GENERATE_DEPRECATEDLIST@
ENABLED_SECTIONS = @DOXYGEN_ENABLED_SECTIONS@
MAX_INITIALIZER_LINES = @DOXYGEN_MAX_INITIALIZER_LINES@
SHOW_USED_FILES = @DOXYGEN_SHOW_USED_FILES@
SHOW_FILES = @DOXYGEN_SHOW_FILES@
SHOW_NAMESPACES = @DOXYGEN_SHOW_NAMESPACES@
FILE_VERSION_FILTER = @DOXYGEN_FILE_VERSION_FILTER@
LAYOUT_FILE = @DOXYGEN_LAYOUT_FILE@
CITE_BIB_FILES = @DOXYGEN_CITE_BIB_FILES@
QUIET = @DOXYGEN_QUIET@
WARNINGS = @DOXYGEN_WARNINGS@
WARN_IF_UNDOCUMENTED = @DOXYGEN_WARN_IF_UNDOCUMENTED@
WARN_IF_DOC_ERROR = @DOXYGEN_WARN_IF_DOC_ERROR@
WARN_NO_PARAMDOC = @DOXYGEN_WARN_NO_PARAMDOC@
WARN_AS_ERROR = @DOXYGEN_WARN_AS_ERROR@
WARN_FORMAT = @DOXYGEN_WARN_FORMAT@
WARN_LOGFILE = @DOXYGEN_WARN_LOGFILE@
INPUT = @DOXYGEN_INPUT@
INPUT_ENCODING = @DOXYGEN_INPUT_ENCODING@
FILE_PATTERNS = @DOXYGEN_FILE_PATTERNS@
RECURSIVE = @DOXYGEN_RECURSIVE@
EXCLUDE = @DOXYGEN_EXCLUDE@
EXCLUDE_SYMLINKS = @DOXYGEN_EXCLUDE_SYMLINKS@
EXCLUDE_PATTERNS = @DOXYGEN_EXCLUDE_PATTERNS@
EXCLUDE_SYMBOLS = @DOXYGEN_EXCLUDE_SYMBOLS@
EXAMPLE_PATH = @DOXYGEN_EXAMPLE_PATH@
EXAMPLE_PATTERNS = @DOXYGEN_EXAMPLE_PATTERNS@
EXAMPLE_RECURSIVE = @DOXYGEN_EXAMPLE_RECURSIVE@
IMAGE_PATH = @DOXYGEN_IMAGE_PATH@
INPUT_FILTER = @DOXYGEN_INPUT_FILTER@
FILTER_PATTERNS = @DOXYGEN_FILTER_PATTERNS@
FILTER_SOURCE_FILES = @DOXYGEN_FILTER_SOURCE_FILES@
FILTER_SOURCE_PATTERNS = @DOXYGEN_FILTER_SOURCE_PATTERNS@
USE_MDFILE_AS_MAINPAGE = @DOXYGEN_USE_MDFILE_AS_MAINPAGE@
SOURCE_BROWSER = @DOXYGEN_SOURCE_BROWSER@
INLINE_SOURCES = @DOXYGEN_INLINE_SOURCES@
STRIP_CODE_COMMENTS = @DOXYGEN_STRIP_CODE_COMMENTS@
REFERENCED_BY_RELATION = @DOXYGEN_REFERENCED_BY_RELATION@
REFERENCES_RELATION = @DOXYGEN_REFERENCES_RELATION@
REFERENCES_LINK_SOURCE = @DOXYGEN_REFERENCES_LINK_SOURCE@
SOURCE_TOOLTIPS = @DOXYGEN_SOURCE_TOOLTIPS@
USE_HTAGS = @DOXYGEN_USE_HTAGS@
VERBATIM_HEADERS = @DOXYGEN_VERBATIM_HEADERS@
CLANG_ASSISTED_PARSING = @DOXYGEN_CLANG_ASSISTED_PARSING@
CLANG_OPTIONS = @DOXYGEN_CLANG_OPTIONS@
CLANG_DATABASE_PATH = @DOXYGEN_CLANG_DATABASE_PATH@
ALPHABETICAL_INDEX = @DOXYGEN_ALPHABETICAL_INDEX@
COLS_IN_ALPHA_INDEX = @DOXYGEN_COLS_IN_ALPHA_INDEX@
IGNORE_PREFIX = @DOXYGEN_IGNORE_PREFIX@
GENERATE_HTML = @DOXYGEN_GENERATE_HTML@
HTML_OUTPUT = @DOXYGEN_HTML_OUTPUT@
HTML_FILE_EXTENSION = @DOXYGEN_HTML_FILE_EXTENSION@
HTML_HEADER = @DOXYGEN_HTML_HEADER@
HTML_FOOTER = @DOXYGEN_HTML_FOOTER@
HTML_STYLESHEET = @DOXYGEN_HTML_STYLESHEET@
HTML_EXTRA_STYLESHEET = @DOXYGEN_HTML_EXTRA_STYLESHEET@
HTML_EXTRA_FILES = @DOXYGEN_HTML_EXTRA_FILES@
HTML_COLORSTYLE_HUE = @DOXYGEN_HTML_COLORSTYLE_HUE@
HTML_COLORSTYLE_SAT = @DOXYGEN_HTML_COLORSTYLE_SAT@
HTML_COLORSTYLE_GAMMA = @DOXYGEN_HTML_COLORSTYLE_GAMMA@
HTML_TIMESTAMP = @DOXYGEN_HTML_TIMESTAMP@
HTML_DYNAMIC_MENUS = @DOXYGEN_HTML_DYNAMIC_MENUS@
HTML_DYNAMIC_SECTIONS = @DOXYGEN_HTML_DYNAMIC_SECTIONS@
HTML_INDEX_NUM_ENTRIES = @DOXYGEN_HTML_INDEX_NUM_ENTRIES@
GENERATE_DOCSET = @DOXYGEN_GENERATE_DOCSET@
DOCSET_FEEDNAME = @DOXYGEN_DOCSET_FEEDNAME@
DOCSET_BUNDLE_ID = @DOXYGEN_DOCSET_BUNDLE_ID@
DOCSET_PUBLISHER_ID = @DOXYGEN_DOCSET_PUBLISHER_ID@
DOCSET_PUBLISHER_NAME = @DOXYGEN_DOCSET_PUBLISHER_NAME@
GENERATE_HTMLHELP = @DOXYGEN_GENERATE_HTMLHELP@
CHM_FILE = @DOXYGEN_CHM_FILE@
HHC_LOCATION = @DOXYGEN_HHC_LOCATION@
GENERATE_CHI = @DOXYGEN_GENERATE_CHI@
CHM_INDEX_ENCODING = @DOXYGEN_CHM_INDEX_ENCODING@
BINARY_TOC = @DOXYGEN_BINARY_TOC@
TOC_EXPAND = @DOXYGEN_TOC_EXPAND@
GENERATE_QHP = @DOXYGEN_GENERATE_QHP@
QCH_FILE = @DOXYGEN_QCH_FILE@
QHP_NAMESPACE = @DOXYGEN_QHP_NAMESPACE@
QHP_VIRTUAL_FOLDER = @DOXYGEN_QHP_VIRTUAL_FOLDER@
QHP_CUST_FILTER_NAME = @DOXYGEN_QHP_CUST_FILTER_NAME@
QHP_CUST_FILTER_ATTRS = @DOXYGEN_QHP_CUST_FILTER_ATTRS@
QHP_SECT_FILTER_ATTRS = @DOXYGEN_QHP_SECT_FILTER_ATTRS@
QHG_LOCATION = @DOXYGEN_QHG_LOCATION@
GENERATE_ECLIPSEHELP = @DOXYGEN_GENERATE_ECLIPSEHELP@
ECLIPSE_DOC_ID = @DOXYGEN_ECLIPSE_DOC_ID@
DISABLE_INDEX = @DOXYGEN_DISABLE_INDEX@
GENERATE_TREEVIEW = @DOXYGEN_GENERATE_TREEVIEW@
ENUM_VALUES_PER_LINE = @DOXYGEN_ENUM_VALUES_PER_LINE@
TREEVIEW_WIDTH = @DOXYGEN_TREEVIEW_WIDTH@
EXT_LINKS_IN_WINDOW = @DOXYGEN_EXT_LINKS_IN_WINDOW@
FORMULA_FONTSIZE = @DOXYGEN_FORMULA_FONTSIZE@
FORMULA_TRANSPARENT = @DOXYGEN_FORMULA_TRANSPARENT@
USE_MATHJAX = @DOXYGEN_USE_MATHJAX@
MATHJAX_FORMAT = @DOXYGEN_MATHJAX_FORMAT@
MATHJAX_RELPATH = @DOXYGEN_MATHJAX_RELPATH@
MATHJAX_EXTENSIONS = @DOXYGEN_MATHJAX_EXTENSIONS@
MATHJAX_CODEFILE = @DOXYGEN_MATHJAX_CODEFILE@
SEARCHENGINE = @DOXYGEN_SEARCHENGINE@
SERVER_BASED_SEARCH = @DOXYGEN_SERVER_BASED_SEARCH@
EXTERNAL_SEARCH = @DOXYGEN_EXTERNAL_SEARCH@
SEARCHENGINE_URL = @DOXYGEN_SEARCHENGINE_URL@
SEARCHDATA_FILE = @DOXYGEN_SEARCHDATA_FILE@
EXTERNAL_SEARCH_ID = @DOXYGEN_EXTERNAL_SEARCH_ID@
EXTRA_SEARCH_MAPPINGS = @DOXYGEN_EXTRA_SEARCH_MAPPINGS@
GENERATE_LATEX = @DOXYGEN_GENERATE_LATEX@
LATEX_OUTPUT = @DOXYGEN_LATEX_OUTPUT@
LATEX_CMD_NAME = @DOXYGEN_LATEX_CMD_NAME@
MAKEINDEX_CMD_NAME = @DOXYGEN_MAKEINDEX_CMD_NAME@
LATEX_MAKEINDEX_CMD = @DOXYGEN_LATEX_MAKEINDEX_CMD@
COMPACT_LATEX = @DOXYGEN_COMPACT_LATEX@
PAPER_TYPE = @DOXYGEN_PAPER_TYPE@
EXTRA_PACKAGES = @DOXYGEN_EXTRA_PACKAGES@
LATEX_HEADER = @DOXYGEN_LATEX_HEADER@
LATEX_FOOTER = @DOXYGEN_LATEX_FOOTER@
LATEX_EXTRA_STYLESHEET = @DOXYGEN_LATEX_EXTRA_STYLESHEET@
LATEX_EXTRA_FILES = @DOXYGEN_LATEX_EXTRA_FILES@
PDF_HYPERLINKS = @DOXYGEN_PDF_HYPERLINKS@
USE_PDFLATEX = @DOXYGEN_USE_PDFLATEX@
LATEX_BATCHMODE = @DOXYGEN_LATEX_BATCHMODE@
LATEX_HIDE_INDICES = @DOXYGEN_LATEX_HIDE_INDICES@
LATEX_SOURCE_CODE = @DOXYGEN_LATEX_SOURCE_CODE@
LATEX_BIB_STYLE = @DOXYGEN_LATEX_BIB_STYLE@
LATEX_TIMESTAMP = @DOXYGEN_LATEX_TIMESTAMP@
LATEX_EMOJI_DIRECTORY = @DOXYGEN_LATEX_EMOJI_DIRECTORY@
GENERATE_RTF = @DOXYGEN_GENERATE_RTF@
RTF_OUTPUT = @DOXYGEN_RTF_OUTPUT@
COMPACT_RTF = @DOXYGEN_COMPACT_RTF@
RTF_HYPERLINKS = @DOXYGEN_RTF_HYPERLINKS@
RTF_STYLESHEET_FILE = @DOXYGEN_RTF_STYLESHEET_FILE@
RTF_EXTENSIONS_FILE = @DOXYGEN_RTF_EXTENSIONS_FILE@
RTF_SOURCE_CODE = @DOXYGEN_RTF_SOURCE_CODE@
GENERATE_MAN = @DOXYGEN_GENERATE_MAN@
MAN_OUTPUT = @DOXYGEN_MAN_OUTPUT@
MAN_EXTENSION = @DOXYGEN_MAN_EXTENSION@
MAN_SUBDIR = @DOXYGEN_MAN_SUBDIR@
MAN_LINKS = @DOXYGEN_MAN_LINKS@
GENERATE_XML = @DOXYGEN_GENERATE_XML@
XML_OUTPUT = @DOXYGEN_XML_OUTPUT@
XML_PROGRAMLISTING = @DOXYGEN_XML_PROGRAMLISTING@
XML_NS_MEMB_FILE_SCOPE = @DOXYGEN_XML_NS_MEMB_FILE_SCOPE@
GENERATE_DOCBOOK = @DOXYGEN_GENERATE_DOCBOOK@
DOCBOOK_OUTPUT = @DOXYGEN_DOCBOOK_OUTPUT@
DOCBOOK_PROGRAMLISTING = @DOXYGEN_DOCBOOK_PROGRAMLISTING@
GENERATE_AUTOGEN_DEF = @DOXYGEN_GENERATE_AUTOGEN_DEF@
GENERATE_PERLMOD = @DOXYGEN_GENERATE_PERLMOD@
PERLMOD_LATEX = @DOXYGEN_PERLMOD_LATEX@
PERLMOD_PRETTY = @DOXYGEN_PERLMOD_PRETTY@
PERLMOD_MAKEVAR_PREFIX = @DOXYGEN_PERLMOD_MAKEVAR_PREFIX@
ENABLE_PREPROCESSING = @DOXYGEN_ENABLE_PREPROCESSING@
MACRO_EXPANSION = @DOXYGEN_MACRO_EXPANSION@
EXPAND_ONLY_PREDEF = @DOXYGEN_EXPAND_ONLY_PREDEF@
SEARCH_INCLUDES = @DOXYGEN_SEARCH_INCLUDES@
INCLUDE_PATH = @DOXYGEN_INCLUDE_PATH@
INCLUDE_FILE_PATTERNS = @DOXYGEN_INCLUDE_FILE_PATTERNS@
PREDEFINED = @DOXYGEN_PREDEFINED@
EXPAND_AS_DEFINED = @DOXYGEN_EXPAND_AS_DEFINED@
SKIP_FUNCTION_MACROS = @DOXYGEN_SKIP_FUNCTION_MACROS@
TAGFILES = @DOXYGEN_TAGFILES@
GENERATE_TAGFILE = @DOXYGEN_GENERATE_TAGFILE@
ALLEXTERNALS = @DOXYGEN_ALLEXTERNALS@
EXTERNAL_GROUPS = @DOXYGEN_EXTERNAL_GROUPS@
EXTERNAL_PAGES = @DOXYGEN_EXTERNAL_PAGES@
CLASS_DIAGRAMS = @DOXYGEN_CLASS_DIAGRAMS@
DIA_PATH = @DOXYGEN_DIA_PATH@
HIDE_UNDOC_RELATIONS = @DOXYGEN_HIDE_UNDOC_RELATIONS@
HAVE_DOT = @DOXYGEN_HAVE_DOT@
DOT_NUM_THREADS = @DOXYGEN_DOT_NUM_THREADS@
DOT_FONTNAME = @DOXYGEN_DOT_FONTNAME@
DOT_FONTSIZE = @DOXYGEN_DOT_FONTSIZE@
DOT_FONTPATH = @DOXYGEN_DOT_FONTPATH@
CLASS_GRAPH = @DOXYGEN_CLASS_GRAPH@
COLLABORATION_GRAPH = @DOXYGEN_COLLABORATION_GRAPH@
GROUP_GRAPHS = @DOXYGEN_GROUP_GRAPHS@
UML_LOOK = @DOXYGEN_UML_LOOK@
UML_LIMIT_NUM_FIELDS = @DOXYGEN_UML_LIMIT_NUM_FIELDS@
TEMPLATE_RELATIONS = @DOXYGEN_TEMPLATE_RELATIONS@
INCLUDE_GRAPH = @DOXYGEN_INCLUDE_GRAPH@
INCLUDED_BY_GRAPH = @DOXYGEN_INCLUDED_BY_GRAPH@
CALL_GRAPH = @DOXYGEN_CALL_GRAPH@
CALLER_GRAPH = @DOXYGEN_CALLER_GRAPH@
GRAPHICAL_HIERARCHY = @DOXYGEN_GRAPHICAL_HIERARCHY@
DIRECTORY_GRAPH = @DOXYGEN_DIRECTORY_GRAPH@
DOT_IMAGE_FORMAT = @DOXYGEN_DOT_IMAGE_FORMAT@
INTERACTIVE_SVG = @DOXYGEN_INTERACTIVE_SVG@
DOT_PATH = @DOXYGEN_DOT_PATH@
DOTFILE_DIRS = @DOXYGEN_DOTFILE_DIRS@
MSCFILE_DIRS = @DOXYGEN_MSCFILE_DIRS@
DIAFILE_DIRS = @DOXYGEN_DIAFILE_DIRS@
PLANTUML_JAR_PATH = @DOXYGEN_PLANTUML_JAR_PATH@
PLANTUML_CFG_FILE = @DOXYGEN_PLANTUML_CFG_FILE@
PLANTUML_INCLUDE_PATH = @DOXYGEN_PLANTUML_INCLUDE_PATH@
DOT_GRAPH_MAX_NODES = @DOXYGEN_DOT_GRAPH_MAX_NODES@
MAX_DOT_GRAPH_DEPTH = @DOXYGEN_MAX_DOT_GRAPH_DEPTH@
DOT_TRANSPARENT = @DOXYGEN_DOT_TRANSPARENT@
DOT_MULTI_TARGETS = @DOXYGEN_DOT_MULTI_TARGETS@
GENERATE_LEGEND = @DOXYGEN_GENERATE_LEGEND@
DOT_CLEANUP = @DOXYGEN_DOT_CLEANUP@

View file

@ -135,7 +135,7 @@ else( WIN32 ) # Apple AND Linux
endif( APPLE ) endif( APPLE )
if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" ) if( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-builtin-memcmp -Wno-class-memaccess -Wno-parentheses -Wno-terminate -Wno-invalid-offsetof" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-builtin-memcmp -Wno-parentheses -Wno-terminate -Wno-invalid-offsetof -Wno-sign-compare" )
elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" ) elseif( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
if( CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.0.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0.0 ) if( CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 4.0.0 OR CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0.0 )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-partial-specialization" ) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-partial-specialization" )

View file

@ -13,6 +13,7 @@ RUN \
build-essential \ build-essential \
ca-certificates \ ca-certificates \
cmake \ cmake \
dnsutils \
doxygen \ doxygen \
git \ git \
graphviz \ graphviz \
@ -22,6 +23,7 @@ RUN \
libreadline-dev \ libreadline-dev \
libssl-dev \ libssl-dev \
libtool \ libtool \
libzmq3-dev \
locales \ locales \
ntp \ ntp \
pkg-config \ pkg-config \
@ -57,7 +59,7 @@ RUN \
cd build/release && \ cd build/release && \
cmake \ cmake \
-DBOOST_ROOT="$BOOST_ROOT" \ -DBOOST_ROOT="$BOOST_ROOT" \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Debug \
../.. && \ ../.. && \
make witness_node cli_wallet && \ make witness_node cli_wallet && \
install -s programs/witness_node/witness_node programs/cli_wallet/cli_wallet /usr/local/bin && \ install -s programs/witness_node/witness_node programs/cli_wallet/cli_wallet /usr/local/bin && \

277
README.md
View file

@ -2,26 +2,275 @@ Intro for new developers and witnesses
------------------------ ------------------------
This is a quick introduction to get new developers and witnesses up to speed on Peerplays blockchain. It is intended for witnesses plannig to join a live, already deployed blockchain. This is a quick introduction to get new developers and witnesses up to speed on Peerplays blockchain. It is intended for witnesses plannig to join a live, already deployed blockchain.
# Building on Ubuntu 18.04 LTS and Installation Instructions
Witness Node Setup The following dependencies were necessary for a clean install of Ubuntu 18.04 LTS:
```
sudo apt-get install autoconf bash build-essential ca-certificates cmake \
doxygen git graphviz libbz2-dev libcurl4-openssl-dev libncurses-dev \
libreadline-dev libssl-dev libtool libzmq3-dev locales ntp pkg-config \
wget
```
## Build Boost 1.67.0
```
mkdir $HOME/src
cd $HOME/src
export BOOST_ROOT=$HOME/src/boost_1_67_0
sudo apt-get update
sudo apt-get install -y autotools-dev build-essential libbz2-dev libicu-dev python-dev
wget -c 'http://sourceforge.net/projects/boost/files/boost/1.67.0/boost_1_67_0.tar.bz2/download'\
-O boost_1_67_0.tar.bz2
tar xjf boost_1_67_0.tar.bz2
cd boost_1_67_0/
./bootstrap.sh "--prefix=$BOOST_ROOT"
./b2 install
```
## Building Peerplays
```
cd $HOME/src
export BOOST_ROOT=$HOME/src/boost_1_67_0
git clone https://github.com/peerplays-network/peerplays.git
cd peerplays
git submodule update --init --recursive
cmake -DBOOST_ROOT="$BOOST_ROOT" -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
make install # this can install the executable files under /usr/local
```
docker build -t peerplays .
## Docker image
```
# Install docker
sudo apt install docker.io
# Add current user to docker group
sudo usermod -a -G docker $USER
# You need to restart your shell session, to apply group membership
# Type 'groups' to verify that you are a member of a docker group
# Build docker image (from the project root, must be a docker group member)
docker build -t peerplays .
# Start docker image
docker start peerplays
# Exposed ports
# # rpc service:
# EXPOSE 8090
# # p2p service:
# EXPOSE 1776
```
Rest of the instructions on starting the chain remains same.
Starting A Peerplays Node
----------------- -----------------
For instructions on witness node installation and configuration refer to the Peerplays Documentation here:
https://www.peerplays.tech/witnesses/setting-up-a-witness-node For Ubuntu 14.04 LTS and up users, see
[this](https://github.com/cryptonomex/graphene/wiki/build-ubuntu) and
then proceed with:
git clone https://github.com/peerplays-network/peerplays.git
BOS and MINT Setup cd peerplays
git submodule update --init --recursive
cmake -DBOOST_ROOT="$BOOST_ROOT" -DCMAKE_BUILD_TYPE=Release .
make
./programs/witness_node/witness_node
Launching the witness creates required directories. Next, **stop the witness** and continue.
$ vi witness_node_data_dir/config.ini
p2p-endpoint = 0.0.0.0:9777
rpc-endpoint = 127.0.0.1:8090
seed-node = 213.184.225.234:59500
Start the witness back up
./programs/witness_node/witness_node
Upgrading A Peerplays Node
----------------- -----------------
The Bookie Oracle System (BOS) and Manual Intervention Tool (MINT) need to be installed as part of a witness setup. To minimize downtime of your peerplays node when upgrading, one upgrade
They are both prerequisites for the operation of the BookiePro app. idea was written in [this steemit
article](https://steemit.com/peerplays/@joseph/peerplays-update-setting-a-backup-witness-server-switching-servers).
Full instructions on BOS and MINT installation can be found here:
https://www.peerplays.tech/bookie-oracle-suite-bos/intro-bos
Wallet Setup Wallet Setup
----------------- -----------------
Full instructions on setting up a cli_wallet can be found here: Then, in a separate terminal window, start the command-line wallet `cli_wallet`:
https://www.peerplays.tech/witnesses/setting-up-a-witness-node./cli-wallet-setup ./programs/cli_wallet/cli_wallet
To set your initial password to 'password' use:
>>> set_password password
>>> unlock password
A list of CLI wallet commands is available
[here](https://github.com/PBSA/peerplays/blob/master/libraries/wallet/include/graphene/wallet/wallet.hpp).
Testnet - "Beatrice"
----------------------
- chain-id - T.B.D.
Use the `get_private_key_from_password` command
---------------------------------
You will to generate owner and active keys
```
get_private_key_from_password your_witness_username active the_key_you_received_from_the_faucet
```
This will reveal an array for your active key `["PPYxxx", "xxxx"]`
import_keys into your cli_wallet
-------------------------------
- use the second value in the array returned from the previous step for the private key
- be sure to wrap your username in quotes
- import the key with this command
```
import_key "your_witness_username" xxxx
```
Upgrade your account to lifetime membership
--------------------------------
```
upgrade_account your_witness_username true
```
Create your witness (substitute the url for your witness information)
-------------------------------
- place quotes around url
```
create_witness your_witness_username "url" true
```
**Be sure to take note of the block_signing_key**
IMPORTANT (issue below command using block_signing_key just obtained)
```
get_private_key block_signing_key
```
Compare this result to
```
dump_private_keys
```
You should see 3 pairs of keys. One of the pairs should match your block_signing_key and this is the one you will use in the next step!
Get your witness id
-----------------
```
get_witness username (note the "id" for your config)
```
Modify your witness_node config.ini to include **your** witness id and private key pair.
-------------------------
Comment out the existing private-key before adding yours
```
vim witness_node_data_dir/config.ini
witness-id = "1.6.x"
private-key = ["block_signing_key","private_key_for_your_block_signing_key"]
```
start your witness back up
------------------
```
./programs/witness_node/witness_node
```
If it fails to start, try with these flags (not for permanent use)
```
./programs/witness_node/witness_node --resync --replay
```
Vote for yourself
--------------
```
vote_for_witness your_witness_account your_witness_account true true
```
Ask to be voted in!
--------------
Join @Peerplays Telegram group to find information about the witness group.
http://t.me/@peerplayswitness
You will get logs that look like this:
```
2070264ms th_a application.cpp:506 handle_block ] Got block: #87913 time: 2017-05-27T16:34:30 latency: 264 ms from: bhuz-witness irreversible: 87903 (-10)
```
Assuming you've received votes, you will start producing as a witness at the next maintenance interval (once per hour). You can check your votes with.
```
get_witness your_witness_account
```
systemd
----------------
It's important for your witness to start when your system boots up. The filepaths here assume that you installed your witness into `/home/ubuntu/peerplays`
Create a logfile to hold your stdout/err logging
```bash
sudo touch /var/log/peerplays.log
```
Save this file in your peerplays directory. `vi /home/ubuntu/peerplays/start.sh`
```bash
#!/bin/bash
cd /home/ubuntu/peerplays
./programs/witness_node/witness_node &> /var/log/peerplays.log
```
Make it executable
```bash
chmod 744 /home/ubuntu/peerplays/start.sh
```
Create this file: `sudo vi /etc/systemd/system/peerplays.service`
Note the path for start.sh. Change it to match where your start.sh file is if necessary.
```
[Unit]
Description=Peerplays Witness
After=network.target
[Service]
ExecStart=/home/ubuntu/peerplays/start.sh
[Install]
WantedBy = multi-user.target
```
Enable the service
```bash
sudo systemctl enable peerplays.service
```
Make sure you don't get any errors
```bash
sudo systemctl status peerplays.service
```
Stop your witness if it is currently running from previous steps, then start it with the service.
```bash
sudo systemctl start peerplays.service
```
Check your logfile for entries
```bash
tail -f /var/log/peerplays.log
```
Running specific tests
----------------------
- `tests/chain_tests -t block_tests/name_of_test`

View file

@ -14,6 +14,7 @@ VERSION=`cat /etc/peerplays/version`
# * $PEERPLAYSD_P2P_ENDPOINT # * $PEERPLAYSD_P2P_ENDPOINT
# * $PEERPLAYSD_WITNESS_ID # * $PEERPLAYSD_WITNESS_ID
# * $PEERPLAYSD_PRIVATE_KEY # * $PEERPLAYSD_PRIVATE_KEY
# * $PEERPLAYSD_DEBUG_PRIVATE_KEY
# * $PEERPLAYSD_TRACK_ACCOUNTS # * $PEERPLAYSD_TRACK_ACCOUNTS
# * $PEERPLAYSD_PARTIAL_OPERATIONS # * $PEERPLAYSD_PARTIAL_OPERATIONS
# * $PEERPLAYSD_MAX_OPS_PER_ACCOUNT # * $PEERPLAYSD_MAX_OPS_PER_ACCOUNT
@ -51,6 +52,10 @@ if [[ ! -z "$PEERPLAYSD_PRIVATE_KEY" ]]; then
ARGS+=" --private-key=$PEERPLAYSD_PRIVATE_KEY" ARGS+=" --private-key=$PEERPLAYSD_PRIVATE_KEY"
fi fi
if [[ ! -z "$PEERPLAYSD_DEBUG_PRIVATE_KEY" ]]; then
ARGS+=" --debug-private-key=$PEERPLAYSD_DEBUG_PRIVATE_KEY"
fi
if [[ ! -z "$PEERPLAYSD_TRACK_ACCOUNTS" ]]; then if [[ ! -z "$PEERPLAYSD_TRACK_ACCOUNTS" ]]; then
for ACCOUNT in $PEERPLAYSD_TRACK_ACCOUNTS ; do for ACCOUNT in $PEERPLAYSD_TRACK_ACCOUNTS ; do
ARGS+=" --track-account=$ACCOUNT" ARGS+=" --track-account=$ACCOUNT"

View file

@ -13,7 +13,7 @@ add_library( graphene_app
# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246 # need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
#target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness ) #target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness )
target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_chain fc graphene_db graphene_net graphene_time graphene_utilities graphene_debug_witness graphene_bookie graphene_elasticsearch ) target_link_libraries( graphene_app graphene_market_history graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_chain fc graphene_db graphene_net graphene_time graphene_utilities graphene_debug_witness graphene_bookie graphene_elasticsearch peerplays_sidechain )
target_include_directories( graphene_app target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/../egenesis/include" ) "${CMAKE_CURRENT_SOURCE_DIR}/../egenesis/include" )

View file

@ -38,7 +38,6 @@
#include <graphene/chain/tournament_object.hpp> #include <graphene/chain/tournament_object.hpp>
#include <fc/crypto/hex.hpp> #include <fc/crypto/hex.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/rpc/api_connection.hpp> #include <fc/rpc/api_connection.hpp>
#include <fc/thread/future.hpp> #include <fc/thread/future.hpp>
@ -182,7 +181,7 @@ namespace graphene { namespace app {
void network_broadcast_api::broadcast_transaction(const signed_transaction& trx) void network_broadcast_api::broadcast_transaction(const signed_transaction& trx)
{ {
trx.validate(); trx.validate();
database_api( *(_app.chain_database() ) ).check_transaction_for_duplicated_operations(trx); _app.chain_database()->check_transaction_for_duplicated_operations(trx);
_app.chain_database()->push_transaction(trx); _app.chain_database()->push_transaction(trx);
if( _app.p2p_node() != nullptr ) if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast_transaction(trx); _app.p2p_node()->broadcast_transaction(trx);
@ -190,7 +189,7 @@ namespace graphene { namespace app {
fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction& trx) fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction& trx)
{ {
database_api( *(_app.chain_database() ) ).check_transaction_for_duplicated_operations(trx); _app.chain_database()->check_transaction_for_duplicated_operations(trx);
fc::promise<fc::variant>::ptr prom( new fc::promise<fc::variant>() ); fc::promise<fc::variant>::ptr prom( new fc::promise<fc::variant>() );
broadcast_transaction_with_callback( [=]( const fc::variant& v ){ broadcast_transaction_with_callback( [=]( const fc::variant& v ){
@ -448,7 +447,17 @@ namespace graphene { namespace app {
} case balance_object_type:{ } case balance_object_type:{
/** these are free from any accounts */ /** these are free from any accounts */
break; break;
} } case son_object_type:{
const auto& aobj = dynamic_cast<const son_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->son_account );
break;
} case sidechain_address_object_type:{
const auto& aobj = dynamic_cast<const sidechain_address_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->sidechain_address_account );
break;
}
case sport_object_type: case sport_object_type:
case event_group_object_type: case event_group_object_type:
case event_object_type: case event_object_type:

View file

@ -37,8 +37,6 @@
#include <graphene/utilities/key_conversion.hpp> #include <graphene/utilities/key_conversion.hpp>
#include <graphene/chain/worker_evaluator.hpp> #include <graphene/chain/worker_evaluator.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/io/fstream.hpp> #include <fc/io/fstream.hpp>
#include <fc/rpc/api_connection.hpp> #include <fc/rpc/api_connection.hpp>
#include <fc/rpc/websocket_api.hpp> #include <fc/rpc/websocket_api.hpp>
@ -80,7 +78,7 @@ namespace detail {
auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key))); dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key)));
genesis_state_type initial_state; genesis_state_type initial_state;
initial_state.initial_parameters.current_fees = fee_schedule::get_default();//->set_all_fees(GRAPHENE_BLOCKCHAIN_PRECISION); initial_state.initial_parameters.current_fees = std::make_shared<fee_schedule>(fee_schedule::get_default());
initial_state.initial_active_witnesses = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT; initial_state.initial_active_witnesses = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT;
initial_state.initial_timestamp = time_point_sec(time_point::now().sec_since_epoch() / initial_state.initial_timestamp = time_point_sec(time_point::now().sec_since_epoch() /
initial_state.initial_parameters.block_interval * initial_state.initial_parameters.block_interval *
@ -162,41 +160,13 @@ namespace detail {
{ {
// t.me/peerplays #seednodes // t.me/peerplays #seednodes
vector<string> seeds = { vector<string> seeds = {
"seed.ppy.blckchnd.com:6666", // blckchnd "173.249.23.108:9777",
"ppy.esteem.ws:7777", // good-karma "node.peerblock.trade:9777",
"peerplays.bitcoiner.me:9777", // bitcoiner "peerplays.blockoperations.com:9777",
"peerplays.roelandp.nl:9777", // roelandp "pms.blockveritas.co:7777",
"ppyseed.bacchist.me:42420", // bacchist-witness "seed.ppy.alex-pu.info:8888",
"5.9.18.213:18828", // pfunk "seed.ppy.blckchnd.com:6116",
"31.171.244.121:7777", // taconator "seed01.eifos.org:7777"
"seed.peerplaysdb.com:9777", // jesta
"ppy-seed.xeldal.com:19777", // xeldal
"seed.ppy.altcap.io:61388", // winner.winner.chicken.dinner
"seed.peerplaysnodes.com:9777", // wackou
"peerplays-seed.privex.io:7777", // someguy123/privex
"51.15.78.16:9777", // agoric.systems
"212.71.253.163:9777", // xtar
"51.15.35.96:9777", // lafona
"anyx.ca:9777", // anyx
"82.223.108.91:7777", // hiltos-witness
"seed.ppy.nuevax.com:9777", // nuevax
"peerplays.butler.net:9777", // billbutler-witness
"peerplays.bitcoiner.me:9777", // bitcoiner
"ppyseed.bacchist.me:42420", // bacchist-witness
"peerplays.bhuz.info:9777", // bhuz
"node.peerblock.trade:9777", // bitcoinsig
"peerplays.crypto.fans:9777", // sc-steemit
"54.38.193.20:9777", // royal-flush
"ppy001.bts-nodes.net:7777", // baxters-sports-witness
"ppy002.bts-nodes.net:7777", // baxters-sports-witness
"ppy003.bts-nodes.net:7777", // baxters-sports-witness
"ppy004.bts-nodes.net:7777", // baxters-sports-witness
"ppy.proxyhosts.info:7777", // baxters-sports-witness
"ppyseed.spacemx.tech:9777", // spacecrypt-witness
"peerplaysblockchain.net:9777", // houdini-witness
"54.37.235.164:7777", // melea-trust
"seed01.eifos.org:7777" // eifos
"peerplays-seed.lukestokes.info:7777" // lukestokes-witness
}; };
for( const string& endpoint_string : seeds ) for( const string& endpoint_string : seeds )
@ -257,7 +227,7 @@ namespace detail {
void new_connection( const fc::http::websocket_connection_ptr& c ) void new_connection( const fc::http::websocket_connection_ptr& c )
{ {
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(*c, GRAPHENE_MAX_NESTED_OBJECTS); auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_MAX_NESTED_OBJECTS);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) ); auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
login->enable_api("database_api"); login->enable_api("database_api");

File diff suppressed because it is too large Load diff

View file

@ -61,8 +61,14 @@ namespace graphene { namespace app {
plug->plugin_set_program_options(plugin_cli_options, plugin_cfg_options); plug->plugin_set_program_options(plugin_cli_options, plugin_cfg_options);
if( !plugin_cli_options.options().empty() ) if( !plugin_cli_options.options().empty() )
_cli_options.add(plugin_cli_options); _cli_options.add(plugin_cli_options);
if( !plugin_cfg_options.options().empty() ) if( !plugin_cfg_options.options().empty() )
{
std::string header_name = "plugin-cfg-header-" + plug->plugin_name();
std::string header_desc = plug->plugin_name() + " plugin options";
_cfg_options.add_options()(header_name.c_str(), header_desc.c_str());
_cfg_options.add(plugin_cfg_options); _cfg_options.add(plugin_cfg_options);
}
add_available_plugin( plug ); add_available_plugin( plug );
return plug; return plug;

View file

@ -43,11 +43,20 @@
#include <graphene/chain/event_object.hpp> #include <graphene/chain/event_object.hpp>
#include <graphene/chain/betting_market_object.hpp> #include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp> #include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/worker_object.hpp> #include <graphene/chain/worker_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/tournament_object.hpp> #include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/market_history/market_history_plugin.hpp> #include <graphene/market_history/market_history_plugin.hpp>
#include <fc/api.hpp> #include <fc/api.hpp>
@ -202,12 +211,6 @@ class database_api
*/ */
optional<signed_transaction> get_recent_transaction_by_id( const transaction_id_type& id )const; optional<signed_transaction> get_recent_transaction_by_id( const transaction_id_type& id )const;
/**
* TODO
*
*/
void check_transaction_for_duplicated_operations(const signed_transaction& trx);
///////////// /////////////
// Globals // // Globals //
///////////// /////////////
@ -600,6 +603,102 @@ class database_api
*/ */
map<string, committee_member_id_type> lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const; map<string, committee_member_id_type> lookup_committee_member_accounts(const string& lower_bound_name, uint32_t limit)const;
/////////////////
// SON members //
/////////////////
/**
* @brief Get a list of SONs by ID
* @param son_ids IDs of the SONs to retrieve
* @return The SONs corresponding to the provided IDs
*
* This function has semantics identical to @ref get_objects
*/
vector<optional<son_object>> get_sons(const vector<son_id_type>& son_ids)const;
/**
* @brief Get the SON owned by a given account
* @param account The ID of the account whose SON should be retrieved
* @return The SON object, or null if the account does not have a SON
*/
fc::optional<son_object> get_son_by_account(account_id_type account)const;
/**
* @brief Get names and IDs for registered SONs
* @param lower_bound_name Lower bound of the first name to return
* @param limit Maximum number of results to return -- must not exceed 1000
* @return Map of SON names to corresponding IDs
*/
map<string, son_id_type> lookup_son_accounts(const string& lower_bound_name, uint32_t limit)const;
/**
* @brief Get the total number of SONs registered with the blockchain
*/
uint64_t get_son_count()const;
/////////////////////////
// SON Wallets //
/////////////////////////
/**
* @brief Get active SON wallet
* @return Active SON wallet object
*/
optional<son_wallet_object> get_active_son_wallet();
/**
* @brief Get SON wallet that was active for a given time point
* @param time_point Time point
* @return SON wallet object, for the wallet that was active for a given time point
*/
optional<son_wallet_object> get_son_wallet_by_time_point(time_point_sec time_point);
/**
* @brief Get full list of SON wallets
* @param limit Maximum number of results to return
* @return A list of SON wallet objects
*/
vector<optional<son_wallet_object>> get_son_wallets(uint32_t limit);
/////////////////////////
// Sidechain Addresses //
/////////////////////////
/**
* @brief Get a list of sidechain addresses
* @param sidechain_address_ids IDs of the sidechain addresses to retrieve
* @return The sidechain accounts corresponding to the provided IDs
*
* This function has semantics identical to @ref get_objects
*/
vector<optional<sidechain_address_object>> get_sidechain_addresses(const vector<sidechain_address_id_type>& sidechain_address_ids)const;
/**
* @brief Get the sidechain addresses for a given account
* @param account The ID of the account whose sidechain addresses should be retrieved
* @return The sidechain addresses objects, or null if the account does not have a sidechain addresses
*/
vector<optional<sidechain_address_object>> get_sidechain_addresses_by_account(account_id_type account)const;
/**
* @brief Get the sidechain addresses for a given sidechain
* @param sidechain Sidechain for which addresses should be retrieved
* @return The sidechain addresses objects, or null if the sidechain does not have any addresses
*/
vector<optional<sidechain_address_object>> get_sidechain_addresses_by_sidechain(sidechain_type sidechain)const;
/**
* @brief Get the sidechain addresses for a given account and sidechain
* @param account The ID of the account whose sidechain addresses should be retrieved
* @param sidechain Sidechain for which address should be retrieved
* @return The sidechain addresses objects, or null if the account does not have a sidechain addresses for a given sidechain
*/
fc::optional<sidechain_address_object> get_sidechain_address_by_account_and_sidechain(account_id_type account, sidechain_type sidechain)const;
/**
* @brief Get the total number of sidechain addresses registered with the blockchain
*/
uint64_t get_sidechain_addresses_count()const;
/// WORKERS /// WORKERS
@ -715,8 +814,126 @@ class database_api
*/ */
gpos_info get_gpos_info(const account_id_type account) const; gpos_info get_gpos_info(const account_id_type account) const;
//////////
// RBAC //
//////////
/**
* @return account and custom permissions/account-authorities info
*/
vector<custom_permission_object> get_custom_permissions(const account_id_type account) const;
fc::optional<custom_permission_object> get_custom_permission_by_name(const account_id_type account, const string& permission_name) const;
vector<custom_account_authority_object> get_custom_account_authorities(const account_id_type account) const;
vector<custom_account_authority_object> get_custom_account_authorities_by_permission_id(const custom_permission_id_type permission_id) const;
vector<custom_account_authority_object> get_custom_account_authorities_by_permission_name(const account_id_type account, const string& permission_name) const;
vector<authority> get_active_custom_account_authorities_by_operation(const account_id_type account, int operation_type) const;
/////////
// NFT //
/////////
/**
* @brief Returns the number of NFT owned by account
* @param owner Owner account ID
* @return Number of NFTs owned by account
*/
uint64_t nft_get_balance(const account_id_type owner) const;
/**
* @brief Returns the NFT owner
* @param token_id NFT ID
* @return NFT owner account ID
*/
optional<account_id_type> nft_owner_of(const nft_id_type token_id) const;
/**
* @brief Returns the NFT approved account ID
* @param token_id NFT ID
* @return NFT approved account ID
*/
optional<account_id_type> nft_get_approved(const nft_id_type token_id) const;
/**
* @brief Returns operator approved state for all NFT owned by owner
* @param owner NFT owner account ID
* @param token_id NFT ID
* @return True if operator is approved for all NFT owned by owner, else False
*/
bool nft_is_approved_for_all(const account_id_type owner, const account_id_type operator_) const;
/**
* @brief Returns NFT name from NFT metadata
* @param nft_metadata_id NFT metadata ID
* @return NFT name
*/
string nft_get_name(const nft_metadata_id_type nft_metadata_id) const;
/**
* @brief Returns NFT symbol from NFT metadata
* @param nft_metadata_id NFT metadata ID
* @return NFT symbol
*/
string nft_get_symbol(const nft_metadata_id_type nft_metadata_id) const;
/**
* @brief Returns NFT URI
* @param token_id NFT ID
* @return NFT URI
*/
string nft_get_token_uri(const nft_id_type token_id) const;
/**
* @brief Returns total number of NFTs assigned to NFT metadata
* @param nft_metadata_id NFT metadata ID
* @return Total number of NFTs assigned to NFT metadata
*/
uint64_t nft_get_total_supply(const nft_metadata_id_type nft_metadata_id) const;
/**
* @brief Returns NFT by index from NFT metadata
* @param nft_metadata_id NFT metadata ID
* @param token_idx NFT index in the list of tokens
* @return NFT symbol
*/
nft_object nft_token_by_index(const nft_metadata_id_type nft_metadata_id, const uint64_t token_idx) const;
/**
* @brief Returns NFT by owner and index
* @param nft_metadata_id NFT metadata ID
* @param owner NFT owner
* @param token_idx NFT index in the list of tokens
* @return NFT object
*/
nft_object nft_token_of_owner_by_index(const nft_metadata_id_type nft_metadata_id, const account_id_type owner, const uint64_t token_idx) const;
/**
* @brief Returns list of all available NTF's
* @return List of all available NFT's
*/
vector<nft_object> nft_get_all_tokens() const;
/**
* @brief Returns NFT's owned by owner
* @param owner NFT owner
* @return List of NFT owned by owner
*/
vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner) const;
//////////////////
// MARKET PLACE //
//////////////////
vector<offer_object> list_offers(const offer_id_type lower_id, uint32_t limit) const;
vector<offer_object> list_sell_offers(const offer_id_type lower_id, uint32_t limit) const;
vector<offer_object> list_buy_offers(const offer_id_type lower_id, uint32_t limit) const;
vector<offer_history_object> list_offer_history(const offer_history_id_type lower_id, uint32_t limit) const;
vector<offer_object> get_offers_by_issuer(const offer_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const;
vector<offer_object> get_offers_by_item(const offer_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_issuer(const offer_history_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const;
//////////////////
// ACCOUNT ROLE //
//////////////////
vector<account_role_object> get_account_roles_by_owner(account_id_type owner) const;
private: private:
std::shared_ptr< database_api_impl > my; std::shared_ptr< database_api_impl > my;
}; };
@ -825,6 +1042,24 @@ FC_API(graphene::app::database_api,
(get_committee_member_by_account) (get_committee_member_by_account)
(lookup_committee_member_accounts) (lookup_committee_member_accounts)
// SON members
(get_sons)
(get_son_by_account)
(lookup_son_accounts)
(get_son_count)
// SON wallets
(get_active_son_wallet)
(get_son_wallet_by_time_point)
(get_son_wallets)
// Sidechain addresses
(get_sidechain_addresses)
(get_sidechain_addresses_by_account)
(get_sidechain_addresses_by_sidechain)
(get_sidechain_address_by_account_and_sidechain)
(get_sidechain_addresses_count)
// workers // workers
(get_workers_by_account) (get_workers_by_account)
// Votes // Votes
@ -854,4 +1089,40 @@ FC_API(graphene::app::database_api,
// gpos // gpos
(get_gpos_info) (get_gpos_info)
//rbac
(get_custom_permissions)
(get_custom_permission_by_name)
(get_custom_account_authorities)
(get_custom_account_authorities_by_permission_id)
(get_custom_account_authorities_by_permission_name)
(get_active_custom_account_authorities_by_operation)
// NFT
(nft_get_balance)
(nft_owner_of)
(nft_get_approved)
(nft_is_approved_for_all)
(nft_get_name)
(nft_get_symbol)
(nft_get_token_uri)
(nft_get_total_supply)
(nft_token_by_index)
(nft_token_of_owner_by_index)
(nft_get_all_tokens)
(nft_get_tokens_by_owner)
// Marketplace
(list_offers)
(list_sell_offers)
(list_buy_offers)
(list_offer_history)
(get_offers_by_issuer)
(get_offers_by_item)
(get_offer_history_by_issuer)
(get_offer_history_by_item)
(get_offer_history_by_bidder)
// Account Roles
(get_account_roles_by_owner)
) )

View file

@ -67,6 +67,7 @@ FC_REFLECT( graphene::app::full_account,
(limit_orders) (limit_orders)
(call_orders) (call_orders)
(settle_orders) (settle_orders)
(proposals)
(assets) (assets)
(withdraws) (withdraws)
(proposals) (proposals)

23
libraries/chain/CMakeLists.txt Normal file → Executable file
View file

@ -43,6 +43,7 @@ add_library( graphene_chain
protocol/assert.cpp protocol/assert.cpp
protocol/account.cpp protocol/account.cpp
protocol/transfer.cpp protocol/transfer.cpp
protocol/chain_parameters.cpp
protocol/committee_member.cpp protocol/committee_member.cpp
protocol/witness.cpp protocol/witness.cpp
protocol/market.cpp protocol/market.cpp
@ -61,6 +62,9 @@ add_library( graphene_chain
protocol/vote.cpp protocol/vote.cpp
protocol/tournament.cpp protocol/tournament.cpp
protocol/small_ops.cpp protocol/small_ops.cpp
protocol/custom_permission.cpp
protocol/custom_account_authority.cpp
protocol/offer.cpp
genesis_state.cpp genesis_state.cpp
get_config.cpp get_config.cpp
@ -112,9 +116,28 @@ add_library( graphene_chain
betting_market_evaluator.cpp betting_market_evaluator.cpp
betting_market_object.cpp betting_market_object.cpp
betting_market_group_object.cpp betting_market_group_object.cpp
custom_permission_evaluator.cpp
custom_account_authority_evaluator.cpp
affiliate_payout.cpp affiliate_payout.cpp
offer_object.cpp
offer_evaluator.cpp
nft_evaluator.cpp
protocol/nft.cpp
protocol/account_role.cpp
account_role_evaluator.cpp
son_evaluator.cpp
son_object.cpp
son_wallet_evaluator.cpp
son_wallet_deposit_evaluator.cpp
son_wallet_withdraw_evaluator.cpp
sidechain_address_evaluator.cpp
sidechain_transaction_evaluator.cpp
${HEADERS} ${HEADERS}
${PROTOCOL_HEADERS} ${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"

View file

@ -22,8 +22,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <fc/smart_ref_impl.hpp>
#include <graphene/chain/account_evaluator.hpp> #include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/buyback.hpp> #include <graphene/chain/buyback.hpp>
#include <graphene/chain/buyback_object.hpp> #include <graphene/chain/buyback_object.hpp>
@ -110,6 +108,8 @@ void_result account_create_evaluator::do_evaluate( const account_create_operatio
} }
if( d.head_block_time() < HARDFORK_999_TIME ) if( d.head_block_time() < HARDFORK_999_TIME )
FC_ASSERT( !op.extensions.value.affiliate_distributions.valid(), "Affiliate reward distributions not allowed yet" ); FC_ASSERT( !op.extensions.value.affiliate_distributions.valid(), "Affiliate reward distributions not allowed yet" );
if (d.head_block_time() < HARDFORK_SON_TIME)
FC_ASSERT(op.name != "son-account", "Son account creation before SON hardfork");
FC_ASSERT( fee_paying_account->is_lifetime_member(), "Only Lifetime members may register an account." ); FC_ASSERT( fee_paying_account->is_lifetime_member(), "Only Lifetime members may register an account." );
FC_ASSERT( op.referrer(d).is_member(d.head_block_time()), "The referrer must be either a lifetime or annual subscriber." ); FC_ASSERT( op.referrer(d).is_member(d.head_block_time()), "The referrer must be either a lifetime or annual subscriber." );

View file

@ -0,0 +1,162 @@
#include <graphene/chain/account_role_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/rbac_hardfork_visitor.hpp>
namespace graphene
{
namespace chain
{
void_result account_role_create_evaluator::do_evaluate(const account_role_create_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner(d);
rbac_operation_hardfork_visitor arvtor(now);
for (const auto &op_type : op.allowed_operations)
{
arvtor(op_type);
}
for (const auto &acc : op.whitelisted_accounts)
{
acc(d);
}
FC_ASSERT(op.valid_to > now, "valid_to expiry should be in future");
FC_ASSERT((op.valid_to - now) <= fc::seconds(d.get_global_properties().parameters.account_roles_max_lifetime()), "Validity of the account role beyond max expiry");
const auto &ar_idx = d.get_index_type<account_role_index>().indices().get<by_owner>();
auto aro_range = ar_idx.equal_range(op.owner);
FC_ASSERT(std::distance(aro_range.first, aro_range.second) < d.get_global_properties().parameters.account_roles_max_per_account(), "Max account roles that can be created by one owner is reached");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type account_role_create_evaluator::do_apply(const account_role_create_operation &op)
{
try
{
database &d = db();
return d.create<account_role_object>([&op](account_role_object &obj) mutable {
obj.owner = op.owner;
obj.name = op.name;
obj.metadata = op.metadata;
obj.allowed_operations = op.allowed_operations;
obj.whitelisted_accounts = op.whitelisted_accounts;
obj.valid_to = op.valid_to;
})
.id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result account_role_update_evaluator::do_evaluate(const account_role_update_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner(d);
const account_role_object &aobj = op.account_role_id(d);
FC_ASSERT(aobj.owner == op.owner, "Only owner account can update account role object");
for (const auto &op_type : op.allowed_operations_to_remove)
{
FC_ASSERT(aobj.allowed_operations.find(op_type) != aobj.allowed_operations.end(),
"Cannot remove non existent operation");
}
for (const auto &acc : op.accounts_to_remove)
{
FC_ASSERT(aobj.whitelisted_accounts.find(acc) != aobj.whitelisted_accounts.end(),
"Cannot remove non existent account");
}
rbac_operation_hardfork_visitor arvtor(now);
for (const auto &op_type : op.allowed_operations_to_add)
{
arvtor(op_type);
}
FC_ASSERT((aobj.allowed_operations.size() + op.allowed_operations_to_add.size() - op.allowed_operations_to_remove.size()) > 0, "Allowed operations should be positive");
for (const auto &acc : op.accounts_to_add)
{
acc(d);
}
FC_ASSERT((aobj.whitelisted_accounts.size() + op.accounts_to_add.size() - op.accounts_to_remove.size()) > 0, "Accounts should be positive");
if (op.valid_to)
{
FC_ASSERT(*op.valid_to > now, "valid_to expiry should be in future");
FC_ASSERT((*op.valid_to - now) <= fc::seconds(d.get_global_properties().parameters.account_roles_max_lifetime()), "Validity of the account role beyond max expiry");
}
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result account_role_update_evaluator::do_apply(const account_role_update_operation &op)
{
try
{
database &d = db();
const account_role_object &aobj = op.account_role_id(d);
d.modify(aobj, [&op](account_role_object &obj) {
if (op.name)
obj.name = *op.name;
if (op.metadata)
obj.metadata = *op.metadata;
obj.allowed_operations.insert(op.allowed_operations_to_add.begin(), op.allowed_operations_to_add.end());
obj.whitelisted_accounts.insert(op.accounts_to_add.begin(), op.accounts_to_add.end());
for (const auto &op_type : op.allowed_operations_to_remove)
obj.allowed_operations.erase(op_type);
for (const auto &acc : op.accounts_to_remove)
obj.whitelisted_accounts.erase(acc);
if (op.valid_to)
obj.valid_to = *op.valid_to;
});
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result account_role_delete_evaluator::do_evaluate(const account_role_delete_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner(d);
const account_role_object &aobj = op.account_role_id(d);
FC_ASSERT(aobj.owner == op.owner, "Only owner account can delete account role object");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result account_role_delete_evaluator::do_apply(const account_role_delete_operation &op)
{
try
{
database &d = db();
const account_role_object &aobj = op.account_role_id(d);
d.remove(aobj);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -42,6 +42,9 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
database& d = db(); database& d = db();
if (d.head_block_time() < HARDFORK_SON_TIME)
FC_ASSERT(op.symbol != "BTC", "BTC asset creation before SON hardfork");
const auto& chain_parameters = d.get_global_properties().parameters; const auto& chain_parameters = d.get_global_properties().parameters;
FC_ASSERT( op.common_options.whitelist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities ); FC_ASSERT( op.common_options.whitelist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );
FC_ASSERT( op.common_options.blacklist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities ); FC_ASSERT( op.common_options.blacklist_authorities.size() <= chain_parameters.maximum_asset_whitelist_authorities );
@ -58,37 +61,36 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
if( d.head_block_time() > HARDFORK_385_TIME ) if( d.head_block_time() > HARDFORK_385_TIME )
{ {
if( d.head_block_time() <= HARDFORK_409_TIME )
if( d.head_block_time() <= HARDFORK_409_TIME )
{
auto dotpos = op.symbol.find( '.' );
if( dotpos != std::string::npos )
{ {
auto dotpos = op.symbol.find( '.' ); auto prefix = op.symbol.substr( 0, dotpos );
if( dotpos != std::string::npos ) auto asset_symbol_itr = asset_indx.find( op.symbol );
{ FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
auto prefix = op.symbol.substr( 0, dotpos ); ("s",op.symbol)("p",prefix) );
auto asset_symbol_itr = asset_indx.find( op.symbol ); FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
FC_ASSERT( asset_symbol_itr != asset_indx.end(), ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
"Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
("s",op.symbol)("p",prefix) );
FC_ASSERT( asset_symbol_itr->issuer == op.issuer,
"Asset ${s} may only be created by issuer of ${p}, ${i}",
("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
}
} }
else }
else
{
auto dotpos = op.symbol.rfind( '.' );
if( dotpos != std::string::npos )
{ {
auto dotpos = op.symbol.rfind( '.' ); auto prefix = op.symbol.substr( 0, dotpos );
if( dotpos != std::string::npos ) auto asset_symbol_itr = asset_indx.find( prefix );
{ FC_ASSERT( asset_symbol_itr != asset_indx.end(), "Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
auto prefix = op.symbol.substr( 0, dotpos ); ("s",op.symbol)("p",prefix) );
auto asset_symbol_itr = asset_indx.find( prefix ); FC_ASSERT( asset_symbol_itr->issuer == op.issuer, "Asset ${s} may only be created by issuer of ${p}, ${i}",
FC_ASSERT( asset_symbol_itr != asset_indx.end(), ("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
"Asset ${s} may only be created by issuer of ${p}, but ${p} has not been registered",
("s",op.symbol)("p",prefix) );
FC_ASSERT( asset_symbol_itr->issuer == op.issuer,
"Asset ${s} may only be created by issuer of ${p}, ${i}",
("s",op.symbol)("p",prefix)("i", op.issuer(d).name) );
}
} }
} }
}
else else
{ {
auto dotpos = op.symbol.find( '.' ); auto dotpos = op.symbol.find( '.' );
@ -120,7 +122,7 @@ void_result asset_create_evaluator::do_evaluate( const asset_create_operation& o
FC_ASSERT( op.bitasset_opts ); FC_ASSERT( op.bitasset_opts );
FC_ASSERT( op.precision == op.bitasset_opts->short_backing_asset(d).precision ); FC_ASSERT( op.precision == op.bitasset_opts->short_backing_asset(d).precision );
} }
return void_result(); return void_result();
} FC_CAPTURE_AND_RETHROW( (op) ) } } FC_CAPTURE_AND_RETHROW( (op) ) }
@ -175,7 +177,7 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
a.options.core_exchange_rate.base.asset_id = next_asset_id; a.options.core_exchange_rate.base.asset_id = next_asset_id;
a.dynamic_asset_data_id = dyn_asset.id; a.dynamic_asset_data_id = dyn_asset.id;
if( op.bitasset_opts.valid() ) if( op.bitasset_opts.valid() )
a.bitasset_data_id = bit_asset_id; a.bitasset_data_id = bit_asset_id;
}); });
@ -223,7 +225,7 @@ void_result lottery_asset_create_evaluator::do_evaluate( const lottery_asset_cre
{ {
auto dotpos = op.symbol.rfind( '.' ); auto dotpos = op.symbol.rfind( '.' );
if( dotpos != std::string::npos ) if( dotpos != std::string::npos )
{ {
auto prefix = op.symbol.substr( 0, dotpos ); auto prefix = op.symbol.substr( 0, dotpos );
auto asset_symbol_itr = asset_indx.find( prefix ); auto asset_symbol_itr = asset_indx.find( prefix );
@ -576,7 +578,7 @@ void_result asset_update_dividend_evaluator::do_evaluate(const asset_update_divi
auto& params = db().get_global_properties().parameters; auto& params = db().get_global_properties().parameters;
if (o.new_options.payout_interval && if (o.new_options.payout_interval &&
*o.new_options.payout_interval < params.maintenance_interval) *o.new_options.payout_interval < params.maintenance_interval)
FC_THROW("New payout interval may not be less than the maintenance interval", FC_THROW("New payout interval may not be less than the maintenance interval",
("new_payout_interval", o.new_options.payout_interval)("maintenance_interval", params.maintenance_interval)); ("new_payout_interval", o.new_options.payout_interval)("maintenance_interval", params.maintenance_interval));
return void_result(); return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) } } FC_CAPTURE_AND_RETHROW( (o) ) }

View file

@ -22,7 +22,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#define DEFAULT_LOGGER "betting" #define DEFAULT_LOGGER "betting"
#include <fc/smart_ref_impl.hpp>
#include <graphene/chain/betting_market_evaluator.hpp> #include <graphene/chain/betting_market_evaluator.hpp>
#include <graphene/chain/betting_market_object.hpp> #include <graphene/chain/betting_market_object.hpp>

View file

@ -24,7 +24,6 @@
#include <graphene/chain/block_database.hpp> #include <graphene/chain/block_database.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/io/raw.hpp> #include <fc/io/raw.hpp>
#include <fc/smart_ref_impl.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {

View file

@ -30,8 +30,6 @@
#include <graphene/chain/protocol/vote.hpp> #include <graphene/chain/protocol/vote.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp> #include <graphene/chain/transaction_evaluation_state.hpp>
#include <fc/smart_ref_impl.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
void_result committee_member_create_evaluator::do_evaluate( const committee_member_create_operation& op ) void_result committee_member_create_evaluator::do_evaluate( const committee_member_create_operation& op )

View file

@ -29,8 +29,6 @@
#include <graphene/chain/fba_accumulator_id.hpp> #include <graphene/chain/fba_accumulator_id.hpp>
#include <graphene/chain/hardfork.hpp> #include <graphene/chain/hardfork.hpp>
#include <fc/smart_ref_impl.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
void_result transfer_to_blind_evaluator::do_evaluate( const transfer_to_blind_operation& o ) void_result transfer_to_blind_evaluator::do_evaluate( const transfer_to_blind_operation& o )

View file

@ -0,0 +1,128 @@
#include <graphene/chain/custom_account_authority_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/rbac_hardfork_visitor.hpp>
namespace graphene
{
namespace chain
{
void_result create_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_create_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
const custom_permission_object &pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
FC_ASSERT(op.valid_to > now, "valid_to expiry should be in future");
FC_ASSERT((op.valid_to - op.valid_from) <= fc::seconds(d.get_global_properties().parameters.rbac_max_account_authority_lifetime()), "Validity of the auth beyond max expiry");
rbac_operation_hardfork_visitor rvtor(now);
rvtor(op.operation_type);
const auto& cindex = d.get_index_type<custom_account_authority_index>().indices().get<by_permission_and_op>();
auto count = cindex.count(boost::make_tuple(op.permission_id));
FC_ASSERT(count < d.get_global_properties().parameters.rbac_max_authorities_per_permission(), "Max operations that can be linked to a permission reached");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type create_custom_account_authority_evaluator::do_apply(const custom_account_authority_create_operation &op)
{
try
{
database &d = db();
return d.create<custom_account_authority_object>([&op](custom_account_authority_object &obj) mutable {
obj.permission_id = op.permission_id;
obj.operation_type = op.operation_type;
obj.valid_from = op.valid_from;
obj.valid_to = op.valid_to;
})
.id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result update_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_update_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
const custom_account_authority_object &aobj = op.auth_id(d);
const custom_permission_object &pobj = aobj.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
auto valid_from = aobj.valid_from;
auto valid_to = aobj.valid_to;
if (op.new_valid_from)
{
valid_from = *op.new_valid_from;
}
if (op.new_valid_to)
{
FC_ASSERT(*op.new_valid_to > now, "New valid_to expiry should be in the future");
valid_to = *op.new_valid_to;
}
FC_ASSERT(valid_from < valid_to, "valid_from should be before valid_to");
FC_ASSERT((valid_to - valid_from) <= fc::seconds(d.get_global_properties().parameters.rbac_max_account_authority_lifetime()), "Validity of the auth beyond max expiry");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type update_custom_account_authority_evaluator::do_apply(const custom_account_authority_update_operation &op)
{
try
{
database &d = db();
const custom_account_authority_object &aobj = op.auth_id(d);
d.modify(aobj, [&op](custom_account_authority_object &obj) {
if (op.new_valid_from)
obj.valid_from = *op.new_valid_from;
if (op.new_valid_to)
obj.valid_to = *op.new_valid_to;
});
return op.auth_id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_delete_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
const custom_account_authority_object &aobj = op.auth_id(d);
const custom_permission_object &pobj = aobj.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete account authority object");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_account_authority_evaluator::do_apply(const custom_account_authority_delete_operation &op)
{
try
{
database &d = db();
const custom_account_authority_object &aobj = op.auth_id(d);
d.remove(aobj);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,133 @@
#include <graphene/chain/custom_permission_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/hardfork.hpp>
namespace graphene
{
namespace chain
{
void_result create_custom_permission_evaluator::do_evaluate(const custom_permission_create_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
for (const auto &account_weight_pair : op.auth.account_auths)
{
account_weight_pair.first(d);
}
const auto &pindex = d.get_index_type<custom_permission_index>().indices().get<by_account_and_permission>();
auto pitr = pindex.find(boost::make_tuple(op.owner_account, op.permission_name));
FC_ASSERT(pitr == pindex.end(), "Permission name already exists for the given account");
auto count = pindex.count(boost::make_tuple(op.owner_account));
FC_ASSERT(count < d.get_global_properties().parameters.rbac_max_permissions_per_account(), "Max permissions per account reached");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type create_custom_permission_evaluator::do_apply(const custom_permission_create_operation &op)
{
try
{
database &d = db();
return d.create<custom_permission_object>([&op](custom_permission_object &obj) mutable {
obj.account = op.owner_account;
obj.permission_name = op.permission_name;
obj.auth = op.auth;
})
.id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result update_custom_permission_evaluator::do_evaluate(const custom_permission_update_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
const custom_permission_object &pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update permission object");
if (op.new_auth)
{
FC_ASSERT(!(*op.new_auth == pobj.auth), "New authority provided is not different from old authority");
for (const auto &account_weight_pair : op.new_auth->account_auths)
{
account_weight_pair.first(d);
}
}
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type update_custom_permission_evaluator::do_apply(const custom_permission_update_operation &op)
{
try
{
database &d = db();
const custom_permission_object &pobj = op.permission_id(d);
d.modify(pobj, [&op](custom_permission_object &obj) {
if (op.new_auth)
obj.auth = *op.new_auth;
});
return op.permission_id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_permission_evaluator::do_evaluate(const custom_permission_delete_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_NFT_TIME, "Not allowed until NFT HF");
op.owner_account(d);
const custom_permission_object &pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete permission object");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_permission_evaluator::do_apply(const custom_permission_delete_operation &op)
{
try
{
database &d = db();
const custom_permission_object &pobj = op.permission_id(d);
// Remove the account authority objects linked to this permission
const auto& cindex = d.get_index_type<custom_account_authority_index>().indices().get<by_permission_and_op>();
vector<std::reference_wrapper<const custom_account_authority_object>> custom_auths;
auto crange = cindex.equal_range(boost::make_tuple(pobj.id));
// Store the references to the account authorities
for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second))
{
custom_auths.push_back(cobj);
}
// Now remove the account authorities
for(const auto& cauth : custom_auths)
{
d.remove(cauth);
}
// Now finally remove the permission
d.remove(pobj);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -21,7 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <fc/smart_ref_impl.hpp>
#include "db_balance.cpp" #include "db_balance.cpp"
#include "db_bet.cpp" #include "db_bet.cpp"
#include "db_block.cpp" #include "db_block.cpp"

View file

@ -42,7 +42,46 @@
#include <graphene/chain/witness_schedule_object.hpp> #include <graphene/chain/witness_schedule_object.hpp>
#include <fc/crypto/digest.hpp> #include <fc/crypto/digest.hpp>
#include <fc/smart_ref_impl.hpp>
namespace {
struct proposed_operations_digest_accumulator
{
typedef void result_type;
void operator()(const graphene::chain::proposal_create_operation& proposal)
{
for (auto& operation: proposal.proposed_ops)
{
proposed_operations_digests.push_back(fc::digest(operation.op));
}
}
//empty template method is needed for all other operation types
//we can ignore them, we are interested in only proposal_create_operation
template<class T>
void operator()(const T&)
{}
std::vector<fc::sha256> proposed_operations_digests;
};
std::vector<fc::sha256> gather_proposed_operations_digests(const graphene::chain::transaction& trx)
{
proposed_operations_digest_accumulator digest_accumulator;
for (auto& operation: trx.operations)
{
if( operation.which() != graphene::chain::operation::tag<graphene::chain::betting_market_group_create_operation>::value
&& operation.which() != graphene::chain::operation::tag<graphene::chain::betting_market_create_operation>::value )
operation.visit(digest_accumulator);
else
edump( ("Found dup"));
}
return digest_accumulator.proposed_operations_digests;
}
}
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -109,7 +148,31 @@ std::vector<block_id_type> database::get_block_ids_on_fork(block_id_type head_of
result.emplace_back(branches.first.back()->previous_id()); result.emplace_back(branches.first.back()->previous_id());
return result; return result;
} }
void database::check_transaction_for_duplicated_operations(const signed_transaction& trx)
{
const auto& proposal_index = get_index<proposal_object>();
std::set<fc::sha256> existed_operations_digests;
proposal_index.inspect_all_objects( [&](const object& obj){
const proposal_object& proposal = static_cast<const proposal_object&>(obj);
auto proposed_operations_digests = gather_proposed_operations_digests( proposal.proposed_transaction );
existed_operations_digests.insert( proposed_operations_digests.begin(), proposed_operations_digests.end() );
});
for (auto& pending_transaction: _pending_tx)
{
auto proposed_operations_digests = gather_proposed_operations_digests(pending_transaction);
existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end());
}
auto proposed_operations_digests = gather_proposed_operations_digests(trx);
for (auto& digest: proposed_operations_digests)
{
FC_ASSERT(existed_operations_digests.count(digest) == 0, "Proposed operation is already pending for approval.");
}
}
/** /**
* Push block "may fail" in which case every partial change is unwound. After * Push block "may fail" in which case every partial change is unwound. After
* push block is successful the block is appended to the chain database on disk. * push block is successful the block is appended to the chain database on disk.
@ -274,7 +337,7 @@ void database::verify_signing_witness( const signed_block& new_block, const fork
FC_ASSERT( new_block.witness == wid, "Witness produced block at wrong time", FC_ASSERT( new_block.witness == wid, "Witness produced block at wrong time",
("block witness",new_block.witness)("scheduled",wid)("slot_num",slot_num) ); ("block witness",new_block.witness)("scheduled",wid)("slot_num",slot_num) );
FC_ASSERT( new_block.validate_signee( wid(*this).signing_key ) ); FC_ASSERT( new_block.validate_signee( wid(*this).signing_key ) );
} }
} }
void database::update_witnesses( fork_item& fork_entry )const void database::update_witnesses( fork_item& fork_entry )const
@ -288,7 +351,7 @@ void database::update_witnesses( fork_item& fork_entry )const
const witness_schedule_object& wso = get_witness_schedule_object(); const witness_schedule_object& wso = get_witness_schedule_object();
fork_entry.scheduled_witnesses = std::make_shared< vector< pair< witness_id_type, public_key_type > > >(); fork_entry.scheduled_witnesses = std::make_shared< vector< pair< witness_id_type, public_key_type > > >();
fork_entry.scheduled_witnesses->reserve( wso.current_shuffled_witnesses.size() ); fork_entry.scheduled_witnesses->reserve( wso.current_shuffled_witnesses.size() );
for( size_t i = 0; i < wso.current_shuffled_witnesses.size(); ++i ) for( size_t i = 0; i < wso.current_shuffled_witnesses.size(); ++i )
{ {
const auto& witness = wso.current_shuffled_witnesses[i](*this); const auto& witness = wso.current_shuffled_witnesses[i](*this);
@ -362,6 +425,7 @@ processed_transaction database::push_proposal(const proposal_object& proposal)
auto session = _undo_db.start_undo_session(true); auto session = _undo_db.start_undo_session(true);
for( auto& op : proposal.proposed_transaction.operations ) for( auto& op : proposal.proposed_transaction.operations )
eval_state.operation_results.emplace_back(apply_operation(eval_state, op)); eval_state.operation_results.emplace_back(apply_operation(eval_state, op));
remove_son_proposal(proposal);
remove(proposal); remove(proposal);
session.merge(); session.merge();
} catch ( const fc::exception& e ) { } catch ( const fc::exception& e ) {
@ -487,7 +551,7 @@ signed_block database::_generate_block(
pending_block.timestamp = when; pending_block.timestamp = when;
pending_block.transaction_merkle_root = pending_block.calculate_merkle_root(); pending_block.transaction_merkle_root = pending_block.calculate_merkle_root();
pending_block.witness = witness_id; pending_block.witness = witness_id;
// Genesis witnesses start with a default initial secret // Genesis witnesses start with a default initial secret
if( witness_obj.next_secret_hash == secret_hash_type::hash( secret_hash_type() ) ) { if( witness_obj.next_secret_hash == secret_hash_type::hash( secret_hash_type() ) ) {
pending_block.previous_secret = secret_hash_type(); pending_block.previous_secret = secret_hash_type();
@ -497,7 +561,7 @@ signed_block database::_generate_block(
fc::raw::pack( last_enc, witness_obj.previous_secret ); fc::raw::pack( last_enc, witness_obj.previous_secret );
pending_block.previous_secret = last_enc.result(); pending_block.previous_secret = last_enc.result();
} }
secret_hash_type::encoder next_enc; secret_hash_type::encoder next_enc;
fc::raw::pack( next_enc, block_signing_private_key ); fc::raw::pack( next_enc, block_signing_private_key );
fc::raw::pack( next_enc, pending_block.previous_secret ); fc::raw::pack( next_enc, pending_block.previous_secret );
@ -628,14 +692,19 @@ void database::_apply_block( const signed_block& next_block )
// For VOPs derived directly from a real op, // For VOPs derived directly from a real op,
// use the real op's (block_num,trx_in_block,op_in_trx), virtual_op starts from 1. // use the real op's (block_num,trx_in_block,op_in_trx), virtual_op starts from 1.
// For VOPs created after processed all transactions, // For VOPs created after processed all transactions,
// trx_in_block = the_block.trsanctions.size(), virtual_op starts from 0. // trx_in_block = the_block.trsanctions.size(), virtual_op starts from 0.
++_current_trx_in_block; ++_current_trx_in_block;
_current_op_in_trx = 0; _current_op_in_trx = 0;
_current_virtual_op = 0; _current_virtual_op = 0;
}
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) {
update_witness_schedule(next_block);
if(global_props.active_sons.size() > 0) {
update_son_schedule(next_block);
}
} }
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM)
update_witness_schedule(next_block);
const uint32_t missed = update_witness_missed_blocks( next_block ); const uint32_t missed = update_witness_missed_blocks( next_block );
update_global_dynamic_data( next_block, missed ); update_global_dynamic_data( next_block, missed );
update_signing_witness(signing_witness, next_block); update_signing_witness(signing_witness, next_block);
@ -644,9 +713,9 @@ void database::_apply_block( const signed_block& next_block )
// Are we at the maintenance interval? // Are we at the maintenance interval?
if( maint_needed ) if( maint_needed )
perform_chain_maintenance(next_block, global_props); perform_chain_maintenance(next_block, global_props);
check_ending_lotteries(); check_ending_lotteries();
create_block_summary(next_block); create_block_summary(next_block);
place_delayed_bets(); // must happen after update_global_dynamic_data() updates the time place_delayed_bets(); // must happen after update_global_dynamic_data() updates the time
clear_expired_transactions(); clear_expired_transactions();
@ -657,6 +726,7 @@ void database::_apply_block( const signed_block& next_block )
update_withdraw_permissions(); update_withdraw_permissions();
update_tournaments(); update_tournaments();
update_betting_markets(next_block.timestamp); update_betting_markets(next_block.timestamp);
finalize_expired_offers();
// n.b., update_maintenance_flag() happens this late // n.b., update_maintenance_flag() happens this late
// because get_slot_time() / get_slot_at_time() is needed above // because get_slot_time() / get_slot_at_time() is needed above
@ -664,8 +734,13 @@ void database::_apply_block( const signed_block& next_block )
// update_global_dynamic_data() as perhaps these methods only need // update_global_dynamic_data() as perhaps these methods only need
// to be called for header validation? // to be called for header validation?
update_maintenance_flag( maint_needed ); update_maintenance_flag( maint_needed );
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) {
update_witness_schedule(); update_witness_schedule();
if(global_props.active_sons.size() > 0) {
update_son_schedule();
}
}
if( !_node_property_object.debug_updates.empty() ) if( !_node_property_object.debug_updates.empty() )
apply_debug_updates(); apply_debug_updates();
@ -711,7 +786,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
auto& trx_idx = get_mutable_index_type<transaction_index>(); auto& trx_idx = get_mutable_index_type<transaction_index>();
const chain_id_type& chain_id = get_chain_id(); const chain_id_type& chain_id = get_chain_id();
transaction_id_type trx_id; transaction_id_type trx_id;
if( !(skip & skip_transaction_dupe_check) ) if( !(skip & skip_transaction_dupe_check) )
{ {
trx_id = trx.id(); trx_id = trx.id();
@ -724,9 +799,14 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
if( !(skip & (skip_transaction_signatures | skip_authority_check) ) ) if( !(skip & (skip_transaction_signatures | skip_authority_check) ) )
{ {
auto get_active = [&]( account_id_type id ) { return &id(*this).active; }; auto get_active = [this]( account_id_type id ) { return &id(*this).active; };
auto get_owner = [&]( account_id_type id ) { return &id(*this).owner; }; auto get_owner = [this]( account_id_type id ) { return &id(*this).owner; };
trx.verify_authority( chain_id, get_active, get_owner, get_global_properties().parameters.max_authority_depth ); auto get_custom = [this]( account_id_type id, const operation& op ) {
return get_account_custom_authorities(id, op);
};
trx.verify_authority( chain_id, get_active, get_owner, get_custom,
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(head_block_time()),
get_global_properties().parameters.max_authority_depth );
} }
//Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is //Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is
@ -804,7 +884,7 @@ const witness_object& database::validate_block_header( uint32_t skip, const sign
FC_ASSERT( secret_hash_type::hash( next_block.previous_secret ) == witness.next_secret_hash, "", FC_ASSERT( secret_hash_type::hash( next_block.previous_secret ) == witness.next_secret_hash, "",
( "previous_secret", next_block.previous_secret )( "next_secret_hash", witness.next_secret_hash ) ); ( "previous_secret", next_block.previous_secret )( "next_secret_hash", witness.next_secret_hash ) );
if( !(skip&skip_witness_signature) ) if( !(skip&skip_witness_signature) )
FC_ASSERT( next_block.validate_signee( witness.signing_key ) ); FC_ASSERT( next_block.validate_signee( witness.signing_key ) );
if( !(skip&skip_witness_schedule_check) ) if( !(skip&skip_witness_schedule_check) )

View file

@ -27,8 +27,12 @@
#include <graphene/chain/asset_object.hpp> #include <graphene/chain/asset_object.hpp>
#include <graphene/chain/chain_property_object.hpp> #include <graphene/chain/chain_property_object.hpp>
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <fc/smart_ref_impl.hpp> #include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_proposal_object.hpp>
#include <ctime> #include <ctime>
#include <algorithm> #include <algorithm>
@ -62,7 +66,7 @@ const dynamic_global_property_object& database::get_dynamic_global_properties()
const fee_schedule& database::current_fee_schedule()const const fee_schedule& database::current_fee_schedule()const
{ {
return get_global_properties().parameters.current_fees; return std::ref( *get_global_properties().parameters.current_fees );
} }
time_point_sec database::head_block_time()const time_point_sec database::head_block_time()const
@ -159,4 +163,156 @@ const witness_schedule_object& database::get_witness_schedule_object()const
return *_p_witness_schedule_obj; return *_p_witness_schedule_obj;
} }
vector<authority> database::get_account_custom_authorities(account_id_type account, const operation& op)const
{
const auto& pindex = get_index_type<custom_permission_index>().indices().get<by_account_and_permission>();
const auto& cindex = get_index_type<custom_account_authority_index>().indices().get<by_permission_and_op>();
auto prange = pindex.equal_range(boost::make_tuple(account));
time_point_sec now = head_block_time();
vector<authority> custom_auths;
for(const custom_permission_object& pobj : boost::make_iterator_range(prange.first, prange.second))
{
auto crange = cindex.equal_range(boost::make_tuple(pobj.id, op.which()));
for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second))
{
if(now >= cobj.valid_from && now < cobj.valid_to)
{
custom_auths.push_back(pobj.auth);
}
}
}
return custom_auths;
}
bool database::item_locked(const nft_id_type &item) const
{
const auto &offer_idx = get_index_type<offer_index>();
const auto &oidx = dynamic_cast<const base_primary_index &>(offer_idx);
const auto &market_items = oidx.get_secondary_index<graphene::chain::offer_item_index>();
auto items_itr = market_items._locked_items.find(item);
return (items_itr != market_items._locked_items.end());
}
bool database::account_role_valid(const account_role_object &aro, account_id_type account, optional<int> op_type) const
{
return (aro.valid_to > head_block_time()) &&
(aro.whitelisted_accounts.find(account) != aro.whitelisted_accounts.end()) &&
(!op_type || (aro.allowed_operations.find(*op_type) != aro.allowed_operations.end()));
}
std::set<son_id_type> database::get_sons_being_deregistered()
{
std::set<son_id_type> ret;
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get< by_id >();
for( auto& son_proposal : son_proposal_idx )
{
if(son_proposal.proposal_type == son_proposal_type::son_deregister_proposal)
{
ret.insert(son_proposal.son_id);
}
}
return ret;
}
std::set<son_id_type> database::get_sons_to_be_deregistered()
{
std::set<son_id_type> ret;
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
for( auto& son : son_idx )
{
if(son.status == son_status::in_maintenance)
{
auto stats = son.statistics(*this);
// TODO : We need to add a function that returns if we can deregister SON
// i.e. with introduction of PW code, we have to make a decision if the SON
// is needed for release of funds from the PW
if(head_block_time() - stats.last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time()))
{
ret.insert(son.id);
}
}
}
return ret;
}
std::set<son_id_type> database::get_sons_being_reported_down()
{
std::set<son_id_type> ret;
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get< by_id >();
for( auto& son_proposal : son_proposal_idx )
{
if(son_proposal.proposal_type == son_proposal_type::son_report_down_proposal)
{
ret.insert(son_proposal.son_id);
}
}
return ret;
}
fc::optional<operation> database::create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son )
{
son_deregister_operation son_dereg_op;
son_dereg_op.payer = get_global_properties().parameters.son_account();
son_dereg_op.son_id = son_id;
proposal_create_operation proposal_op;
proposal_op.fee_paying_account = paying_son;
proposal_op.proposed_ops.push_back( op_wrapper( son_dereg_op ) );
uint32_t lifetime = ( get_global_properties().parameters.block_interval * get_global_properties().active_witnesses.size() ) * 3;
proposal_op.expiration_time = time_point_sec( head_block_time().sec_since_epoch() + lifetime );
return proposal_op;
}
signed_transaction database::create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op )
{
signed_transaction processed_trx;
auto dyn_props = get_dynamic_global_properties();
processed_trx.set_reference_block( dyn_props.head_block_id );
processed_trx.set_expiration( head_block_time() + get_global_properties().parameters.maximum_time_until_expiration );
processed_trx.operations.push_back( op );
current_fee_schedule().set_fee( processed_trx.operations.back() );
processed_trx.sign( signing_private_key, get_chain_id() );
return processed_trx;
}
bool database::is_son_dereg_valid( son_id_type son_id )
{
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
auto son = son_idx.find( son_id );
if(son == son_idx.end())
{
return false;
}
return (son->status == son_status::in_maintenance &&
(head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time())));
}
bool database::is_son_active( son_id_type son_id )
{
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
auto son = son_idx.find( son_id );
if(son == son_idx.end())
{
return false;
}
const global_property_object& gpo = get_global_properties();
vector<son_id_type> active_son_ids;
active_son_ids.reserve(gpo.active_sons.size());
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
std::inserter(active_son_ids, active_son_ids.end()),
[](const son_info& swi) {
return swi.son_id;
});
auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), son_id);
return (it_son != active_son_ids.end());
}
} } } }

View file

@ -49,13 +49,25 @@
#include <graphene/chain/tournament_object.hpp> #include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/match_object.hpp> #include <graphene/chain/match_object.hpp>
#include <graphene/chain/game_object.hpp> #include <graphene/chain/game_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/sport_object.hpp> #include <graphene/chain/sport_object.hpp>
#include <graphene/chain/event_group_object.hpp> #include <graphene/chain/event_group_object.hpp>
#include <graphene/chain/event_object.hpp> #include <graphene/chain/event_object.hpp>
#include <graphene/chain/betting_market_object.hpp> #include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp> #include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_proposal_object.hpp>
#include <graphene/chain/son_wallet_object.hpp>
#include <graphene/chain/son_wallet_deposit_object.hpp>
#include <graphene/chain/son_wallet_withdraw_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/sidechain_transaction_object.hpp>
#include <graphene/chain/account_evaluator.hpp> #include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/asset_evaluator.hpp> #include <graphene/chain/asset_evaluator.hpp>
@ -77,10 +89,20 @@
#include <graphene/chain/event_evaluator.hpp> #include <graphene/chain/event_evaluator.hpp>
#include <graphene/chain/betting_market_evaluator.hpp> #include <graphene/chain/betting_market_evaluator.hpp>
#include <graphene/chain/tournament_evaluator.hpp> #include <graphene/chain/tournament_evaluator.hpp>
#include <graphene/chain/custom_permission_evaluator.hpp>
#include <graphene/chain/custom_account_authority_evaluator.hpp>
#include <graphene/chain/offer_evaluator.hpp>
#include <graphene/chain/nft_evaluator.hpp>
#include <graphene/chain/account_role_evaluator.hpp>
#include <graphene/chain/son_evaluator.hpp>
#include <graphene/chain/son_wallet_evaluator.hpp>
#include <graphene/chain/son_wallet_deposit_evaluator.hpp>
#include <graphene/chain/son_wallet_withdraw_evaluator.hpp>
#include <graphene/chain/sidechain_address_evaluator.hpp>
#include <graphene/chain/sidechain_transaction_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#include <fc/crypto/digest.hpp> #include <fc/crypto/digest.hpp>
@ -163,12 +185,23 @@ const uint8_t betting_market_object::type_id;
const uint8_t bet_object::space_id; const uint8_t bet_object::space_id;
const uint8_t bet_object::type_id; const uint8_t bet_object::type_id;
const uint8_t nft_object::space_id;
const uint8_t nft_object::type_id;
const uint8_t betting_market_position_object::space_id; const uint8_t betting_market_position_object::space_id;
const uint8_t betting_market_position_object::type_id; const uint8_t betting_market_position_object::type_id;
const uint8_t global_betting_statistics_object::space_id; const uint8_t global_betting_statistics_object::space_id;
const uint8_t global_betting_statistics_object::type_id; const uint8_t global_betting_statistics_object::type_id;
const uint8_t offer_object::space_id;
const uint8_t offer_object::type_id;
const uint8_t offer_history_object::space_id;
const uint8_t offer_history_object::type_id;
const uint8_t account_role_object::space_id;
const uint8_t account_role_object::type_id;
void database::initialize_evaluators() void database::initialize_evaluators()
{ {
@ -243,6 +276,44 @@ void database::initialize_evaluators()
register_evaluator<lottery_reward_evaluator>(); register_evaluator<lottery_reward_evaluator>();
register_evaluator<lottery_end_evaluator>(); register_evaluator<lottery_end_evaluator>();
register_evaluator<sweeps_vesting_claim_evaluator>(); register_evaluator<sweeps_vesting_claim_evaluator>();
register_evaluator<create_custom_permission_evaluator>();
register_evaluator<update_custom_permission_evaluator>();
register_evaluator<delete_custom_permission_evaluator>();
register_evaluator<create_custom_account_authority_evaluator>();
register_evaluator<update_custom_account_authority_evaluator>();
register_evaluator<delete_custom_account_authority_evaluator>();
register_evaluator<offer_evaluator>();
register_evaluator<bid_evaluator>();
register_evaluator<cancel_offer_evaluator>();
register_evaluator<finalize_offer_evaluator>();
register_evaluator<nft_metadata_create_evaluator>();
register_evaluator<nft_metadata_update_evaluator>();
register_evaluator<nft_mint_evaluator>();
register_evaluator<nft_safe_transfer_from_evaluator>();
register_evaluator<nft_approve_evaluator>();
register_evaluator<nft_set_approval_for_all_evaluator>();
register_evaluator<account_role_create_evaluator>();
register_evaluator<account_role_update_evaluator>();
register_evaluator<account_role_delete_evaluator>();
register_evaluator<create_son_evaluator>();
register_evaluator<update_son_evaluator>();
register_evaluator<deregister_son_evaluator>();
register_evaluator<son_heartbeat_evaluator>();
register_evaluator<son_report_down_evaluator>();
register_evaluator<son_maintenance_evaluator>();
register_evaluator<recreate_son_wallet_evaluator>();
register_evaluator<update_son_wallet_evaluator>();
register_evaluator<create_son_wallet_deposit_evaluator>();
register_evaluator<process_son_wallet_deposit_evaluator>();
register_evaluator<create_son_wallet_withdraw_evaluator>();
register_evaluator<process_son_wallet_withdraw_evaluator>();
register_evaluator<add_sidechain_address_evaluator>();
register_evaluator<update_sidechain_address_evaluator>();
register_evaluator<delete_sidechain_address_evaluator>();
register_evaluator<sidechain_transaction_create_evaluator>();
register_evaluator<sidechain_transaction_sign_evaluator>();
register_evaluator<sidechain_transaction_send_evaluator>();
register_evaluator<sidechain_transaction_settle_evaluator>();
} }
void database::initialize_indexes() void database::initialize_indexes()
@ -259,6 +330,7 @@ void database::initialize_indexes()
acnt_index->add_secondary_index<account_referrer_index>(); acnt_index->add_secondary_index<account_referrer_index>();
add_index< primary_index<committee_member_index, 8> >(); // 256 members per chunk add_index< primary_index<committee_member_index, 8> >(); // 256 members per chunk
add_index< primary_index<son_index> >();
add_index< primary_index<witness_index, 10> >(); // 1024 witnesses per chunk add_index< primary_index<witness_index, 10> >(); // 1024 witnesses per chunk
add_index< primary_index<limit_order_index > >(); add_index< primary_index<limit_order_index > >();
add_index< primary_index<call_order_index > >(); add_index< primary_index<call_order_index > >();
@ -284,6 +356,22 @@ void database::initialize_indexes()
tournament_details_idx->add_secondary_index<tournament_players_index>(); tournament_details_idx->add_secondary_index<tournament_players_index>();
add_index< primary_index<match_index> >(); add_index< primary_index<match_index> >();
add_index< primary_index<game_index> >(); add_index< primary_index<game_index> >();
add_index< primary_index<custom_permission_index> >();
add_index< primary_index<custom_account_authority_index> >();
auto offer_idx = add_index< primary_index<offer_index> >();
offer_idx->add_secondary_index<offer_item_index>();
add_index< primary_index<nft_metadata_index > >();
add_index< primary_index<nft_index > >();
add_index< primary_index<account_role_index> >();
add_index< primary_index<son_proposal_index> >();
add_index< primary_index<son_wallet_index> >();
add_index< primary_index<son_wallet_deposit_index> >();
add_index< primary_index<son_wallet_withdraw_index> >();
add_index< primary_index<sidechain_address_index> >();
add_index< primary_index<sidechain_transaction_index> >();
//Implementation object indexes //Implementation object indexes
add_index< primary_index<transaction_index > >(); add_index< primary_index<transaction_index > >();
@ -300,6 +388,7 @@ void database::initialize_indexes()
add_index< primary_index<flat_index< block_summary_object >> >(); add_index< primary_index<flat_index< block_summary_object >> >();
add_index< primary_index<simple_index<chain_property_object > > >(); add_index< primary_index<simple_index<chain_property_object > > >();
add_index< primary_index<simple_index<witness_schedule_object > > >(); add_index< primary_index<simple_index<witness_schedule_object > > >();
add_index< primary_index<simple_index<son_schedule_object > > >();
add_index< primary_index<simple_index<budget_record_object > > >(); add_index< primary_index<simple_index<budget_record_object > > >();
add_index< primary_index< special_authority_index > >(); add_index< primary_index< special_authority_index > >();
add_index< primary_index< buyback_index > >(); add_index< primary_index< buyback_index > >();
@ -313,6 +402,8 @@ void database::initialize_indexes()
add_index< primary_index<lottery_balance_index > >(); add_index< primary_index<lottery_balance_index > >();
add_index< primary_index<sweeps_vesting_balance_index > >(); add_index< primary_index<sweeps_vesting_balance_index > >();
add_index< primary_index<offer_history_index > >();
add_index< primary_index<son_stats_index > >();
} }
@ -957,6 +1048,29 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}); });
FC_ASSERT( _p_witness_schedule_obj->id == witness_schedule_id_type() ); FC_ASSERT( _p_witness_schedule_obj->id == witness_schedule_id_type() );
// Initialize witness schedule
#ifndef NDEBUG
const son_schedule_object& sso =
#endif
create<son_schedule_object>([&](son_schedule_object& _sso)
{
// for scheduled
memset(_sso.rng_seed.begin(), 0, _sso.rng_seed.size());
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
auto init_witnesses = get_global_properties().active_witnesses;
_sso.scheduler = son_scheduler();
_sso.scheduler._min_token_count = std::max(int(init_witnesses.size()) / 2, 1);
_sso.last_scheduling_block = 0;
_sso.recent_slots_filled = fc::uint128::max_value();
});
assert( sso.id == son_schedule_id_type() );
// Enable fees // Enable fees
modify(get_global_properties(), [&genesis_state](global_property_object& p) { modify(get_global_properties(), [&genesis_state](global_property_object& p) {
p.parameters.current_fees = genesis_state.initial_parameters.current_fees; p.parameters.current_fees = genesis_state.initial_parameters.current_fees;

View file

@ -24,7 +24,6 @@
#include <boost/multiprecision/integer.hpp> #include <boost/multiprecision/integer.hpp>
#include <fc/smart_ref_impl.hpp>
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
@ -42,11 +41,13 @@
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/market_object.hpp> #include <graphene/chain/market_object.hpp>
#include <graphene/chain/special_authority_object.hpp> #include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp> #include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/vote_count.hpp> #include <graphene/chain/vote_count.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp> #include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/worker_object.hpp> #include <graphene/chain/worker_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#define USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX // vesting_balance_object by_asset_balance index needed #define USE_VESTING_OBJECT_BY_ASSET_BALANCE_INDEX // vesting_balance_object by_asset_balance index needed
@ -76,6 +77,32 @@ vector<std::reference_wrapper<const typename Index::object_type>> database::sort
return refs; return refs;
} }
template<>
vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<son_index>(size_t count) const
{
const auto& all_sons = get_index_type<son_index>().indices().get< by_id >();
std::vector<std::reference_wrapper<const son_object>> refs;
for( auto& son : all_sons )
{
if(son.has_valid_config() && son.status != son_status::deregistered)
{
refs.push_back(std::cref(son));
}
}
count = std::min(count, refs.size());
std::partial_sort(refs.begin(), refs.begin() + count, refs.end(),
[this](const son_object& a, const son_object& b)->bool {
share_type oa_vote = _vote_tally_buffer[a.vote_id];
share_type ob_vote = _vote_tally_buffer[b.vote_id];
if( oa_vote != ob_vote )
return oa_vote > ob_vote;
return a.vote_id < b.vote_id;
});
refs.resize(count, refs.front());
return refs;
}
template<class Type> template<class Type>
void database::perform_account_maintenance(Type tally_helper) void database::perform_account_maintenance(Type tally_helper)
{ {
@ -149,6 +176,215 @@ void database::update_worker_votes()
} }
} }
void database::pay_sons()
{
auto get_weight = []( uint64_t total_votes ) {
int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0);
uint16_t weight = std::max((total_votes >> bits_to_drop), uint64_t(1) );
return weight;
};
time_point_sec now = head_block_time();
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
// Current requirement is that we have to pay every 24 hours, so the following check
if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time()))) {
uint64_t weighted_total_txs_signed = 0;
share_type son_budget = dpo.son_budget;
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &get_weight](const object& o) {
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner );
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id]);
weighted_total_txs_signed += (s.txs_signed * son_weight);
});
// Now pay off each SON proportional to the number of transactions signed.
get_index_type<son_stats_index>().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight](const object& o) {
const son_statistics_object& s = static_cast<const son_statistics_object&>(o);
if(s.txs_signed > 0){
auto son_params = get_global_properties().parameters;
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner );
auto son_weight = get_weight(_vote_tally_buffer[son_obj->vote_id]);
share_type pay = (s.txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
modify( *son_obj, [&]( son_object& _son_obj)
{
_son_obj.pay_son_fee(pay, *this);
});
//Remove the amount paid out to SON from global SON Budget
modify( dpo, [&]( dynamic_global_property_object& _dpo )
{
_dpo.son_budget -= pay;
} );
//Reset the tx counter in each son statistics object
modify( s, [&]( son_statistics_object& _s)
{
_s.total_txs_signed += _s.txs_signed;
_s.txs_signed = 0;
});
}
});
//Note the last son pay out time
modify( dpo, [&]( dynamic_global_property_object& _dpo )
{
_dpo.last_son_payout_time = now;
});
}
}
void database::update_son_metrics(const vector<son_info>& curr_active_sons)
{
vector<son_id_type> current_sons;
current_sons.reserve(curr_active_sons.size());
std::transform(curr_active_sons.begin(), curr_active_sons.end(),
std::inserter(current_sons, current_sons.end()),
[](const son_info &swi) {
return swi.son_id;
});
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
for( auto& son : son_idx )
{
auto& stats = son.statistics(*this);
bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end());
modify( stats, [&]( son_statistics_object& _stats )
{
_stats.total_downtime += _stats.current_interval_downtime;
_stats.current_interval_downtime = 0;
if(is_active_son)
{
_stats.total_voted_time = _stats.total_voted_time + get_global_properties().parameters.maintenance_interval;
}
});
}
}
void database::update_son_statuses(const vector<son_info>& curr_active_sons, const vector<son_info>& new_active_sons)
{
vector<son_id_type> current_sons, new_sons;
vector<son_id_type> sons_to_remove, sons_to_add;
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
current_sons.reserve(curr_active_sons.size());
std::transform(curr_active_sons.begin(), curr_active_sons.end(),
std::inserter(current_sons, current_sons.end()),
[](const son_info &swi) {
return swi.son_id;
});
new_sons.reserve(new_active_sons.size());
std::transform(new_active_sons.begin(), new_active_sons.end(),
std::inserter(new_sons, new_sons.end()),
[](const son_info &swi) {
return swi.son_id;
});
// find all cur_active_sons members that is not in new_active_sons
for_each(current_sons.begin(), current_sons.end(),
[&sons_to_remove, &new_sons](const son_id_type& si)
{
if(std::find(new_sons.begin(), new_sons.end(), si) ==
new_sons.end())
{
sons_to_remove.push_back(si);
}
}
);
for( const auto& sid : sons_to_remove )
{
auto son = idx.find( sid );
if(son == idx.end()) // SON is deleted already
continue;
// keep maintenance status for nodes becoming inactive
if(son->status == son_status::active)
{
modify( *son, [&]( son_object& obj ){
obj.status = son_status::inactive;
});
}
}
// find all new_active_sons members that is not in cur_active_sons
for_each(new_sons.begin(), new_sons.end(),
[&sons_to_add, &current_sons](const son_id_type& si)
{
if(std::find(current_sons.begin(), current_sons.end(), si) ==
current_sons.end())
{
sons_to_add.push_back(si);
}
}
);
for( const auto& sid : sons_to_add )
{
auto son = idx.find( sid );
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid));
// keep maintenance status for new nodes
if(son->status == son_status::inactive)
{
modify( *son, [&]( son_object& obj ){
obj.status = son_status::active;
});
}
}
ilog("New SONS");
for(size_t i = 0; i < new_sons.size(); i++) {
auto son = idx.find( new_sons[i] );
if(son == idx.end()) // SON is deleted already
continue;
ilog( "${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->status)("sv", son->total_votes) );
}
if( sons_to_remove.size() > 0 )
{
remove_inactive_son_proposals(sons_to_remove);
}
}
void database::update_son_wallet(const vector<son_info>& new_active_sons)
{
bool should_recreate_pw = true;
// Expire for current son_wallet_object wallet, if exists
const auto& idx_swi = get_index_type<son_wallet_index>().indices().get<by_id>();
auto obj = idx_swi.rbegin();
if (obj != idx_swi.rend()) {
// Compare current wallet SONs and to-be lists of active sons
auto cur_wallet_sons = (*obj).sons;
bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size());
if (wallet_son_sets_equal) {
for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) {
wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i);
}
}
should_recreate_pw = !wallet_son_sets_equal;
if (should_recreate_pw) {
modify(*obj, [&, obj](son_wallet_object &swo) {
swo.expires = head_block_time();
});
}
}
should_recreate_pw = should_recreate_pw && (new_active_sons.size() >= get_chain_properties().immutable_parameters.min_son_count);
if (should_recreate_pw) {
// Create new son_wallet_object, to initiate wallet recreation
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
obj.valid_from = head_block_time();
obj.expires = time_point_sec::maximum();
obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end());
});
}
}
void database::pay_workers( share_type& budget ) void database::pay_workers( share_type& budget )
{ {
const auto head_time = head_block_time(); const auto head_time = head_block_time();
@ -206,7 +442,7 @@ void database::update_active_witnesses()
/// accounts that vote for 0 or 1 witness do not get to express an opinion on /// accounts that vote for 0 or 1 witness do not get to express an opinion on
/// the number of witnesses to have (they abstain and are non-voting accounts) /// the number of witnesses to have (they abstain and are non-voting accounts)
share_type stake_tally = 0; share_type stake_tally = 0;
size_t witness_count = 0; size_t witness_count = 0;
if( stake_target > 0 ) if( stake_target > 0 )
@ -305,7 +541,7 @@ void database::update_active_witnesses()
void database::update_active_committee_members() void database::update_active_committee_members()
{ try { { try {
assert( _committee_count_histogram_buffer.size() > 0 ); assert( _committee_count_histogram_buffer.size() > 0 );
share_type stake_target = (_total_voting_stake-_witness_count_histogram_buffer[0]) / 2; share_type stake_target = (_total_voting_stake-_committee_count_histogram_buffer[0]) / 2;
/// accounts that vote for 0 or 1 witness do not get to express an opinion on /// accounts that vote for 0 or 1 witness do not get to express an opinion on
/// the number of witnesses to have (they abstain and are non-voting accounts) /// the number of witnesses to have (they abstain and are non-voting accounts)
@ -394,6 +630,146 @@ void database::update_active_committee_members()
}); });
} FC_CAPTURE_AND_RETHROW() } } FC_CAPTURE_AND_RETHROW() }
void database::update_active_sons()
{ try {
assert( _son_count_histogram_buffer.size() > 0 );
share_type stake_target = (_total_voting_stake-_son_count_histogram_buffer[0]) / 2;
/// accounts that vote for 0 or 1 son do not get to express an opinion on
/// the number of sons to have (they abstain and are non-voting accounts)
share_type stake_tally = 0;
size_t son_count = 0;
if( stake_target > 0 )
{
while( (son_count < _son_count_histogram_buffer.size() - 1)
&& (stake_tally <= stake_target) )
{
stake_tally += _son_count_histogram_buffer[++son_count];
}
}
const global_property_object& gpo = get_global_properties();
const chain_parameters& cp = gpo.parameters;
auto sons = sort_votable_objects<son_index>(cp.maximum_son_count());
const auto& all_sons = get_index_type<son_index>().indices();
auto& local_vote_buffer_ref = _vote_tally_buffer;
for( const son_object& son : all_sons )
{
if(son.status == son_status::request_maintenance)
{
auto& stats = son.statistics(*this);
modify( stats, [&]( son_statistics_object& _s){
_s.last_down_timestamp = head_block_time();
});
}
modify( son, [local_vote_buffer_ref]( son_object& obj ){
obj.total_votes = local_vote_buffer_ref[obj.vote_id];
if(obj.status == son_status::request_maintenance)
obj.status = son_status::in_maintenance;
});
}
// Update SON authority
if( gpo.parameters.son_account() != GRAPHENE_NULL_ACCOUNT )
{
modify( get(gpo.parameters.son_account()), [&]( account_object& a )
{
if( head_block_time() < HARDFORK_533_TIME )
{
map<account_id_type, uint64_t> weights;
a.active.weight_threshold = 0;
a.active.account_auths.clear();
for( const son_object& son : sons )
{
weights.emplace(son.son_account, uint64_t(1));
}
for( const auto& weight : weights )
{
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
a.active.account_auths[weight.first] += 1;
a.active.weight_threshold += 1;
}
a.active.weight_threshold *= 2;
a.active.weight_threshold /= 3;
a.active.weight_threshold += 1;
}
else
{
vote_counter vc;
for( const son_object& son : sons )
vc.add( son.son_account, UINT64_C(1) );
vc.finish_2_3( a.active );
}
} );
}
// Compare current and to-be lists of active sons
auto cur_active_sons = gpo.active_sons;
vector<son_info> new_active_sons;
const auto &acc = get(gpo.parameters.son_account());
for( const son_object& son : sons ) {
son_info swi;
swi.son_id = son.id;
swi.weight = acc.active.account_auths.at(son.son_account);
swi.signing_key = son.signing_key;
swi.sidechain_public_keys = son.sidechain_public_keys;
new_active_sons.push_back(swi);
}
bool son_sets_equal = (cur_active_sons.size() == new_active_sons.size());
if (son_sets_equal) {
for( size_t i = 0; i < cur_active_sons.size(); i++ ) {
son_sets_equal = son_sets_equal && cur_active_sons.at(i) == new_active_sons.at(i);
}
}
if (son_sets_equal) {
ilog( "Active SONs set NOT CHANGED" );
} else {
ilog( "Active SONs set CHANGED" );
update_son_wallet(new_active_sons);
update_son_statuses(cur_active_sons, new_active_sons);
}
// Update son performance metrics
update_son_metrics(cur_active_sons);
modify(gpo, [&]( global_property_object& gp ){
gp.active_sons.clear();
gp.active_sons.reserve(new_active_sons.size());
gp.active_sons.insert(gp.active_sons.end(), new_active_sons.begin(), new_active_sons.end());
});
const son_schedule_object& sso = son_schedule_id_type()(*this);
modify(sso, [&](son_schedule_object& _sso)
{
flat_set<son_id_type> active_sons;
active_sons.reserve(gpo.active_sons.size());
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
std::inserter(active_sons, active_sons.end()),
[](const son_info& swi) {
return swi.son_id;
});
_sso.scheduler.update(active_sons);
// similar to witness, produce schedule for sons
if(cur_active_sons.size() == 0 && new_active_sons.size() > 0)
{
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
for( size_t i=0; i<new_active_sons.size(); ++i )
_sso.scheduler.produce_schedule(rng);
}
});
} FC_CAPTURE_AND_RETHROW() }
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const
{ {
const dynamic_global_property_object& dpo = get_dynamic_global_properties(); const dynamic_global_property_object& dpo = get_dynamic_global_properties();
@ -482,6 +858,17 @@ void database::process_budget()
rec.witness_budget = witness_budget; rec.witness_budget = witness_budget;
available_funds -= witness_budget; available_funds -= witness_budget;
// We should not factor-in the son budget before SON HARDFORK
share_type son_budget = 0;
if(now >= HARDFORK_SON_TIME){
rec.leftover_son_funds = dpo.son_budget;
available_funds += rec.leftover_son_funds;
son_budget = gpo.parameters.son_pay_max();
son_budget = std::min(son_budget, available_funds);
rec.son_budget = son_budget;
available_funds -= son_budget;
}
fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value; fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value;
worker_budget_u128 *= uint64_t(time_to_maint); worker_budget_u128 *= uint64_t(time_to_maint);
worker_budget_u128 /= 60*60*24; worker_budget_u128 /= 60*60*24;
@ -501,9 +888,11 @@ void database::process_budget()
rec.supply_delta = rec.witness_budget rec.supply_delta = rec.witness_budget
+ rec.worker_budget + rec.worker_budget
+ rec.son_budget
- rec.leftover_worker_funds - rec.leftover_worker_funds
- rec.from_accumulated_fees - rec.from_accumulated_fees
- rec.from_unused_witness_budget; - rec.from_unused_witness_budget
- rec.leftover_son_funds;
modify(core, [&]( asset_dynamic_data_object& _core ) modify(core, [&]( asset_dynamic_data_object& _core )
{ {
@ -512,9 +901,11 @@ void database::process_budget()
assert( rec.supply_delta == assert( rec.supply_delta ==
witness_budget witness_budget
+ worker_budget + worker_budget
+ son_budget
- leftover_worker_funds - leftover_worker_funds
- _core.accumulated_fees - _core.accumulated_fees
- dpo.witness_budget - dpo.witness_budget
- dpo.son_budget
); );
_core.accumulated_fees = 0; _core.accumulated_fees = 0;
}); });
@ -525,6 +916,7 @@ void database::process_budget()
// available_funds, we replace it with witness_budget // available_funds, we replace it with witness_budget
// instead of adding it. // instead of adding it.
_dpo.witness_budget = witness_budget; _dpo.witness_budget = witness_budget;
_dpo.son_budget = son_budget;
_dpo.last_budget_time = now; _dpo.last_budget_time = now;
}); });
@ -803,8 +1195,6 @@ uint32_t database::get_gpos_current_subperiod()
const auto now = this->head_block_time(); const auto now = this->head_block_time();
auto seconds_since_period_start = now.sec_since_epoch() - period_start.sec_since_epoch(); auto seconds_since_period_start = now.sec_since_epoch() - period_start.sec_since_epoch();
FC_ASSERT(period_start <= now && now <= period_end);
// get in what sub period we are // get in what sub period we are
uint32_t current_subperiod = 0; uint32_t current_subperiod = 0;
std::list<uint32_t> period_list(number_of_subperiods); std::list<uint32_t> period_list(number_of_subperiods);
@ -926,21 +1316,39 @@ void rolling_period_start(database& db)
if(now.sec_since_epoch() >= (period_start + vesting_period)) if(now.sec_since_epoch() >= (period_start + vesting_period))
{ {
// roll // roll
db.modify(db.get_global_properties(), [now](global_property_object& p) { db.modify(db.get_global_properties(), [period_start, vesting_period](global_property_object& p) {
p.parameters.extensions.value.gpos_period_start = now.sec_since_epoch(); p.parameters.extensions.value.gpos_period_start = period_start + vesting_period;
}); });
} }
} }
} }
void clear_expired_custom_account_authorities(database& db)
{
const auto& cindex = db.get_index_type<custom_account_authority_index>().indices().get<by_expiration>();
while(!cindex.empty() && cindex.begin()->valid_to < db.head_block_time())
{
db.remove(*cindex.begin());
}
}
void clear_expired_account_roles(database& db)
{
const auto& arindex = db.get_index_type<account_role_index>().indices().get<by_expiration>();
while(!arindex.empty() && arindex.begin()->valid_to < db.head_block_time())
{
db.remove(*arindex.begin());
}
}
// Schedules payouts from a dividend distribution account to the current holders of the // Schedules payouts from a dividend distribution account to the current holders of the
// dividend-paying asset. This takes any deposits made to the dividend distribution account // dividend-paying asset. This takes any deposits made to the dividend distribution account
// since the last time it was called, and distributes them to the current owners of the // since the last time it was called, and distributes them to the current owners of the
// dividend-paying asset according to the amount they own. // dividend-paying asset according to the amount they own.
void schedule_pending_dividend_balances(database& db, void schedule_pending_dividend_balances(database& db,
const asset_object& dividend_holder_asset_obj, const asset_object& dividend_holder_asset_obj,
const asset_dividend_data_object& dividend_data, const asset_dividend_data_object& dividend_data,
const fc::time_point_sec& current_head_block_time, const fc::time_point_sec& current_head_block_time,
const account_balance_index& balance_index, const account_balance_index& balance_index,
const vesting_balance_index& vesting_index, const vesting_balance_index& vesting_index,
const total_distributed_dividend_balance_object_index& distributed_dividend_balance_index, const total_distributed_dividend_balance_object_index& distributed_dividend_balance_index,
@ -949,7 +1357,7 @@ void schedule_pending_dividend_balances(database& db,
dlog("Processing dividend payments for dividend holder asset type ${holder_asset} at time ${t}", dlog("Processing dividend payments for dividend holder asset type ${holder_asset} at time ${t}",
("holder_asset", dividend_holder_asset_obj.symbol)("t", db.head_block_time())); ("holder_asset", dividend_holder_asset_obj.symbol)("t", db.head_block_time()));
auto balance_by_acc_index = db.get_index_type< primary_index< account_balance_index > >().get_secondary_index< balances_by_account_index >(); auto balance_by_acc_index = db.get_index_type< primary_index< account_balance_index > >().get_secondary_index< balances_by_account_index >();
auto current_distribution_account_balance_range = auto current_distribution_account_balance_range =
//balance_index.indices().get<by_account_asset>().equal_range(boost::make_tuple(dividend_data.dividend_distribution_account)); //balance_index.indices().get<by_account_asset>().equal_range(boost::make_tuple(dividend_data.dividend_distribution_account));
balance_by_acc_index.get_account_balances(dividend_data.dividend_distribution_account); balance_by_acc_index.get_account_balances(dividend_data.dividend_distribution_account);
auto previous_distribution_account_balance_range = auto previous_distribution_account_balance_range =
@ -960,7 +1368,7 @@ void schedule_pending_dividend_balances(database& db,
const auto& gpo = db.get_global_properties(); const auto& gpo = db.get_global_properties();
// get the list of accounts that hold nonzero balances of the dividend asset // get the list of accounts that hold nonzero balances of the dividend asset
auto holder_balances_begin = auto holder_balances_begin =
balance_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(dividend_holder_asset_obj.id)); balance_index.indices().get<by_asset_balance>().lower_bound(boost::make_tuple(dividend_holder_asset_obj.id));
auto holder_balances_end = auto holder_balances_end =
balance_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(dividend_holder_asset_obj.id, share_type())); balance_index.indices().get<by_asset_balance>().upper_bound(boost::make_tuple(dividend_holder_asset_obj.id, share_type()));
@ -1020,7 +1428,7 @@ void schedule_pending_dividend_balances(database& db,
("previous", (int64_t)std::distance(previous_distribution_account_balance_range.first, previous_distribution_account_balance_range.second))); ("previous", (int64_t)std::distance(previous_distribution_account_balance_range.first, previous_distribution_account_balance_range.second)));
// when we pay out the dividends to the holders, we need to know the total balance of the dividend asset in all // when we pay out the dividends to the holders, we need to know the total balance of the dividend asset in all
// accounts other than the distribution account (it would be silly to distribute dividends back to // accounts other than the distribution account (it would be silly to distribute dividends back to
// the distribution account) // the distribution account)
share_type total_balance_of_dividend_asset; share_type total_balance_of_dividend_asset;
if(db.head_block_time() >= HARDFORK_GPOS_TIME && dividend_holder_asset_obj.symbol == GRAPHENE_SYMBOL) { // only core if(db.head_block_time() >= HARDFORK_GPOS_TIME && dividend_holder_asset_obj.symbol == GRAPHENE_SYMBOL) { // only core
@ -1051,7 +1459,7 @@ void schedule_pending_dividend_balances(database& db,
share_type previous_balance; share_type previous_balance;
asset_id_type payout_asset_type; asset_id_type payout_asset_type;
if (previous_distribution_account_balance_iter == previous_distribution_account_balance_range.second || if (previous_distribution_account_balance_iter == previous_distribution_account_balance_range.second ||
current_distribution_account_balance_iter->second->asset_type < previous_distribution_account_balance_iter->dividend_payout_asset_type) current_distribution_account_balance_iter->second->asset_type < previous_distribution_account_balance_iter->dividend_payout_asset_type)
{ {
// there are no more previous balances or there is no previous balance for this particular asset type // there are no more previous balances or there is no previous balance for this particular asset type
@ -1059,7 +1467,7 @@ void schedule_pending_dividend_balances(database& db,
current_balance = current_distribution_account_balance_iter->second->balance; current_balance = current_distribution_account_balance_iter->second->balance;
idump((payout_asset_type)(current_balance)); idump((payout_asset_type)(current_balance));
} }
else if (current_distribution_account_balance_iter == current_distribution_account_balance_range.end() || else if (current_distribution_account_balance_iter == current_distribution_account_balance_range.end() ||
previous_distribution_account_balance_iter->dividend_payout_asset_type < current_distribution_account_balance_iter->second->asset_type) previous_distribution_account_balance_iter->dividend_payout_asset_type < current_distribution_account_balance_iter->second->asset_type)
{ {
// there are no more current balances or there is no current balance for this particular previous asset type // there are no more current balances or there is no current balance for this particular previous asset type
@ -1078,7 +1486,7 @@ void schedule_pending_dividend_balances(database& db,
share_type delta_balance = current_balance - previous_balance; share_type delta_balance = current_balance - previous_balance;
// Next, figure out if we want to share this out -- if the amount added to the distribution // Next, figure out if we want to share this out -- if the amount added to the distribution
// account since last payout is too small, we won't bother. // account since last payout is too small, we won't bother.
share_type total_fee_per_asset_in_payout_asset; share_type total_fee_per_asset_in_payout_asset;
@ -1087,7 +1495,7 @@ void schedule_pending_dividend_balances(database& db,
{ {
payout_asset_object = &db.get_core_asset(); payout_asset_object = &db.get_core_asset();
total_fee_per_asset_in_payout_asset = total_fee_per_asset_in_core; total_fee_per_asset_in_payout_asset = total_fee_per_asset_in_core;
dlog("Fee for distributing ${payout_asset_type}: ${fee}", dlog("Fee for distributing ${payout_asset_type}: ${fee}",
("payout_asset_type", asset_id_type()(db).symbol) ("payout_asset_type", asset_id_type()(db).symbol)
("fee", asset(total_fee_per_asset_in_core, asset_id_type()))); ("fee", asset(total_fee_per_asset_in_core, asset_id_type())));
} }
@ -1103,7 +1511,7 @@ void schedule_pending_dividend_balances(database& db,
FC_ASSERT(total_fee_per_asset.asset_id == payout_asset_type); FC_ASSERT(total_fee_per_asset.asset_id == payout_asset_type);
total_fee_per_asset_in_payout_asset = total_fee_per_asset.amount; total_fee_per_asset_in_payout_asset = total_fee_per_asset.amount;
dlog("Fee for distributing ${payout_asset_type}: ${fee}", dlog("Fee for distributing ${payout_asset_type}: ${fee}",
("payout_asset_type", payout_asset_type(db).symbol)("fee", total_fee_per_asset_in_payout_asset)); ("payout_asset_type", payout_asset_type(db).symbol)("fee", total_fee_per_asset_in_payout_asset));
} }
@ -1116,7 +1524,7 @@ void schedule_pending_dividend_balances(database& db,
wdump((total_fee_per_asset_in_payout_asset)(dividend_data.options)); wdump((total_fee_per_asset_in_payout_asset)(dividend_data.options));
minimum_shares_to_distribute = minimum_amount_to_distribute.to_uint64(); minimum_shares_to_distribute = minimum_amount_to_distribute.to_uint64();
} }
dlog("Processing dividend payments of asset type ${payout_asset_type}, delta balance is ${delta_balance}", ("payout_asset_type", payout_asset_type(db).symbol)("delta_balance", delta_balance)); dlog("Processing dividend payments of asset type ${payout_asset_type}, delta balance is ${delta_balance}", ("payout_asset_type", payout_asset_type(db).symbol)("delta_balance", delta_balance));
if (delta_balance > 0) if (delta_balance > 0)
{ {
@ -1129,7 +1537,7 @@ void schedule_pending_dividend_balances(database& db,
db.modify(asset_dynamic_data_id_type()(db), [total_fee_per_asset_in_core](asset_dynamic_data_object& d) { db.modify(asset_dynamic_data_id_type()(db), [total_fee_per_asset_in_core](asset_dynamic_data_object& d) {
d.accumulated_fees += total_fee_per_asset_in_core; d.accumulated_fees += total_fee_per_asset_in_core;
}); });
db.adjust_balance(dividend_data.dividend_distribution_account, db.adjust_balance(dividend_data.dividend_distribution_account,
asset(-total_fee_per_asset_in_core, asset_id_type())); asset(-total_fee_per_asset_in_core, asset_id_type()));
delta_balance -= total_fee_per_asset_in_core; delta_balance -= total_fee_per_asset_in_core;
} }
@ -1144,7 +1552,7 @@ void schedule_pending_dividend_balances(database& db,
("need", asset(total_fee_per_asset_in_core, asset_id_type())) ("need", asset(total_fee_per_asset_in_core, asset_id_type()))
("have", asset(dynamic_data.fee_pool, payout_asset_type))); ("have", asset(dynamic_data.fee_pool, payout_asset_type)));
// deduct the fee from the dividend distribution account // deduct the fee from the dividend distribution account
db.adjust_balance(dividend_data.dividend_distribution_account, db.adjust_balance(dividend_data.dividend_distribution_account,
asset(-total_fee_per_asset_in_payout_asset, payout_asset_type)); asset(-total_fee_per_asset_in_payout_asset, payout_asset_type));
// convert it to core // convert it to core
db.modify(payout_asset_object->dynamic_data(db), [total_fee_per_asset_in_core, total_fee_per_asset_in_payout_asset](asset_dynamic_data_object& d) { db.modify(payout_asset_object->dynamic_data(db), [total_fee_per_asset_in_core, total_fee_per_asset_in_payout_asset](asset_dynamic_data_object& d) {
@ -1158,7 +1566,7 @@ void schedule_pending_dividend_balances(database& db,
delta_balance -= total_fee_per_asset_in_payout_asset; delta_balance -= total_fee_per_asset_in_payout_asset;
} }
dlog("There are ${count} holders of the dividend-paying asset, with a total balance of ${total}", dlog("There are ${count} holders of the dividend-paying asset, with a total balance of ${total}",
("count", holder_account_count) ("count", holder_account_count)
("total", total_balance_of_dividend_asset)); ("total", total_balance_of_dividend_asset));
share_type remaining_amount_to_distribute = delta_balance; share_type remaining_amount_to_distribute = delta_balance;
@ -1230,7 +1638,7 @@ void schedule_pending_dividend_balances(database& db,
dlog("Pending payout: ${account_name} -> ${amount}", dlog("Pending payout: ${account_name} -> ${amount}",
("account_name", pending_payout.owner(db).name) ("account_name", pending_payout.owner(db).name)
("amount", asset(pending_payout.pending_balance, pending_payout.dividend_payout_asset_type))); ("amount", asset(pending_payout.pending_balance, pending_payout.dividend_payout_asset_type)));
dlog("Remaining balance not paid out: ${amount}", dlog("Remaining balance not paid out: ${amount}",
("amount", asset(remaining_amount_to_distribute, payout_asset_type))); ("amount", asset(remaining_amount_to_distribute, payout_asset_type)));
share_type distributed_amount = delta_balance - remaining_amount_to_distribute; share_type distributed_amount = delta_balance - remaining_amount_to_distribute;
@ -1260,7 +1668,7 @@ void schedule_pending_dividend_balances(database& db,
// This should be extremely rare (caused by an override transfer by the asset owner). // This should be extremely rare (caused by an override transfer by the asset owner).
// Reduce all pending payouts proportionally // Reduce all pending payouts proportionally
share_type total_pending_balances; share_type total_pending_balances;
auto pending_payouts_range = auto pending_payouts_range =
pending_payout_balance_index.indices().get<by_dividend_payout_account>().equal_range(boost::make_tuple(dividend_holder_asset_obj.id, payout_asset_type)); pending_payout_balance_index.indices().get<by_dividend_payout_account>().equal_range(boost::make_tuple(dividend_holder_asset_obj.id, payout_asset_type));
for (const pending_dividend_payout_balance_for_holder_object& pending_balance_object : boost::make_iterator_range(pending_payouts_range.first, pending_payouts_range.second)) for (const pending_dividend_payout_balance_for_holder_object& pending_balance_object : boost::make_iterator_range(pending_payouts_range.first, pending_payouts_range.second))
@ -1297,10 +1705,10 @@ void schedule_pending_dividend_balances(database& db,
} }
// iterate // iterate
if (previous_distribution_account_balance_iter == previous_distribution_account_balance_range.second || if (previous_distribution_account_balance_iter == previous_distribution_account_balance_range.second ||
current_distribution_account_balance_iter->second->asset_type < previous_distribution_account_balance_iter->dividend_payout_asset_type) current_distribution_account_balance_iter->second->asset_type < previous_distribution_account_balance_iter->dividend_payout_asset_type)
++current_distribution_account_balance_iter; ++current_distribution_account_balance_iter;
else if (current_distribution_account_balance_iter == current_distribution_account_balance_range.end() || else if (current_distribution_account_balance_iter == current_distribution_account_balance_range.end() ||
previous_distribution_account_balance_iter->dividend_payout_asset_type < current_distribution_account_balance_iter->second->asset_type) previous_distribution_account_balance_iter->dividend_payout_asset_type < current_distribution_account_balance_iter->second->asset_type)
++previous_distribution_account_balance_iter; ++previous_distribution_account_balance_iter;
else else
@ -1342,7 +1750,7 @@ void process_dividend_assets(database& db)
{ {
try try
{ {
dlog("Dividend payout time has arrived for asset ${holder_asset}", dlog("Dividend payout time has arrived for asset ${holder_asset}",
("holder_asset", dividend_holder_asset_obj.symbol)); ("holder_asset", dividend_holder_asset_obj.symbol));
#ifndef NDEBUG #ifndef NDEBUG
// dump balances before the payouts for debugging // dump balances before the payouts for debugging
@ -1354,14 +1762,14 @@ void process_dividend_assets(database& db)
// when we do the payouts, we first increase the balances in all of the receiving accounts // when we do the payouts, we first increase the balances in all of the receiving accounts
// and use this map to keep track of the total amount of each asset paid out. // and use this map to keep track of the total amount of each asset paid out.
// Afterwards, we decrease the distribution account's balance by the total amount paid out, // Afterwards, we decrease the distribution account's balance by the total amount paid out,
// and modify the distributed_balances accordingly // and modify the distributed_balances accordingly
std::map<asset_id_type, share_type> amounts_paid_out_by_asset; std::map<asset_id_type, share_type> amounts_paid_out_by_asset;
auto pending_payouts_range = auto pending_payouts_range =
pending_payout_balance_index.indices().get<by_dividend_account_payout>().equal_range(boost::make_tuple(dividend_holder_asset_obj.id)); pending_payout_balance_index.indices().get<by_dividend_account_payout>().equal_range(boost::make_tuple(dividend_holder_asset_obj.id));
// the pending_payouts_range is all payouts for this dividend asset, sorted by the holder's account // the pending_payouts_range is all payouts for this dividend asset, sorted by the holder's account
// we iterate in this order so we can build up a list of payouts for each account to put in the // we iterate in this order so we can build up a list of payouts for each account to put in the
// virtual op // virtual op
vector<asset> payouts_for_this_holder; vector<asset> payouts_for_this_holder;
fc::optional<account_id_type> last_holder_account_id; fc::optional<account_id_type> last_holder_account_id;
@ -1373,7 +1781,7 @@ void process_dividend_assets(database& db)
auto approved_assets_iter = approved_assets.find(asset_id); auto approved_assets_iter = approved_assets.find(asset_id);
if (approved_assets_iter != approved_assets.end()) if (approved_assets_iter != approved_assets.end())
return approved_assets_iter->second; return approved_assets_iter->second;
bool is_approved = is_authorized_asset(db, dividend_distribution_account_object, bool is_approved = is_authorized_asset(db, dividend_distribution_account_object,
asset_id(db)); asset_id(db));
approved_assets[asset_id] = is_approved; approved_assets[asset_id] = is_approved;
return is_approved; return is_approved;
@ -1386,8 +1794,8 @@ void process_dividend_assets(database& db)
if (last_holder_account_id && *last_holder_account_id != pending_balance_object.owner && payouts_for_this_holder.size()) if (last_holder_account_id && *last_holder_account_id != pending_balance_object.owner && payouts_for_this_holder.size())
{ {
// we've moved on to a new account, generate the dividend payment virtual op for the previous one // we've moved on to a new account, generate the dividend payment virtual op for the previous one
db.push_applied_operation(asset_dividend_distribution_operation(dividend_holder_asset_obj.id, db.push_applied_operation(asset_dividend_distribution_operation(dividend_holder_asset_obj.id,
*last_holder_account_id, *last_holder_account_id,
payouts_for_this_holder)); payouts_for_this_holder));
dlog("Just pushed virtual op for payout to ${account}", ("account", (*last_holder_account_id)(db).name)); dlog("Just pushed virtual op for payout to ${account}", ("account", (*last_holder_account_id)(db).name));
payouts_for_this_holder.clear(); payouts_for_this_holder.clear();
@ -1399,14 +1807,14 @@ void process_dividend_assets(database& db)
is_authorized_asset(db, pending_balance_object.owner(db), pending_balance_object.dividend_payout_asset_type(db)) && is_authorized_asset(db, pending_balance_object.owner(db), pending_balance_object.dividend_payout_asset_type(db)) &&
is_asset_approved_for_distribution_account(pending_balance_object.dividend_payout_asset_type)) is_asset_approved_for_distribution_account(pending_balance_object.dividend_payout_asset_type))
{ {
dlog("Processing payout of ${asset} to account ${account}", dlog("Processing payout of ${asset} to account ${account}",
("asset", asset(pending_balance_object.pending_balance, pending_balance_object.dividend_payout_asset_type)) ("asset", asset(pending_balance_object.pending_balance, pending_balance_object.dividend_payout_asset_type))
("account", pending_balance_object.owner(db).name)); ("account", pending_balance_object.owner(db).name));
db.adjust_balance(pending_balance_object.owner, db.adjust_balance(pending_balance_object.owner,
asset(pending_balance_object.pending_balance, asset(pending_balance_object.pending_balance,
pending_balance_object.dividend_payout_asset_type)); pending_balance_object.dividend_payout_asset_type));
payouts_for_this_holder.push_back(asset(pending_balance_object.pending_balance, payouts_for_this_holder.push_back(asset(pending_balance_object.pending_balance,
pending_balance_object.dividend_payout_asset_type)); pending_balance_object.dividend_payout_asset_type));
last_holder_account_id = pending_balance_object.owner; last_holder_account_id = pending_balance_object.owner;
amounts_paid_out_by_asset[pending_balance_object.dividend_payout_asset_type] += pending_balance_object.pending_balance; amounts_paid_out_by_asset[pending_balance_object.dividend_payout_asset_type] += pending_balance_object.pending_balance;
@ -1422,8 +1830,8 @@ void process_dividend_assets(database& db)
if (last_holder_account_id && payouts_for_this_holder.size()) if (last_holder_account_id && payouts_for_this_holder.size())
{ {
// we've moved on to a new account, generate the dividend payment virtual op for the previous one // we've moved on to a new account, generate the dividend payment virtual op for the previous one
db.push_applied_operation(asset_dividend_distribution_operation(dividend_holder_asset_obj.id, db.push_applied_operation(asset_dividend_distribution_operation(dividend_holder_asset_obj.id,
*last_holder_account_id, *last_holder_account_id,
payouts_for_this_holder)); payouts_for_this_holder));
dlog("Just pushed virtual op for payout to ${account}", ("account", (*last_holder_account_id)(db).name)); dlog("Just pushed virtual op for payout to ${account}", ("account", (*last_holder_account_id)(db).name));
} }
@ -1436,11 +1844,11 @@ void process_dividend_assets(database& db)
const asset_id_type& asset_paid_out = value.first; const asset_id_type& asset_paid_out = value.first;
const share_type& amount_paid_out = value.second; const share_type& amount_paid_out = value.second;
db.adjust_balance(dividend_data.dividend_distribution_account, db.adjust_balance(dividend_data.dividend_distribution_account,
asset(-amount_paid_out, asset(-amount_paid_out,
asset_paid_out)); asset_paid_out));
auto distributed_balance_iter = auto distributed_balance_iter =
distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().find(boost::make_tuple(dividend_holder_asset_obj.id, distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().find(boost::make_tuple(dividend_holder_asset_obj.id,
asset_paid_out)); asset_paid_out));
assert(distributed_balance_iter != distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().end()); assert(distributed_balance_iter != distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().end());
if (distributed_balance_iter != distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().end()) if (distributed_balance_iter != distributed_dividend_balance_index.indices().get<by_dividend_payout_asset>().end())
@ -1457,7 +1865,7 @@ void process_dividend_assets(database& db)
fc::optional<fc::time_point_sec> next_payout_time; fc::optional<fc::time_point_sec> next_payout_time;
if (dividend_data_obj.options.payout_interval) if (dividend_data_obj.options.payout_interval)
{ {
// if there was a previous payout, make our next payment one interval // if there was a previous payout, make our next payment one interval
uint32_t current_time_sec = current_head_block_time.sec_since_epoch(); uint32_t current_time_sec = current_head_block_time.sec_since_epoch();
fc::time_point_sec reference_time = *dividend_data_obj.last_scheduled_payout_time; fc::time_point_sec reference_time = *dividend_data_obj.last_scheduled_payout_time;
uint32_t next_possible_time_sec = dividend_data_obj.last_scheduled_payout_time->sec_since_epoch(); uint32_t next_possible_time_sec = dividend_data_obj.last_scheduled_payout_time->sec_since_epoch();
@ -1472,12 +1880,84 @@ void process_dividend_assets(database& db)
(dividend_data_obj.last_payout_time) (dividend_data_obj.last_payout_time)
(dividend_data_obj.options.next_payout_time)); (dividend_data_obj.options.next_payout_time));
}); });
} }
FC_RETHROW_EXCEPTIONS(error, "Error while paying out dividends for holder asset ${holder_asset}", ("holder_asset", dividend_holder_asset_obj.symbol)) FC_RETHROW_EXCEPTIONS(error, "Error while paying out dividends for holder asset ${holder_asset}", ("holder_asset", dividend_holder_asset_obj.symbol))
} }
} }
} FC_CAPTURE_AND_RETHROW() } } FC_CAPTURE_AND_RETHROW() }
void database::perform_son_tasks()
{
const global_property_object& gpo = get_global_properties();
if(gpo.parameters.son_account() == GRAPHENE_NULL_ACCOUNT && head_block_time() >= HARDFORK_SON_TIME)
{
const auto& son_account = create<account_object>([&](account_object& a) {
a.name = "son-account";
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 0;
a.registrar = a.lifetime_referrer = a.referrer = a.id;
a.membership_expiration_date = time_point_sec::maximum();
a.network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
a.lifetime_referrer_fee_percentage = GRAPHENE_100_PERCENT - GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
});
modify( gpo, [&son_account]( global_property_object& gpo ) {
gpo.parameters.extensions.value.son_account = son_account.get_id();
if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.son_account = son_account.get_id();
});
}
// create BTC asset here because son_account is the issuer of the BTC
if (gpo.parameters.btc_asset() == asset_id_type() && head_block_time() >= HARDFORK_SON_TIME)
{
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& btc_asset =
create<asset_object>( [&gpo, &dyn_asset]( asset_object& a ) {
a.symbol = "BTC";
a.precision = 8;
a.issuer = gpo.parameters.son_account();
a.options.max_supply = GRAPHENE_MAX_SHARE_SUPPLY;
a.options.market_fee_percent = 500; // 5%
a.options.issuer_permissions = UIA_ASSET_ISSUER_PERMISSION_MASK;
a.options.flags = asset_issuer_permission_flags::charge_market_fee |
//asset_issuer_permission_flags::white_list |
asset_issuer_permission_flags::override_authority |
asset_issuer_permission_flags::transfer_restricted |
asset_issuer_permission_flags::disable_confidential;
a.options.core_exchange_rate.base.amount = 100000;
a.options.core_exchange_rate.base.asset_id = asset_id_type(0);
a.options.core_exchange_rate.quote.amount = 2500; // CoinMarketCap approx value
a.options.core_exchange_rate.quote.asset_id = a.id;
a.options.whitelist_authorities.clear(); // accounts allowed to use asset, if not empty
a.options.blacklist_authorities.clear(); // accounts who can blacklist other accounts to use asset, if white_list flag is set
a.options.whitelist_markets.clear(); // might be traded with
a.options.blacklist_markets.clear(); // might not be traded with
a.dynamic_asset_data_id = dyn_asset.id;
});
modify( gpo, [&btc_asset]( global_property_object& gpo ) {
gpo.parameters.extensions.value.btc_asset = btc_asset.get_id();
if( gpo.pending_parameters )
gpo.pending_parameters->extensions.value.btc_asset = btc_asset.get_id();
});
}
// Pay the SONs
if (head_block_time() >= HARDFORK_SON_TIME)
{
// Before making a budget we should pay out SONs
// This function should check if its time to pay sons
// and modify the global son funds accordingly, whatever is left is passed on to next budget
pay_sons();
}
}
void database::perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props) void database::perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props)
{ try { { try {
const auto& gpo = get_global_properties(); const auto& gpo = get_global_properties();
@ -1500,6 +1980,7 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
d._vote_tally_buffer.resize(props.next_available_vote_id); d._vote_tally_buffer.resize(props.next_available_vote_id);
d._witness_count_histogram_buffer.resize(props.parameters.maximum_witness_count / 2 + 1); d._witness_count_histogram_buffer.resize(props.parameters.maximum_witness_count / 2 + 1);
d._committee_count_histogram_buffer.resize(props.parameters.maximum_committee_count / 2 + 1); d._committee_count_histogram_buffer.resize(props.parameters.maximum_committee_count / 2 + 1);
d._son_count_histogram_buffer.resize(props.parameters.maximum_son_count() / 2 + 1);
d._total_voting_stake = 0; d._total_voting_stake = 0;
auto balance_type = vesting_balance_type::normal; auto balance_type = vesting_balance_type::normal;
@ -1611,6 +2092,18 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
// same rationale as for witnesses // same rationale as for witnesses
d._committee_count_histogram_buffer[offset] += voting_stake; d._committee_count_histogram_buffer[offset] += voting_stake;
} }
if( opinion_account.options.num_son <= props.parameters.maximum_son_count() )
{
uint16_t offset = std::min(size_t(opinion_account.options.num_son/2),
d._son_count_histogram_buffer.size() - 1);
// votes for a number greater than maximum_son_count
// are turned into votes for maximum_son_count.
//
// in particular, this takes care of the case where a
// member was voting for a high number, then the
// parameter was lowered.
d._son_count_histogram_buffer[offset] += voting_stake;
}
d._total_voting_stake += voting_stake; d._total_voting_stake += voting_stake;
} }
@ -1626,11 +2119,14 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
}; };
clear_canary a(_witness_count_histogram_buffer), clear_canary a(_witness_count_histogram_buffer),
b(_committee_count_histogram_buffer), b(_committee_count_histogram_buffer),
d(_son_count_histogram_buffer),
c(_vote_tally_buffer); c(_vote_tally_buffer);
perform_son_tasks();
update_top_n_authorities(*this); update_top_n_authorities(*this);
update_active_witnesses(); update_active_witnesses();
update_active_committee_members(); update_active_committee_members();
update_active_sons();
update_worker_votes(); update_worker_votes();
const dynamic_global_property_object& dgpo = get_dynamic_global_properties(); const dynamic_global_property_object& dgpo = get_dynamic_global_properties();
@ -1660,6 +2156,38 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod; p.pending_parameters->extensions.value.gpos_subperiod = p.parameters.extensions.value.gpos_subperiod;
if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() ) if( !p.pending_parameters->extensions.value.gpos_vesting_lockin_period.valid() )
p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period; p.pending_parameters->extensions.value.gpos_vesting_lockin_period = p.parameters.extensions.value.gpos_vesting_lockin_period;
if( !p.pending_parameters->extensions.value.rbac_max_permissions_per_account.valid() )
p.pending_parameters->extensions.value.rbac_max_permissions_per_account = p.parameters.extensions.value.rbac_max_permissions_per_account;
if( !p.pending_parameters->extensions.value.rbac_max_account_authority_lifetime.valid() )
p.pending_parameters->extensions.value.rbac_max_account_authority_lifetime = p.parameters.extensions.value.rbac_max_account_authority_lifetime;
if( !p.pending_parameters->extensions.value.rbac_max_authorities_per_permission.valid() )
p.pending_parameters->extensions.value.rbac_max_authorities_per_permission = p.parameters.extensions.value.rbac_max_authorities_per_permission;
if( !p.pending_parameters->extensions.value.account_roles_max_per_account.valid() )
p.pending_parameters->extensions.value.account_roles_max_per_account = p.parameters.extensions.value.account_roles_max_per_account;
if( !p.pending_parameters->extensions.value.account_roles_max_lifetime.valid() )
p.pending_parameters->extensions.value.account_roles_max_lifetime = p.parameters.extensions.value.account_roles_max_lifetime;
if( !p.pending_parameters->extensions.value.son_vesting_amount.valid() )
p.pending_parameters->extensions.value.son_vesting_amount = p.parameters.extensions.value.son_vesting_amount;
if( !p.pending_parameters->extensions.value.son_vesting_period.valid() )
p.pending_parameters->extensions.value.son_vesting_period = p.parameters.extensions.value.son_vesting_period;
if( !p.pending_parameters->extensions.value.son_pay_max.valid() )
p.pending_parameters->extensions.value.son_pay_max = p.parameters.extensions.value.son_pay_max;
if( !p.pending_parameters->extensions.value.son_pay_time.valid() )
p.pending_parameters->extensions.value.son_pay_time = p.parameters.extensions.value.son_pay_time;
if( !p.pending_parameters->extensions.value.son_deregister_time.valid() )
p.pending_parameters->extensions.value.son_deregister_time = p.parameters.extensions.value.son_deregister_time;
if( !p.pending_parameters->extensions.value.son_heartbeat_frequency.valid() )
p.pending_parameters->extensions.value.son_heartbeat_frequency = p.parameters.extensions.value.son_heartbeat_frequency;
if( !p.pending_parameters->extensions.value.son_down_time.valid() )
p.pending_parameters->extensions.value.son_down_time = p.parameters.extensions.value.son_down_time;
if( !p.pending_parameters->extensions.value.son_bitcoin_min_tx_confirmations.valid() )
p.pending_parameters->extensions.value.son_bitcoin_min_tx_confirmations = p.parameters.extensions.value.son_bitcoin_min_tx_confirmations;
if( !p.pending_parameters->extensions.value.son_account.valid() )
p.pending_parameters->extensions.value.son_account = p.parameters.extensions.value.son_account;
if( !p.pending_parameters->extensions.value.btc_asset.valid() )
p.pending_parameters->extensions.value.btc_asset = p.parameters.extensions.value.btc_asset;
if( !p.pending_parameters->extensions.value.maximum_son_count.valid() )
p.pending_parameters->extensions.value.maximum_son_count = p.parameters.extensions.value.maximum_son_count;
p.parameters = std::move(*p.pending_parameters); p.parameters = std::move(*p.pending_parameters);
p.pending_parameters.reset(); p.pending_parameters.reset();
} }
@ -1707,7 +2235,11 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
//for( const asset_bitasset_data_object* d : get_index_type<asset_bitasset_data_index>() ) //for( const asset_bitasset_data_object* d : get_index_type<asset_bitasset_data_index>() )
for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() ) for( const auto& d : get_index_type<asset_bitasset_data_index>().indices() )
modify( d, [](asset_bitasset_data_object& o) { o.force_settled_volume = 0; }); modify( d, [](asset_bitasset_data_object& o) { o.force_settled_volume = 0; });
// Ideally we have to do this after every block but that leads to longer block applicaiton/replay times.
// So keep it here as it is not critical. valid_to check ensures
// these custom account auths and account roles are not usable.
clear_expired_custom_account_authorities(*this);
clear_expired_account_roles(*this);
// process_budget needs to run at the bottom because // process_budget needs to run at the bottom because
// it needs to know the next_maintenance_time // it needs to know the next_maintenance_time
process_budget(); process_budget();

View file

@ -40,6 +40,7 @@
#include <graphene/chain/vesting_balance_object.hpp> #include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/transaction_object.hpp> #include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/impacted.hpp> #include <graphene/chain/impacted.hpp>
#include <graphene/chain/hardfork.hpp>
using namespace fc; using namespace fc;
@ -49,8 +50,13 @@ using namespace graphene::chain;
struct get_impacted_account_visitor struct get_impacted_account_visitor
{ {
flat_set<account_id_type>& _impacted; flat_set<account_id_type>& _impacted;
get_impacted_account_visitor( flat_set<account_id_type>& impact ):_impacted(impact) {} bool _ignore_custom_op_reqd_auths;
typedef void result_type;
get_impacted_account_visitor( flat_set<account_id_type>& impact, bool ignore_custom_operation_required_auths )
: _impacted( impact ), _ignore_custom_op_reqd_auths( ignore_custom_operation_required_auths )
{}
using result_type = void;
void operator()( const transfer_operation& op ) void operator()( const transfer_operation& op )
{ {
@ -136,7 +142,7 @@ struct get_impacted_account_visitor
{ {
vector<authority> other; vector<authority> other;
for( const auto& proposed_op : op.proposed_ops ) for( const auto& proposed_op : op.proposed_ops )
operation_get_required_authorities( proposed_op.op, _impacted, _impacted, other ); operation_get_required_authorities( proposed_op.op, _impacted, _impacted, other, _ignore_custom_op_reqd_auths );
for( auto& o : other ) for( auto& o : other )
add_authority_accounts( _impacted, o ); add_authority_accounts( _impacted, o );
} }
@ -293,22 +299,136 @@ struct get_impacted_account_visitor
void operator()( const sweeps_vesting_claim_operation& op ) { void operator()( const sweeps_vesting_claim_operation& op ) {
_impacted.insert( op.account ); _impacted.insert( op.account );
} }
void operator()( const custom_permission_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_permission_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_permission_delete_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_delete_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const nft_metadata_create_operation& op ) {
_impacted.insert( op.owner );
}
void operator()( const nft_metadata_update_operation& op ) {
_impacted.insert( op.owner );
}
void operator()( const nft_mint_operation& op ) {
_impacted.insert( op.owner );
}
void operator()( const nft_safe_transfer_from_operation& op ) {
_impacted.insert( op.from );
_impacted.insert( op.to );
}
void operator()( const nft_approve_operation& op ) {
_impacted.insert( op.operator_ );
_impacted.insert( op.approved );
}
void operator()( const nft_set_approval_for_all_operation& op ) {
_impacted.insert( op.owner );
_impacted.insert( op.operator_ );
}
void operator()( const offer_operation& op ) {
_impacted.insert( op.issuer );
}
void operator()( const bid_operation& op ) {
_impacted.insert( op.bidder );
}
void operator()( const cancel_offer_operation& op ) {
_impacted.insert( op.issuer );
}
void operator()( const finalize_offer_operation& op ) {
_impacted.insert( op.fee_paying_account );
}
void operator()( const account_role_create_operation& op ){
_impacted.insert( op.owner );
}
void operator()( const account_role_update_operation& op ){
_impacted.insert( op.owner );
}
void operator()( const account_role_delete_operation& op ){
_impacted.insert( op.owner );
}
void operator()( const son_create_operation& op ) {
_impacted.insert( op.owner_account );
}
void operator()( const son_update_operation& op ) {
_impacted.insert( op.owner_account );
}
void operator()( const son_deregister_operation& op ) {
_impacted.insert( op.payer);
}
void operator()( const son_heartbeat_operation& op ) {
_impacted.insert( op.owner_account );
}
void operator()( const son_report_down_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_maintenance_operation& op ) {
_impacted.insert( op.owner_account );
}
void operator()( const son_wallet_recreate_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_wallet_update_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_wallet_deposit_create_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_wallet_deposit_process_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_wallet_withdraw_create_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const son_wallet_withdraw_process_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_address_add_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_address_update_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_address_delete_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_create_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_sign_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_send_operation& op ) {
_impacted.insert( op.payer );
}
void operator()( const sidechain_transaction_settle_operation& op ) {
_impacted.insert( op.payer );
}
}; };
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result ) void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result, bool ignore_custom_operation_required_auths ) {
{ get_impacted_account_visitor vtor = get_impacted_account_visitor( result, ignore_custom_operation_required_auths );
get_impacted_account_visitor vtor = get_impacted_account_visitor( result );
op.visit( vtor ); op.visit( vtor );
} }
void graphene::chain::transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result ) void graphene::chain::transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result, bool ignore_custom_operation_required_auths ) {
{
for( const auto& op : tx.operations ) for( const auto& op : tx.operations )
operation_get_impacted_accounts( op, result ); operation_get_impacted_accounts( op, result, ignore_custom_operation_required_auths );
} }
void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts ) void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts, bool ignore_custom_operation_required_auths ) {
{
if( obj->id.space() == protocol_ids ) if( obj->id.space() == protocol_ids )
{ {
switch( (object_type)obj->id.type() ) switch( (object_type)obj->id.type() )
@ -355,12 +475,14 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case proposal_object_type:{ } case proposal_object_type:{
const auto& aobj = dynamic_cast<const proposal_object*>(obj); const auto& aobj = dynamic_cast<const proposal_object*>(obj);
assert( aobj != nullptr ); assert( aobj != nullptr );
transaction_get_impacted_accounts( aobj->proposed_transaction, accounts ); transaction_get_impacted_accounts( aobj->proposed_transaction, accounts,
ignore_custom_operation_required_auths);
break; break;
} case operation_history_object_type:{ } case operation_history_object_type:{
const auto& aobj = dynamic_cast<const operation_history_object*>(obj); const auto& aobj = dynamic_cast<const operation_history_object*>(obj);
assert( aobj != nullptr ); assert( aobj != nullptr );
operation_get_impacted_accounts( aobj->op, accounts ); operation_get_impacted_accounts( aobj->op, accounts,
ignore_custom_operation_required_auths);
break; break;
} case withdraw_permission_object_type:{ } case withdraw_permission_object_type:{
const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj); const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj);
@ -381,6 +503,30 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case balance_object_type:{ } case balance_object_type:{
/** these are free from any accounts */ /** these are free from any accounts */
break; break;
} case account_role_type:{
const auto& aobj = dynamic_cast<const account_role_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->owner );
accounts.insert( aobj->whitelisted_accounts.begin(), aobj->whitelisted_accounts.end() );
break;
} case son_object_type:{
const auto& aobj = dynamic_cast<const son_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->son_account );
break;
} case son_wallet_object_type:{
break;
} case son_wallet_deposit_object_type:{
break;
} case son_wallet_withdraw_object_type:{
break;
} case sidechain_address_object_type:{
const auto& aobj = dynamic_cast<const sidechain_address_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->sidechain_address_account );
break;
} case sidechain_transaction_object_type:{
break;
} }
} }
} }
@ -411,7 +557,8 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case impl_transaction_object_type:{ } case impl_transaction_object_type:{
const auto& aobj = dynamic_cast<const transaction_object*>(obj); const auto& aobj = dynamic_cast<const transaction_object*>(obj);
assert( aobj != nullptr ); assert( aobj != nullptr );
transaction_get_impacted_accounts( aobj->trx, accounts ); transaction_get_impacted_accounts( aobj->trx, accounts,
ignore_custom_operation_required_auths);
break; break;
} case impl_blinded_balance_object_type:{ } case impl_blinded_balance_object_type:{
const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj); const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj);
@ -456,6 +603,7 @@ void database::notify_changed_objects()
if( _undo_db.enabled() ) if( _undo_db.enabled() )
{ {
const auto& head_undo = _undo_db.head(); const auto& head_undo = _undo_db.head();
auto chain_time = head_block_time();
// New // New
if( !new_objects.empty() ) if( !new_objects.empty() )
@ -467,7 +615,8 @@ void database::notify_changed_objects()
new_ids.push_back(item); new_ids.push_back(item);
auto obj = find_object(item); auto obj = find_object(item);
if(obj != nullptr) if(obj != nullptr)
get_relevant_accounts(obj, new_accounts_impacted); get_relevant_accounts(obj, new_accounts_impacted,
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
} }
GRAPHENE_TRY_NOTIFY( new_objects, new_ids, new_accounts_impacted) GRAPHENE_TRY_NOTIFY( new_objects, new_ids, new_accounts_impacted)
@ -481,7 +630,8 @@ void database::notify_changed_objects()
for( const auto& item : head_undo.old_values ) for( const auto& item : head_undo.old_values )
{ {
changed_ids.push_back(item.first); changed_ids.push_back(item.first);
get_relevant_accounts(item.second.get(), changed_accounts_impacted); get_relevant_accounts(item.second.get(), changed_accounts_impacted,
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
} }
GRAPHENE_TRY_NOTIFY( changed_objects, changed_ids, changed_accounts_impacted) GRAPHENE_TRY_NOTIFY( changed_objects, changed_ids, changed_accounts_impacted)
@ -498,7 +648,8 @@ void database::notify_changed_objects()
removed_ids.emplace_back( item.first ); removed_ids.emplace_back( item.first );
auto obj = item.second.get(); auto obj = item.second.get();
removed.emplace_back( obj ); removed.emplace_back( obj );
get_relevant_accounts(obj, removed_accounts_impacted); get_relevant_accounts(obj, removed_accounts_impacted,
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
} }
GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted) GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted)

View file

@ -225,6 +225,7 @@ void database::clear_expired_proposals()
elog("Failed to apply proposed transaction on its expiration. Deleting it.\n${proposal}\n${error}", elog("Failed to apply proposed transaction on its expiration. Deleting it.\n${proposal}\n${error}",
("proposal", proposal)("error", e.to_detail_string())); ("proposal", proposal)("error", e.to_detail_string()));
} }
remove_son_proposal(proposal);
remove(proposal); remove(proposal);
} }
} }
@ -705,4 +706,75 @@ void database::update_betting_markets(fc::time_point_sec current_block_time)
remove_completed_events(); remove_completed_events();
} }
void database::finalize_expired_offers(){
try {
detail::with_skip_flags( *this,
get_node_properties().skip_flags | skip_authority_check, [&](){
transaction_evaluation_state cancel_context(this);
//Cancel expired limit orders
auto& limit_index = get_index_type<offer_index>().indices().get<by_expiration_date>();
auto itr = limit_index.begin();
while( itr != limit_index.end() && itr->offer_expiration_date <= head_block_time() )
{
const offer_object& offer = *itr;
++itr;
finalize_offer_operation finalize;
finalize.fee_paying_account = offer.issuer;
finalize.offer_id = offer.id;
finalize.fee = asset( 0, asset_id_type() );
finalize.result = offer.bidder ? result_type::Expired : result_type::ExpiredNoBid;
cancel_context.skip_fee_schedule_check = true;
apply_operation(cancel_context, finalize);
}
});
} FC_CAPTURE_AND_RETHROW()}
void database::remove_son_proposal( const proposal_object& proposal )
{ try {
if( proposal.proposed_transaction.operations.size() == 1 &&
( proposal.proposed_transaction.operations.back().which() == operation::tag<son_deregister_operation>::value ||
proposal.proposed_transaction.operations.back().which() == operation::tag<son_report_down_operation>::value) )
{
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get<by_proposal>();
auto son_proposal_itr = son_proposal_idx.find( proposal.id );
if( son_proposal_itr == son_proposal_idx.end() ) {
return;
}
remove( *son_proposal_itr );
}
} FC_CAPTURE_AND_RETHROW( (proposal) ) }
void database::remove_inactive_son_down_proposals( const vector<son_id_type>& son_ids_to_remove )
{
const auto& son_proposal_idx = get_index_type<son_proposal_index>().indices().get< by_id >();
std::vector<proposal_id_type> proposals_to_remove;
for( auto& son_proposal : son_proposal_idx )
{
if(son_proposal.proposal_type == son_proposal_type::son_report_down_proposal)
{
auto it = std::find(son_ids_to_remove.begin(), son_ids_to_remove.end(), son_proposal.son_id);
if (it != son_ids_to_remove.end())
{
ilog( "Removing inactive proposal ${p} for son ${s}", ("p", son_proposal.proposal_id) ("s",son_proposal.son_id));
proposals_to_remove.push_back(son_proposal.proposal_id);
}
}
}
for( auto& proposal_id : proposals_to_remove )
{
const auto& proposal_obj = proposal_id(*this);
remove_son_proposal(proposal_obj);
remove(proposal_obj);
}
}
void database::remove_inactive_son_proposals( const vector<son_id_type>& son_ids_to_remove )
{
remove_inactive_son_down_proposals( son_ids_to_remove );
}
} } } }

View file

@ -26,6 +26,8 @@
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp> #include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_info.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -72,6 +74,47 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
return wid; return wid;
} }
son_id_type database::get_scheduled_son( uint32_t slot_num )const
{
son_id_type sid;
const global_property_object& gpo = get_global_properties();
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const son_schedule_object& sso = son_schedule_id_type()(*this);
uint64_t current_aslot = dpo.current_aslot + slot_num;
return sso.current_shuffled_sons[ current_aslot % sso.current_shuffled_sons.size() ];
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 )
{
const son_schedule_object& sso = son_schedule_id_type()(*this);
// ask the near scheduler who goes in the given slot
bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid);
if(! slot_is_near)
{
// if the near scheduler doesn't know, we have to extend it to
// a far scheduler.
// n.b. instantiating it is slow, but block gaps long enough to
// need it are likely pretty rare.
witness_scheduler_rng far_rng(sso.rng_seed.begin(), GRAPHENE_FAR_SCHEDULE_CTR_IV);
far_future_son_scheduler far_scheduler =
far_future_son_scheduler(sso.scheduler, far_rng);
if(!far_scheduler.get_slot(slot_num-1, sid))
{
// no scheduled son -- somebody set up us the bomb
// n.b. this code path is impossible, the present
// implementation of far_future_son_scheduler
// returns true unconditionally
assert( false );
}
}
}
return sid;
}
fc::time_point_sec database::get_slot_time(uint32_t slot_num)const fc::time_point_sec database::get_slot_time(uint32_t slot_num)const
{ {
if( slot_num == 0 ) if( slot_num == 0 )
@ -146,6 +189,41 @@ void database::update_witness_schedule()
} }
} }
void database::update_son_schedule()
{
const son_schedule_object& sso = son_schedule_id_type()(*this);
const global_property_object& gpo = get_global_properties();
if( head_block_num() % gpo.active_sons.size() == 0 )
{
modify( sso, [&]( son_schedule_object& _sso )
{
_sso.current_shuffled_sons.clear();
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
for( const son_info& w : gpo.active_sons )
_sso.current_shuffled_sons.push_back( w.son_id );
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i )
{
/// High performance random generator
/// http://xorshift.di.unimi.it/
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
k ^= (k >> 12);
k ^= (k << 25);
k ^= (k >> 27);
k *= 2685821657736338717ULL;
uint32_t jmax = _sso.current_shuffled_sons.size() - i;
uint32_t j = i + k%jmax;
std::swap( _sso.current_shuffled_sons[i],
_sso.current_shuffled_sons[j] );
}
});
}
}
vector<witness_id_type> database::get_near_witness_schedule()const vector<witness_id_type> database::get_near_witness_schedule()const
{ {
const witness_schedule_object& wso = get_witness_schedule_object(); const witness_schedule_object& wso = get_witness_schedule_object();
@ -226,6 +304,71 @@ void database::update_witness_schedule(const signed_block& next_block)
idump( ( double(total_time/1000000.0)/calls) ); idump( ( double(total_time/1000000.0)/calls) );
} }
void database::update_son_schedule(const signed_block& next_block)
{
auto start = fc::time_point::now();
const global_property_object& gpo = get_global_properties();
const son_schedule_object& sso = get(son_schedule_id_type());
uint32_t schedule_needs_filled = gpo.active_sons.size();
uint32_t schedule_slot = get_slot_at_time(next_block.timestamp);
// We shouldn't be able to generate _pending_block with timestamp
// in the past, and incoming blocks from the network with timestamp
// in the past shouldn't be able to make it this far without
// triggering FC_ASSERT elsewhere
assert( schedule_slot > 0 );
son_id_type first_son;
bool slot_is_near = sso.scheduler.get_slot( schedule_slot-1, first_son );
son_id_type son;
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
assert( dpo.random.data_size() == witness_scheduler_rng::seed_length );
assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() );
modify(sso, [&](son_schedule_object& _sso)
{
_sso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(sso.rng_seed.data, _sso.slots_since_genesis);
_sso.scheduler._min_token_count = std::max(int(gpo.active_sons.size()) / 2, 1);
if( slot_is_near )
{
uint32_t drain = schedule_slot;
while( drain > 0 )
{
if( _sso.scheduler.size() == 0 )
break;
_sso.scheduler.consume_schedule();
--drain;
}
}
else
{
_sso.scheduler.reset_schedule( first_son );
}
while( !_sso.scheduler.get_slot(schedule_needs_filled, son) )
{
if( _sso.scheduler.produce_schedule(rng) & emit_turn )
memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size());
}
_sso.last_scheduling_block = next_block.block_num();
_sso.recent_slots_filled = (
(_sso.recent_slots_filled << 1)
+ 1) << (schedule_slot - 1);
});
auto end = fc::time_point::now();
static uint64_t total_time = 0;
static uint64_t calls = 0;
total_time += (end - start).count();
if( ++calls % 1000 == 0 )
idump( ( double(total_time/1000000.0)/calls) );
}
uint32_t database::update_witness_missed_blocks( const signed_block& b ) uint32_t database::update_witness_missed_blocks( const signed_block& b )
{ {
uint32_t missed_blocks = get_slot_at_time( b.timestamp ); uint32_t missed_blocks = get_slot_at_time( b.timestamp );

View file

@ -24,7 +24,6 @@
#include <graphene/chain/fork_database.hpp> #include <graphene/chain/fork_database.hpp>
#include <graphene/chain/exceptions.hpp> #include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/smart_ref_impl.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
fork_database::fork_database() fork_database::fork_database()

View file

@ -25,7 +25,6 @@
#include <graphene/chain/genesis_state.hpp> #include <graphene/chain/genesis_state.hpp>
// these are required to serialize a genesis_state // these are required to serialize a genesis_state
#include <fc/smart_ref_impl.hpp> // required for gcc in release mode
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {

View file

@ -108,6 +108,11 @@ fc::variant_object get_config()
result[ "GRAPHENE_RELAXED_COMMITTEE_ACCOUNT" ] = fc::variant(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); result[ "GRAPHENE_RELAXED_COMMITTEE_ACCOUNT" ] = fc::variant(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_NULL_ACCOUNT" ] = fc::variant(GRAPHENE_NULL_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); result[ "GRAPHENE_NULL_ACCOUNT" ] = fc::variant(GRAPHENE_NULL_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_TEMP_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS); result[ "GRAPHENE_TEMP_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_PROXY_TO_SELF_ACCOUNT" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_RAKE_FEE_ACCOUNT_ID" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_NULL_WITNESS" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
result[ "GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE" ] = fc::variant(GRAPHENE_TEMP_ACCOUNT, GRAPHENE_MAX_NESTED_OBJECTS);
return result; return result;
} }

View file

@ -0,0 +1,6 @@
// #210 Check authorities on custom_operation
#ifndef HARDFORK_CORE_210_TIME
#define HARDFORK_CORE_210_TIME (fc::time_point_sec(1893456000)) // Jan 1 00:00:00 2030 (Not yet scheduled)
// Bugfix: pre-HF 210, custom_operation's required_auths field was ignored.
#define MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time) (chain_time <= HARDFORK_CORE_210_TIME)
#endif

View file

@ -0,0 +1,4 @@
// GPOS HARDFORK 2020-12-21 00:00:00 GMT
#ifndef HARDFORK_NFT_TIME
#define HARDFORK_NFT_TIME (fc::time_point_sec( 1608508800 ))
#endif

View file

@ -0,0 +1,4 @@
// GPOS HARDFORK 2020-12-21 00:00:00 GMT
#ifndef HARDFORK_SON_TIME
#define HARDFORK_SON_TIME (fc::time_point_sec( 1608508800 ))
#endif

View file

@ -0,0 +1,35 @@
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
class account_role_create_evaluator : public evaluator<account_role_create_evaluator>
{
public:
typedef account_role_create_operation operation_type;
void_result do_evaluate( const account_role_create_operation& o );
object_id_type do_apply( const account_role_create_operation& o );
};
class account_role_update_evaluator : public evaluator<account_role_update_evaluator>
{
public:
typedef account_role_update_operation operation_type;
void_result do_evaluate( const account_role_update_operation& o );
void_result do_apply( const account_role_update_operation& o );
};
class account_role_delete_evaluator : public evaluator<account_role_delete_evaluator>
{
public:
typedef account_role_delete_operation operation_type;
void_result do_evaluate( const account_role_delete_operation& o );
void_result do_apply( const account_role_delete_operation& o );
};
} } // graphene::chain

View file

@ -0,0 +1,49 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene
{
namespace chain
{
using namespace graphene::db;
class account_role_object : public abstract_object<account_role_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = account_role_type;
account_id_type owner;
std::string name;
std::string metadata;
flat_set<int> allowed_operations;
flat_set<account_id_type> whitelisted_accounts;
time_point_sec valid_to;
};
struct by_owner;
struct by_expiration;
using account_role_multi_index_type = multi_index_container<
account_role_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_non_unique< tag<by_owner>,
member<account_role_object, account_id_type, &account_role_object::owner>
>,
ordered_unique< tag<by_expiration>,
composite_key<account_role_object,
member<account_role_object, time_point_sec, &account_role_object::valid_to>,
member<object, object_id_type, &object::id>>
>
>
>;
using account_role_index = generic_index<account_role_object, account_role_multi_index_type>;
} // namespace chain
} // namespace graphene
FC_REFLECT_DERIVED(graphene::chain::account_role_object, (graphene::db::object),
(owner)(name)(metadata)(allowed_operations)(whitelisted_accounts)(valid_to))

View file

@ -45,9 +45,11 @@ struct budget_record
// sinks of budget, should sum up to total_budget // sinks of budget, should sum up to total_budget
share_type witness_budget = 0; share_type witness_budget = 0;
share_type worker_budget = 0; share_type worker_budget = 0;
share_type son_budget = 0;
// unused budget // unused budget
share_type leftover_worker_funds = 0; share_type leftover_worker_funds = 0;
share_type leftover_son_funds = 0;
// change in supply due to budget operations // change in supply due to budget operations
share_type supply_delta = 0; share_type supply_delta = 0;
@ -74,7 +76,9 @@ FC_REFLECT(graphene::chain::budget_record,
(total_budget) (total_budget)
(witness_budget) (witness_budget)
(worker_budget) (worker_budget)
(son_budget)
(leftover_worker_funds) (leftover_worker_funds)
(leftover_son_funds)
(supply_delta) (supply_delta)
) )

View file

@ -90,8 +90,10 @@
#define GRAPHENE_DEFAULT_MIN_WITNESS_COUNT (11) #define GRAPHENE_DEFAULT_MIN_WITNESS_COUNT (11)
#define GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT (11) #define GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT (11)
#define GRAPHENE_DEFAULT_MIN_SON_COUNT (5)
#define GRAPHENE_DEFAULT_MAX_WITNESSES (1001) // SHOULD BE ODD #define GRAPHENE_DEFAULT_MAX_WITNESSES (1001) // SHOULD BE ODD
#define GRAPHENE_DEFAULT_MAX_COMMITTEE (1001) // SHOULD BE ODD #define GRAPHENE_DEFAULT_MAX_COMMITTEE (1001) // SHOULD BE ODD
#define GRAPHENE_DEFAULT_MAX_SONS (15)
#define GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC (60*60*24*7*4) // Four weeks #define GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC (60*60*24*7*4) // Four weeks
#define GRAPHENE_DEFAULT_COMMITTEE_PROPOSAL_REVIEW_PERIOD_SEC (60*60*24*7*2) // Two weeks #define GRAPHENE_DEFAULT_COMMITTEE_PROPOSAL_REVIEW_PERIOD_SEC (60*60*24*7*2) // Two weeks
#define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT) #define GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT)
@ -227,6 +229,14 @@
#define TOURNAMENT_MAX_WHITELIST_LENGTH 1000 #define TOURNAMENT_MAX_WHITELIST_LENGTH 1000
#define TOURNAMENT_MAX_START_TIME_IN_FUTURE (60*60*24*7*4) // 1 month #define TOURNAMENT_MAX_START_TIME_IN_FUTURE (60*60*24*7*4) // 1 month
#define TOURNAMENT_MAX_START_DELAY (60*60*24*7) // 1 week #define TOURNAMENT_MAX_START_DELAY (60*60*24*7) // 1 week
#define SON_VESTING_AMOUNT (50*GRAPHENE_BLOCKCHAIN_PRECISION) // 50 PPY
#define SON_VESTING_PERIOD (60*60*24*2) // 2 days
#define SON_DEREGISTER_TIME (60*60*12) // 12 Hours in seconds
#define SON_HEARTBEAT_FREQUENCY (60*3) // 3 minutes in seconds
#define SON_DOWN_TIME (60*3*2) // 2 Heartbeats in seconds
#define SON_BITCOIN_MIN_TX_CONFIRMATIONS (1)
#define SON_PAY_TIME (60*60*24) // 1 day
#define SON_PAY_MAX (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(200))
#define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT) #define SWEEPS_DEFAULT_DISTRIBUTION_PERCENTAGE (2*GRAPHENE_1_PERCENT)
#define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0)) #define SWEEPS_DEFAULT_DISTRIBUTION_ASSET (graphene::chain::asset_id_type(0))
#define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000 #define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000
@ -234,3 +244,16 @@
#define GPOS_PERIOD (60*60*24*30*6) // 6 months #define GPOS_PERIOD (60*60*24*30*6) // 6 months
#define GPOS_SUBPERIOD (60*60*24*30) // 1 month #define GPOS_SUBPERIOD (60*60*24*30) // 1 month
#define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month #define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month
#define RBAC_MIN_PERMISSION_NAME_LENGTH 3
#define RBAC_MAX_PERMISSION_NAME_LENGTH 10
#define RBAC_MAX_PERMISSIONS_PER_ACCOUNT 5 // 5 per account
#define RBAC_MAX_ACCOUNT_AUTHORITY_LIFETIME 180*24*60*60 // 6 months
#define RBAC_MAX_AUTHS_PER_PERMISSION 15 // 15 ops linked per permission
#define NFT_TOKEN_MIN_LENGTH 3
#define NFT_TOKEN_MAX_LENGTH 15
#define NFT_URI_MAX_LENGTH GRAPHENE_MAX_URL_LENGTH
#define ACCOUNT_ROLES_MAX_PER_ACCOUNT 20 // Max 20 roles can be created by a resource owner
#define ACCOUNT_ROLES_MAX_LIFETIME 365*24*60*60 // 1 Year

View file

@ -0,0 +1,38 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
namespace graphene
{
namespace chain
{
class create_custom_account_authority_evaluator : public evaluator<create_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_create_operation operation_type;
void_result do_evaluate(const custom_account_authority_create_operation &o);
object_id_type do_apply(const custom_account_authority_create_operation &o);
};
class update_custom_account_authority_evaluator : public evaluator<update_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_update_operation operation_type;
void_result do_evaluate(const custom_account_authority_update_operation &o);
object_id_type do_apply(const custom_account_authority_update_operation &o);
};
class delete_custom_account_authority_evaluator : public evaluator<delete_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_delete_operation operation_type;
void_result do_evaluate(const custom_account_authority_delete_operation &o);
void_result do_apply(const custom_account_authority_delete_operation &o);
};
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,55 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class custom_account_authority_object
* @brief Tracks the mappings between permission and operation types.
* @ingroup object
*/
class custom_account_authority_object : public abstract_object<custom_account_authority_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = custom_account_authority_object_type;
custom_permission_id_type permission_id;
int operation_type;
time_point_sec valid_from;
time_point_sec valid_to;
};
struct by_id;
struct by_permission_and_op;
struct by_expiration;
using custom_account_authority_multi_index_type = multi_index_container<
custom_account_authority_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_permission_and_op>,
composite_key<custom_account_authority_object,
member<custom_account_authority_object, custom_permission_id_type, &custom_account_authority_object::permission_id>,
member<custom_account_authority_object, int, &custom_account_authority_object::operation_type>,
member<object, object_id_type, &object::id>
>
>,
ordered_unique<tag<by_expiration>,
composite_key<custom_account_authority_object,
member<custom_account_authority_object, time_point_sec, &custom_account_authority_object::valid_to>,
member<object, object_id_type, &object::id>
>
>
>
>;
using custom_account_authority_index = generic_index<custom_account_authority_object, custom_account_authority_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::custom_account_authority_object, (graphene::db::object),
(permission_id)(operation_type)(valid_from)(valid_to) )

View file

@ -0,0 +1,38 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_permission.hpp>
namespace graphene
{
namespace chain
{
class create_custom_permission_evaluator : public evaluator<create_custom_permission_evaluator>
{
public:
typedef custom_permission_create_operation operation_type;
void_result do_evaluate(const custom_permission_create_operation &o);
object_id_type do_apply(const custom_permission_create_operation &o);
};
class update_custom_permission_evaluator : public evaluator<update_custom_permission_evaluator>
{
public:
typedef custom_permission_update_operation operation_type;
void_result do_evaluate(const custom_permission_update_operation &o);
object_id_type do_apply(const custom_permission_update_operation &o);
};
class delete_custom_permission_evaluator : public evaluator<delete_custom_permission_evaluator>
{
public:
typedef custom_permission_delete_operation operation_type;
void_result do_evaluate(const custom_permission_delete_operation &o);
void_result do_apply(const custom_permission_delete_operation &o);
};
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,49 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class custom_permission_object
* @brief Tracks all the custom permission of an account.
* @ingroup object
*/
class custom_permission_object : public abstract_object<custom_permission_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = custom_permission_object_type;
// Account for which this permission is being created
account_id_type account;
// Permission name
string permission_name;
// Authority required for this permission
authority auth;
};
struct by_id;
struct by_account_and_permission;
using custom_permission_multi_index_type = multi_index_container<
custom_permission_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_account_and_permission>,
composite_key<custom_permission_object,
member<custom_permission_object, account_id_type, &custom_permission_object::account>,
member<custom_permission_object, string, &custom_permission_object::permission_name>
>
>
>
>;
using custom_permission_index = generic_index<custom_permission_object, custom_permission_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::custom_permission_object, (graphene::db::object),
(account)(permission_name)(auth) )

View file

@ -40,6 +40,8 @@
#include <graphene/chain/protocol/protocol.hpp> #include <graphene/chain/protocol/protocol.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <fc/log/logger.hpp> #include <fc/log/logger.hpp>
#include <map> #include <map>
@ -139,6 +141,8 @@ namespace graphene { namespace chain {
const flat_map<uint32_t,block_id_type> get_checkpoints()const { return _checkpoints; } const flat_map<uint32_t,block_id_type> get_checkpoints()const { return _checkpoints; }
bool before_last_checkpoint()const; bool before_last_checkpoint()const;
void check_transaction_for_duplicated_operations(const signed_transaction& trx);
bool push_block( const signed_block& b, uint32_t skip = skip_nothing ); bool push_block( const signed_block& b, uint32_t skip = skip_nothing );
processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing ); processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
bool _push_block( const signed_block& b ); bool _push_block( const signed_block& b );
@ -238,6 +242,22 @@ namespace graphene { namespace chain {
*/ */
witness_id_type get_scheduled_witness(uint32_t slot_num)const; witness_id_type get_scheduled_witness(uint32_t slot_num)const;
/**
* @brief Get the son scheduled for block production in a slot.
*
* slot_num always corresponds to a time in the future.
*
* If slot_num == 1, returns the next scheduled son.
* If slot_num == 2, returns the next scheduled son after
* 1 block gap.
*
* Use the get_slot_time() and get_slot_at_time() functions
* to convert between slot_num and timestamp.
*
* Passing slot_num == 0 returns GRAPHENE_NULL_WITNESS
*/
son_id_type get_scheduled_son(uint32_t slot_num)const;
/** /**
* Get the time at which the given slot occurs. * Get the time at which the given slot occurs.
* *
@ -261,6 +281,8 @@ namespace graphene { namespace chain {
vector<witness_id_type> get_near_witness_schedule()const; vector<witness_id_type> get_near_witness_schedule()const;
void update_witness_schedule(); void update_witness_schedule();
void update_witness_schedule(const signed_block& next_block); void update_witness_schedule(const signed_block& next_block);
void update_son_schedule();
void update_son_schedule(const signed_block& next_block);
void check_lottery_end_by_participants( asset_id_type asset_id ); void check_lottery_end_by_participants( asset_id_type asset_id );
void check_ending_lotteries(); void check_ending_lotteries();
@ -280,6 +302,15 @@ namespace graphene { namespace chain {
std::vector<uint32_t> get_seeds( asset_id_type for_asset, uint8_t count_winners )const; std::vector<uint32_t> get_seeds( asset_id_type for_asset, uint8_t count_winners )const;
uint64_t get_random_bits( uint64_t bound ); uint64_t get_random_bits( uint64_t bound );
const witness_schedule_object& get_witness_schedule_object()const; const witness_schedule_object& get_witness_schedule_object()const;
bool item_locked(const nft_id_type& item)const;
bool account_role_valid(const account_role_object& aro, account_id_type account, optional<int> op_type = optional<int>()) const;
std::set<son_id_type> get_sons_being_deregistered();
std::set<son_id_type> get_sons_being_reported_down();
std::set<son_id_type> get_sons_to_be_deregistered();
fc::optional<operation> create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son );
signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op );
bool is_son_dereg_valid( son_id_type son_id );
bool is_son_active( son_id_type son_id );
time_point_sec head_block_time()const; time_point_sec head_block_time()const;
uint32_t head_block_num()const; uint32_t head_block_num()const;
@ -292,6 +323,7 @@ namespace graphene { namespace chain {
uint32_t last_non_undoable_block_num() const; uint32_t last_non_undoable_block_num() const;
vector<authority> get_account_custom_authorities(account_id_type account, const operation& op)const;
//////////////////// db_init.cpp //////////////////// //////////////////// db_init.cpp ////////////////////
void initialize_evaluators(); void initialize_evaluators();
@ -517,6 +549,7 @@ namespace graphene { namespace chain {
void update_betting_markets(fc::time_point_sec current_block_time); void update_betting_markets(fc::time_point_sec current_block_time);
bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true, bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true,
const asset_bitasset_data_object* bitasset_ptr = nullptr ); const asset_bitasset_data_object* bitasset_ptr = nullptr );
void finalize_expired_offers();
///Steps performed only at maintenance intervals ///Steps performed only at maintenance intervals
///@{ ///@{
@ -526,9 +559,18 @@ namespace graphene { namespace chain {
void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const; void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const;
void process_budget(); void process_budget();
void pay_workers( share_type& budget ); void pay_workers( share_type& budget );
void pay_sons();
void perform_son_tasks();
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props); void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
void update_active_witnesses(); void update_active_witnesses();
void update_active_committee_members(); void update_active_committee_members();
void update_son_metrics( const vector<son_info>& curr_active_sons );
void update_active_sons();
void remove_son_proposal( const proposal_object& proposal );
void remove_inactive_son_down_proposals( const vector<son_id_type>& son_ids_to_remove );
void remove_inactive_son_proposals( const vector<son_id_type>& son_ids_to_remove );
void update_son_statuses( const vector<son_info>& cur_active_sons, const vector<son_info>& new_active_sons );
void update_son_wallet( const vector<son_info>& new_active_sons );
void update_worker_votes(); void update_worker_votes();
public: public:
@ -570,6 +612,7 @@ namespace graphene { namespace chain {
vector<uint64_t> _vote_tally_buffer; vector<uint64_t> _vote_tally_buffer;
vector<uint64_t> _witness_count_histogram_buffer; vector<uint64_t> _witness_count_histogram_buffer;
vector<uint64_t> _committee_count_histogram_buffer; vector<uint64_t> _committee_count_histogram_buffer;
vector<uint64_t> _son_count_histogram_buffer;
uint64_t _total_voting_stake; uint64_t _total_voting_stake;
flat_map<uint32_t,block_id_type> _checkpoints; flat_map<uint32_t,block_id_type> _checkpoints;

View file

@ -27,6 +27,7 @@
#include <graphene/chain/protocol/chain_parameters.hpp> #include <graphene/chain/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/son_info.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -51,6 +52,7 @@ namespace graphene { namespace chain {
uint32_t next_available_vote_id = 0; uint32_t next_available_vote_id = 0;
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
vector<son_info> active_sons; // updated once per maintenance interval
// n.b. witness scheduling is done by witness_schedule object // n.b. witness scheduling is done by witness_schedule object
}; };
@ -77,6 +79,9 @@ namespace graphene { namespace chain {
time_point_sec next_maintenance_time; time_point_sec next_maintenance_time;
time_point_sec last_budget_time; time_point_sec last_budget_time;
share_type witness_budget; share_type witness_budget;
//Last SON Payout time, it can be different to the maintenance interval time
time_point_sec last_son_payout_time = HARDFORK_SON_TIME;
share_type son_budget = 0;
uint32_t accounts_registered_this_interval = 0; uint32_t accounts_registered_this_interval = 0;
/** /**
* Every time a block is missed this increases by * Every time a block is missed this increases by
@ -133,6 +138,8 @@ FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::
(next_maintenance_time) (next_maintenance_time)
(last_budget_time) (last_budget_time)
(witness_budget) (witness_budget)
(last_son_payout_time)
(son_budget)
(accounts_registered_this_interval) (accounts_registered_this_interval)
(recently_missed_count) (recently_missed_count)
(current_aslot) (current_aslot)
@ -147,6 +154,7 @@ FC_REFLECT_DERIVED( graphene::chain::global_property_object, (graphene::db::obje
(next_available_vote_id) (next_available_vote_id)
(active_committee_members) (active_committee_members)
(active_witnesses) (active_witnesses)
(active_sons)
) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::dynamic_global_property_object ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::dynamic_global_property_object )

View file

@ -32,6 +32,7 @@ struct immutable_chain_parameters
{ {
uint16_t min_committee_member_count = GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT; uint16_t min_committee_member_count = GRAPHENE_DEFAULT_MIN_COMMITTEE_MEMBER_COUNT;
uint16_t min_witness_count = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT; uint16_t min_witness_count = GRAPHENE_DEFAULT_MIN_WITNESS_COUNT;
uint16_t min_son_count = GRAPHENE_DEFAULT_MIN_SON_COUNT;
uint32_t num_special_accounts = 0; uint32_t num_special_accounts = 0;
uint32_t num_special_assets = 0; uint32_t num_special_assets = 0;
}; };
@ -41,6 +42,7 @@ struct immutable_chain_parameters
FC_REFLECT( graphene::chain::immutable_chain_parameters, FC_REFLECT( graphene::chain::immutable_chain_parameters,
(min_committee_member_count) (min_committee_member_count)
(min_witness_count) (min_witness_count)
(min_son_count)
(num_special_accounts) (num_special_accounts)
(num_special_assets) (num_special_assets)
) )

View file

@ -30,13 +30,12 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
void operation_get_impacted_accounts( void operation_get_impacted_accounts( const graphene::chain::operation& op,
const graphene::chain::operation& op, fc::flat_set<graphene::chain::account_id_type>& result,
fc::flat_set<graphene::chain::account_id_type>& result ); bool ignore_custom_operation_required_auths );
void transaction_get_impacted_accounts( void transaction_get_impacted_accounts( const graphene::chain::transaction& tx,
const graphene::chain::transaction& tx, fc::flat_set<graphene::chain::account_id_type>& result,
fc::flat_set<graphene::chain::account_id_type>& result bool ignore_custom_operation_required_auths );
);
} } // graphene::app } } // graphene::app

View file

@ -0,0 +1,59 @@
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
class nft_metadata_create_evaluator : public evaluator<nft_metadata_create_evaluator>
{
public:
typedef nft_metadata_create_operation operation_type;
void_result do_evaluate( const nft_metadata_create_operation& o );
object_id_type do_apply( const nft_metadata_create_operation& o );
};
class nft_metadata_update_evaluator : public evaluator<nft_metadata_update_evaluator>
{
public:
typedef nft_metadata_update_operation operation_type;
void_result do_evaluate( const nft_metadata_update_operation& o );
void_result do_apply( const nft_metadata_update_operation& o );
};
class nft_mint_evaluator : public evaluator<nft_mint_evaluator>
{
public:
typedef nft_mint_operation operation_type;
void_result do_evaluate( const nft_mint_operation& o );
object_id_type do_apply( const nft_mint_operation& o );
};
class nft_safe_transfer_from_evaluator : public evaluator<nft_safe_transfer_from_evaluator>
{
public:
typedef nft_safe_transfer_from_operation operation_type;
void_result do_evaluate( const nft_safe_transfer_from_operation& o );
object_id_type do_apply( const nft_safe_transfer_from_operation& o );
};
class nft_approve_evaluator : public evaluator<nft_approve_evaluator>
{
public:
typedef nft_approve_operation operation_type;
void_result do_evaluate( const nft_approve_operation& o );
object_id_type do_apply( const nft_approve_operation& o );
};
class nft_set_approval_for_all_evaluator : public evaluator<nft_set_approval_for_all_evaluator>
{
public:
typedef nft_set_approval_for_all_operation operation_type;
void_result do_evaluate( const nft_set_approval_for_all_operation& o );
void_result do_apply( const nft_set_approval_for_all_operation& o );
};
} } // graphene::chain

View file

@ -0,0 +1,108 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
class nft_metadata_object : public abstract_object<nft_metadata_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = nft_metadata_type;
account_id_type owner;
std::string name;
std::string symbol;
std::string base_uri;
optional<account_id_type> revenue_partner;
optional<uint16_t> revenue_split;
bool is_transferable = false;
bool is_sellable = true;
optional<account_role_id_type> account_role;
};
class nft_object : public abstract_object<nft_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = nft_object_type;
nft_metadata_id_type nft_metadata_id;
account_id_type owner;
account_id_type approved;
vector<account_id_type> approved_operators;
std::string token_uri;
};
struct by_name;
struct by_symbol;
using nft_metadata_multi_index_type = multi_index_container<
nft_metadata_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_name>,
member<nft_metadata_object, std::string, &nft_metadata_object::name>
>,
ordered_unique< tag<by_symbol>,
member<nft_metadata_object, std::string, &nft_metadata_object::symbol>
>
>
>;
using nft_metadata_index = generic_index<nft_metadata_object, nft_metadata_multi_index_type>;
struct by_metadata;
struct by_metadata_and_owner;
struct by_owner;
struct by_owner_and_id;
using nft_multi_index_type = multi_index_container<
nft_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_non_unique< tag<by_metadata>,
member<nft_object, nft_metadata_id_type, &nft_object::nft_metadata_id>
>,
ordered_non_unique< tag<by_metadata_and_owner>,
composite_key<nft_object,
member<nft_object, nft_metadata_id_type, &nft_object::nft_metadata_id>,
member<nft_object, account_id_type, &nft_object::owner>
>
>,
ordered_non_unique< tag<by_owner>,
member<nft_object, account_id_type, &nft_object::owner>
>,
ordered_unique< tag<by_owner_and_id>,
composite_key<nft_object,
member<nft_object, account_id_type, &nft_object::owner>,
member<object, object_id_type, &object::id>
>
>
>
>;
using nft_index = generic_index<nft_object, nft_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::nft_metadata_object, (graphene::db::object),
(owner)
(name)
(symbol)
(base_uri)
(revenue_partner)
(revenue_split)
(is_transferable)
(is_sellable)
(account_role) )
FC_REFLECT_DERIVED( graphene::chain::nft_object, (graphene::db::object),
(nft_metadata_id)
(owner)
(approved)
(approved_operators)
(token_uri) )

View file

@ -0,0 +1,47 @@
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene
{
namespace chain
{
class offer_evaluator : public evaluator<offer_evaluator>
{
public:
typedef offer_operation operation_type;
void_result do_evaluate(const offer_operation &o);
object_id_type do_apply(const offer_operation &o);
};
class bid_evaluator : public evaluator<bid_evaluator>
{
public:
typedef bid_operation operation_type;
void_result do_evaluate(const bid_operation &o);
void_result do_apply(const bid_operation &o);
};
class cancel_offer_evaluator : public evaluator<cancel_offer_evaluator>
{
public:
typedef cancel_offer_operation operation_type;
void_result do_evaluate(const cancel_offer_operation &o);
void_result do_apply(const cancel_offer_operation &o);
};
class finalize_offer_evaluator : public evaluator<finalize_offer_evaluator>
{
public:
typedef finalize_offer_operation operation_type;
void_result do_evaluate(const finalize_offer_operation &op);
void_result do_apply(const finalize_offer_operation &op);
};
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,109 @@
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene
{
namespace chain
{
class database;
struct by_expiration_date
{
};
class offer_object : public graphene::db::abstract_object<offer_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = offer_object_type;
account_id_type issuer;
set<nft_id_type> item_ids;
optional<account_id_type> bidder;
optional<asset> bid_price;
asset minimum_price;
asset maximum_price;
bool buying_item;
fc::time_point_sec offer_expiration_date;
offer_id_type get_id() const { return id; }
};
class offer_history_object
: public graphene::db::abstract_object<offer_history_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_offer_history_object_type;
account_id_type issuer;
set<nft_id_type> item_ids;
optional<account_id_type> bidder;
optional<asset> bid_price;
asset minimum_price;
asset maximum_price;
bool buying_item;
fc::time_point_sec offer_expiration_date;
result_type result;
offer_history_id_type get_id() const { return id; }
};
class offer_item_index : public secondary_index
{
public:
virtual void object_inserted(const object &obj) override;
virtual void object_removed(const object &obj) override;
virtual void about_to_modify(const object &before) override{};
virtual void object_modified(const object &after) override;
set<nft_id_type> _locked_items;
};
struct compare_by_expiration_date
{
bool operator()(const fc::time_point_sec &o1,
const fc::time_point_sec &o2) const
{
return o1 < o2;
}
};
using offer_multi_index_type = multi_index_container<
offer_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id>>,
ordered_non_unique<tag<by_expiration_date>,
member<offer_object, fc::time_point_sec,
&offer_object::offer_expiration_date>,
compare_by_expiration_date>>>;
using offer_history_multi_index_type = multi_index_container<
offer_history_object,
indexed_by<
ordered_unique<tag<by_id>, member<object, object_id_type, &object::id>>,
ordered_non_unique<tag<by_expiration_date>,
member<offer_history_object, fc::time_point_sec,
&offer_history_object::offer_expiration_date>,
compare_by_expiration_date>>>;
using offer_index = generic_index<offer_object, offer_multi_index_type>;
using offer_history_index =
generic_index<offer_history_object, offer_history_multi_index_type>;
} // namespace chain
} // namespace graphene
FC_REFLECT_DERIVED(graphene::chain::offer_object, (graphene::db::object),
(issuer)(item_ids)(bidder)(bid_price)(minimum_price)(
maximum_price)(buying_item)(offer_expiration_date))
FC_REFLECT_DERIVED(graphene::chain::offer_history_object,
(graphene::db::object),
(issuer)(item_ids)(bidder)(bid_price)(minimum_price)(
maximum_price)(buying_item)(offer_expiration_date)(result))

View file

@ -30,6 +30,22 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
class son_hardfork_visitor
{
public:
typedef void result_type;
database& db;
proposal_id_type prop_id;
son_hardfork_visitor( database& _db, const proposal_id_type& _prop_id ) : db( _db ), prop_id( _prop_id ) {}
template<typename T>
void operator()( const T &v ) const {}
void operator()( const son_deregister_operation &v );
void operator()( const son_report_down_operation &v );
};
class proposal_create_evaluator : public evaluator<proposal_create_evaluator> class proposal_create_evaluator : public evaluator<proposal_create_evaluator>
{ {
public: public:

View file

@ -52,6 +52,9 @@ namespace graphene { namespace chain {
/// The number of active committee members this account votes the blockchain should appoint /// The number of active committee members this account votes the blockchain should appoint
/// Must not exceed the actual number of committee members voted for in @ref votes /// Must not exceed the actual number of committee members voted for in @ref votes
uint16_t num_committee = 0; uint16_t num_committee = 0;
/// The number of active son members this account votes the blockchain should appoint
/// Must not exceed the actual number of son members voted for in @ref votes
uint16_t num_son = 0;
/// This is the list of vote IDs this account votes for. The weight of these votes is determined by this /// This is the list of vote IDs this account votes for. The weight of these votes is determined by this
/// account's balance of core asset. /// account's balance of core asset.
flat_set<vote_id_type> votes; flat_set<vote_id_type> votes;

View file

@ -0,0 +1,82 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene
{
namespace chain
{
struct account_role_create_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner;
std::string name;
std::string metadata;
flat_set<int> allowed_operations;
flat_set<account_id_type> whitelisted_accounts;
time_point_sec valid_to;
extensions_type extensions;
account_id_type fee_payer() const { return owner; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct account_role_update_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner;
account_role_id_type account_role_id;
optional<std::string> name;
optional<std::string> metadata;
flat_set<int> allowed_operations_to_add;
flat_set<int> allowed_operations_to_remove;
flat_set<account_id_type> accounts_to_add;
flat_set<account_id_type> accounts_to_remove;
optional<time_point_sec> valid_to;
extensions_type extensions;
account_id_type fee_payer() const { return owner; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct account_role_delete_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner;
account_role_id_type account_role_id;
extensions_type extensions;
account_id_type fee_payer() const { return owner; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
} // namespace chain
} // namespace graphene
FC_REFLECT(graphene::chain::account_role_create_operation::fee_parameters_type, (fee)(price_per_kbyte))
FC_REFLECT(graphene::chain::account_role_update_operation::fee_parameters_type, (fee)(price_per_kbyte))
FC_REFLECT(graphene::chain::account_role_delete_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::account_role_create_operation, (fee)(owner)(name)(metadata)(allowed_operations)(whitelisted_accounts)(valid_to)(extensions))
FC_REFLECT(graphene::chain::account_role_update_operation, (fee)(owner)(account_role_id)(name)(metadata)(allowed_operations_to_add)(allowed_operations_to_remove)(accounts_to_add)(accounts_to_remove)(valid_to)(extensions))
FC_REFLECT(graphene::chain::account_role_delete_operation, (fee)(owner)(account_role_id)(owner)(extensions))

View file

@ -22,11 +22,12 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <memory>
#include <graphene/chain/protocol/base.hpp> #include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/ext.hpp> #include <graphene/chain/protocol/ext.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/protocol/types.hpp>
#include <fc/smart_ref_fwd.hpp>
#include <graphene/chain/hardfork.hpp>
#include <../hardfork.d/GPOS.hf> #include <../hardfork.d/GPOS.hf>
#include <memory> #include <memory>
@ -48,12 +49,36 @@ namespace graphene { namespace chain {
optional < uint32_t > gpos_subperiod = GPOS_SUBPERIOD; optional < uint32_t > gpos_subperiod = GPOS_SUBPERIOD;
optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch(); optional < uint32_t > gpos_period_start = HARDFORK_GPOS_TIME.sec_since_epoch();
optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD; optional < uint32_t > gpos_vesting_lockin_period = GPOS_VESTING_LOCKIN_PERIOD;
/* rbac parameters */
optional < uint16_t > rbac_max_permissions_per_account = RBAC_MAX_PERMISSIONS_PER_ACCOUNT;
optional < uint32_t > rbac_max_account_authority_lifetime = RBAC_MAX_ACCOUNT_AUTHORITY_LIFETIME;
optional < uint16_t > rbac_max_authorities_per_permission = RBAC_MAX_AUTHS_PER_PERMISSION;
/* Account Roles - Permissions Parameters */
optional < uint16_t > account_roles_max_per_account = ACCOUNT_ROLES_MAX_PER_ACCOUNT;
optional < uint32_t > account_roles_max_lifetime = ACCOUNT_ROLES_MAX_LIFETIME;
optional < uint32_t > son_vesting_amount = SON_VESTING_AMOUNT;
optional < uint32_t > son_vesting_period = SON_VESTING_PERIOD;
optional < uint64_t > son_pay_max = SON_PAY_MAX;
optional < uint32_t > son_pay_time = SON_PAY_TIME;
optional < uint32_t > son_deregister_time = SON_DEREGISTER_TIME;
optional < uint32_t > son_heartbeat_frequency = SON_HEARTBEAT_FREQUENCY;
optional < uint32_t > son_down_time = SON_DOWN_TIME;
optional < uint16_t > son_bitcoin_min_tx_confirmations = SON_BITCOIN_MIN_TX_CONFIRMATIONS;
optional < account_id_type > son_account = GRAPHENE_NULL_ACCOUNT;
optional < asset_id_type > btc_asset = asset_id_type();
optional < uint16_t > maximum_son_count = GRAPHENE_DEFAULT_MAX_SONS; ///< maximum number of active SONS
}; };
struct chain_parameters struct chain_parameters
{ {
chain_parameters();
chain_parameters(const chain_parameters& other);
chain_parameters(chain_parameters&& other);
chain_parameters& operator=(const chain_parameters& other);
chain_parameters& operator=(chain_parameters&& other);
/** using a smart ref breaks the circular dependency created between operations and the fee schedule */ /** using a smart ref breaks the circular dependency created between operations and the fee schedule */
smart_ref<fee_schedule> current_fees; ///< current schedule of fees std::shared_ptr<fee_schedule> current_fees; ///< current schedule of fees
uint8_t block_interval = GRAPHENE_DEFAULT_BLOCK_INTERVAL; ///< interval in seconds between blocks uint8_t block_interval = GRAPHENE_DEFAULT_BLOCK_INTERVAL; ///< interval in seconds between blocks
uint32_t maintenance_interval = GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL; ///< interval in sections between blockchain maintenance events uint32_t maintenance_interval = GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL; ///< interval in sections between blockchain maintenance events
uint8_t maintenance_skip_slots = GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS; ///< number of block_intervals to skip at maintenance time uint8_t maintenance_skip_slots = GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS; ///< number of block_intervals to skip at maintenance time
@ -97,7 +122,7 @@ namespace graphene { namespace chain {
uint32_t maximum_tournament_start_time_in_future = TOURNAMENT_MAX_START_TIME_IN_FUTURE; uint32_t maximum_tournament_start_time_in_future = TOURNAMENT_MAX_START_TIME_IN_FUTURE;
uint32_t maximum_tournament_start_delay = TOURNAMENT_MAX_START_DELAY; uint32_t maximum_tournament_start_delay = TOURNAMENT_MAX_START_DELAY;
uint16_t maximum_tournament_number_of_wins = TOURNAMENT_MAX_NUMBER_OF_WINS; uint16_t maximum_tournament_number_of_wins = TOURNAMENT_MAX_NUMBER_OF_WINS;
extension<parameter_extension> extensions; extension<parameter_extension> extensions;
/** defined in fee_schedule.cpp */ /** defined in fee_schedule.cpp */
@ -138,7 +163,57 @@ namespace graphene { namespace chain {
} }
inline uint32_t gpos_vesting_lockin_period()const { inline uint32_t gpos_vesting_lockin_period()const {
return extensions.value.gpos_vesting_lockin_period.valid() ? *extensions.value.gpos_vesting_lockin_period : GPOS_VESTING_LOCKIN_PERIOD; /// GPOS vesting lockin period return extensions.value.gpos_vesting_lockin_period.valid() ? *extensions.value.gpos_vesting_lockin_period : GPOS_VESTING_LOCKIN_PERIOD; /// GPOS vesting lockin period
} }
inline uint16_t rbac_max_permissions_per_account()const {
return extensions.value.rbac_max_permissions_per_account.valid() ? *extensions.value.rbac_max_permissions_per_account : RBAC_MAX_PERMISSIONS_PER_ACCOUNT;
}
inline uint32_t rbac_max_account_authority_lifetime()const {
return extensions.value.rbac_max_account_authority_lifetime.valid() ? *extensions.value.rbac_max_account_authority_lifetime : RBAC_MAX_ACCOUNT_AUTHORITY_LIFETIME;
}
inline uint16_t rbac_max_authorities_per_permission()const {
return extensions.value.rbac_max_authorities_per_permission.valid() ? *extensions.value.rbac_max_authorities_per_permission : RBAC_MAX_AUTHS_PER_PERMISSION;
}
inline uint16_t account_roles_max_per_account()const {
return extensions.value.account_roles_max_per_account.valid() ? *extensions.value.account_roles_max_per_account : ACCOUNT_ROLES_MAX_PER_ACCOUNT;
}
inline uint32_t account_roles_max_lifetime()const {
return extensions.value.account_roles_max_lifetime.valid() ? *extensions.value.account_roles_max_lifetime : ACCOUNT_ROLES_MAX_LIFETIME;
}
inline uint32_t son_vesting_amount()const {
return extensions.value.son_vesting_amount.valid() ? *extensions.value.son_vesting_amount : SON_VESTING_AMOUNT; /// current period start date
}
inline uint32_t son_vesting_period()const {
return extensions.value.son_vesting_period.valid() ? *extensions.value.son_vesting_period : SON_VESTING_PERIOD; /// current period start date
}
inline uint64_t son_pay_max()const {
return extensions.value.son_pay_max.valid() ? *extensions.value.son_pay_max : SON_PAY_MAX;
}
inline uint32_t son_pay_time()const {
return extensions.value.son_pay_time.valid() ? *extensions.value.son_pay_time : SON_PAY_TIME;
}
inline uint32_t son_deregister_time()const {
return extensions.value.son_deregister_time.valid() ? *extensions.value.son_deregister_time : SON_DEREGISTER_TIME;
}
inline uint32_t son_heartbeat_frequency()const {
return extensions.value.son_heartbeat_frequency.valid() ? *extensions.value.son_heartbeat_frequency : SON_HEARTBEAT_FREQUENCY;
}
inline uint32_t son_down_time()const {
return extensions.value.son_down_time.valid() ? *extensions.value.son_down_time : SON_DOWN_TIME;
}
inline uint16_t son_bitcoin_min_tx_confirmations()const {
return extensions.value.son_bitcoin_min_tx_confirmations.valid() ? *extensions.value.son_bitcoin_min_tx_confirmations : SON_BITCOIN_MIN_TX_CONFIRMATIONS;
}
inline account_id_type son_account() const {
return extensions.value.son_account.valid() ? *extensions.value.son_account : GRAPHENE_NULL_ACCOUNT;
}
inline asset_id_type btc_asset() const {
return extensions.value.btc_asset.valid() ? *extensions.value.btc_asset : asset_id_type();
}
inline uint16_t maximum_son_count()const {
return extensions.value.maximum_son_count.valid() ? *extensions.value.maximum_son_count : GRAPHENE_DEFAULT_MAX_SONS;
}
private:
static void safe_copy(chain_parameters& to, const chain_parameters& from);
}; };
} } // graphene::chain } } // graphene::chain
@ -156,6 +231,22 @@ FC_REFLECT( graphene::chain::parameter_extension,
(gpos_subperiod) (gpos_subperiod)
(gpos_period_start) (gpos_period_start)
(gpos_vesting_lockin_period) (gpos_vesting_lockin_period)
(rbac_max_permissions_per_account)
(rbac_max_account_authority_lifetime)
(rbac_max_authorities_per_permission)
(account_roles_max_per_account)
(account_roles_max_lifetime)
(son_vesting_amount)
(son_vesting_period)
(son_pay_max)
(son_pay_time)
(son_deregister_time)
(son_heartbeat_frequency)
(son_down_time)
(son_bitcoin_min_tx_confirmations)
(son_account)
(btc_asset)
(maximum_son_count)
) )
FC_REFLECT( graphene::chain::chain_parameters, FC_REFLECT( graphene::chain::chain_parameters,

View file

@ -50,6 +50,9 @@ namespace graphene { namespace chain {
account_id_type fee_payer()const { return payer; } account_id_type fee_payer()const { return payer; }
void validate()const; void validate()const;
share_type calculate_fee(const fee_parameters_type& k)const; share_type calculate_fee(const fee_parameters_type& k)const;
void get_required_active_authorities( flat_set<account_id_type>& auths )const {
auths.insert( required_auths.begin(), required_auths.end() );
}
}; };
} } // namespace graphene::chain } } // namespace graphene::chain

View file

@ -0,0 +1,76 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
namespace graphene
{
namespace chain
{
struct custom_account_authority_create_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
custom_permission_id_type permission_id;
int operation_type;
time_point_sec valid_from;
time_point_sec valid_to;
account_id_type owner_account;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct custom_account_authority_update_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
custom_account_authority_id_type auth_id;
optional<time_point_sec> new_valid_from;
optional<time_point_sec> new_valid_to;
account_id_type owner_account;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
struct custom_account_authority_delete_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
custom_account_authority_id_type auth_id;
account_id_type owner_account;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
} // namespace chain
} // namespace graphene
FC_REFLECT(graphene::chain::custom_account_authority_create_operation::fee_parameters_type, (fee)(price_per_kbyte))
FC_REFLECT(graphene::chain::custom_account_authority_create_operation, (fee)(permission_id)(operation_type)(valid_from)(valid_to)(owner_account)(extensions))
FC_REFLECT(graphene::chain::custom_account_authority_update_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::custom_account_authority_update_operation, (fee)(auth_id)(new_valid_from)(new_valid_to)(owner_account)(extensions))
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation, (fee)(auth_id)(owner_account)(extensions))

View file

@ -0,0 +1,73 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
namespace graphene
{
namespace chain
{
struct custom_permission_create_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner_account;
string permission_name;
authority auth;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct custom_permission_update_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
custom_permission_id_type permission_id;
optional<authority> new_auth;
account_id_type owner_account;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
struct custom_permission_delete_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
custom_permission_id_type permission_id;
account_id_type owner_account;
extensions_type extensions;
account_id_type fee_payer() const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const { return k.fee; }
};
} // namespace chain
} // namespace graphene
FC_REFLECT(graphene::chain::custom_permission_create_operation::fee_parameters_type, (fee)(price_per_kbyte))
FC_REFLECT(graphene::chain::custom_permission_create_operation, (fee)(owner_account)(permission_name)(auth)(extensions))
FC_REFLECT(graphene::chain::custom_permission_update_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::custom_permission_update_operation, (fee)(permission_id)(new_auth)(owner_account)(extensions))
FC_REFLECT(graphene::chain::custom_permission_delete_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::custom_permission_delete_operation, (fee)(permission_id)(owner_account)(extensions))

View file

@ -22,7 +22,6 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <fc/smart_ref_fwd.hpp>
#include <graphene/chain/protocol/operations.hpp> #include <graphene/chain/protocol/operations.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -73,13 +72,6 @@ namespace graphene { namespace chain {
return itr->template get<typename Operation::fee_parameters_type>(); return itr->template get<typename Operation::fee_parameters_type>();
} }
template<typename Operation>
const bool exists()const
{
auto itr = parameters.find(typename Operation::fee_parameters_type());
return itr != parameters.end();
}
/** /**
* @note must be sorted by fee_parameters.which() and have no duplicates * @note must be sorted by fee_parameters.which() and have no duplicates
*/ */
@ -91,6 +83,10 @@ namespace graphene { namespace chain {
} } // graphene::chain } } // graphene::chain
namespace fc {
template<> struct get_typename<std::shared_ptr<graphene::chain::fee_schedule>> { static const char* name() { return "shared_ptr<fee_schedule>"; } };
}
FC_REFLECT_TYPENAME( graphene::chain::fee_parameters ) FC_REFLECT_TYPENAME( graphene::chain::fee_parameters )
FC_REFLECT( graphene::chain::fee_schedule, (parameters)(scale) ) FC_REFLECT( graphene::chain::fee_schedule, (parameters)(scale) )

View file

@ -0,0 +1,148 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
struct nft_metadata_create_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner;
std::string name;
std::string symbol;
std::string base_uri;
optional<account_id_type> revenue_partner;
optional<uint16_t> revenue_split;
bool is_transferable = false;
bool is_sellable = true;
// Accounts Role
optional<account_role_id_type> account_role;
extensions_type extensions;
account_id_type fee_payer()const { return owner; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_metadata_update_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type owner;
nft_metadata_id_type nft_metadata_id;
optional<std::string> name;
optional<std::string> symbol;
optional<std::string> base_uri;
optional<account_id_type> revenue_partner;
optional<uint16_t> revenue_split;
optional<bool> is_transferable;
optional<bool> is_sellable;
// Accounts Role
optional<account_role_id_type> account_role;
extensions_type extensions;
account_id_type fee_payer()const { return owner; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_mint_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type payer;
nft_metadata_id_type nft_metadata_id;
account_id_type owner;
account_id_type approved;
vector<account_id_type> approved_operators;
std::string token_uri;
extensions_type extensions;
account_id_type fee_payer()const { return payer; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_safe_transfer_from_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type operator_;
account_id_type from;
account_id_type to;
nft_id_type token_id;
string data;
extensions_type extensions;
account_id_type fee_payer()const { return operator_; }
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_approve_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
account_id_type operator_;
account_id_type approved;
nft_id_type token_id;
extensions_type extensions;
account_id_type fee_payer()const { return operator_; }
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct nft_set_approval_for_all_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION; };
asset fee;
account_id_type owner;
account_id_type operator_;
bool approved;
extensions_type extensions;
account_id_type fee_payer()const { return owner; }
share_type calculate_fee(const fee_parameters_type &k) const;
};
} } // graphene::chain
FC_REFLECT( graphene::chain::nft_metadata_create_operation::fee_parameters_type, (fee) (price_per_kbyte) )
FC_REFLECT( graphene::chain::nft_metadata_update_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_mint_operation::fee_parameters_type, (fee) (price_per_kbyte) )
FC_REFLECT( graphene::chain::nft_safe_transfer_from_operation::fee_parameters_type, (fee) (price_per_kbyte) )
FC_REFLECT( graphene::chain::nft_approve_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_set_approval_for_all_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::nft_metadata_create_operation, (fee) (owner) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) (is_transferable) (is_sellable) (account_role) (extensions) )
FC_REFLECT( graphene::chain::nft_metadata_update_operation, (fee) (owner) (nft_metadata_id) (name) (symbol) (base_uri) (revenue_partner) (revenue_split) (is_transferable) (is_sellable) (account_role) (extensions) )
FC_REFLECT( graphene::chain::nft_mint_operation, (fee) (payer) (nft_metadata_id) (owner) (approved) (approved_operators) (token_uri) (extensions) )
FC_REFLECT( graphene::chain::nft_safe_transfer_from_operation, (fee) (operator_) (from) (to) (token_id) (data) (extensions) )
FC_REFLECT( graphene::chain::nft_approve_operation, (fee) (operator_) (approved) (token_id) (extensions) )
FC_REFLECT( graphene::chain::nft_set_approval_for_all_operation, (fee) (owner) (operator_) (approved) (extensions) )

View file

@ -0,0 +1,143 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/memo.hpp>
namespace graphene
{
namespace chain
{
/*
* @class offer_operation
* @brief To place an offer to buy or sell an item, a user broadcasts a
* proposed transaction
* @ingroup operations
* operation
*/
struct offer_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
uint32_t price_per_kbyte = GRAPHENE_BLOCKCHAIN_PRECISION; /// only required for large memos.
};
asset fee;
set<nft_id_type> item_ids;
// /**
// * minimum_price.asset_id == maximum_price.asset_id.
// * to set fixed price without auction minimum_price == maximum_price
// * If buying_item is true, and minimum_price != maximum_price, the user is
// proposing a “reverse auction”
// * where bidders can offer to sell the item for progressively lower prices.
// * In this case, minimum_price functions as the sell-it-now price for the
// reverse auction
// */
account_id_type issuer;
/// minimum_price is minimum bid price. 0 if no minimum_price required
asset minimum_price;
/// buy_it_now price. 0 if no maximum price
asset maximum_price;
/// true means user wants to buy item, false mean user is selling item
bool buying_item;
/// not transaction expiration date
fc::time_point_sec offer_expiration_date;
/// User provided data encrypted to the memo key of the "to" account
optional<memo_data> memo;
extensions_type extensions;
account_id_type fee_payer() const { return issuer; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct bid_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type bidder;
asset bid_price;
offer_id_type offer_id;
extensions_type extensions;
account_id_type fee_payer() const { return bidder; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
struct cancel_offer_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = GRAPHENE_BLOCKCHAIN_PRECISION;
};
asset fee;
account_id_type issuer;
offer_id_type offer_id;
extensions_type extensions;
account_id_type fee_payer() const { return issuer; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
enum class result_type
{
Expired = 0,
ExpiredNoBid = 1,
Cancelled = 2
};
struct finalize_offer_operation : public base_operation
{
struct fee_parameters_type
{
uint64_t fee = 0;
};
asset fee;
account_id_type fee_paying_account;
offer_id_type offer_id;
result_type result;
extensions_type extensions;
account_id_type fee_payer() const { return fee_paying_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type &k) const;
};
} // namespace chain
} // namespace graphene
FC_REFLECT(graphene::chain::offer_operation::fee_parameters_type,
(fee)(price_per_kbyte));
FC_REFLECT(graphene::chain::offer_operation,
(fee)(item_ids)(issuer)(minimum_price)(maximum_price)(buying_item)(offer_expiration_date)(memo)(extensions));
FC_REFLECT(graphene::chain::bid_operation::fee_parameters_type,
(fee));
FC_REFLECT(graphene::chain::bid_operation,
(fee)(bidder)(bid_price)(offer_id)(extensions));
FC_REFLECT(graphene::chain::cancel_offer_operation::fee_parameters_type,
(fee));
FC_REFLECT(graphene::chain::cancel_offer_operation,
(fee)(issuer)(offer_id)(extensions));
FC_REFLECT_ENUM(graphene::chain::result_type, (Expired)(ExpiredNoBid)(Cancelled));
FC_REFLECT(graphene::chain::finalize_offer_operation::fee_parameters_type,
(fee));
FC_REFLECT(graphene::chain::finalize_offer_operation,
(fee)(fee_paying_account)(offer_id)(result)(extensions));

View file

@ -45,6 +45,17 @@
#include <graphene/chain/protocol/event.hpp> #include <graphene/chain/protocol/event.hpp>
#include <graphene/chain/protocol/betting_market.hpp> #include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/chain/protocol/tournament.hpp> #include <graphene/chain/protocol/tournament.hpp>
#include <graphene/chain/protocol/custom_permission.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
#include <graphene/chain/protocol/offer.hpp>
#include <graphene/chain/protocol/nft_ops.hpp>
#include <graphene/chain/protocol/account_role.hpp>
#include <graphene/chain/protocol/son.hpp>
#include <graphene/chain/protocol/sidechain_address.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
#include <graphene/chain/protocol/son_wallet_deposit.hpp>
#include <graphene/chain/protocol/son_wallet_withdraw.hpp>
#include <graphene/chain/protocol/sidechain_transaction.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -135,7 +146,45 @@ namespace graphene { namespace chain {
ticket_purchase_operation, ticket_purchase_operation,
lottery_reward_operation, lottery_reward_operation,
lottery_end_operation, lottery_end_operation,
sweeps_vesting_claim_operation sweeps_vesting_claim_operation,
custom_permission_create_operation,
custom_permission_update_operation,
custom_permission_delete_operation,
custom_account_authority_create_operation,
custom_account_authority_update_operation,
custom_account_authority_delete_operation,
offer_operation,
bid_operation,
cancel_offer_operation,
finalize_offer_operation,
nft_metadata_create_operation,
nft_metadata_update_operation,
nft_mint_operation,
nft_safe_transfer_from_operation,
nft_approve_operation,
nft_set_approval_for_all_operation,
account_role_create_operation,
account_role_update_operation,
account_role_delete_operation,
son_create_operation,
son_update_operation,
son_deregister_operation,
son_heartbeat_operation,
son_report_down_operation,
son_maintenance_operation,
son_wallet_recreate_operation,
son_wallet_update_operation,
son_wallet_deposit_create_operation,
son_wallet_deposit_process_operation,
son_wallet_withdraw_create_operation,
son_wallet_withdraw_process_operation,
sidechain_address_add_operation,
sidechain_address_update_operation,
sidechain_address_delete_operation,
sidechain_transaction_create_operation,
sidechain_transaction_sign_operation,
sidechain_transaction_send_operation,
sidechain_transaction_settle_operation
> operation; > operation;
/// @} // operations group /// @} // operations group
@ -146,10 +195,11 @@ namespace graphene { namespace chain {
* *
* @return a set of required authorities for @ref op * @return a set of required authorities for @ref op
*/ */
void operation_get_required_authorities( const operation& op, void operation_get_required_authorities( const operation& op,
flat_set<account_id_type>& active, flat_set<account_id_type>& active,
flat_set<account_id_type>& owner, flat_set<account_id_type>& owner,
vector<authority>& other ); vector<authority>& other,
bool ignore_custom_operation_required_auths );
void operation_validate( const operation& op ); void operation_validate( const operation& op );

View file

@ -0,0 +1,80 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
struct sidechain_address_add_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
account_id_type sidechain_address_account;
sidechain_type sidechain;
string deposit_public_key;
string deposit_address;
string deposit_address_data;
string withdraw_public_key;
string withdraw_address;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct sidechain_address_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
sidechain_address_id_type sidechain_address_id;
account_id_type sidechain_address_account;
sidechain_type sidechain;
optional<string> deposit_public_key;
optional<string> deposit_address;
optional<string> deposit_address_data;
optional<string> withdraw_public_key;
optional<string> withdraw_address;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct sidechain_address_delete_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
sidechain_address_id_type sidechain_address_id;
account_id_type sidechain_address_account;
sidechain_type sidechain;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::sidechain_address_add_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::sidechain_address_add_operation, (fee)(payer)
(sidechain_address_account)(sidechain)
(deposit_public_key)(deposit_address)(deposit_address_data)
(withdraw_public_key)(withdraw_address) )
FC_REFLECT(graphene::chain::sidechain_address_update_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::sidechain_address_update_operation, (fee)(payer)
(sidechain_address_id)
(sidechain_address_account)(sidechain)
(deposit_public_key)(deposit_address)(deposit_address_data)
(withdraw_public_key)(withdraw_address) )
FC_REFLECT(graphene::chain::sidechain_address_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::sidechain_address_delete_operation, (fee)(payer)
(sidechain_address_id)
(sidechain_address_account)(sidechain) )

View file

@ -0,0 +1,88 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <graphene/chain/son_info.hpp>
namespace graphene { namespace chain {
struct sidechain_transaction_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
sidechain_type sidechain;
object_id_type object_id;
std::string transaction;
std::vector<son_info> signers;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct sidechain_transaction_sign_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type signer;
account_id_type payer;
sidechain_transaction_id_type sidechain_transaction_id;
std::string signature;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
};
struct sidechain_transaction_send_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
sidechain_transaction_id_type sidechain_transaction_id;
std::string sidechain_transaction;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
};
struct sidechain_transaction_settle_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
sidechain_transaction_id_type sidechain_transaction_id;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee( const fee_parameters_type& k )const { return 0; }
};
} } // graphene::chain
FC_REFLECT( graphene::chain::sidechain_transaction_create_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sidechain_transaction_create_operation, (fee)(payer)
(sidechain)
(object_id)
(transaction)
(signers) )
FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sidechain_transaction_sign_operation, (fee)(signer)(payer)
(sidechain_transaction_id)
(signature) )
FC_REFLECT( graphene::chain::sidechain_transaction_send_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sidechain_transaction_send_operation, (fee)(payer)
(sidechain_transaction_id)
(sidechain_transaction) )
FC_REFLECT( graphene::chain::sidechain_transaction_settle_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::sidechain_transaction_settle_operation, (fee)(payer)
(sidechain_transaction_id) )

View file

@ -0,0 +1,119 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
struct son_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type owner_account;
std::string url;
vesting_balance_id_type deposit;
public_key_type signing_key;
flat_map<sidechain_type, string> sidechain_public_keys;
vesting_balance_id_type pay_vb;
account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type son_id;
account_id_type owner_account;
optional<std::string> new_url;
optional<vesting_balance_id_type> new_deposit;
optional<public_key_type> new_signing_key;
optional<flat_map<sidechain_type, string>> new_sidechain_public_keys;
optional<vesting_balance_id_type> new_pay_vb;
account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_deregister_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type son_id;
account_id_type payer;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_heartbeat_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type son_id;
account_id_type owner_account;
time_point_sec ts;
account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_report_down_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type son_id;
account_id_type payer;
time_point_sec down_ts;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
enum class son_maintenance_request_type
{
request_maintenance,
cancel_request_maintenance
};
struct son_maintenance_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
son_id_type son_id;
account_id_type owner_account;
son_maintenance_request_type request_type = son_maintenance_request_type::request_maintenance;
account_id_type fee_payer()const { return owner_account; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::son_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_create_operation, (fee)(owner_account)(url)(deposit)(signing_key)(sidechain_public_keys)
(pay_vb) )
FC_REFLECT(graphene::chain::son_update_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_update_operation, (fee)(son_id)(owner_account)(new_url)(new_deposit)
(new_signing_key)(new_sidechain_public_keys)(new_pay_vb) )
FC_REFLECT(graphene::chain::son_deregister_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_deregister_operation, (fee)(son_id)(payer) )
FC_REFLECT(graphene::chain::son_heartbeat_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_heartbeat_operation, (fee)(son_id)(owner_account)(ts) )
FC_REFLECT(graphene::chain::son_report_down_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_report_down_operation, (fee)(son_id)(payer)(down_ts) )
FC_REFLECT_ENUM( graphene::chain::son_maintenance_request_type, (request_maintenance)(cancel_request_maintenance) )
FC_REFLECT(graphene::chain::son_maintenance_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_maintenance_operation, (fee)(son_id)(owner_account)(request_type) )

View file

@ -0,0 +1,40 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/son_info.hpp>
namespace graphene { namespace chain {
struct son_wallet_recreate_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
vector<son_info> sons;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_wallet_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
son_wallet_id_type son_wallet_id;
sidechain_type sidechain;
string address;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::son_wallet_recreate_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_recreate_operation, (fee)(payer)(sons) )
FC_REFLECT(graphene::chain::son_wallet_update_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_update_operation, (fee)(payer)(son_wallet_id)(sidechain)(address) )

View file

@ -0,0 +1,57 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <fc/safe.hpp>
namespace graphene { namespace chain {
struct son_wallet_deposit_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
son_id_type son_id;
fc::time_point_sec timestamp;
uint32_t block_num;
sidechain_type sidechain;
std::string sidechain_uid;
std::string sidechain_transaction_id;
std::string sidechain_from;
std::string sidechain_to;
std::string sidechain_currency;
fc::safe<int64_t> sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
chain::asset peerplays_asset;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_wallet_deposit_process_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
son_wallet_deposit_id_type son_wallet_deposit_id;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation, (fee)(payer)
(son_id) (timestamp) (block_num) (sidechain)
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
(peerplays_from) (peerplays_to) (peerplays_asset) )
FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation, (fee)(payer)
(son_wallet_deposit_id) )

View file

@ -0,0 +1,56 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <fc/safe.hpp>
namespace graphene { namespace chain {
struct son_wallet_withdraw_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
son_id_type son_id;
fc::time_point_sec timestamp;
uint32_t block_num;
sidechain_type sidechain;
std::string peerplays_uid;
std::string peerplays_transaction_id;
chain::account_id_type peerplays_from;
chain::asset peerplays_asset;
sidechain_type withdraw_sidechain;
std::string withdraw_address;
std::string withdraw_currency;
safe<int64_t> withdraw_amount;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct son_wallet_withdraw_process_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type payer;
son_wallet_withdraw_id_type son_wallet_withdraw_id;
account_id_type fee_payer()const { return payer; }
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer)
(son_id) (timestamp) (block_num) (sidechain)
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) )
FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation, (fee)(payer)
(son_wallet_withdraw_id) )

View file

@ -112,7 +112,10 @@ namespace graphene { namespace chain {
return results; return results;
} }
void get_required_authorities( flat_set<account_id_type>& active, flat_set<account_id_type>& owner, vector<authority>& other )const; void get_required_authorities( flat_set<account_id_type>& active,
flat_set<account_id_type>& owner,
vector<authority>& other,
bool ignore_custom_operation_required_auths )const;
}; };
/** /**
@ -141,6 +144,8 @@ namespace graphene { namespace chain {
const flat_set<public_key_type>& available_keys, const flat_set<public_key_type>& available_keys,
const std::function<const authority*(account_id_type)>& get_active, const std::function<const authority*(account_id_type)>& get_active,
const std::function<const authority*(account_id_type)>& get_owner, const std::function<const authority*(account_id_type)>& get_owner,
const std::function<vector<authority>(account_id_type, const operation&)>& get_custom,
bool ignore_custom_operation_required_authorities,
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH
)const; )const;
@ -148,6 +153,8 @@ namespace graphene { namespace chain {
const chain_id_type& chain_id, const chain_id_type& chain_id,
const std::function<const authority*(account_id_type)>& get_active, const std::function<const authority*(account_id_type)>& get_active,
const std::function<const authority*(account_id_type)>& get_owner, const std::function<const authority*(account_id_type)>& get_owner,
const std::function<vector<authority>(account_id_type, const operation&)>& get_custom,
bool ignore_custom_operation_required_auths,
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH )const; uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH )const;
/** /**
@ -156,12 +163,13 @@ namespace graphene { namespace chain {
* some cases where get_required_signatures() returns a * some cases where get_required_signatures() returns a
* non-minimal set. * non-minimal set.
*/ */
set<public_key_type> minimize_required_signatures( set<public_key_type> minimize_required_signatures(
const chain_id_type& chain_id, const chain_id_type& chain_id,
const flat_set<public_key_type>& available_keys, const flat_set<public_key_type>& available_keys,
const std::function<const authority*(account_id_type)>& get_active, const std::function<const authority*(account_id_type)>& get_active,
const std::function<const authority*(account_id_type)>& get_owner, const std::function<const authority*(account_id_type)>& get_owner,
const std::function<vector<authority>(account_id_type, const operation&)>& get_custom,
bool ignore_custom_operation_required_auths,
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH
) const; ) const;
@ -194,10 +202,12 @@ namespace graphene { namespace chain {
void verify_authority( const vector<operation>& ops, const flat_set<public_key_type>& sigs, void verify_authority( const vector<operation>& ops, const flat_set<public_key_type>& sigs,
const std::function<const authority*(account_id_type)>& get_active, const std::function<const authority*(account_id_type)>& get_active,
const std::function<const authority*(account_id_type)>& get_owner, const std::function<const authority*(account_id_type)>& get_owner,
const std::function<vector<authority>(account_id_type, const operation&)>& get_custom,
bool ignore_custom_operation_required_auths,
uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH, uint32_t max_recursion = GRAPHENE_MAX_SIG_CHECK_DEPTH,
bool allow_committe = false, bool allow_committee = false,
const flat_set<account_id_type>& active_aprovals = flat_set<account_id_type>(), const flat_set<account_id_type>& active_aprovals = flat_set<account_id_type>(),
const flat_set<account_id_type>& owner_approvals = flat_set<account_id_type>()); const flat_set<account_id_type>& owner_approvals = flat_set<account_id_type>() );
/** /**
* @brief captures the result of evaluating the operations contained in the transaction * @brief captures the result of evaluating the operations contained in the transaction

View file

@ -38,7 +38,6 @@
#include <fc/io/raw_fwd.hpp> #include <fc/io/raw_fwd.hpp>
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#include <fc/static_variant.hpp> #include <fc/static_variant.hpp>
#include <fc/smart_ref_fwd.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -171,6 +170,19 @@ namespace graphene { namespace chain {
betting_market_group_object_type, betting_market_group_object_type,
betting_market_object_type, betting_market_object_type,
bet_object_type, bet_object_type,
custom_permission_object_type,
custom_account_authority_object_type,
offer_object_type,
nft_metadata_type,
nft_object_type,
account_role_type,
son_object_type,
son_proposal_object_type,
son_wallet_object_type,
son_wallet_deposit_object_type,
son_wallet_withdraw_object_type,
sidechain_address_object_type,
sidechain_transaction_object_type,
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
}; };
@ -199,7 +211,10 @@ namespace graphene { namespace chain {
impl_betting_market_position_object_type, impl_betting_market_position_object_type,
impl_global_betting_statistics_object_type, impl_global_betting_statistics_object_type,
impl_lottery_balance_object_type, impl_lottery_balance_object_type,
impl_sweeps_vesting_balance_object_type impl_sweeps_vesting_balance_object_type,
impl_offer_history_object_type,
impl_son_statistics_object_type,
impl_son_schedule_object_type
}; };
//typedef fc::unsigned_int object_id_type; //typedef fc::unsigned_int object_id_type;
@ -230,6 +245,19 @@ namespace graphene { namespace chain {
class betting_market_group_object; class betting_market_group_object;
class betting_market_object; class betting_market_object;
class bet_object; class bet_object;
class custom_permission_object;
class custom_account_authority_object;
class offer_object;
class nft_metadata_object;
class nft_object;
class account_role_object;
class son_object;
class son_proposal_object;
class son_wallet_object;
class son_wallet_deposit_object;
class son_wallet_withdraw_object;
class sidechain_address_object;
class sidechain_transaction_object;
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type; typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
@ -256,6 +284,19 @@ namespace graphene { namespace chain {
typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type; typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type;
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type; typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type; typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
typedef object_id< protocol_ids, custom_permission_object_type, custom_permission_object> custom_permission_id_type;
typedef object_id< protocol_ids, custom_account_authority_object_type, custom_account_authority_object> custom_account_authority_id_type;
typedef object_id< protocol_ids, offer_object_type, offer_object> offer_id_type;
typedef object_id< protocol_ids, nft_metadata_type, nft_metadata_object> nft_metadata_id_type;
typedef object_id< protocol_ids, nft_object_type, nft_object> nft_id_type;
typedef object_id< protocol_ids, account_role_type, account_role_object> account_role_id_type;
typedef object_id< protocol_ids, son_object_type, son_object> son_id_type;
typedef object_id< protocol_ids, son_proposal_object_type, son_proposal_object> son_proposal_id_type;
typedef object_id< protocol_ids, son_wallet_object_type, son_wallet_object> son_wallet_id_type;
typedef object_id< protocol_ids, son_wallet_deposit_object_type, son_wallet_deposit_object> son_wallet_deposit_id_type;
typedef object_id< protocol_ids, son_wallet_withdraw_object_type, son_wallet_withdraw_object> son_wallet_withdraw_id_type;
typedef object_id< protocol_ids, sidechain_address_object_type, sidechain_address_object> sidechain_address_id_type;
typedef object_id< protocol_ids, sidechain_transaction_object_type,sidechain_transaction_object> sidechain_transaction_id_type;
// implementation types // implementation types
class global_property_object; class global_property_object;
@ -279,6 +320,9 @@ namespace graphene { namespace chain {
class global_betting_statistics_object; class global_betting_statistics_object;
class lottery_balance_object; class lottery_balance_object;
class sweeps_vesting_balance_object; class sweeps_vesting_balance_object;
class offer_history_object;
class son_statistics_object;
class son_schedule_object;
typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type; typedef object_id< implementation_ids, impl_global_property_object_type, global_property_object> global_property_id_type;
typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type; typedef object_id< implementation_ids, impl_dynamic_global_property_object_type, dynamic_global_property_object> dynamic_global_property_id_type;
@ -307,6 +351,9 @@ namespace graphene { namespace chain {
typedef object_id< implementation_ids, impl_global_betting_statistics_object_type, global_betting_statistics_object > global_betting_statistics_id_type; typedef object_id< implementation_ids, impl_global_betting_statistics_object_type, global_betting_statistics_object > global_betting_statistics_id_type;
typedef object_id< implementation_ids, impl_lottery_balance_object_type, lottery_balance_object > lottery_balance_id_type; typedef object_id< implementation_ids, impl_lottery_balance_object_type, lottery_balance_object > lottery_balance_id_type;
typedef object_id< implementation_ids, impl_sweeps_vesting_balance_object_type, sweeps_vesting_balance_object> sweeps_vesting_balance_id_type; typedef object_id< implementation_ids, impl_sweeps_vesting_balance_object_type, sweeps_vesting_balance_object> sweeps_vesting_balance_id_type;
typedef object_id< implementation_ids, impl_offer_history_object_type, offer_history_object> offer_history_id_type;
typedef object_id< implementation_ids, impl_son_statistics_object_type, son_statistics_object > son_statistics_id_type;
typedef object_id< implementation_ids, impl_son_schedule_object_type, son_schedule_object> son_schedule_id_type;
typedef fc::array<char, GRAPHENE_MAX_ASSET_SYMBOL_LENGTH> symbol_type; typedef fc::array<char, GRAPHENE_MAX_ASSET_SYMBOL_LENGTH> symbol_type;
typedef fc::ripemd160 block_id_type; typedef fc::ripemd160 block_id_type;
@ -436,6 +483,19 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
(betting_market_group_object_type) (betting_market_group_object_type)
(betting_market_object_type) (betting_market_object_type)
(bet_object_type) (bet_object_type)
(custom_permission_object_type)
(custom_account_authority_object_type)
(offer_object_type)
(nft_metadata_type)
(nft_object_type)
(account_role_type)
(son_object_type)
(son_proposal_object_type)
(son_wallet_object_type)
(son_wallet_deposit_object_type)
(son_wallet_withdraw_object_type)
(sidechain_address_object_type)
(sidechain_transaction_object_type)
(OBJECT_TYPE_COUNT) (OBJECT_TYPE_COUNT)
) )
FC_REFLECT_ENUM( graphene::chain::impl_object_type, FC_REFLECT_ENUM( graphene::chain::impl_object_type,
@ -463,6 +523,9 @@ FC_REFLECT_ENUM( graphene::chain::impl_object_type,
(impl_global_betting_statistics_object_type) (impl_global_betting_statistics_object_type)
(impl_lottery_balance_object_type) (impl_lottery_balance_object_type)
(impl_sweeps_vesting_balance_object_type) (impl_sweeps_vesting_balance_object_type)
(impl_offer_history_object_type)
(impl_son_statistics_object_type)
(impl_son_schedule_object_type)
) )
FC_REFLECT_TYPENAME( graphene::chain::share_type ) FC_REFLECT_TYPENAME( graphene::chain::share_type )
@ -489,6 +552,7 @@ FC_REFLECT_TYPENAME( graphene::chain::betting_market_group_id_type )
FC_REFLECT_TYPENAME( graphene::chain::betting_market_id_type ) FC_REFLECT_TYPENAME( graphene::chain::betting_market_id_type )
FC_REFLECT_TYPENAME( graphene::chain::bet_id_type ) FC_REFLECT_TYPENAME( graphene::chain::bet_id_type )
FC_REFLECT_TYPENAME( graphene::chain::tournament_id_type ) FC_REFLECT_TYPENAME( graphene::chain::tournament_id_type )
FC_REFLECT_TYPENAME( graphene::chain::offer_id_type )
FC_REFLECT_TYPENAME( graphene::chain::global_property_id_type ) FC_REFLECT_TYPENAME( graphene::chain::global_property_id_type )
FC_REFLECT_TYPENAME( graphene::chain::dynamic_global_property_id_type ) FC_REFLECT_TYPENAME( graphene::chain::dynamic_global_property_id_type )
FC_REFLECT_TYPENAME( graphene::chain::asset_dynamic_data_id_type ) FC_REFLECT_TYPENAME( graphene::chain::asset_dynamic_data_id_type )
@ -505,6 +569,20 @@ FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type )
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type ) FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type ) FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type )
FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type ) FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_permission_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_account_authority_id_type )
FC_REFLECT_TYPENAME( graphene::chain::offer_history_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_metadata_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_id_type )
FC_REFLECT_TYPENAME( graphene::chain::account_role_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_proposal_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_deposit_id_type )
FC_REFLECT_TYPENAME( graphene::chain::son_wallet_withdraw_id_type )
FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type )
FC_REFLECT_TYPENAME( graphene::chain::sidechain_transaction_id_type )
FC_REFLECT( graphene::chain::void_t, ) FC_REFLECT( graphene::chain::void_t, )

View file

@ -27,12 +27,14 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
enum class vesting_balance_type { normal, gpos }; enum class vesting_balance_type { normal, gpos, son };
inline std::string get_vesting_balance_type(vesting_balance_type type) { inline std::string get_vesting_balance_type(vesting_balance_type type) {
switch (type) { switch (type) {
case vesting_balance_type::normal: case vesting_balance_type::normal:
return "NORMAL"; return "NORMAL";
case vesting_balance_type::son:
return "SON";
case vesting_balance_type::gpos: case vesting_balance_type::gpos:
default: default:
return "GPOS"; return "GPOS";
@ -55,9 +57,10 @@ namespace graphene { namespace chain {
cdd_vesting_policy_initializer( uint32_t vest_sec = 0, fc::time_point_sec sc = fc::time_point_sec() ):start_claim(sc),vesting_seconds(vest_sec){} cdd_vesting_policy_initializer( uint32_t vest_sec = 0, fc::time_point_sec sc = fc::time_point_sec() ):start_claim(sc),vesting_seconds(vest_sec){}
}; };
typedef fc::static_variant<linear_vesting_policy_initializer, cdd_vesting_policy_initializer> vesting_policy_initializer; struct dormant_vesting_policy_initializer {};
typedef fc::static_variant<linear_vesting_policy_initializer, cdd_vesting_policy_initializer,
dormant_vesting_policy_initializer> vesting_policy_initializer;
/** /**
* @brief Create a vesting balance. * @brief Create a vesting balance.
@ -127,13 +130,14 @@ FC_REFLECT( graphene::chain::vesting_balance_create_operation::fee_parameters_ty
FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type, (fee) ) FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type, (fee) )
FC_REFLECT( graphene::chain::vesting_balance_create_operation, (fee)(creator)(owner)(amount)(policy)(balance_type) ) FC_REFLECT( graphene::chain::vesting_balance_create_operation, (fee)(creator)(owner)(amount)(policy)(balance_type) )
FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation, (fee)(vesting_balance)(owner)(amount)) FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation, (fee)(vesting_balance)(owner)(amount) )
FC_REFLECT(graphene::chain::linear_vesting_policy_initializer, (begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds) ) FC_REFLECT(graphene::chain::linear_vesting_policy_initializer, (begin_timestamp)(vesting_cliff_seconds)(vesting_duration_seconds) )
FC_REFLECT(graphene::chain::cdd_vesting_policy_initializer, (start_claim)(vesting_seconds) ) FC_REFLECT(graphene::chain::cdd_vesting_policy_initializer, (start_claim)(vesting_seconds) )
FC_REFLECT(graphene::chain::dormant_vesting_policy_initializer, )
FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer ) FC_REFLECT_TYPENAME( graphene::chain::vesting_policy_initializer )
FC_REFLECT_ENUM( graphene::chain::vesting_balance_type, (normal)(gpos) ) FC_REFLECT_ENUM( graphene::chain::vesting_balance_type, (normal)(gpos)(son) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_create_operation::fee_parameters_type ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_create_operation::fee_parameters_type )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vesting_balance_withdraw_operation::fee_parameters_type )

View file

@ -59,6 +59,7 @@ struct vote_id_type
committee, committee,
witness, witness,
worker, worker,
son,
VOTE_TYPE_COUNT VOTE_TYPE_COUNT
}; };
@ -143,7 +144,7 @@ void from_variant( const fc::variant& var, graphene::chain::vote_id_type& vo, ui
FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> ) FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(VOTE_TYPE_COUNT) ) FC_REFLECT_ENUM( graphene::chain::vote_id_type::vote_type, (witness)(committee)(worker)(son)(VOTE_TYPE_COUNT) )
FC_REFLECT( graphene::chain::vote_id_type, (content) ) FC_REFLECT( graphene::chain::vote_id_type, (content) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vote_id_type ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::vote_id_type )

View file

@ -0,0 +1,69 @@
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/hardfork.hpp>
namespace graphene
{
namespace chain
{
struct rbac_operation_hardfork_visitor
{
typedef void result_type;
const fc::time_point_sec block_time;
rbac_operation_hardfork_visitor(const fc::time_point_sec bt) : block_time(bt) {}
void operator()(int op_type) const
{
int first_allowed_op = operation::tag<custom_permission_create_operation>::value;
switch (op_type)
{
case operation::tag<son_create_operation>::value:
case operation::tag<son_update_operation>::value:
case operation::tag<son_deregister_operation>::value:
case operation::tag<son_heartbeat_operation>::value:
case operation::tag<son_report_down_operation>::value:
case operation::tag<son_maintenance_operation>::value:
case operation::tag<son_wallet_recreate_operation>::value:
case operation::tag<son_wallet_update_operation>::value:
case operation::tag<son_wallet_deposit_create_operation>::value:
case operation::tag<son_wallet_deposit_process_operation>::value:
case operation::tag<son_wallet_withdraw_create_operation>::value:
case operation::tag<son_wallet_withdraw_process_operation>::value:
case operation::tag<sidechain_address_add_operation>::value:
case operation::tag<sidechain_address_update_operation>::value:
case operation::tag<sidechain_address_delete_operation>::value:
case operation::tag<sidechain_transaction_create_operation>::value:
case operation::tag<sidechain_transaction_sign_operation>::value:
case operation::tag<sidechain_transaction_send_operation>::value:
case operation::tag<sidechain_transaction_settle_operation>::value:
FC_ASSERT(block_time >= HARDFORK_SON_TIME, "Custom permissions and roles not allowed on this operation yet!");
break;
case operation::tag<custom_permission_create_operation>::value:
case operation::tag<custom_permission_update_operation>::value:
case operation::tag<custom_permission_delete_operation>::value:
case operation::tag<custom_account_authority_create_operation>::value:
case operation::tag<custom_account_authority_update_operation>::value:
case operation::tag<custom_account_authority_delete_operation>::value:
case operation::tag<offer_operation>::value:
case operation::tag<bid_operation>::value:
case operation::tag<cancel_offer_operation>::value:
case operation::tag<finalize_offer_operation>::value:
case operation::tag<nft_metadata_create_operation>::value:
case operation::tag<nft_metadata_update_operation>::value:
case operation::tag<nft_mint_operation>::value:
case operation::tag<nft_safe_transfer_from_operation>::value:
case operation::tag<nft_approve_operation>::value:
case operation::tag<nft_set_approval_for_all_operation>::value:
case operation::tag<account_role_create_operation>::value:
case operation::tag<account_role_update_operation>::value:
case operation::tag<account_role_delete_operation>::value:
FC_ASSERT(block_time >= HARDFORK_NFT_TIME, "Custom permissions and roles not allowed on this operation yet!");
break;
default:
FC_ASSERT(op_type >= operation::tag<transfer_operation>::value && op_type < first_allowed_op, "Custom permissions and roles not allowed on this operation!");
}
}
};
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,34 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/sidechain_address.hpp>
namespace graphene { namespace chain {
class add_sidechain_address_evaluator : public evaluator<add_sidechain_address_evaluator>
{
public:
typedef sidechain_address_add_operation operation_type;
void_result do_evaluate(const sidechain_address_add_operation& o);
object_id_type do_apply(const sidechain_address_add_operation& o);
};
class update_sidechain_address_evaluator : public evaluator<update_sidechain_address_evaluator>
{
public:
typedef sidechain_address_update_operation operation_type;
void_result do_evaluate(const sidechain_address_update_operation& o);
object_id_type do_apply(const sidechain_address_update_operation& o);
};
class delete_sidechain_address_evaluator : public evaluator<delete_sidechain_address_evaluator>
{
public:
typedef sidechain_address_delete_operation operation_type;
void_result do_evaluate(const sidechain_address_delete_operation& o);
void_result do_apply(const sidechain_address_delete_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,92 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class sidechain_address_object
* @brief tracks information about a sidechain addresses for user accounts.
* @ingroup object
*/
class sidechain_address_object : public abstract_object<sidechain_address_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = sidechain_address_object_type;
account_id_type sidechain_address_account;
sidechain_type sidechain;
string deposit_public_key;
string deposit_address;
string deposit_address_data;
string withdraw_public_key;
string withdraw_address;
time_point_sec valid_from;
time_point_sec expires;
sidechain_address_object() :
sidechain(sidechain_type::bitcoin),
deposit_public_key(""),
deposit_address(""),
withdraw_public_key(""),
withdraw_address("") {}
};
struct by_account;
struct by_sidechain;
struct by_sidechain_and_deposit_public_key_and_expires;
struct by_withdraw_public_key;
struct by_account_and_sidechain_and_expires;
struct by_sidechain_and_deposit_address_and_expires;
using sidechain_address_multi_index_type = multi_index_container<
sidechain_address_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_non_unique< tag<by_account>,
member<sidechain_address_object, account_id_type, &sidechain_address_object::sidechain_address_account>
>,
ordered_non_unique< tag<by_sidechain>,
member<sidechain_address_object, sidechain_type, &sidechain_address_object::sidechain>
>,
ordered_unique< tag<by_sidechain_and_deposit_public_key_and_expires>,
composite_key<sidechain_address_object,
member<sidechain_address_object, sidechain_type, &sidechain_address_object::sidechain>,
member<sidechain_address_object, string, &sidechain_address_object::deposit_public_key>,
member<sidechain_address_object, time_point_sec, &sidechain_address_object::expires>
>
>,
ordered_non_unique< tag<by_withdraw_public_key>,
member<sidechain_address_object, string, &sidechain_address_object::withdraw_public_key>
>,
ordered_non_unique< tag<by_account_and_sidechain_and_expires>,
composite_key<sidechain_address_object,
member<sidechain_address_object, account_id_type, &sidechain_address_object::sidechain_address_account>,
member<sidechain_address_object, sidechain_type, &sidechain_address_object::sidechain>,
member<sidechain_address_object, time_point_sec, &sidechain_address_object::expires>
>
>,
ordered_non_unique< tag<by_sidechain_and_deposit_address_and_expires>,
composite_key<sidechain_address_object,
member<sidechain_address_object, sidechain_type, &sidechain_address_object::sidechain>,
member<sidechain_address_object, string, &sidechain_address_object::deposit_address>,
member<sidechain_address_object, time_point_sec, &sidechain_address_object::expires>
>
>
>
>;
using sidechain_address_index = generic_index<sidechain_address_object, sidechain_address_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::sidechain_address_object, (graphene::db::object),
(sidechain_address_account) (sidechain)
(deposit_public_key) (deposit_address) (deposit_address_data)
(withdraw_public_key) (withdraw_address) (valid_from) (expires) )

View file

@ -0,0 +1,22 @@
#pragma once
#include <fc/reflect/reflect.hpp>
namespace graphene { namespace chain {
enum class sidechain_type {
unknown,
bitcoin,
ethereum,
eos,
peerplays
};
} }
FC_REFLECT_ENUM(graphene::chain::sidechain_type,
(unknown)
(bitcoin)
(ethereum)
(eos)
(peerplays) )

View file

@ -0,0 +1,43 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/sidechain_transaction.hpp>
namespace graphene { namespace chain {
class sidechain_transaction_create_evaluator : public evaluator<sidechain_transaction_create_evaluator>
{
public:
typedef sidechain_transaction_create_operation operation_type;
void_result do_evaluate(const sidechain_transaction_create_operation& o);
object_id_type do_apply(const sidechain_transaction_create_operation& o);
};
class sidechain_transaction_sign_evaluator : public evaluator<sidechain_transaction_sign_evaluator>
{
public:
typedef sidechain_transaction_sign_operation operation_type;
void_result do_evaluate(const sidechain_transaction_sign_operation& o);
object_id_type do_apply(const sidechain_transaction_sign_operation& o);
};
class sidechain_transaction_send_evaluator : public evaluator<sidechain_transaction_send_evaluator>
{
public:
typedef sidechain_transaction_send_operation operation_type;
void_result do_evaluate(const sidechain_transaction_send_operation& o);
object_id_type do_apply(const sidechain_transaction_send_operation& o);
};
class sidechain_transaction_settle_evaluator : public evaluator<sidechain_transaction_settle_evaluator>
{
public:
typedef sidechain_transaction_settle_operation operation_type;
void_result do_evaluate(const sidechain_transaction_settle_operation& o);
object_id_type do_apply(const sidechain_transaction_settle_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,82 @@
#pragma once
#include <boost/multi_index/composite_key.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <graphene/chain/son_info.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
enum class sidechain_transaction_status {
invalid,
valid,
complete,
sent,
settled
};
/**
* @class sidechain_transaction_object
* @brief tracks state of sidechain transaction during signing process.
* @ingroup object
*/
class sidechain_transaction_object : public abstract_object<sidechain_transaction_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = sidechain_transaction_object_type;
sidechain_type sidechain;
object_id_type object_id;
std::string transaction;
std::vector<son_info> signers;
std::vector<std::pair<son_id_type, std::string>> signatures;
std::string sidechain_transaction;
uint32_t total_weight = 0;
uint32_t current_weight = 0;
uint32_t threshold = 0;
sidechain_transaction_status status;
};
struct by_object_id;
struct by_sidechain_and_status;
using sidechain_transaction_multi_index_type = multi_index_container<
sidechain_transaction_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_object_id>,
member<sidechain_transaction_object, object_id_type, &sidechain_transaction_object::object_id>
>,
ordered_non_unique< tag<by_sidechain_and_status>,
composite_key<sidechain_transaction_object,
member<sidechain_transaction_object, sidechain_type, &sidechain_transaction_object::sidechain>,
member<sidechain_transaction_object, sidechain_transaction_status, &sidechain_transaction_object::status>
>
>
>
>;
using sidechain_transaction_index = generic_index<sidechain_transaction_object, sidechain_transaction_multi_index_type>;
} } // graphene::chain
FC_REFLECT_ENUM( graphene::chain::sidechain_transaction_status,
(invalid)
(valid)
(complete)
(sent)
(settled) )
FC_REFLECT_DERIVED( graphene::chain::sidechain_transaction_object, (graphene::db::object ),
(sidechain)
(object_id)
(transaction)
(signers)
(signatures)
(sidechain_transaction)
(total_weight)
(current_weight)
(threshold)
(status) )

View file

@ -0,0 +1,61 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/son.hpp>
namespace graphene { namespace chain {
class create_son_evaluator : public evaluator<create_son_evaluator>
{
public:
typedef son_create_operation operation_type;
void_result do_evaluate(const son_create_operation& o);
object_id_type do_apply(const son_create_operation& o);
};
class update_son_evaluator : public evaluator<update_son_evaluator>
{
public:
typedef son_update_operation operation_type;
void_result do_evaluate(const son_update_operation& o);
object_id_type do_apply(const son_update_operation& o);
};
class deregister_son_evaluator : public evaluator<deregister_son_evaluator>
{
public:
typedef son_deregister_operation operation_type;
void_result do_evaluate(const son_deregister_operation& o);
void_result do_apply(const son_deregister_operation& o);
};
class son_heartbeat_evaluator : public evaluator<son_heartbeat_evaluator>
{
public:
typedef son_heartbeat_operation operation_type;
void_result do_evaluate(const son_heartbeat_operation& o);
object_id_type do_apply(const son_heartbeat_operation& o);
};
class son_report_down_evaluator : public evaluator<son_report_down_evaluator>
{
public:
typedef son_report_down_operation operation_type;
void_result do_evaluate(const son_report_down_operation& o);
object_id_type do_apply(const son_report_down_operation& o);
};
class son_maintenance_evaluator : public evaluator<son_maintenance_evaluator>
{
public:
typedef son_maintenance_operation operation_type;
void_result do_evaluate(const son_maintenance_operation& o);
object_id_type do_apply(const son_maintenance_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,47 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class son_info
* @brief tracks information about a SON info required to re/create primary wallet
* @ingroup object
*/
struct son_info {
son_id_type son_id;
weight_type weight = 0;
public_key_type signing_key;
flat_map<sidechain_type, string> sidechain_public_keys;
bool operator==(const son_info& rhs) {
bool son_sets_equal =
(son_id == rhs.son_id) &&
(weight == rhs.weight) &&
(signing_key == rhs.signing_key) &&
(sidechain_public_keys.size() == rhs.sidechain_public_keys.size());
if (son_sets_equal) {
bool sidechain_public_keys_equal = true;
for (size_t i = 0; i < sidechain_public_keys.size(); i++) {
const auto lhs_scpk = sidechain_public_keys.nth(i);
const auto rhs_scpk = rhs.sidechain_public_keys.nth(i);
sidechain_public_keys_equal = sidechain_public_keys_equal &&
(lhs_scpk->first == rhs_scpk->first) &&
(lhs_scpk->second == rhs_scpk->second);
}
son_sets_equal = son_sets_equal && sidechain_public_keys_equal;
}
return son_sets_equal;
}
};
} }
FC_REFLECT( graphene::chain::son_info,
(son_id)
(weight)
(signing_key)
(sidechain_public_keys) )

View file

@ -0,0 +1,133 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
enum class son_status
{
inactive,
active,
request_maintenance,
in_maintenance,
deregistered
};
/**
* @class son_statistics_object
* @ingroup object
* @ingroup implementation
*
* This object contains regularly updated statistical data about an SON. It is provided for the purpose of
* separating the SON transaction data that changes frequently from the SON object data that is mostly static.
*/
class son_statistics_object : public graphene::db::abstract_object<son_statistics_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_son_statistics_object_type;
son_id_type owner;
// Lifetime total transactions signed
uint64_t total_txs_signed = 0;
// Transactions signed since the last son payouts
uint64_t txs_signed = 0;
// Total Voted Active time i.e. duration selected as part of voted active SONs
uint64_t total_voted_time = 0;
// Total Downtime barring the current down time in seconds, used for stats to present to user
uint64_t total_downtime = 0;
// Current Interval Downtime since last maintenance
uint64_t current_interval_downtime = 0;
// Down timestamp, if son status is in_maintenance use this
fc::time_point_sec last_down_timestamp;
// Last Active heartbeat timestamp
fc::time_point_sec last_active_timestamp;
// Deregistered Timestamp
fc::time_point_sec deregistered_timestamp;
// Total sidechain transactions reported by SON network while SON was active
uint64_t total_sidechain_txs_reported = 0;
// Sidechain transactions reported by this SON
uint64_t sidechain_txs_reported = 0;
};
/**
* @class son_object
* @brief tracks information about a SON account.
* @ingroup object
*/
class son_object : public abstract_object<son_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_object_type;
account_id_type son_account;
vote_id_type vote_id;
uint64_t total_votes = 0;
string url;
vesting_balance_id_type deposit;
public_key_type signing_key;
vesting_balance_id_type pay_vb;
son_statistics_id_type statistics;
son_status status = son_status::inactive;
flat_map<sidechain_type, string> sidechain_public_keys;
void pay_son_fee(share_type pay, database& db);
bool has_valid_config()const;
};
struct by_account;
struct by_vote_id;
using son_multi_index_type = multi_index_container<
son_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_account>,
member<son_object, account_id_type, &son_object::son_account>
>,
ordered_unique< tag<by_vote_id>,
member<son_object, vote_id_type, &son_object::vote_id>
>
>
>;
using son_index = generic_index<son_object, son_multi_index_type>;
struct by_owner;
using son_stats_multi_index_type = multi_index_container<
son_statistics_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_owner>,
member<son_statistics_object, son_id_type, &son_statistics_object::owner>
>
>
>;
using son_stats_index = generic_index<son_statistics_object, son_stats_multi_index_type>;
} } // graphene::chain
FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(request_maintenance)(in_maintenance)(deregistered) )
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
(son_account)(vote_id)(total_votes)(url)(deposit)(signing_key)(pay_vb)(statistics)(status)(sidechain_public_keys) )
FC_REFLECT_DERIVED( graphene::chain::son_statistics_object,
(graphene::db::object),
(owner)
(total_txs_signed)
(txs_signed)
(total_voted_time)
(total_downtime)
(current_interval_downtime)
(last_down_timestamp)
(last_active_timestamp)
(deregistered_timestamp)
(total_sidechain_txs_reported)
(sidechain_txs_reported)
)

View file

@ -0,0 +1,42 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
enum class son_proposal_type
{
son_deregister_proposal,
son_report_down_proposal
};
class son_proposal_object : public abstract_object<son_proposal_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_proposal_object_type;
son_proposal_id_type get_id()const { return id; }
proposal_id_type proposal_id;
son_id_type son_id;
son_proposal_type proposal_type;
};
struct by_proposal;
using son_proposal_multi_index_container = multi_index_container<
son_proposal_object,
indexed_by<
ordered_unique< tag< by_id >, member< object, object_id_type, &object::id > >,
ordered_unique< tag< by_proposal >, member< son_proposal_object, proposal_id_type, &son_proposal_object::proposal_id > >
>
>;
using son_proposal_index = generic_index<son_proposal_object, son_proposal_multi_index_container>;
} } // graphene::chain
FC_REFLECT_ENUM( graphene::chain::son_proposal_type, (son_deregister_proposal)(son_report_down_proposal) )
FC_REFLECT_DERIVED( graphene::chain::son_proposal_object, (graphene::chain::object), (proposal_id)(son_id)(proposal_type) )

View file

@ -0,0 +1,24 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
namespace graphene { namespace chain {
class create_son_wallet_deposit_evaluator : public evaluator<create_son_wallet_deposit_evaluator>
{
public:
typedef son_wallet_deposit_create_operation operation_type;
void_result do_evaluate(const son_wallet_deposit_create_operation& o);
object_id_type do_apply(const son_wallet_deposit_create_operation& o);
};
class process_son_wallet_deposit_evaluator : public evaluator<process_son_wallet_deposit_evaluator>
{
public:
typedef son_wallet_deposit_process_operation operation_type;
void_result do_evaluate(const son_wallet_deposit_process_operation& o);
object_id_type do_apply(const son_wallet_deposit_process_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,69 @@
#pragma once
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class son_wallet_deposit_object
* @brief tracks information about a SON wallet deposit.
* @ingroup object
*/
class son_wallet_deposit_object : public abstract_object<son_wallet_deposit_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_wallet_deposit_object_type;
time_point_sec timestamp;
uint32_t block_num;
sidechain_type sidechain = sidechain_type::unknown;
std::string sidechain_uid;
std::string sidechain_transaction_id;
std::string sidechain_from;
std::string sidechain_to;
std::string sidechain_currency;
safe<int64_t> sidechain_amount;
chain::account_id_type peerplays_from;
chain::account_id_type peerplays_to;
chain::asset peerplays_asset;
std::map<son_id_type, weight_type> expected_reports;
std::set<son_id_type> received_reports;
bool confirmed = false;
bool processed = false;
};
struct by_sidechain_uid;
struct by_sidechain_and_confirmed_and_processed;
using son_wallet_deposit_multi_index_type = multi_index_container<
son_wallet_deposit_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_sidechain_uid>,
member<son_wallet_deposit_object, std::string, &son_wallet_deposit_object::sidechain_uid>
>,
ordered_non_unique< tag<by_sidechain_and_confirmed_and_processed>,
composite_key<son_wallet_deposit_object,
member<son_wallet_deposit_object, sidechain_type, &son_wallet_deposit_object::sidechain>,
member<son_wallet_deposit_object, bool, &son_wallet_deposit_object::confirmed>,
member<son_wallet_deposit_object, bool, &son_wallet_deposit_object::processed>
>
>
>
>;
using son_wallet_deposit_index = generic_index<son_wallet_deposit_object, son_wallet_deposit_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::son_wallet_deposit_object, (graphene::db::object),
(timestamp) (block_num) (sidechain)
(sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount)
(peerplays_from) (peerplays_to) (peerplays_asset)
(expected_reports) (received_reports)
(confirmed) (processed) )

View file

@ -0,0 +1,25 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/son_wallet.hpp>
namespace graphene { namespace chain {
class recreate_son_wallet_evaluator : public evaluator<recreate_son_wallet_evaluator>
{
public:
typedef son_wallet_recreate_operation operation_type;
void_result do_evaluate(const son_wallet_recreate_operation& o);
object_id_type do_apply(const son_wallet_recreate_operation& o);
};
class update_son_wallet_evaluator : public evaluator<update_son_wallet_evaluator>
{
public:
typedef son_wallet_update_operation operation_type;
void_result do_evaluate(const son_wallet_update_operation& o);
object_id_type do_apply(const son_wallet_update_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,47 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/son_info.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class son_wallet_object
* @brief tracks information about a SON wallet.
* @ingroup object
*/
class son_wallet_object : public abstract_object<son_wallet_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_wallet_object_type;
time_point_sec valid_from;
time_point_sec expires;
flat_map<sidechain_type, string> addresses;
vector<son_info> sons;
};
struct by_valid_from;
struct by_expires;
using son_wallet_multi_index_type = multi_index_container<
son_wallet_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_valid_from>,
member<son_wallet_object, time_point_sec, &son_wallet_object::valid_from>
>,
ordered_unique< tag<by_expires>,
member<son_wallet_object, time_point_sec, &son_wallet_object::expires>
>
>
>;
using son_wallet_index = generic_index<son_wallet_object, son_wallet_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::son_wallet_object, (graphene::db::object),
(valid_from) (expires) (addresses) (sons) )

View file

@ -0,0 +1,24 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
namespace graphene { namespace chain {
class create_son_wallet_withdraw_evaluator : public evaluator<create_son_wallet_withdraw_evaluator>
{
public:
typedef son_wallet_withdraw_create_operation operation_type;
void_result do_evaluate(const son_wallet_withdraw_create_operation& o);
object_id_type do_apply(const son_wallet_withdraw_create_operation& o);
};
class process_son_wallet_withdraw_evaluator : public evaluator<process_son_wallet_withdraw_evaluator>
{
public:
typedef son_wallet_withdraw_process_operation operation_type;
void_result do_evaluate(const son_wallet_withdraw_process_operation& o);
object_id_type do_apply(const son_wallet_withdraw_process_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,68 @@
#pragma once
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/sidechain_defs.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class son_wallet_withdraw_object
* @brief tracks information about a SON wallet withdrawal.
* @ingroup object
*/
class son_wallet_withdraw_object : public abstract_object<son_wallet_withdraw_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = son_wallet_withdraw_object_type;
time_point_sec timestamp;
uint32_t block_num;
sidechain_type sidechain = sidechain_type::unknown;
std::string peerplays_uid;
std::string peerplays_transaction_id;
chain::account_id_type peerplays_from;
chain::asset peerplays_asset;
sidechain_type withdraw_sidechain;
std::string withdraw_address;
std::string withdraw_currency;
safe<int64_t> withdraw_amount;
std::map<son_id_type, weight_type> expected_reports;
std::set<son_id_type> received_reports;
bool confirmed = false;
bool processed = false;
};
struct by_peerplays_uid;
struct by_withdraw_sidechain_and_confirmed_and_processed;
using son_wallet_withdraw_multi_index_type = multi_index_container<
son_wallet_withdraw_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_peerplays_uid>,
member<son_wallet_withdraw_object, std::string, &son_wallet_withdraw_object::peerplays_uid>
>,
ordered_non_unique< tag<by_withdraw_sidechain_and_confirmed_and_processed>,
composite_key<son_wallet_withdraw_object,
member<son_wallet_withdraw_object, sidechain_type, &son_wallet_withdraw_object::withdraw_sidechain>,
member<son_wallet_withdraw_object, bool, &son_wallet_withdraw_object::confirmed>,
member<son_wallet_withdraw_object, bool, &son_wallet_withdraw_object::processed>
>
>
>
>;
using son_wallet_withdraw_index = generic_index<son_wallet_withdraw_object, son_wallet_withdraw_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object),
(timestamp) (block_num) (sidechain)
(peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset)
(withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount)
(expected_reports) (received_reports)
(confirmed) (processed) )

View file

@ -118,10 +118,32 @@ namespace graphene { namespace chain {
void on_withdraw(const vesting_policy_context& ctx); void on_withdraw(const vesting_policy_context& ctx);
}; };
/**
* @brief Cant withdraw anything while balance is in this policy.
*
* This policy is needed to register SON users where balance may be claimable only after
* the SON object is deleted(plus a linear policy).
* When deleting a SON member the dormant mode will be replaced by a linear policy.
*
* @note New funds may not be added to a dormant vesting balance.
*/
struct dormant_vesting_policy
{
asset get_allowed_withdraw(const vesting_policy_context& ctx)const;
bool is_deposit_allowed(const vesting_policy_context& ctx)const;
bool is_deposit_vested_allowed(const vesting_policy_context&)const { return false; }
bool is_withdraw_allowed(const vesting_policy_context& ctx)const;
void on_deposit(const vesting_policy_context& ctx);
void on_deposit_vested(const vesting_policy_context&)
{ FC_THROW( "May not deposit vested into a linear vesting balance." ); }
void on_withdraw(const vesting_policy_context& ctx);
};
typedef fc::static_variant< typedef fc::static_variant<
linear_vesting_policy, linear_vesting_policy,
cdd_vesting_policy cdd_vesting_policy,
> vesting_policy; dormant_vesting_policy
> vesting_policy;
/** /**
* Vesting balance object is a balance that is locked by the blockchain for a period of time. * Vesting balance object is a balance that is locked by the blockchain for a period of time.
@ -140,7 +162,7 @@ namespace graphene { namespace chain {
/// The vesting policy stores details on when funds vest, and controls when they may be withdrawn /// The vesting policy stores details on when funds vest, and controls when they may be withdrawn
vesting_policy policy; vesting_policy policy;
/// We can have 2 types of vesting, gpos and all the rest /// We can have 3 types of vesting, gpos, son and the rest
vesting_balance_type balance_type = vesting_balance_type::normal; vesting_balance_type balance_type = vesting_balance_type::normal;
vesting_balance_object() {} vesting_balance_object() {}
@ -224,6 +246,8 @@ FC_REFLECT(graphene::chain::cdd_vesting_policy,
(coin_seconds_earned_last_update) (coin_seconds_earned_last_update)
) )
FC_REFLECT(graphene::chain::dormant_vesting_policy, )
FC_REFLECT_TYPENAME( graphene::chain::vesting_policy ) FC_REFLECT_TYPENAME( graphene::chain::vesting_policy )
FC_REFLECT_DERIVED(graphene::chain::vesting_balance_object, (graphene::db::object), FC_REFLECT_DERIVED(graphene::chain::vesting_balance_object, (graphene::db::object),

View file

@ -63,6 +63,17 @@ struct vote_counter
out_auth = auth; out_auth = auth;
} }
void finish_2_3( authority& out_auth )
{
if( total_votes == 0 )
return;
assert( total_votes <= std::numeric_limits<uint32_t>::max() );
uint32_t weight = uint32_t( total_votes );
weight = (weight * 2 / 3) + 1;
auth.weight_threshold = weight;
out_auth = auth;
}
bool is_empty()const bool is_empty()const
{ {
return (total_votes == 0); return (total_votes == 0);

View file

@ -30,6 +30,9 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
class witness_schedule_object;
class son_schedule_object;
typedef hash_ctr_rng< typedef hash_ctr_rng<
/* HashClass = */ fc::sha256, /* HashClass = */ fc::sha256,
/* SeedLength = */ GRAPHENE_RNG_SEED_LENGTH /* SeedLength = */ GRAPHENE_RNG_SEED_LENGTH
@ -51,6 +54,22 @@ typedef generic_far_future_witness_scheduler<
/* debug = */ true /* debug = */ true
> far_future_witness_scheduler; > far_future_witness_scheduler;
typedef generic_witness_scheduler<
/* WitnessID = */ son_id_type,
/* RNG = */ witness_scheduler_rng,
/* CountType = */ decltype( chain_parameters::extensions.value.maximum_son_count )::value_type,
/* OffsetType = */ uint32_t,
/* debug = */ true
> son_scheduler;
typedef generic_far_future_witness_scheduler<
/* WitnessID = */ son_id_type,
/* RNG = */ witness_scheduler_rng,
/* CountType = */ decltype( chain_parameters::extensions.value.maximum_son_count )::value_type,
/* OffsetType = */ uint32_t,
/* debug = */ true
> far_future_son_scheduler;
class witness_schedule_object : public graphene::db::abstract_object<witness_schedule_object> class witness_schedule_object : public graphene::db::abstract_object<witness_schedule_object>
{ {
public: public:
@ -71,6 +90,26 @@ class witness_schedule_object : public graphene::db::abstract_object<witness_sch
fc::uint128 recent_slots_filled; fc::uint128 recent_slots_filled;
}; };
class son_schedule_object : public graphene::db::abstract_object<son_schedule_object>
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_son_schedule_object_type;
vector< son_id_type > current_shuffled_sons;
son_scheduler scheduler;
uint32_t last_scheduling_block;
uint64_t slots_since_genesis = 0;
fc::array< char, sizeof(secret_hash_type) > rng_seed;
/**
* Not necessary for consensus, but used for figuring out the participation rate.
* The nth bit is 0 if the nth slot was unfilled, else it is 1.
*/
fc::uint128 recent_slots_filled;
};
} } } }
@ -94,6 +133,26 @@ FC_REFLECT_DERIVED(
(recent_slots_filled) (recent_slots_filled)
(current_shuffled_witnesses) (current_shuffled_witnesses)
) )
FC_REFLECT( graphene::chain::son_scheduler,
(_turns)
(_tokens)
(_min_token_count)
(_ineligible_waiting_for_token)
(_ineligible_no_turn)
(_eligible)
(_schedule)
(_lame_duck)
)
FC_REFLECT_DERIVED(
graphene::chain::son_schedule_object,
(graphene::db::object),
(scheduler)
(last_scheduling_block)
(slots_since_genesis)
(rng_seed)
(recent_slots_filled)
(current_shuffled_sons)
)
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_scheduler ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_scheduler )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_schedule_object ) GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::witness_schedule_object )

Some files were not shown because too many files have changed in this diff Show more