Compare commits

..

84 commits

Author SHA1 Message Date
Nathaniel
f9fcffbb4d
Safety Check: Part 2 -- Implement and Integrate Checks
Implement a safety check mechanism on object_database, based on the
safety_check_policy abstract interface. Create two standard
implementations of the safety_check_policy interface, one
(null_safety_check) which allows all modifications unconditionally, and
the other (database_lock_safety_check) which allows modifications only
when unlocked.

Integrate these safety checks into chain::database and plugins, so that
the consensus databases are locked at all times except during core
consensus code pathways. Also ensures that databases are re-locked when
calling code outside of consensus pathways from consensus pathways.

To make this work, it was necessary to move two objects from the
consensus object spaces to a new API object space. The
operation_history_object and account_transaction_history_object were
moved to the API object space, as they are not actually used by
consensus and are maintained by a plugin (which can no longer modify the
consensus object spaces, due to the safety checks).

Finally, add a mechanism to application and chain::database, which
allows the chain to start in "unit testing mode" and allows unchecked
actions upon the database within delimited scopes. This was necessary
because many tests edit the database directly to set up the environment
for their respective tests. This mode is activated by database_fixture so
tests can utilize it conveniently, but it is architecturally difficult to
enable this mode in production, i.e. from a plugin.
2022-03-12 14:04:08 -06:00
Nathaniel
e8b432c19f
Safety Check: Part 1 -- Evaluator Tagging
Pursuant to the requested safety checks on the database, to ensure that
plugin code (i.e., third party code) cannot modify the database, we
implement evaluator tagging so the chain can distinguish between
consensus evaluators and third party evaluators. Also, define a new kind
of evaluator base class, third_party_evaluator, so that fees are not
charged multiple times for operations with multiple evaluators.

Next step, implement the actual safety check mechanism on the database.
2022-03-07 16:37:53 -06:00
Nathaniel
659d135b9b
Merge remote-tracking branch 'glu/develop' into dapp-support 2022-02-13 14:25:06 -06:00
Nathaniel
2da369453e
Merge branch 'develop' into dapp-support 2022-02-08 13:15:07 -06:00
Nathaniel
d2ced50bbf
Bump FC 2022-02-08 11:27:26 -06:00
serkixenos
c456d4ec6b
Update README.md 2022-02-08 11:26:34 -06:00
serkixenos
f46a223dce
Update README for Ubuntu 20.04 2022-02-08 11:26:34 -06:00
serkixenos
7c7f768ce4
Replace vulnerable XML library 2022-02-08 11:26:34 -06:00
Vlad Dobromyslov
3a7187baba
bug #245 exception seen in witness logs 2022-02-08 11:26:34 -06:00
Vlad Dobromyslov
45e501b916
Resolve "port ES changes from Bitshares" 2022-02-08 11:26:34 -06:00
Vlad Dobromyslov
62a553ab5f
bug #267 Fix error in chain_test in gitlab autobuild 2022-02-08 11:26:34 -06:00
serkixenos
8c402d2e70
Fix list_active_son command output on deregistered SONs 2022-02-08 11:26:34 -06:00
serkixenos
dcdf406a2d
Fix cli wallet memo displaying 2022-02-08 11:26:34 -06:00
Nathaniel Hourt
ee0d2b21e0
Fix build
In some environments, build fails here due to `curl` dependency not being linked in time for `utilities` to see it.
2022-01-29 16:21:13 -06:00
Nathaniel Hourt
2a37d8a0a1
Fix build
In some environments, this fails to build without this header.
2022-01-27 15:29:23 -06:00
Nathaniel
f667fda2e4
Merge remote-tracking branch 'origin/beatrice' into to-upstream 2022-01-26 13:16:02 -06:00
Nathaniel
d17eb5ec72
Add wallet command for custom_operation
Create a new cli_wallet command, run_custom_operation, which makes it
convenient to run custom_operation transactions which invoke third party
contracts (i.e., dapps)
2022-01-14 20:10:16 -06:00
Nathaniel
de87e1b82c
Canonicalize chain ID calculation
When using an external genesis file, it doesn't make sense to calculate
the chain ID as the literal text contents of the file, which are quite
volatile. Rather, it should be calculated based on the logical content
of the file. Serialize the genesis object to get a canonical
representation, and calculate the chain ID off of that.
2022-01-12 16:55:45 -06:00
Nathaniel
c833ca646f
Set CMAKE_INSTALL_RPATH for dynamic builds
When building dynamic libraries, set the RPATH so that binaries know
where to find their libraries.
2022-01-12 16:55:01 -06:00
Nathaniel
fe02a13685
Replace count_objects_in_space with inspect_all_indexes
The count_objects_in_space function, while providing the necessary
functionality, was clumsy and inconvenient, and was not idiomatic.
Replace it with inspect_all_indexes which resolves these shortcomings.
2022-01-05 17:27:52 -06:00
Nathaniel Hourt
25faf9b084
Merge pull request #2 from MichelSantos/graphene-dapp-support
Adjustments for snapshot validation
2022-01-04 13:06:42 -06:00
Michel Santos
4fea001586 Fix Bookie plugin to provide a consistent data state
even when the node is started in replay mode
2022-01-03 10:24:32 -05:00
Michel Santos
8ec87b404f Enhance secondary_index
Enhance secondary_index by distinguishing between
previous objects loaded from persistence versus
new objects created during the session
2022-01-03 09:49:44 -05:00
Michel Santos
8325b25d0e Harmonize the activation date of GPOS 2022-01-03 09:49:44 -05:00
Michel Santos
c2675b4423 Re-allow build of programs for compatibility with Commit 082df7 2022-01-03 09:49:44 -05:00
Nathaniel
5fe3408893
Allow querying number of objects in object space
Previously, there was no good way to determine how many objects are in
an object space. Add a way to do so.
2022-01-02 14:50:17 -06:00
Nathaniel
d2dedbc4e4
Remove database unity build
Upstream dropped it and it was causing problems, so let it go!
2022-01-02 14:32:56 -06:00
Nathaniel
8df442a65f
Add secondary_index concerns
Add a way to create a secondary index with the space/type ID of the
object rather than the compile-time type, which may not always be
available.

Also, add a way to delete a secondary index (whether by compile-time
type or by object space/type ID).
2022-01-02 14:22:03 -06:00
Michel Santos
a5a78dacf1 Update fc to merger of latest-fc into dapp-support-fc 2021-11-13 08:42:42 -05:00
Michel Santos
c8cfaeb529 Fix test by reverting to the original timestamp used for the genesis 2021-11-11 18:48:49 -05:00
Michel Santos
ec66970d78 Add missing header 2021-11-11 18:48:43 -05:00
Nathan Hourt
906ffa6351 Fix tests better
The solution being used for initializing the boost test modules is
now deprecated, so update it to use the global test fixture instead
2021-11-11 14:38:36 -05:00
Nathan Hourt
8a6bae6006 Fix tests
These tests did not properly define their BOOST_TEST_MODULE macro,
causing linking to fail in some environments.
2021-11-11 14:35:53 -05:00
Nathan Hourt
0c320fdc71 Add missing header 2021-11-11 14:35:53 -05:00
Nathan Hourt
0d18523d8f Fix dynamic build
In some environments, dynamic linking fails if Boost is static
2021-11-11 14:32:47 -05:00
Nathan Hourt
95afb342c3 Fix to dynamic builds
FC wasn't always getting the memo that it should build dynamically
if Graphene is.
2021-11-11 14:31:47 -05:00
Nathan Hourt
e168d2d830 Fix install of hardfork.hpp 2021-11-11 14:29:34 -05:00
Nathan Hourt
3f50447013 Fix dynamic libs build 2021-11-11 14:29:34 -05:00
Nathan Hourt
c76e1f3157 Toward dynamically reloading contracts...
Add the ability to dynamically unload an auxiliary evaluator (any
evaluator for a given operation type except the first one registered for
that operation type), and as an added convenience, add an idiomatically
consistent way to check if a given index is already registered or not.
2021-11-11 14:27:50 -05:00
Nathan Hourt
082df7ab4a Allow build of dynamic libraries
In order to support dynamically linked nodes based on Graphene, add
support for building dynamic libraries for the core Graphene
modules: chain, db, protocol, net, and utilities.
2021-11-11 14:20:40 -05:00
Nathan Hourt
95d4cbdf4a Add build/IDE artifacts to gitignore 2021-11-11 11:25:47 -05:00
Nathan Hourt
ab113b2fc4 Add support for multiple evaluators per operation type
This commit adds the ability to register multiple evaluator types for a
given operation type. This will be used to allow plug-ins to define their
own evaluators for various operation types (most notably, custom
operations) so that they may be used to carry app-specific data which can
be parsed by a plug-in.
2021-11-11 11:25:47 -05:00
Nathan Hourt
4d836dacb9 Ref !3/#376: Graphene Updates
This adds the most important updates to Graphene from BitShares. Most notably,
https://github.com/bitshares/bitshares-core/issues/1506

Second most notably, it updates Peerplays' FC to be in sync with BitShares FC.

This is a squash commit of several subcommits. The subcommit messages are
reproduced below:

Replace fc::uint128 with boost::multiprecision::uint128_t

replace smart_ref with shared_ptr

Fixes/Remove Unused

Remove NTP time

Remove old macro

This macro is now in FC, so no need to define it here anymore

Replaced fc::array with std::array

Separate exception declaration and implementation

Adapted to fc promise changes

Fixes

Add back in some of Peter's fixes that got lost in the cherry pick

_hash endianness fixes

Remove all uses of fc/smart_ref

It's gone, can't use it anymore

Replace improper static_variant operator overloads with comparators

Fixes

Remove boost::signals from build system; it's header-only so it's not
listed in cmake anymore.

Also remove some unused hashing code

Impl. pack/unpack functions for extension class

Ref #1506: Isolate chain/protocol to its own library

Ref #1506: Add object_downcast_t

Allows the more concise expression `object_downcast_t<xyz>` instead of
the old `typename object_downcast<xyz>::type`

Ref #1506: Move ID types from db to protocol

The ID types, object_id and object_id_type, were defined in the db
library, and the protocol library depends on db to get these types.
Technically, the ID types are defined by the protocol and used by the
database, and not vice versa. Therefore these types should be in the
protocol library, and db should depend on protocol to get them.

This commit makes it so.

Ref #1506: Isolate chain/protocol to its own library

Remove commented-out index code

Wrap overlength line

Remove unused key types

Probably fix Docker build

Fix build after rebase

Ref #1506/#1737: Some requested changes

Ref #1506/#1737: Macro-fy ID type definitions

Define macros to fully de-boilerplate ID type definitions.

Externalities:
 - Rename transaction_object -> transaction_history_object
 - Rename impl_asset_dynamic_data_type ->
impl_asset_dynamic_data_object_type
 - Rename impl_asset_bitasset_data_type ->
impl_asset_bitasset_data_object_type

The first is to avoid a naming collision on transaction_id_type, and the
other two are to maintain consistency with the naming of the other
types.

Ref #1506/#1737: Fix clean_name()

Ref #1506/#1737: Oops

Fix .gitignore

Externalized serialization in protocol library

Fix compile sets

Delete a couple of ghost files that were in the tree but not part
of the project (I accidentally added them to CMakeLists while
merging, but they're broken and not part of the Peerplays code), and
add several files that got dropped from the build during merge.

General fixes

Fix warnings, build issues, unused code, etc.

Fix #1772 by decprecating cli_wallet -H

More fixes

Fix errors and warnings and generally coax it to build

Fix test

I'm pretty sure this didn't break from what I did... But I can't build
the original code, so I can't tell. Anyways, this one now passes...
Others still fail...

Small fix

Fix crash in auth checks

Final fixes

Last round of fixes following the rebase to Beatrice

Rename project in CMakeLists.txt

The CMakeLists.txt declared this project as BitShares and not Peerplays,
which makes it confusing in IDEs. Rename it to be clear which project is
open.

Resolve #374

Replace all object refs in macros with IDs, and fix affected tests to look
up objects by ID rather than using invalidated refs.

A full audit of all tests should be performed to eliminate any further
usage of invalidated object references.

Resolve #373: Add object notifiers

Various fixes

Fixes to various issues, primarily reflections, that cropped up
during merge conflict resolution

Fix startup bug in Bookie plugin

Bookie plugin was preventing the node from starting up because it
registered its secondary indexes to create objects in its own primary
indexes to track objects being created in other primary indexes, and did
so during its `initialize()` step, which is to say, before the database
was loaded from disk at startup. This caused the secondary indexes to
create tracker objects when the observed indexes were loading objects
from disk. This then caused a failure when these tracker indexes were
later loaded from disk, and the first object IDs collided.

This is fixed by refraining from defining secondary indexes until the
`startup()` stage rather than the `initialize()` stage. Primary indexes
are registered in `initialize()`, secondary indexes are registered in
`startup()`.

This also involved adding a new method, "add_secondary_index()", to
`object_database`, as before there was no way to do this because you
couldn't get a non-const index from a non-const database.

I have no idea how this was working before I got here...

Fix egenesis install

Fixes after updates

Rebase on updated develop branch and fix conflicts
2021-11-11 11:25:47 -05:00
Michel Santos
111ac16e92 Merge branch master into graphene-updates 2021-11-09 16:24:26 -05:00
Nathan Hourt
ed7b8b60e0
Resolve #373: Add object notifiers 2020-08-27 20:07:36 -05:00
Nathan Hourt
f2d4bce003
Resolve #374
Replace all object refs in macros with IDs, and fix affected tests to look
up objects by ID rather than using invalidated refs.

A full audit of all tests should be performed to eliminate any further
usage of invalidated object references.
2020-08-27 18:55:37 -05:00
Nathan Hourt
6b59f8269f
Rename project in CMakeLists.txt
The CMakeLists.txt declared this project as BitShares and not Peerplays,
which makes it confusing in IDEs. Rename it to be clear which project is
open.
2020-08-25 13:02:45 -05:00
Nathan Hourt
4e3e0e010a
Final fixes
Last round of fixes following the rebase to Beatrice
2020-08-25 13:01:51 -05:00
Nathan Hourt
a9135cbdd2
Fix crash in auth checks 2020-08-23 19:31:38 -05:00
Nathan Hourt
3dd78de312
Small fix 2020-08-23 14:51:47 -05:00
Nathan Hourt
ce8caae327
Fix test
I'm pretty sure this didn't break from what I did... But I can't build
the original code, so I can't tell. Anyways, this one now passes...
Others still fail...
2020-08-23 14:51:47 -05:00
Nathan Hourt
b8c3e63f1b
More fixes
Fix errors and warnings and generally coax it to build
2020-08-23 14:51:47 -05:00
Peter Conrad
a31e56f531
Fix #1772 by decprecating cli_wallet -H 2020-08-23 14:51:47 -05:00
Nathan Hourt
1c0de74aa7
General fixes
Fix warnings, build issues, unused code, etc.
2020-08-23 14:51:45 -05:00
Nathan Hourt
2af062e7cf
Fix compile sets
Delete a couple of ghost files that were in the tree but not part
of the project (I accidentally added them to CMakeLists while
merging, but they're broken and not part of the Peerplays code), and
add several files that got dropped from the build during merge.
2020-08-23 14:43:21 -05:00
Peter Conrad
9ae796c0a2
Externalized serialization in protocol library 2020-08-23 14:43:21 -05:00
Nathan Hourt
841c6319f9
Fix .gitignore 2020-08-23 14:43:21 -05:00
Nathan Hourt
d02bea9ef0
Ref #1506/#1737: Oops 2020-08-23 14:43:21 -05:00
Nathan Hourt
f2814a451c
Ref #1506/#1737: Fix clean_name() 2020-08-23 14:43:21 -05:00
Nathan Hourt
c94e46f451
Ref #1506/#1737: Macro-fy ID type definitions
Define macros to fully de-boilerplate ID type definitions.

Externalities:
 - Rename transaction_object -> transaction_history_object
 - Rename impl_asset_dynamic_data_type ->
impl_asset_dynamic_data_object_type
 - Rename impl_asset_bitasset_data_type ->
impl_asset_bitasset_data_object_type

The first is to avoid a naming collision on transaction_id_type, and the
other two are to maintain consistency with the naming of the other
types.
2020-08-23 14:43:19 -05:00
Nathan Hourt
6074749813
Ref #1506/#1737: Some requested changes 2020-08-23 14:37:35 -05:00
Nathan Hourt
ad670ecde1
Fix build after rebase 2020-08-23 14:37:02 -05:00
Nathan Hourt
f57dc27f55
Probably fix Docker build 2020-08-23 14:37:02 -05:00
Nathan Hourt
35d864e269
Remove unused key types 2020-08-23 14:37:02 -05:00
Nathan Hourt
3a15577617
Wrap overlength line 2020-08-23 14:37:02 -05:00
Nathan Hourt
9a52c29023
Remove commented-out index code 2020-08-23 14:37:02 -05:00
Nathan Hourt
9c71579d6e
Ref #1506: Isolate chain/protocol to its own library 2020-08-23 14:37:02 -05:00
Nathan Hourt
f076bb2586
Ref #1506: Move ID types from db to protocol
The ID types, object_id and object_id_type, were defined in the db
library, and the protocol library depends on db to get these types.
Technically, the ID types are defined by the protocol and used by the
database, and not vice versa. Therefore these types should be in the
protocol library, and db should depend on protocol to get them.

This commit makes it so.
2020-08-23 14:37:02 -05:00
Nathan Hourt
9bada13735
Ref #1506: Add object_downcast_t
Allows the more concise expression `object_downcast_t<xyz>` instead of
the old `typename object_downcast<xyz>::type`
2020-08-23 14:37:02 -05:00
Nathan Hourt
14f627c014
Ref #1506: Isolate chain/protocol to its own library 2020-08-23 14:37:00 -05:00
abitmore
d54cc47a4f
Impl. pack/unpack functions for extension class 2020-08-23 14:18:59 -05:00
Nathan Hourt
9ac63ce0b3
Fixes
Remove boost::signals from build system; it's header-only so it's not
listed in cmake anymore.

Also remove some unused hashing code
2020-08-23 14:18:59 -05:00
Nathan Hourt
13a76d25ac
Replace improper static_variant operator overloads with comparators 2020-08-23 14:18:59 -05:00
Nathan Hourt
54ce371a4a
Remove all uses of fc/smart_ref
It's gone, can't use it anymore
2020-08-23 14:18:59 -05:00
Peter Conrad
68c57a7414
_hash endianness fixes 2020-08-23 14:18:59 -05:00
Nathan Hourt
cc77a08891
Fixes
Add back in some of Peter's fixes that got lost in the cherry pick
2020-08-23 14:18:59 -05:00
Peter Conrad
7eb3729cc0
Adapted to fc promise changes 2020-08-23 14:18:59 -05:00
Peter Conrad
784221986a
Separate exception declaration and implementation 2020-08-23 14:18:59 -05:00
Peter Conrad
0569efc068
Replaced fc::array with std::array 2020-08-23 14:18:59 -05:00
Nathan Hourt
ced4380664
Remove old macro
This macro is now in FC, so no need to define it here anymore
2020-08-23 14:18:55 -05:00
Vikram Rajkumar
10adf05881
Remove NTP time 2020-08-23 14:18:24 -05:00
Nathan Hourt
953a1314a3
Fixes/Remove Unused 2020-08-23 14:18:24 -05:00
John Jones
a24a6bfc68
replace smart_ref with shared_ptr 2020-08-23 14:18:22 -05:00
Peter Conrad
f25c4f6ae6
Replace fc::uint128 with boost::multiprecision::uint128_t 2020-08-23 14:16:41 -05:00
460 changed files with 12654 additions and 17435 deletions

View file

@ -1,5 +1,6 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -3
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
@ -11,7 +12,7 @@ AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: None
@ -56,7 +57,6 @@ ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 6
ContinuationIndentWidth: 6
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
@ -69,17 +69,12 @@ IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 3
IndentWrappedFunctionNames: false
@ -115,22 +110,18 @@ SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 3
UseCRLF: false
UseTab: Never
...

4
.gitignore vendored
View file

@ -1,6 +1,10 @@
*.a
*.sw*
/build
/build-*
CMakeLists.txt.user
*.cmake
CMakeCache.txt
CMakeFiles

View file

@ -8,11 +8,8 @@ include:
stages:
- build
- test
- dockerize
- python-test
- deploy
build-mainnet:
build:
stage: build
script:
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc
@ -22,7 +19,7 @@ build-mainnet:
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release ..
- make -j$(nproc)
- make -j4
artifacts:
untracked: true
paths:
@ -32,140 +29,28 @@ build-mainnet:
tags:
- builder
test-mainnet:
stage: test
dependencies:
- build-mainnet
script:
- ./build/libraries/fc/tests/all_tests
- ./build/tests/betting_test --log_level=message
- ./build/tests/chain_test --log_level=message
- ./build/tests/cli_test --log_level=message
tags:
- builder
dockerize-mainnet:
stage: dockerize
variables:
IMAGE: $CI_REGISTRY_IMAGE/mainnet/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
before_script:
- docker info
- docker builder prune -a -f
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker build --no-cache -t $IMAGE .
- docker push $IMAGE
after_script:
- docker rmi $IMAGE
tags:
- builder
timeout:
3h
build-testnet:
dockerize:
stage: build
variables:
IMAGE: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
before_script:
- docker info
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc
- git submodule sync
- git submodule update --init --recursive
- rm -rf build
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 ..
- make -j$(nproc)
artifacts:
untracked: true
paths:
- build/libraries/
- build/programs/
- build/tests/
when: manual
- docker build -t $IMAGE .
- docker push $IMAGE
tags:
- builder
when: manual
timeout: 3h
deploy-testnet:
stage: deploy
dependencies:
- build-testnet
script:
- sudo systemctl stop witness
- rm $WORK_DIR/peerplays/witness_node || true
- cp build/programs/witness_node/witness_node $WORK_DIR/peerplays/
- sudo systemctl restart witness
rules:
- if: $CI_COMMIT_BRANCH == "master"
when: always
environment:
name: devnet
url: $DEVNET_URL
tags:
- devnet
test-testnet:
test:
stage: test
dependencies:
- build-testnet
- build
script:
- ./build/libraries/fc/tests/all_tests
- ./build/tests/betting_test --log_level=message
- ./build/tests/chain_test --log_level=message
- ./build/tests/cli_test --log_level=message
tags:
- builder
when:
manual
timeout:
1h
dockerize-testnet:
stage: dockerize
variables:
IMAGE: $CI_REGISTRY_IMAGE/testnet/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
before_script:
- docker info
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker build --no-cache -t $IMAGE .
- docker push $IMAGE
after_script:
- docker rmi $IMAGE
tags:
- builder
when:
manual
timeout:
3h
test-e2e:
stage: python-test
variables:
IMAGE: $CI_REGISTRY_IMAGE/mainnet/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA
before_script:
- docker info
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- git clone https://gitlab.com/PBSA/tools-libs/peerplays-utils.git
- cd peerplays-utils/peerplays-qa-environment
- git checkout origin/feature/python-e2e-tests-for-CI
- cd e2e-tests/
- python3 -m venv venv
- source venv/bin/activate
- pip3 install -r requirements.txt
- docker-compose down --remove-orphans
- docker ps -a
- docker pull $IMAGE
- docker tag $IMAGE peerplays-base:latest
- docker image ls -a
- docker-compose build
- python3 main.py --start all
- docker ps -a
- python3 -m pytest test_btc_init_state.py test_hive_inital_state.py test_pp_inital_state.py
- python3 main.py --stop
- deactivate
- docker ps -a
after_script:
- docker rmi $(docker images -a | grep -v 'hive-for-peerplays\|ethereum-for-peerplays\|bitcoin-for-peerplays\|ubuntu-for-peerplays' | awk '{print $3}')
tags:
- python-tests
when:
manual

2
.gitmodules vendored
View file

@ -5,5 +5,5 @@
[submodule "libraries/fc"]
path = libraries/fc
url = https://gitlab.com/PBSA/tools-libs/peerplays-fc.git
branch = develop
branch = dapp-support
ignore = dirty

View file

@ -8,6 +8,15 @@ set( CLI_CLIENT_EXECUTABLE_NAME graphene_client )
set( GUI_CLIENT_EXECUTABLE_NAME Peerplays )
set( CUSTOM_URL_SCHEME "gcs" )
set( INSTALLER_APP_ID "68ad7005-8eee-49c9-95ce-9eed97e5b347" )
set( CMAKE_CXX_STANDARD 14 )
set( GRAPHENE_BUILD_DYNAMIC_LIBRARIES OFF CACHE BOOL
"Whether to build dynamic libraries instead of static. Applies only to chain, db, protocol, net, and utilities" )
if( GRAPHENE_BUILD_DYNAMIC_LIBRARIES )
set( CMAKE_POSITION_INDEPENDENT_CODE ON )
set( CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib" )
endif()
set( FC_BUILD_DYNAMIC_LIBRARIES ${GRAPHENE_BUILD_DYNAMIC_LIBRARIES} CACHE BOOL "Whether FC should build as a dynamic library rather than static" )
# http://stackoverflow.com/a/18369825
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
@ -22,37 +31,6 @@ endif()
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" )
function(get_linux_lsb_release_information)
find_program(LSB_RELEASE_EXEC lsb_release)
if(NOT LSB_RELEASE_EXEC)
message(FATAL_ERROR "Could not detect lsb_release executable, can not gather required information")
endif()
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --id OUTPUT_VARIABLE LSB_RELEASE_ID_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --release OUTPUT_VARIABLE LSB_RELEASE_VERSION_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND "${LSB_RELEASE_EXEC}" --short --codename OUTPUT_VARIABLE LSB_RELEASE_CODENAME_SHORT OUTPUT_STRIP_TRAILING_WHITESPACE)
set(LSB_RELEASE_ID_SHORT "${LSB_RELEASE_ID_SHORT}" PARENT_SCOPE)
set(LSB_RELEASE_VERSION_SHORT "${LSB_RELEASE_VERSION_SHORT}" PARENT_SCOPE)
set(LSB_RELEASE_CODENAME_SHORT "${LSB_RELEASE_CODENAME_SHORT}" PARENT_SCOPE)
endfunction()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
find_package(cppzmq)
target_link_libraries(cppzmq)
get_linux_lsb_release_information()
message(STATUS "Linux ${LSB_RELEASE_ID_SHORT} ${LSB_RELEASE_VERSION_SHORT} ${LSB_RELEASE_CODENAME_SHORT}")
string(REGEX MATCHALL "([0-9]+)" arg_list ${LSB_RELEASE_VERSION_SHORT})
list( LENGTH arg_list listlen )
if (NOT listlen)
message(FATAL_ERROR "Could not detect Ubuntu version")
endif()
list(GET arg_list 0 output)
message("Ubuntu version is: ${output}")
add_definitions(-DPEERPLAYS_UBUNTU_VERSION=${output})
endif()
# function to help with cUrl
macro(FIND_CURL)
if (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB)
@ -119,7 +97,12 @@ LIST(APPEND BOOST_COMPONENTS thread
unit_test_framework
context
locale)
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
IF( ${GRAPHENE_BUILD_DYNAMIC_LIBRARIES} )
SET( Boost_USE_STATIC_LIBS OFF CACHE STRING "ON or OFF" )
ELSE()
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
ENDIF()
IF( WIN32 )
SET(BOOST_ROOT $ENV{BOOST_ROOT})
@ -173,11 +156,11 @@ else( WIN32 ) # Apple AND Linux
if( APPLE )
# Apple Specific Options Here
message( STATUS "Configuring Peerplays on OS X" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -stdlib=libc++ -Wall" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -stdlib=libc++ -Wall" )
else( APPLE )
# Linux Specific Options Here
message( STATUS "Configuring Peerplays on Linux" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -Wall" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall" )
set( rt_library rt )
#set( pthread_library pthread)
set(CMAKE_LINKER_FLAGS "-pthread" CACHE STRING "Linker Flags" FORCE)

View file

@ -1,4 +1,5 @@
FROM ubuntu:20.04
MAINTAINER PeerPlays Blockchain Standards Association
#===============================================================================
# Ubuntu setup
@ -10,33 +11,35 @@ RUN \
apt-utils \
autoconf \
bash \
bison \
build-essential \
ca-certificates \
cmake \
dnsutils \
doxygen \
expect \
flex \
git \
graphviz \
libboost1.67-all-dev \
libbz2-dev \
libcurl4-openssl-dev \
libncurses-dev \
libreadline-dev \
libsnappy-dev \
libssl-dev \
libtool \
libzip-dev \
libzmq3-dev \
locales \
lsb-release \
mc \
nano \
net-tools \
ntp \
openssh-server \
pkg-config \
perl \
python3 \
python3-jinja2 \
sudo \
systemd-coredump \
wget
ENV HOME /home/peerplays
@ -50,127 +53,12 @@ RUN echo 'peerplays:peerplays' | chpasswd
# SSH
EXPOSE 22
WORKDIR /home/peerplays/src
#===============================================================================
# Boost setup
#===============================================================================
RUN \
wget https://boostorg.jfrog.io/artifactory/main/release/1.72.0/source/boost_1_72_0.tar.gz && \
tar -xzf boost_1_72_0.tar.gz && \
cd boost_1_72_0 && \
./bootstrap.sh && \
./b2 install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# cmake setup
#===============================================================================
RUN \
wget https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2-linux-x86_64.sh && \
chmod 755 ./cmake-3.24.2-linux-x86_64.sh && \
./cmake-3.24.2-linux-x86_64.sh --prefix=/usr --skip-license && \
cmake --version && \
rm -rf /home/peerplays/src/*
#===============================================================================
# libzmq setup
#===============================================================================
RUN \
wget https://github.com/zeromq/libzmq/archive/refs/tags/v4.3.4.tar.gz && \
tar -xzvf v4.3.4.tar.gz && \
cd libzmq-4.3.4 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# cppzmq setup
#===============================================================================
RUN \
wget https://github.com/zeromq/cppzmq/archive/refs/tags/v4.9.0.tar.gz && \
tar -xzvf v4.9.0.tar.gz && \
cd cppzmq-4.9.0 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# gsl setup
#===============================================================================
RUN \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libpcre3-dev
RUN \
wget https://github.com/imatix/gsl/archive/refs/tags/v4.1.4.tar.gz && \
tar -xzvf v4.1.4.tar.gz && \
cd gsl-4.1.4 && \
make -j$(nproc) && \
make install && \
rm -rf /home/peerplays/src/*
#===============================================================================
# libbitcoin-build setup
# libbitcoin-explorer setup
#===============================================================================
RUN \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libsodium-dev
RUN \
git clone --branch version3.8.0 --depth 1 https://gitlab.com/PBSA/peerplays-1.0/libbitcoin-explorer.git && \
cd libbitcoin-explorer && \
./install.sh && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# Doxygen setup
#===============================================================================
RUN \
sudo apt install -y bison flex && \
wget https://github.com/doxygen/doxygen/archive/refs/tags/Release_1_8_17.tar.gz && \
tar -xvf Release_1_8_17.tar.gz && \
cd doxygen-Release_1_8_17 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) install && \
ldconfig
#===============================================================================
# Perl setup
#===============================================================================
RUN \
wget https://github.com/Perl/perl5/archive/refs/tags/v5.30.0.tar.gz && \
tar -xvf v5.30.0.tar.gz && \
cd perl5-5.30.0 && \
./Configure -des && \
make -j$(nproc) install && \
ldconfig
#===============================================================================
# Peerplays setup
#===============================================================================
WORKDIR /home/peerplays/
## Clone Peerplays
#RUN \
# git clone https://gitlab.com/PBSA/peerplays.git && \
@ -186,8 +74,6 @@ ADD . peerplays
# Configure Peerplays
RUN \
cd peerplays && \
git submodule update --init --recursive && \
git log --oneline -n 5 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release ..
@ -201,8 +87,8 @@ WORKDIR /home/peerplays/peerplays-network
# Setup Peerplays runimage
RUN \
ln -s /home/peerplays/src/peerplays/build/programs/cli_wallet/cli_wallet ./ && \
ln -s /home/peerplays/src/peerplays/build/programs/witness_node/witness_node ./
ln -s /home/peerplays/peerplays/build/programs/cli_wallet/cli_wallet ./ && \
ln -s /home/peerplays/peerplays/build/programs/witness_node/witness_node ./
RUN ./witness_node --create-genesis-json genesis.json && \
rm genesis.json

View file

@ -1,219 +0,0 @@
FROM ubuntu:18.04
#===============================================================================
# Ubuntu setup
#===============================================================================
RUN \
apt-get update -y && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
apt-utils \
autoconf \
bash \
bison \
build-essential \
ca-certificates \
dnsutils \
expect \
flex \
git \
graphviz \
libbz2-dev \
libcurl4-openssl-dev \
libncurses-dev \
libsnappy-dev \
libssl-dev \
libtool \
libzip-dev \
locales \
lsb-release \
mc \
nano \
net-tools \
ntp \
openssh-server \
pkg-config \
python3 \
python3-jinja2 \
sudo \
systemd-coredump \
wget
ENV HOME /home/peerplays
RUN useradd -rm -d /home/peerplays -s /bin/bash -g root -G sudo -u 1000 peerplays
RUN echo "peerplays ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/peerplays
RUN chmod 440 /etc/sudoers.d/peerplays
RUN service ssh start
RUN echo 'peerplays:peerplays' | chpasswd
# SSH
EXPOSE 22
WORKDIR /home/peerplays/src
#===============================================================================
# Boost setup
#===============================================================================
RUN \
wget https://boostorg.jfrog.io/artifactory/main/release/1.72.0/source/boost_1_72_0.tar.gz && \
tar -xzf boost_1_72_0.tar.gz && \
cd boost_1_72_0 && \
./bootstrap.sh && \
./b2 install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# cmake setup
#===============================================================================
RUN \
wget https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2-linux-x86_64.sh && \
chmod 755 ./cmake-3.24.2-linux-x86_64.sh && \
./cmake-3.24.2-linux-x86_64.sh --prefix=/usr --skip-license && \
cmake --version && \
rm -rf /home/peerplays/src/*
#===============================================================================
# libzmq setup
#===============================================================================
RUN \
wget https://github.com/zeromq/libzmq/archive/refs/tags/v4.3.4.tar.gz && \
tar -xzvf v4.3.4.tar.gz && \
cd libzmq-4.3.4 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# cppzmq setup
#===============================================================================
RUN \
wget https://github.com/zeromq/cppzmq/archive/refs/tags/v4.9.0.tar.gz && \
tar -xzvf v4.9.0.tar.gz && \
cd cppzmq-4.9.0 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) && \
make install && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# gsl setup
#===============================================================================
RUN \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libpcre3-dev
RUN \
wget https://github.com/imatix/gsl/archive/refs/tags/v4.1.4.tar.gz && \
tar -xzvf v4.1.4.tar.gz && \
cd gsl-4.1.4 && \
make -j$(nproc) && \
make install && \
rm -rf /home/peerplays/src/*
#===============================================================================
# libbitcoin-build setup
# libbitcoin-explorer setup
#===============================================================================
RUN \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libsodium-dev
RUN \
git clone --branch version3.8.0 --depth 1 https://gitlab.com/PBSA/peerplays-1.0/libbitcoin-explorer.git && \
cd libbitcoin-explorer && \
./install.sh && \
ldconfig && \
rm -rf /home/peerplays/src/*
#===============================================================================
# Doxygen setup
#===============================================================================
RUN \
sudo apt install -y bison flex && \
wget https://github.com/doxygen/doxygen/archive/refs/tags/Release_1_8_17.tar.gz && \
tar -xvf Release_1_8_17.tar.gz && \
cd doxygen-Release_1_8_17 && \
mkdir build && \
cd build && \
cmake .. && \
make -j$(nproc) install && \
ldconfig
#===============================================================================
# Perl setup
#===============================================================================
RUN \
wget https://github.com/Perl/perl5/archive/refs/tags/v5.30.0.tar.gz && \
tar -xvf v5.30.0.tar.gz && \
cd perl5-5.30.0 && \
./Configure -des && \
make -j$(nproc) install && \
ldconfig
#===============================================================================
# Peerplays setup
#===============================================================================
## Clone Peerplays
#RUN \
# git clone https://gitlab.com/PBSA/peerplays.git && \
# cd peerplays && \
# git checkout develop && \
# git submodule update --init --recursive && \
# git branch --show-current && \
# git log --oneline -n 5
# Add local source
ADD . peerplays
# Configure Peerplays
RUN \
cd peerplays && \
git submodule update --init --recursive && \
git symbolic-ref --short HEAD && \
git log --oneline -n 5 && \
mkdir build && \
cd build && \
cmake -DCMAKE_BUILD_TYPE=Release ..
# Build Peerplays
RUN \
cd peerplays/build && \
make -j$(nproc) cli_wallet witness_node
WORKDIR /home/peerplays/peerplays-network
# Setup Peerplays runimage
RUN \
ln -s /home/peerplays/src/peerplays/build/programs/cli_wallet/cli_wallet ./ && \
ln -s /home/peerplays/src/peerplays/build/programs/witness_node/witness_node ./
RUN ./witness_node --create-genesis-json genesis.json && \
rm genesis.json
RUN chown peerplays:root -R /home/peerplays/peerplays-network
# Peerplays RPC
EXPOSE 8090
# Peerplays P2P:
EXPOSE 9777
# Peerplays
CMD ["./witness_node", "-d", "./witness_node_data_dir"]

145
README.md
View file

@ -6,129 +6,37 @@ This is a quick introduction to get new developers and witnesses up to speed on
# Building and Installation Instructions
Officially supported OS are Ubuntu 20.04 and Ubuntu 18.04.
Officially supported OS is Ubuntu 20.04.
## Ubuntu 20.04 and 18.04
Following dependencies are needed for a clean install of Ubuntu 20.04 and Ubuntu 18.04:
Following dependencies are needed for a clean install of Ubuntu 20.04:
```
sudo apt-get install \
autoconf bash bison build-essential ca-certificates dnsutils expect flex git \
graphviz libbz2-dev libcurl4-openssl-dev libncurses-dev libpcre3-dev \
libsnappy-dev libsodium-dev libssl-dev libtool libzip-dev locales lsb-release \
mc nano net-tools ntp openssh-server pkg-config python3 python3-jinja2 sudo \
systemd-coredump wget
apt-utils autoconf bash build-essential ca-certificates cmake dnsutils \
doxygen expect git graphviz libboost1.67-all-dev libbz2-dev libcurl4-openssl-dev \
libncurses-dev libreadline-dev libsnappy-dev libssl-dev libtool libzip-dev \
libzmq3-dev locales mc nano net-tools ntp openssh-server pkg-config perl \
python3 python3-jinja2 sudo wget
```
Boost libraries setup:
```
wget https://boostorg.jfrog.io/artifactory/main/release/1.72.0/source/boost_1_72_0.tar.gz
tar -xzf boost_1_72_0.tar.gz boost_1_72_0
cd boost_1_72_0
./bootstrap.sh
./b2
sudo ./b2 install
sudo ldconfig
```
cmake setup:
```
wget https://github.com/Kitware/CMake/releases/download/v3.24.2/cmake-3.24.2-linux-x86_64.sh
chmod 755 ./cmake-3.24.2-linux-x86_64.sh
sudo ./cmake-3.24.2-linux-x86_64.sh --prefix=/usr --skip-license
cmake --version
```
## Building Peerplays
libzmq setup:
```
wget https://github.com/zeromq/libzmq/archive/refs/tags/v4.3.4.tar.gz
tar -xzvf v4.3.4.tar.gz
cd libzmq-4.3.4
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig
```
cppzmq setup:
```
wget https://github.com/zeromq/cppzmq/archive/refs/tags/v4.9.0.tar.gz
tar -xzvf v4.9.0.tar.gz
cd cppzmq-4.9.0
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig
```
gsl setup:
```
wget https://github.com/imatix/gsl/archive/refs/tags/v4.1.4.tar.gz
tar -xzvf v4.1.4.tar.gz
cd gsl-4.1.4
make -j$(nproc)
sudo make install
sudo ldconfig
```
libbitcoin-explorer setup:
```
git clone --branch version3.8.0 --depth 1 https://gitlab.com/PBSA/peerplays-1.0/libbitcoin-explorer.git
cd libbitcoin-explorer
sudo ./install.sh
sudo ldconfig
```
Doxygen setup:
```
wget https://github.com/doxygen/doxygen/archive/refs/tags/Release_1_8_17.tar.gz
tar -xvf Release_1_8_17.tar.gz
cd doxygen-Release_1_8_17
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig
```
Perl setup:
```
wget https://github.com/Perl/perl5/archive/refs/tags/v5.30.0.tar.gz
tar -xvf v5.30.0.tar.gz
cd perl5-5.30.0
./Configure -des
make -j$(nproc)
sudo make install
sudo ldconfig
```
Building Peerplays
```
mkdir $HOME/src
cd $HOME/src
git clone https://gitlab.com/PBSA/peerplays.git
cd peerplays
git submodule update --init --recursive
# If you want to build Mainnet node
cmake -DCMAKE_BUILD_TYPE=Release
# If you want to build Testnet node
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1
# Update -j flag depending on your current system specs;
# Recommended 4GB of RAM per 1 CPU core
# make -j2 for 8GB RAM
# make -j4 for 16GB RAM
# make -j8 for 32GB RAM
make -j$(nproc)
sudo make install # this can install the executable files under /usr/local
make install # this can install the executable files under /usr/local
```
## Docker images
Install docker, and add current user to docker group.
@ -146,36 +54,15 @@ sudo usermod -a -G docker $USER
docker pull datasecuritynode/peerplays:latest
```
### Building docker images manually
### Building docker image manually
```
# Checkout the code
git clone https://gitlab.com/PBSA/peerplays.git
cd peerplays
# Checkout the branch you want
# E.g.
# git checkout beatrice
# git checkout develop
git checkout master
git submodule update --init --recursive
# Execute from the project root, must be a docker group member
# Build docker image, using Ubuntu 20.04 base
docker build --no-cache -f Dockerfile -t peerplays .
# Build docker image, using Ubuntu 18.04 base
docker build --no-cache -f Dockerfile.18.04 -t peerplays-18-04 .
# Build docker image (from the project root, must be a docker group member)
docker build -t peerplays .
```
### Start docker image
```
# Start docker image, using Ubuntu 20.04 base
docker run peerplays:latest
# Start docker image, using Ubuntu 18.04 base
docker run peerplays-18-04:latest
docker start peerplays
```
Rest of the instructions on starting the chain remains same.

View file

@ -3,4 +3,3 @@
find ./libraries/app -regex ".*[c|h]pp" | xargs clang-format -i
find ./libraries/chain/hardfork.d -regex ".*hf" | xargs clang-format -i
find ./libraries/plugins/peerplays_sidechain -regex ".*[c|h]pp" | xargs clang-format -i
find ./programs/cli_wallet -regex ".*[c|h]pp" | xargs clang-format -i

View file

@ -5,7 +5,6 @@ add_subdirectory( egenesis )
add_subdirectory( fc )
add_subdirectory( net )
add_subdirectory( plugins )
add_subdirectory( sha3 )
add_subdirectory( time )
add_subdirectory( utilities )
add_subdirectory( wallet )
add_subdirectory( protocol )

View file

@ -12,10 +12,11 @@ add_library( graphene_app
)
# 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
PUBLIC graphene_net graphene_utilities
graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch graphene_es_objects graphene_generate_genesis graphene_market_history peerplays_sidechain )
PUBLIC graphene_chain graphene_net graphene_utilities
fc graphene_db peerplays_sidechain
graphene_account_history graphene_accounts_list graphene_affiliate_stats graphene_bookie graphene_debug_witness graphene_elasticsearch
graphene_es_objects graphene_generate_genesis graphene_market_history )
target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
@ -43,7 +44,7 @@ add_library( graphene_plugin
)
target_link_libraries( graphene_plugin
PUBLIC graphene_net graphene_utilities )
PUBLIC graphene_chain graphene_net graphene_utilities )
target_include_directories( graphene_plugin
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -29,14 +29,16 @@
#include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/get_config.hpp>
#include <graphene/utilities/key_conversion.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/utilities/key_conversion.hpp>
#include <fc/crypto/base64.hpp>
#include <fc/crypto/hex.hpp>
#include <fc/rpc/api_connection.hpp>
#include <fc/thread/future.hpp>
@ -45,6 +47,7 @@ template class fc::api<graphene::app::block_api>;
template class fc::api<graphene::app::network_broadcast_api>;
template class fc::api<graphene::app::network_node_api>;
template class fc::api<graphene::app::history_api>;
template class fc::api<graphene::app::crypto_api>;
template class fc::api<graphene::app::asset_api>;
template class fc::api<graphene::debug_witness::debug_api>;
template class fc::api<graphene::app::login_api>;
@ -89,6 +92,8 @@ void login_api::enable_api(const std::string &api_name) {
_history_api = std::make_shared<history_api>(_app);
} else if (api_name == "network_node_api") {
_network_node_api = std::make_shared<network_node_api>(std::ref(_app));
} else if (api_name == "crypto_api") {
_crypto_api = std::make_shared<crypto_api>();
} else if (api_name == "asset_api") {
_asset_api = std::make_shared<asset_api>(_app);
} else if (api_name == "debug_api") {
@ -103,10 +108,6 @@ void login_api::enable_api(const std::string &api_name) {
// can only enable this API if the plugin was loaded
if (_app.get_plugin("affiliate_stats"))
_affiliate_stats_api = std::make_shared<graphene::affiliate_stats::affiliate_stats_api>(std::ref(_app));
} else if (api_name == "sidechain_api") {
// can only enable this API if the plugin was loaded
if (_app.get_plugin("peerplays_sidechain"))
_sidechain_api = std::make_shared<graphene::peerplays_sidechain::sidechain_api>(std::ref(_app));
}
return;
}
@ -145,7 +146,7 @@ void network_broadcast_api::on_applied_block(const signed_block &b) {
if (itr != _callbacks.end()) {
auto block_num = b.block_num();
auto &callback = _callbacks.find(id)->second;
fc::async([capture_this, this, id, block_num, trx_num, trx, callback]() {
fc::async([capture_this, id, block_num, trx_num, trx, callback]() {
callback(fc::variant(transaction_confirmation{id, block_num, trx_num, trx},
GRAPHENE_MAX_NESTED_OBJECTS));
});
@ -165,7 +166,7 @@ void network_broadcast_api::broadcast_transaction(const signed_transaction &trx)
fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction &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(fc::promise<fc::variant>::create());
broadcast_transaction_with_callback([=](const fc::variant &v) {
prom->set_value(v);
},
@ -210,8 +211,8 @@ network_node_api::network_node_api(application &a) :
}
/*
* Remove expired transactions from pending_transactions
*/
* Remove expired transactions from pending_transactions
*/
for (const auto &transaction : _pending_transactions) {
if (transaction.second.expiration < block.timestamp) {
auto transaction_it = _pending_transactions.find(transaction.second.id());
@ -286,6 +287,11 @@ fc::api<history_api> login_api::history() const {
return *_history_api;
}
fc::api<crypto_api> login_api::crypto() const {
FC_ASSERT(_crypto_api);
return *_crypto_api;
}
fc::api<asset_api> login_api::asset() const {
FC_ASSERT(_asset_api);
return *_asset_api;
@ -306,11 +312,6 @@ fc::api<graphene::affiliate_stats::affiliate_stats_api> login_api::affiliate_sta
return *_affiliate_stats_api;
}
fc::api<graphene::peerplays_sidechain::sidechain_api> login_api::sidechain() const {
FC_ASSERT(_sidechain_api);
return *_sidechain_api;
}
vector<order_history_object> history_api::get_fill_order_history(std::string asset_a, std::string asset_b, uint32_t limit) const {
FC_ASSERT(_app.chain_database());
const auto &db = *_app.chain_database();
@ -514,6 +515,55 @@ vector<bucket_object> history_api::get_market_history(std::string asset_a, std::
FC_CAPTURE_AND_RETHROW((asset_a)(asset_b)(bucket_seconds)(start)(end))
}
crypto_api::crypto_api(){};
commitment_type crypto_api::blind(const blind_factor_type &blind, uint64_t value) {
return fc::ecc::blind(blind, value);
}
blind_factor_type crypto_api::blind_sum(const std::vector<blind_factor_type> &blinds_in, uint32_t non_neg) {
return fc::ecc::blind_sum(blinds_in, non_neg);
}
bool crypto_api::verify_sum(const std::vector<commitment_type> &commits_in, const std::vector<commitment_type> &neg_commits_in, int64_t excess) {
return fc::ecc::verify_sum(commits_in, neg_commits_in, excess);
}
verify_range_result crypto_api::verify_range(const commitment_type &commit, const std::vector<char> &proof) {
verify_range_result result;
result.success = fc::ecc::verify_range(result.min_val, result.max_val, commit, proof);
return result;
}
std::vector<char> crypto_api::range_proof_sign(uint64_t min_value,
const commitment_type &commit,
const blind_factor_type &commit_blind,
const blind_factor_type &nonce,
int8_t base10_exp,
uint8_t min_bits,
uint64_t actual_value) {
return fc::ecc::range_proof_sign(min_value, commit, commit_blind, nonce, base10_exp, min_bits, actual_value);
}
verify_range_proof_rewind_result crypto_api::verify_range_proof_rewind(const blind_factor_type &nonce,
const commitment_type &commit,
const std::vector<char> &proof) {
verify_range_proof_rewind_result result;
result.success = fc::ecc::verify_range_proof_rewind(result.blind_out,
result.value_out,
result.message_out,
nonce,
result.min_val,
result.max_val,
const_cast<commitment_type &>(commit),
proof);
return result;
}
range_proof_info crypto_api::range_get_info(const std::vector<char> &proof) {
return fc::ecc::range_get_info(proof);
}
// asset_api
asset_api::asset_api(graphene::app::application &app) :
_app(app),

View file

@ -26,8 +26,10 @@
#include <graphene/app/application.hpp>
#include <graphene/app/plugin.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/db_with.hpp>
#include <graphene/chain/genesis_state.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/egenesis/egenesis.hpp>
@ -48,7 +50,6 @@
#include <boost/range/algorithm/reverse.hpp>
#include <boost/signals2.hpp>
#include <atomic>
#include <iostream>
#include <fc/log/file_appender.hpp>
@ -108,7 +109,6 @@ public:
fc::optional<fc::temp_file> _lock_file;
bool _is_block_producer = false;
bool _force_validate = false;
std::atomic_bool _running{true};
void reset_p2p_node(const fc::path &data_dir) {
try {
@ -117,29 +117,67 @@ public:
_p2p_network->load_configuration(data_dir / "p2p");
_p2p_network->set_node_delegate(this);
vector<string> all_seeds;
if (_options->count("seed-node")) {
auto seeds = _options->at("seed-node").as<vector<string>>();
all_seeds.insert(all_seeds.end(), seeds.begin(), seeds.end());
for (const string &endpoint_string : seeds) {
try {
std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string);
for (const fc::ip::endpoint &endpoint : endpoints) {
ilog("Adding seed node ${endpoint}", ("endpoint", endpoint));
_p2p_network->add_node(endpoint);
_p2p_network->connect_to_endpoint(endpoint);
}
} catch (const fc::exception &e) {
wlog("caught exception ${e} while adding seed node ${endpoint}",
("e", e.to_detail_string())("endpoint", endpoint_string));
}
}
}
if (_options->count("seed-nodes")) {
auto seeds_str = _options->at("seed-nodes").as<string>();
auto seeds = fc::json::from_string(seeds_str).as<vector<string>>(2);
all_seeds.insert(all_seeds.end(), seeds.begin(), seeds.end());
}
for (const string &endpoint_string : all_seeds) {
try {
std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string);
for (const fc::ip::endpoint &endpoint : endpoints) {
ilog("Adding seed node ${endpoint}", ("endpoint", endpoint));
_p2p_network->add_node(endpoint);
for (const string &endpoint_string : seeds) {
try {
std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string);
for (const fc::ip::endpoint &endpoint : endpoints) {
ilog("Adding seed node ${endpoint}", ("endpoint", endpoint));
_p2p_network->add_node(endpoint);
}
} catch (const fc::exception &e) {
wlog("caught exception ${e} while adding seed node ${endpoint}",
("e", e.to_detail_string())("endpoint", endpoint_string));
}
}
} else {
// t.me/peerplays #seednodes
vector<string> seeds = {
#ifdef BUILD_PEERPLAYS_TESTNET
#else
"51.222.110.110:9777",
"95.216.90.243:9777",
"96.46.48.98:19777",
"96.46.48.98:29777",
"96.46.48.98:39777",
"96.46.48.98:49777",
"96.46.48.98:59777",
"seed.i9networks.net.br:9777",
"witness.serverpit.com:9777"
#endif
};
for (const string &endpoint_string : seeds) {
try {
std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string);
for (const fc::ip::endpoint &endpoint : endpoints) {
ilog("Adding seed node ${endpoint}", ("endpoint", endpoint));
_p2p_network->add_node(endpoint);
}
} catch (const fc::exception &e) {
wlog("caught exception ${e} while adding seed node ${endpoint}",
("e", e.to_detail_string())("endpoint", endpoint_string));
}
} catch (const fc::exception &e) {
wlog("caught exception ${e} while adding seed node ${endpoint}",
("e", e.to_detail_string())("endpoint", endpoint_string));
}
}
@ -253,6 +291,10 @@ public:
_self(self),
_chain_db(std::make_shared<chain::database>()) {
}
explicit application_impl(application *self, application::TESTING_MODE) :
_self(self),
_chain_db(std::make_shared<chain::database>(true)) {
}
~application_impl() {
}
@ -270,10 +312,10 @@ public:
auto initial_state = [this] {
ilog("Initializing database...");
if (_options->count("genesis-json")) {
std::string genesis_str;
fc::read_file_contents(_options->at("genesis-json").as<boost::filesystem::path>(), genesis_str);
genesis_state_type genesis = fc::json::from_string(genesis_str).as<genesis_state_type>(20);
if( _options->count("genesis-json") )
{
genesis_state_type genesis = fc::json::from_file( _options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>( 20 );
std::string genesis_str = fc::json::to_string(genesis) + "\n";
bool modified_genesis = false;
if (_options->count("genesis-timestamp")) {
genesis.initial_timestamp = fc::time_point_sec(fc::time_point::now()) + genesis.initial_parameters.block_interval + _options->at("genesis-timestamp").as<uint32_t>();
@ -323,7 +365,7 @@ public:
if (_options->count("enable-standby-votes-tracking")) {
_chain_db->enable_standby_votes_tracking(_options->at("enable-standby-votes-tracking").as<bool>());
}
std::string replay_reason = "reason not provided";
if (_options->count("replay-blockchain"))
@ -362,9 +404,9 @@ public:
wild_access.allowed_apis.push_back("database_api");
wild_access.allowed_apis.push_back("network_broadcast_api");
wild_access.allowed_apis.push_back("history_api");
wild_access.allowed_apis.push_back("crypto_api");
wild_access.allowed_apis.push_back("bookie_api");
wild_access.allowed_apis.push_back("affiliate_stats_api");
wild_access.allowed_apis.push_back("sidechain_api");
_apiaccess.permission_map["*"] = wild_access;
}
@ -391,8 +433,8 @@ public:
}
/**
* If delegate has the item, the network has no need to fetch it.
*/
* If delegate has the item, the network has no need to fetch it.
*/
virtual bool has_item(const net::item_id &id) override {
try {
if (id.item_type == graphene::net::block_message_type)
@ -404,21 +446,15 @@ public:
}
/**
* @brief allows the application to validate an item prior to broadcasting to peers.
*
* @param sync_mode true if the message was fetched through the sync process, false during normal operation
* @returns true if this message caused the blockchain to switch forks, false if it did not
*
* @throws exception if error validating the item, otherwise the item is safe to broadcast on.
*/
* @brief allows the application to validate an item prior to broadcasting to peers.
*
* @param sync_mode true if the message was fetched through the sync process, false during normal operation
* @returns true if this message caused the blockchain to switch forks, false if it did not
*
* @throws exception if error validating the item, otherwise the item is safe to broadcast on.
*/
virtual bool handle_block(const graphene::net::block_message &blk_msg, bool sync_mode,
std::vector<fc::uint160_t> &contained_transaction_message_ids) override {
// check point for the threads which may be cancled on application shutdown
if (!_running.load()) {
return true;
}
try {
auto latency = fc::time_point::now() - blk_msg.block.timestamp;
FC_ASSERT((latency.count() / 1000) > -5000, "Rejecting block with timestamp in the future");
@ -498,14 +534,14 @@ public:
}
/**
* Assuming all data elements are ordered in some way, this method should
* return up to limit ids that occur *after* the last ID in synopsis that
* we recognize.
*
* On return, remaining_item_count will be set to the number of items
* in our blockchain after the last item returned in the result,
* or 0 if the result contains the last item in the blockchain
*/
* Assuming all data elements are ordered in some way, this method should
* return up to limit ids that occur *after* the last ID in synopsis that
* we recognize.
*
* On return, remaining_item_count will be set to the number of items
* in our blockchain after the last item returned in the result,
* or 0 if the result contains the last item in the blockchain
*/
virtual std::vector<item_hash_t> get_block_ids(const std::vector<item_hash_t> &blockchain_synopsis,
uint32_t &remaining_item_count,
uint32_t limit) override {
@ -552,8 +588,8 @@ public:
}
/**
* Given the hash of the requested data, fetch the body.
*/
* Given the hash of the requested data, fetch the body.
*/
virtual message get_item(const item_id &id) override {
try {
// ilog("Request for item ${id}", ("id", id));
@ -576,63 +612,63 @@ public:
}
/**
* Returns a synopsis of the blockchain used for syncing. This consists of a list of
* block hashes at intervals exponentially increasing towards the genesis block.
* When syncing to a peer, the peer uses this data to determine if we're on the same
* fork as they are, and if not, what blocks they need to send us to get us on their
* fork.
*
* In the over-simplified case, this is a straighforward synopsis of our current
* preferred blockchain; when we first connect up to a peer, this is what we will be sending.
* It looks like this:
* If the blockchain is empty, it will return the empty list.
* If the blockchain has one block, it will return a list containing just that block.
* If it contains more than one block:
* the first element in the list will be the hash of the highest numbered block that
* we cannot undo
* the second element will be the hash of an item at the half way point in the undoable
* segment of the blockchain
* the third will be ~3/4 of the way through the undoable segment of the block chain
* the fourth will be at ~7/8...
* &c.
* the last item in the list will be the hash of the most recent block on our preferred chain
* so if the blockchain had 26 blocks labeled a - z, the synopsis would be:
* a n u x z
* the idea being that by sending a small (<30) number of block ids, we can summarize a huge
* blockchain. The block ids are more dense near the end of the chain where because we are
* more likely to be almost in sync when we first connect, and forks are likely to be short.
* If the peer we're syncing with in our example is on a fork that started at block 'v',
* then they will reply to our synopsis with a list of all blocks starting from block 'u',
* the last block they know that we had in common.
*
* In the real code, there are several complications.
*
* First, as an optimization, we don't usually send a synopsis of the entire blockchain, we
* send a synopsis of only the segment of the blockchain that we have undo data for. If their
* fork doesn't build off of something in our undo history, we would be unable to switch, so there's
* no reason to fetch the blocks.
*
* Second, when a peer replies to our initial synopsis and gives us a list of the blocks they think
* we are missing, they only send a chunk of a few thousand blocks at once. After we get those
* block ids, we need to request more blocks by sending another synopsis (we can't just say "send me
* the next 2000 ids" because they may have switched forks themselves and they don't track what
* they've sent us). For faster performance, we want to get a fairly long list of block ids first,
* then start downloading the blocks.
* The peer doesn't handle these follow-up block id requests any different from the initial request;
* it treats the synopsis we send as our blockchain and bases its response entirely off that. So to
* get the response we want (the next chunk of block ids following the last one they sent us, or,
* failing that, the shortest fork off of the last list of block ids they sent), we need to construct
* a synopsis as if our blockchain was made up of:
* 1. the blocks in our block chain up to the fork point (if there is a fork) or the head block (if no fork)
* 2. the blocks we've already pushed from their fork (if there's a fork)
* 3. the block ids they've previously sent us
* Segment 3 is handled in the p2p code, it just tells us the number of blocks it has (in
* number_of_blocks_after_reference_point) so we can leave space in the synopsis for them.
* We're responsible for constructing the synopsis of Segments 1 and 2 from our active blockchain and
* fork database. The reference_point parameter is the last block from that peer that has been
* successfully pushed to the blockchain, so that tells us whether the peer is on a fork or on
* the main chain.
*/
* Returns a synopsis of the blockchain used for syncing. This consists of a list of
* block hashes at intervals exponentially increasing towards the genesis block.
* When syncing to a peer, the peer uses this data to determine if we're on the same
* fork as they are, and if not, what blocks they need to send us to get us on their
* fork.
*
* In the over-simplified case, this is a straighforward synopsis of our current
* preferred blockchain; when we first connect up to a peer, this is what we will be sending.
* It looks like this:
* If the blockchain is empty, it will return the empty list.
* If the blockchain has one block, it will return a list containing just that block.
* If it contains more than one block:
* the first element in the list will be the hash of the highest numbered block that
* we cannot undo
* the second element will be the hash of an item at the half way point in the undoable
* segment of the blockchain
* the third will be ~3/4 of the way through the undoable segment of the block chain
* the fourth will be at ~7/8...
* &c.
* the last item in the list will be the hash of the most recent block on our preferred chain
* so if the blockchain had 26 blocks labeled a - z, the synopsis would be:
* a n u x z
* the idea being that by sending a small (<30) number of block ids, we can summarize a huge
* blockchain. The block ids are more dense near the end of the chain where because we are
* more likely to be almost in sync when we first connect, and forks are likely to be short.
* If the peer we're syncing with in our example is on a fork that started at block 'v',
* then they will reply to our synopsis with a list of all blocks starting from block 'u',
* the last block they know that we had in common.
*
* In the real code, there are several complications.
*
* First, as an optimization, we don't usually send a synopsis of the entire blockchain, we
* send a synopsis of only the segment of the blockchain that we have undo data for. If their
* fork doesn't build off of something in our undo history, we would be unable to switch, so there's
* no reason to fetch the blocks.
*
* Second, when a peer replies to our initial synopsis and gives us a list of the blocks they think
* we are missing, they only send a chunk of a few thousand blocks at once. After we get those
* block ids, we need to request more blocks by sending another synopsis (we can't just say "send me
* the next 2000 ids" because they may have switched forks themselves and they don't track what
* they've sent us). For faster performance, we want to get a fairly long list of block ids first,
* then start downloading the blocks.
* The peer doesn't handle these follow-up block id requests any different from the initial request;
* it treats the synopsis we send as our blockchain and bases its response entirely off that. So to
* get the response we want (the next chunk of block ids following the last one they sent us, or,
* failing that, the shortest fork off of the last list of block ids they sent), we need to construct
* a synopsis as if our blockchain was made up of:
* 1. the blocks in our block chain up to the fork point (if there is a fork) or the head block (if no fork)
* 2. the blocks we've already pushed from their fork (if there's a fork)
* 3. the block ids they've previously sent us
* Segment 3 is handled in the p2p code, it just tells us the number of blocks it has (in
* number_of_blocks_after_reference_point) so we can leave space in the synopsis for them.
* We're responsible for constructing the synopsis of Segments 1 and 2 from our active blockchain and
* fork database. The reference_point parameter is the last block from that peer that has been
* successfully pushed to the blockchain, so that tells us whether the peer is on a fork or on
* the main chain.
*/
virtual std::vector<item_hash_t> get_blockchain_synopsis(const item_hash_t &reference_point,
uint32_t number_of_blocks_after_reference_point) override {
try {
@ -733,26 +769,26 @@ public:
low_block_num += (true_high_block_num - low_block_num + 2) / 2;
} while (low_block_num <= high_block_num);
// idump((synopsis));
//idump((synopsis));
return synopsis;
}
FC_CAPTURE_AND_RETHROW()
}
/**
* Call this after the call to handle_message succeeds.
*
* @param item_type the type of the item we're synchronizing, will be the same as item passed to the sync_from() call
* @param item_count the number of items known to the node that haven't been sent to handle_item() yet.
* After `item_count` more calls to handle_item(), the node will be in sync
*/
* Call this after the call to handle_message succeeds.
*
* @param item_type the type of the item we're synchronizing, will be the same as item passed to the sync_from() call
* @param item_count the number of items known to the node that haven't been sent to handle_item() yet.
* After `item_count` more calls to handle_item(), the node will be in sync
*/
virtual void sync_status(uint32_t item_type, uint32_t item_count) override {
// any status reports to GUI go here
}
/**
* Call any time the number of connected peers changes.
*/
* Call any time the number of connected peers changes.
*/
virtual void connection_count_changed(uint32_t c) override {
// any status reports to GUI go here
}
@ -764,14 +800,10 @@ public:
FC_CAPTURE_AND_RETHROW((block_id))
}
virtual fc::time_point_sec get_last_known_hardfork_time() override {
return _chain_db->_hardfork_times[_chain_db->_hardfork_times.size() - 1];
}
/**
* Returns the time a block was produced (if block_id = 0, returns genesis time).
* If we don't know about the block, returns time_point_sec::min()
*/
* Returns the time a block was produced (if block_id = 0, returns genesis time).
* If we don't know about the block, returns time_point_sec::min()
*/
virtual fc::time_point_sec get_block_time(const item_hash_t &block_id) override {
try {
auto opt_block = _chain_db->fetch_block_by_id(block_id);
@ -818,7 +850,11 @@ public:
} // namespace detail
application::application() :
my(new detail::application_impl(this)) {
my(new detail::application_impl(this)) {
}
application::application(TESTING_MODE) :
my(new detail::application_impl(this, TESTING_MODE())) {
}
application::~application() {
@ -833,24 +869,9 @@ application::~application() {
void application::set_program_options(boost::program_options::options_description &cli,
boost::program_options::options_description &cfg) const {
std::vector<string> seed_nodes = {
#ifdef BUILD_PEERPLAYS_TESTNET
#else
"51.222.110.110:9777",
"95.216.90.243:9777",
"ca.peerplays.info:9777",
"de.peerplays.xyz:9777",
"pl.peerplays.org:9777",
"seed.i9networks.net.br:9777",
"witness.serverpit.com:9777"
#endif
};
std::string seed_nodes_str = fc::json::to_string(seed_nodes);
cfg.add_options()("p2p-endpoint", bpo::value<string>()->default_value("0.0.0.0:9777"), "Endpoint for P2P node to listen on");
cfg.add_options()("seed-node,s", bpo::value<vector<string>>()->composing(), "P2P nodes to connect to on startup (may specify multiple times)");
cfg.add_options()("seed-nodes", bpo::value<string>()->composing()->default_value(seed_nodes_str), "JSON array of P2P nodes to connect to on startup");
cfg.add_options()("seed-nodes", bpo::value<string>()->composing(), "JSON array of P2P nodes to connect to on startup");
cfg.add_options()("checkpoint,c", bpo::value<vector<string>>()->composing(), "Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.");
cfg.add_options()("rpc-endpoint", bpo::value<string>()->default_value("127.0.0.1:8090"), "Endpoint for websocket RPC to listen on");
cfg.add_options()("rpc-tls-endpoint", bpo::value<string>()->implicit_value("127.0.0.1:8089"), "Endpoint for TLS websocket RPC to listen on");
@ -917,8 +938,7 @@ void application::initialize(const fc::path &data_dir, const boost::program_opti
wanted.insert("accounts_list");
wanted.insert("affiliate_stats");
}
if (!wanted.count("delayed_node") && !wanted.count("debug_witness") && !wanted.count("witness")) // explicitly requested delayed_node or debug_witness functionality suppresses witness functions
wanted.insert("witness");
wanted.insert("witness");
wanted.insert("bookie");
int es_ah_conflict_counter = 0;
@ -950,7 +970,7 @@ void application::startup() {
}
std::shared_ptr<abstract_plugin> application::get_plugin(const string &name) const {
return is_plugin_enabled(name) ? my->_active_plugins[name] : nullptr;
return my->_active_plugins[name];
}
bool application::is_plugin_enabled(const string &name) const {
@ -997,7 +1017,6 @@ void application::shutdown_plugins() {
return;
}
void application::shutdown() {
my->_running.store(false);
if (my->_p2p_network)
my->_p2p_network->close();
if (my->_chain_db)

View file

@ -198,7 +198,7 @@ static void load_config_file(const fc::path &config_ini_path, const bpo::options
bpo::variables_map &options) {
deduplicator dedup;
bpo::options_description unique_options("Graphene Witness Node");
for (const boost::shared_ptr<bpo::option_description> opt : cfg_options.options()) {
for( const boost::shared_ptr<bpo::option_description>& opt : cfg_options.options() ) {
const boost::shared_ptr<bpo::option_description> od = dedup.next(opt);
if (!od)
continue;
@ -241,8 +241,8 @@ static void create_new_config_file(const fc::path &config_ini_path, const fc::pa
};
deduplicator dedup(modify_option_defaults);
std::ofstream out_cfg(config_ini_path.preferred_string());
std::string plugin_header_surrounding(78, '=');
for (const boost::shared_ptr<bpo::option_description> opt : cfg_options.options()) {
std::string plugin_header_surrounding( 78, '=' );
for( const boost::shared_ptr<bpo::option_description>& opt : cfg_options.options() ) {
const boost::shared_ptr<bpo::option_description> od = dedup.next(opt);
if (!od)
continue;

View file

@ -23,13 +23,14 @@
*/
#include <graphene/app/database_api.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/get_config.hpp>
#include <graphene/chain/protocol/address.hpp>
#include <graphene/chain/pts_address.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/utilities/git_revision.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/get_config.hpp>
#include <graphene/protocol/address.hpp>
#include <graphene/protocol/pts_address.hpp>
#include <fc/bloom_filter.hpp>
@ -37,7 +38,6 @@
#include <fc/rpc/api_connection.hpp>
#include <fc/uint128.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/rational.hpp>
@ -55,33 +55,30 @@ template class fc::api<graphene::app::database_api>;
namespace graphene { namespace app {
template <class T>
optional<T> maybe_id(const string &name_or_id) {
if (std::isdigit(name_or_id.front())) {
try {
template<class T>
optional<T> maybe_id( const string& name_or_id )
{
if( std::isdigit( name_or_id.front() ) )
{
try
{
return fc::variant(name_or_id, 1).as<T>(1);
} catch (const fc::exception &) { // not an ID
}
catch (const fc::exception&)
{ // not an ID
}
}
return optional<T>();
}
std::string object_id_to_string(object_id_type id) {
std::string object_id = fc::to_string(id.space()) + "." + fc::to_string(id.type()) + "." + fc::to_string(id.instance());
std::string object_id_to_string(object_id_type id)
{
std::string object_id = fc::to_string(id.space())
+ "." + fc::to_string(id.type())
+ "." + fc::to_string(id.instance());
return object_id;
}
signed_block_with_info::signed_block_with_info(){};
signed_block_with_info::signed_block_with_info(const signed_block &block) :
signed_block(block) {
block_id = id();
signing_key = signee();
transaction_ids.reserve(transactions.size());
for (const processed_transaction &tx : transactions)
transaction_ids.push_back(tx.id());
}
class database_api_impl : public std::enable_shared_from_this<database_api_impl> {
public:
database_api_impl(graphene::chain::database &db);
@ -100,12 +97,10 @@ public:
optional<block_header> get_block_header(uint32_t block_num) const;
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums) const;
optional<signed_block> get_block(uint32_t block_num) const;
optional<signed_block_with_info> get_block2(uint32_t block_num) const;
vector<optional<signed_block>> get_blocks(uint32_t block_num_from, uint32_t block_num_to) const;
processed_transaction get_transaction(uint32_t block_num, uint32_t trx_in_block) const;
// Globals
version_info get_version_info() const;
chain_property_object get_chain_properties() const;
global_property_object get_global_properties() const;
fc::variant_object get_config() const;
@ -196,10 +191,6 @@ public:
fc::optional<son_object> get_son_by_account(const std::string account_id_or_name) const;
map<string, son_id_type> lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const;
uint64_t get_son_count() const;
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons();
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain);
map<sidechain_type, map<son_id_type, string>> get_son_network_status();
map<son_id_type, string> get_son_network_status_by_sidechain(sidechain_type sidechain);
// SON wallets
optional<son_wallet_object> get_active_son_wallet();
@ -223,16 +214,17 @@ public:
// Votes
vector<variant> lookup_vote_ids(const vector<vote_id_type> &votes) const;
vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const;
template <typename IndexType, typename Tag>
vector<variant> get_votes_objects(const vector<vote_id_type> &votes, unsigned int variant_max_depth = 1) const {
static_assert(std::is_base_of<index, IndexType>::value, "Type must be an index type");
template<typename IndexType, typename Tag>
vector<variant> get_votes_objects(const vector<vote_id_type> &votes, unsigned int variant_max_depth = 1) const
{
static_assert( std::is_base_of<index,IndexType>::value, "Type must be an index type" );
vector<variant> result;
const auto &idx = _db.get_index_type<IndexType>().indices().template get<Tag>();
for (auto id : votes) {
auto itr = idx.find(id);
if (itr != idx.end())
result.emplace_back(variant(*itr, variant_max_depth));
result.emplace_back(variant(*itr,variant_max_depth));
}
return result;
}
@ -253,6 +245,9 @@ public:
// Proposed transactions
vector<proposal_object> get_proposed_transactions(const std::string account_id_or_name) const;
// Blinded balances
vector<blinded_balance_object> get_blinded_balances(const flat_set<commitment_type> &commitments) const;
// Tournaments
vector<tournament_object> get_tournaments_in_state(tournament_state state, uint32_t limit) const;
vector<tournament_object> get_tournaments(tournament_id_type stop, unsigned limit, tournament_id_type start);
@ -281,9 +276,8 @@ public:
uint64_t nft_get_total_supply(const nft_metadata_id_type nft_metadata_id) const;
nft_object nft_token_by_index(const nft_metadata_id_type nft_metadata_id, const uint64_t token_idx) const;
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;
vector<nft_object> nft_get_all_tokens(const nft_id_type lower_id, uint32_t limit) const;
vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner, const nft_id_type lower_id, uint32_t limit) const;
vector<nft_metadata_object> nft_get_metadata_by_owner(const account_id_type owner, const nft_metadata_id_type lower_id, uint32_t limit) const;
vector<nft_object> nft_get_all_tokens() const;
vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner) const;
// Marketplace
vector<offer_object> list_offers(const offer_id_type lower_id, uint32_t limit) const;
@ -304,7 +298,6 @@ public:
uint32_t api_limit_get_limit_orders_by_account = 101;
uint32_t api_limit_get_order_book = 50;
uint32_t api_limit_all_offers_count = 100;
uint32_t api_limit_nft_tokens = 100;
uint32_t api_limit_lookup_accounts = 1000;
uint32_t api_limit_lookup_witness_accounts = 1000;
uint32_t api_limit_lookup_committee_member_accounts = 1000;
@ -313,7 +306,7 @@ public:
uint32_t api_limit_get_trade_history = 100;
uint32_t api_limit_get_trade_history_by_sequence = 100;
// private:
//private:
const account_object *get_account_from_string(const std::string &name_or_id,
bool throw_if_not_found = true) const;
const asset_object *get_asset_from_string(const std::string &symbol_or_id,
@ -437,9 +430,9 @@ fc::variants database_api::get_objects(const vector<object_id_type> &ids) const
fc::variants database_api_impl::get_objects(const vector<object_id_type> &ids) const {
if (_subscribe_callback) {
for (auto id : ids) {
if (id.type() == operation_history_object_type && id.space() == protocol_ids)
if (id.type() == api_operation_history_object_type && id.space() == api_ids)
continue;
if (id.type() == impl_account_transaction_history_object_type && id.space() == implementation_ids)
if (id.type() == api_account_transaction_history_object_type && id.space() == api_ids)
continue;
this->subscribe_to_item(id);
@ -470,7 +463,7 @@ void database_api::set_subscribe_callback(std::function<void(const variant &)> c
}
void database_api_impl::set_subscribe_callback(std::function<void(const variant &)> cb, bool notify_remove_create) {
// edump((clear_filter));
//edump((clear_filter));
_subscribe_callback = cb;
_notify_remove_create = notify_remove_create;
_subscribed_accounts.clear();
@ -544,17 +537,6 @@ optional<signed_block> database_api_impl::get_block(uint32_t block_num) const {
return _db.fetch_block_by_number(block_num);
}
optional<signed_block_with_info> database_api::get_block2(uint32_t block_num) const {
return my->get_block2(block_num);
}
optional<signed_block_with_info> database_api_impl::get_block2(uint32_t block_num) const {
auto result = _db.fetch_block_by_number(block_num);
if (result)
return signed_block_with_info(*result);
return {};
}
vector<optional<signed_block>> database_api::get_blocks(uint32_t block_num_from, uint32_t block_num_to) const {
return my->get_blocks(block_num_from, block_num_to);
}
@ -593,27 +575,6 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin
// //
//////////////////////////////////////////////////////////////////////
version_info database_api::get_version_info() const {
return my->get_version_info();
}
version_info database_api_impl::get_version_info() const {
std::string witness_version(graphene::utilities::git_revision_description);
const size_t pos = witness_version.find('/');
if (pos != std::string::npos && witness_version.size() > pos)
witness_version = witness_version.substr(pos + 1);
version_info vi;
vi.version = witness_version;
vi.git_revision = graphene::utilities::git_revision_sha;
vi.built = std::string(__DATE__) + " at " + std::string(__TIME__);
vi.openssl = OPENSSL_VERSION_TEXT;
vi.boost = boost::replace_all_copy(std::string(BOOST_LIB_VERSION), "_", ".");
return vi;
}
chain_property_object database_api::get_chain_properties() const {
return my->get_chain_properties();
}
@ -1877,80 +1838,6 @@ uint64_t database_api_impl::get_son_count() const {
return _db.get_index_type<son_index>().indices().size();
}
flat_map<sidechain_type, vector<son_sidechain_info>> database_api::get_active_sons() {
return my->get_active_sons();
}
flat_map<sidechain_type, vector<son_sidechain_info>> database_api_impl::get_active_sons() {
return get_global_properties().active_sons;
}
vector<son_sidechain_info> database_api::get_active_sons_by_sidechain(sidechain_type sidechain) {
return my->get_active_sons_by_sidechain(sidechain);
}
vector<son_sidechain_info> database_api_impl::get_active_sons_by_sidechain(sidechain_type sidechain) {
const global_property_object &gpo = get_global_properties();
vector<son_sidechain_info> result;
if (gpo.active_sons.find(sidechain) != gpo.active_sons.end()) {
result = gpo.active_sons.at(sidechain);
}
return result;
}
map<sidechain_type, map<son_id_type, string>> database_api::get_son_network_status() {
return my->get_son_network_status();
}
map<sidechain_type, map<son_id_type, string>> database_api_impl::get_son_network_status() {
map<sidechain_type, map<son_id_type, string>> result;
for (auto active_sidechain_type : active_sidechain_types(_db.head_block_time())) {
result[active_sidechain_type] = get_son_network_status_by_sidechain(active_sidechain_type);
}
return result;
}
map<son_id_type, string> database_api::get_son_network_status_by_sidechain(sidechain_type sidechain) {
return my->get_son_network_status_by_sidechain(sidechain);
}
map<son_id_type, string> database_api_impl::get_son_network_status_by_sidechain(sidechain_type sidechain) {
const global_property_object &gpo = get_global_properties();
map<son_id_type, string> result;
if (gpo.active_sons.find(sidechain) != gpo.active_sons.end()) {
for (const auto si : gpo.active_sons.at(sidechain)) {
const auto son_obj = si.son_id(_db);
const auto sso = son_obj.statistics(_db);
string status;
if (sso.last_active_timestamp.find(sidechain) != sso.last_active_timestamp.end()) {
if (time_point_sec(sso.last_active_timestamp.at(sidechain) + fc::seconds(gpo.parameters.son_heartbeat_frequency())) > _db.head_block_time()) {
status = "OK, regular SON heartbeat";
} else {
if (time_point_sec(sso.last_active_timestamp.at(sidechain) + fc::seconds(gpo.parameters.son_down_time())) > _db.head_block_time()) {
status = "OK, irregular SON heartbeat, but not triggering SON down proposal";
} else {
status = "NOT OK, irregular SON heartbeat, triggering SON down proposal";
}
}
} else {
status = "No heartbeats sent";
}
result[si.son_id] = status;
}
}
return result;
}
//////////////////////////////////////////////////////////////////////
// //
// SON Wallets //
@ -2186,9 +2073,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
const auto &committee_idx = _db.get_index_type<committee_member_index>().indices().get<by_vote_id>();
const auto &for_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_for>();
const auto &against_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_against>();
const auto &son_bictoin_idx = _db.get_index_type<son_index>().indices().get<by_vote_id_bitcoin>();
const auto &son_hive_idx = _db.get_index_type<son_index>().indices().get<by_vote_id_hive>();
const auto &son_ethereum_idx = _db.get_index_type<son_index>().indices().get<by_vote_id_ethereum>();
const auto &son_idx = _db.get_index_type<son_index>().indices().get<by_vote_id>();
vector<variant> result;
result.reserve(votes.size());
@ -2197,7 +2082,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
case vote_id_type::committee: {
auto itr = committee_idx.find(id);
if (itr != committee_idx.end())
result.emplace_back(variant(*itr, 2)); // Depth of committee_member_object is 1, add 1 to be safe
result.emplace_back(variant(*itr, 1));
else
result.emplace_back(variant());
break;
@ -2205,7 +2090,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
case vote_id_type::witness: {
auto itr = witness_idx.find(id);
if (itr != witness_idx.end())
result.emplace_back(variant(*itr, 2)); // Depth of witness_object is 1, add 1 here to be safe
result.emplace_back(variant(*itr, 1));
else
result.emplace_back(variant());
break;
@ -2213,45 +2098,26 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
case vote_id_type::worker: {
auto itr = for_worker_idx.find(id);
if (itr != for_worker_idx.end()) {
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe.
// If we want to extract the balance object inside,
// need to increase this value
result.emplace_back(variant(*itr, 1));
} else {
auto itr = against_worker_idx.find(id);
if (itr != against_worker_idx.end()) {
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe.
// If we want to extract the balance object inside,
// need to increase this value
result.emplace_back(variant(*itr, 1));
} else {
result.emplace_back(variant());
}
}
break;
}
case vote_id_type::son_bitcoin: {
auto itr = son_bictoin_idx.find(id);
if (itr != son_bictoin_idx.end())
result.emplace_back(variant(*itr, 5));
else
result.emplace_back(variant());
break;
}
case vote_id_type::son_hive: {
auto itr = son_hive_idx.find(id);
if (itr != son_hive_idx.end())
result.emplace_back(variant(*itr, 5));
else
result.emplace_back(variant());
break;
}
case vote_id_type::son_ethereum: {
auto itr = son_ethereum_idx.find(id);
if (itr != son_ethereum_idx.end())
case vote_id_type::son: {
auto itr = son_idx.find(id);
if (itr != son_idx.end())
result.emplace_back(variant(*itr, 5));
else
result.emplace_back(variant());
break;
}
case vote_id_type::VOTE_TYPE_COUNT:
break; // supress unused enum value warnings
default:
@ -2266,7 +2132,8 @@ vector<vote_id_type> database_api_impl::get_votes_ids(const string &account_name
const account_object *account = get_account_from_string(account_name_or_id);
//! Iterate throug votes and fill vector
for (const auto &vote : account->options.votes) {
for( const auto& vote : account->options.votes )
{
result.emplace_back(vote);
}
@ -2276,78 +2143,60 @@ vector<vote_id_type> database_api_impl::get_votes_ids(const string &account_name
votes_info database_api_impl::get_votes(const string &account_name_or_id) const {
votes_info result;
const auto votes_ids = get_votes_ids(account_name_or_id);
const auto committee_ids = get_votes_objects<committee_member_index, by_vote_id>(votes_ids);
const auto witness_ids = get_votes_objects<witness_index, by_vote_id>(votes_ids);
const auto for_worker_ids = get_votes_objects<worker_index, by_vote_for>(votes_ids);
const auto against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
const auto son_ids = [this, &votes_ids]() {
flat_map<sidechain_type, vector<variant>> son_ids;
const auto son_bitcoin_ids = get_votes_objects<son_index, by_vote_id_bitcoin>(votes_ids, 5);
if (!son_bitcoin_ids.empty())
son_ids[sidechain_type::bitcoin] = std::move(son_bitcoin_ids);
const auto son_hive_ids = get_votes_objects<son_index, by_vote_id_hive>(votes_ids, 5);
if (!son_hive_ids.empty())
son_ids[sidechain_type::hive] = std::move(son_hive_ids);
const auto son_ethereum_ids = get_votes_objects<son_index, by_vote_id_ethereum>(votes_ids, 5);
if (!son_ethereum_ids.empty())
son_ids[sidechain_type::ethereum] = std::move(son_ethereum_ids);
return son_ids;
}();
const auto& votes_ids = get_votes_ids(account_name_or_id);
const auto& committee_ids = get_votes_objects<committee_member_index, by_vote_id>(votes_ids);
const auto& witness_ids = get_votes_objects<witness_index, by_vote_id>(votes_ids);
const auto& for_worker_ids = get_votes_objects<worker_index, by_vote_for>(votes_ids);
const auto& against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
const auto& son_ids = get_votes_objects<son_index, by_vote_id>(votes_ids, 5);
//! Fill votes info
if (!committee_ids.empty()) {
vector<votes_info_object> votes_for_committee_members;
if(!committee_ids.empty()) {
vector< votes_info_object<committee_member_id_type> > votes_for_committee_members;
votes_for_committee_members.reserve(committee_ids.size());
for (const auto &committee : committee_ids) {
const auto &committee_obj = committee.as<committee_member_object>(2);
votes_for_committee_members.emplace_back(votes_info_object{committee_obj.vote_id, committee_obj.id});
votes_for_committee_members.emplace_back(votes_info_object<committee_member_id_type>{committee_obj.vote_id, committee_obj.id.instance()});
}
result.votes_for_committee_members = std::move(votes_for_committee_members);
}
if (!witness_ids.empty()) {
vector<votes_info_object> votes_for_witnesses;
if(!witness_ids.empty()) {
vector< votes_info_object<witness_id_type> > votes_for_witnesses;
votes_for_witnesses.reserve(witness_ids.size());
for (const auto &witness : witness_ids) {
const auto &witness_obj = witness.as<witness_object>(2);
votes_for_witnesses.emplace_back(votes_info_object{witness_obj.vote_id, witness_obj.id});
votes_for_witnesses.emplace_back(votes_info_object<witness_id_type>{witness_obj.vote_id, witness_obj.id.instance()});
}
result.votes_for_witnesses = std::move(votes_for_witnesses);
}
if (!for_worker_ids.empty()) {
vector<votes_info_object> votes_for_workers;
if(!for_worker_ids.empty()) {
vector< votes_info_object<worker_id_type> > votes_for_workers;
votes_for_workers.reserve(for_worker_ids.size());
for (const auto &for_worker : for_worker_ids) {
const auto &for_worker_obj = for_worker.as<worker_object>(2);
votes_for_workers.emplace_back(votes_info_object{for_worker_obj.vote_for, for_worker_obj.id});
votes_for_workers.emplace_back(votes_info_object<worker_id_type>{for_worker_obj.vote_for, for_worker_obj.id.instance()});
}
result.votes_for_workers = std::move(votes_for_workers);
}
if (!against_worker_ids.empty()) {
vector<votes_info_object> votes_against_workers;
if(!against_worker_ids.empty()) {
vector< votes_info_object<worker_id_type> > votes_against_workers;
votes_against_workers.reserve(against_worker_ids.size());
for (const auto &against_worker : against_worker_ids) {
const auto &against_worker_obj = against_worker.as<worker_object>(2);
votes_against_workers.emplace_back(votes_info_object{against_worker_obj.vote_against, against_worker_obj.id});
votes_against_workers.emplace_back(votes_info_object<worker_id_type>{against_worker_obj.vote_against, against_worker_obj.id.instance()});
}
result.votes_against_workers = std::move(votes_against_workers);
}
if (!son_ids.empty()) {
flat_map<sidechain_type, vector<votes_info_object>> votes_for_sons;
for (const auto &son_sidechain_ids : son_ids) {
const auto &sidechain = son_sidechain_ids.first;
const auto &sidechain_ids = son_sidechain_ids.second;
votes_for_sons[sidechain].reserve(sidechain_ids.size());
for (const auto &son : sidechain_ids) {
const auto &son_obj = son.as<son_object>(6);
if (son_obj.get_sidechain_vote_id(sidechain).valid()) {
votes_for_sons[sidechain].emplace_back(votes_info_object{*son_obj.get_sidechain_vote_id(sidechain), son_obj.id});
}
}
if(!son_ids.empty()) {
vector< votes_info_object<son_id_type> > votes_for_sons;
votes_for_sons.reserve(son_ids.size());
for (const auto &son : son_ids) {
const auto &son_obj = son.as<son_object>(6);
votes_for_sons.emplace_back(votes_info_object<son_id_type>{son_obj.vote_id, son_obj.id.instance()});
}
result.votes_for_sons = std::move(votes_for_sons);
}
@ -2359,9 +2208,10 @@ vector<account_object> database_api_impl::get_voters_by_id(const vote_id_type &v
vector<account_object> result;
//! We search all accounts that have voted for this vote_id
const auto &account_index = _db.get_index_type<graphene::chain::account_index>().indices().get<by_id>();
for (const auto &account : account_index) {
if (account.options.votes.count(vote_id) != 0)
const auto& account_index = _db.get_index_type<graphene::chain::account_index>().indices().get<by_id>();
for( const auto& account: account_index )
{
if(account.options.votes.count(vote_id) != 0)
result.emplace_back(account);
}
@ -2376,78 +2226,83 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons
std::string owner_account_id;
//! Check if we have account by name
const auto &account_object = get_account_by_name(account_name_or_id);
if (account_object) {
const auto& account_object = get_account_by_name(account_name_or_id);
if(account_object) {
//! It is account
owner_account_id = object_id_to_string(account_object->get_id());
owner_account_id = object_id_to_string( account_object->get_id() );
owner_account_found = true;
} else {
}
else {
//! Check if we have account id
const auto &account_id = maybe_id<account_id_type>(account_name_or_id);
if (account_id) {
const auto& account_id = maybe_id<account_id_type>(account_name_or_id);
if(account_id) {
//! It may be account id
const auto &account_objects = get_accounts({account_name_or_id});
if (!account_objects.empty()) {
const auto &account_object = account_objects.front();
if (account_object) {
const auto& account_objects = get_accounts({account_name_or_id});
if(!account_objects.empty()){
const auto& account_object = account_objects.front();
if(account_object) {
//! It is account object
owner_account_id = object_id_to_string(account_object->get_id());
owner_account_id = object_id_to_string( account_object->get_id() );
owner_account_found = true;
}
}
} else {
}
else {
//! Check if we have committee member id
const auto &committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
if (committee_member_id) {
const auto& committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
if(committee_member_id) {
//! It may be committee member id
const auto &committee_member_objects = get_committee_members({*committee_member_id});
if (!committee_member_objects.empty()) {
const auto &committee_member_object = committee_member_objects.front();
if (committee_member_object) {
const auto& committee_member_objects = get_committee_members({*committee_member_id});
if(!committee_member_objects.empty()){
const auto& committee_member_object = committee_member_objects.front();
if(committee_member_object) {
//! It is committee member object
owner_account_id = object_id_to_string(committee_member_object->committee_member_account);
owner_account_id = object_id_to_string( committee_member_object->committee_member_account );
owner_account_found = true;
}
}
} else {
}
else {
//! Check if we have witness id
const auto &witness_id = maybe_id<witness_id_type>(account_name_or_id);
if (witness_id) {
const auto& witness_id = maybe_id<witness_id_type>(account_name_or_id);
if(witness_id) {
//! It may be witness id
const auto &witness_objects = get_witnesses({*witness_id});
if (!witness_objects.empty()) {
const auto &witness_object = witness_objects.front();
if (witness_object) {
const auto& witness_objects = get_witnesses({*witness_id});
if(!witness_objects.empty()){
const auto& witness_object = witness_objects.front();
if(witness_object) {
//! It is witness object
owner_account_id = object_id_to_string(witness_object->witness_account);
owner_account_id = object_id_to_string( witness_object->witness_account );
owner_account_found = true;
}
}
} else {
}
else {
//! Check if we have worker id
const auto &worker_id = maybe_id<worker_id_type>(account_name_or_id);
if (worker_id) {
const auto& worker_id = maybe_id<worker_id_type>(account_name_or_id);
if(worker_id) {
//! It may be worker id
const auto &worker_objects = get_workers({*worker_id});
if (!worker_objects.empty()) {
const auto &worker_object = worker_objects.front();
if (worker_object) {
const auto& worker_objects = get_workers({*worker_id});
if(!worker_objects.empty()){
const auto& worker_object = worker_objects.front();
if(worker_object) {
//! It is worker object
owner_account_id = object_id_to_string(worker_object->worker_account);
owner_account_id = object_id_to_string( worker_object->worker_account );
owner_account_found = true;
}
}
} else {
}
else {
//! Check if we have son id
const auto &son_id = maybe_id<son_id_type>(account_name_or_id);
if (son_id) {
const auto& son_id = maybe_id<son_id_type>(account_name_or_id);
if(son_id) {
//! It may be son id
const auto &son_objects = get_sons({*son_id});
if (!son_objects.empty()) {
const auto &son_object = son_objects.front();
if (son_object) {
const auto& son_objects = get_sons({*son_id});
if(!son_objects.empty()){
const auto& son_object = son_objects.front();
if(son_object) {
//! It is son object
owner_account_id = object_id_to_string(son_object->son_account);
owner_account_id = object_id_to_string( son_object->son_account );
owner_account_found = true;
}
}
@ -2459,41 +2314,41 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons
}
//! We didn't find who it was
if (!owner_account_found)
if(!owner_account_found)
FC_THROW_EXCEPTION(database_query_exception, "Wrong account_name_or_id: ${account_name_or_id}", ("account_name_or_id", account_name_or_id));
//! Fill voters_info
const auto &committee_member_object = get_committee_member_by_account(owner_account_id);
const auto &witness_object = get_witness_by_account(owner_account_id);
const auto &worker_objects = get_workers_by_account(owner_account_id);
const auto &son_object = get_son_by_account(owner_account_id);
const auto& committee_member_object = get_committee_member_by_account(owner_account_id);
const auto& witness_object = get_witness_by_account(owner_account_id);
const auto& worker_objects = get_workers_by_account(owner_account_id);
const auto& son_object = get_son_by_account(owner_account_id);
//! Info for committee member voters
if (committee_member_object) {
const auto &committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
if(committee_member_object) {
const auto& committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
voters_info_object voters_for_committee_member;
voters_for_committee_member.vote_id = committee_member_object->vote_id;
voters_for_committee_member.voters.reserve(committee_member_voters.size());
for (const auto &voter : committee_member_voters) {
for(const auto& voter: committee_member_voters) {
voters_for_committee_member.voters.emplace_back(voter.get_id());
}
result.voters_for_committee_member = std::move(voters_for_committee_member);
}
//! Info for witness voters
if (witness_object) {
const auto &witness_voters = get_voters_by_id(witness_object->vote_id);
if(witness_object) {
const auto& witness_voters = get_voters_by_id(witness_object->vote_id);
voters_info_object voters_for_witness;
voters_for_witness.vote_id = witness_object->vote_id;
voters_for_witness.voters.reserve(witness_voters.size());
for (const auto &voter : witness_voters) {
for(const auto& voter: witness_voters) {
voters_for_witness.voters.emplace_back(voter.get_id());
}
result.voters_for_witness = std::move(voters_for_witness);
}
//! Info for worker voters
if (!worker_objects.empty()) {
if(!worker_objects.empty()) {
vector<voters_info_object> voters_for_workers(worker_objects.size());
vector<voters_info_object> voters_against_workers(worker_objects.size());
for (const auto &worker_object : worker_objects) {
@ -2520,17 +2375,13 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons
}
//! Info for son voters
if (son_object) {
flat_map<sidechain_type, voters_info_object> voters_for_son;
for (const auto &vote_id : son_object->sidechain_vote_ids) {
const auto &son_voters = get_voters_by_id(vote_id.second);
voters_info_object voters_for_sidechain_son;
voters_for_sidechain_son.vote_id = vote_id.second;
voters_for_sidechain_son.voters.reserve(son_voters.size());
for (const auto &voter : son_voters) {
voters_for_sidechain_son.voters.emplace_back(voter.get_id());
}
voters_for_son[vote_id.first] = std::move(voters_for_sidechain_son);
if(son_object) {
const auto& son_voters = get_voters_by_id(son_object->vote_id);
voters_info_object voters_for_son;
voters_for_son.vote_id = son_object->vote_id;
voters_for_son.voters.reserve(son_voters.size());
for(const auto& voter: son_voters) {
voters_for_son.voters.emplace_back(voter.get_id());
}
result.voters_for_son = std::move(voters_for_son);
}
@ -2793,6 +2644,29 @@ vector<proposal_object> database_api_impl::get_proposed_transactions(const std::
return result;
}
//////////////////////////////////////////////////////////////////////
// //
// Blinded balances //
// //
//////////////////////////////////////////////////////////////////////
vector<blinded_balance_object> database_api::get_blinded_balances(const flat_set<commitment_type> &commitments) const {
return my->get_blinded_balances(commitments);
}
vector<blinded_balance_object> database_api_impl::get_blinded_balances(const flat_set<commitment_type> &commitments) const {
vector<blinded_balance_object> result;
result.reserve(commitments.size());
const auto &bal_idx = _db.get_index_type<blinded_balance_index>();
const auto &by_commitment_idx = bal_idx.indices().get<by_commitment>();
for (const auto &c : commitments) {
auto itr = by_commitment_idx.find(c);
if (itr != by_commitment_idx.end())
result.push_back(*itr);
}
return result;
}
//////////////////////////////////////////////////////////////////////
// //
// Tournament methods //
@ -2907,7 +2781,7 @@ graphene::app::gpos_info database_api::get_gpos_info(const account_id_type accou
}
graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type account) const {
FC_ASSERT(_db.head_block_time() > HARDFORK_GPOS_TIME); // Can be deleted after GPOS hardfork time
FC_ASSERT(_db.head_block_time() > HARDFORK_GPOS_TIME); //Can be deleted after GPOS hardfork time
gpos_info result;
result.vesting_factor = _db.calculate_vesting_factor(account(_db));
@ -2931,10 +2805,9 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type
}
vector<vesting_balance_object> account_vbos;
const time_point_sec now = _db.head_block_time();
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account);
std::for_each(vesting_range.first, vesting_range.second,
[&account_vbos, now](const vesting_balance_object &balance) {
[&account_vbos](const vesting_balance_object &balance) {
if (balance.balance.amount > 0 && balance.balance_type == vesting_balance_type::gpos && balance.balance.asset_id == asset_id_type())
account_vbos.emplace_back(balance);
});
@ -3095,8 +2968,8 @@ uint64_t database_api::nft_get_total_supply(const nft_metadata_id_type nft_metad
}
uint64_t database_api_impl::nft_get_total_supply(const nft_metadata_id_type nft_metadata_id) const {
const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_metadata>();
return idx_nft.count(nft_metadata_id);
const auto &idx_nft_md = _db.get_index_type<nft_metadata_index>().indices().get<by_id>();
return idx_nft_md.size();
}
nft_object database_api::nft_token_by_index(const nft_metadata_id_type nft_metadata_id, const uint64_t token_idx) const {
@ -3133,61 +3006,30 @@ nft_object database_api_impl::nft_token_of_owner_by_index(const nft_metadata_id_
return {};
}
vector<nft_object> database_api::nft_get_all_tokens(const nft_id_type lower_id, uint32_t limit) const {
return my->nft_get_all_tokens(lower_id, limit);
vector<nft_object> database_api::nft_get_all_tokens() const {
return my->nft_get_all_tokens();
}
vector<nft_object> database_api_impl::nft_get_all_tokens(const nft_id_type lower_id, uint32_t limit) const {
FC_ASSERT(limit <= api_limit_nft_tokens,
"Number of queried nft tokens can not be greater than ${configured_limit}",
("configured_limit", api_limit_nft_tokens));
vector<nft_object> database_api_impl::nft_get_all_tokens() const {
const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_id>();
vector<nft_object> result;
result.reserve(limit);
auto itr = idx_nft.lower_bound(lower_id);
while (limit-- && itr != idx_nft.end())
result.emplace_back(*itr++);
for (auto itr = idx_nft.begin(); itr != idx_nft.end(); ++itr) {
result.push_back(*itr);
}
return result;
}
vector<nft_object> database_api::nft_get_tokens_by_owner(const account_id_type owner, const nft_id_type lower_id, uint32_t limit) const {
return my->nft_get_tokens_by_owner(owner, lower_id, limit);
vector<nft_object> database_api::nft_get_tokens_by_owner(const account_id_type owner) const {
return my->nft_get_tokens_by_owner(owner);
}
vector<nft_object> database_api_impl::nft_get_tokens_by_owner(const account_id_type owner, const nft_id_type lower_id, uint32_t limit) const {
FC_ASSERT(limit <= api_limit_nft_tokens,
"Number of queried nft tokens can not be greater than ${configured_limit}",
("configured_limit", api_limit_nft_tokens));
vector<nft_object> database_api_impl::nft_get_tokens_by_owner(const account_id_type owner) const {
const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_owner>();
auto idx_nft_range = idx_nft.equal_range(owner);
vector<nft_object> result;
result.reserve(limit);
auto itr = std::find_if(idx_nft_range.first, idx_nft_range.second, [&lower_id](const nft_object &obj) {
return !(obj.id.instance() < lower_id.instance);
});
while (limit-- && itr != idx_nft_range.second)
result.emplace_back(*itr++);
return result;
}
vector<nft_metadata_object> database_api::nft_get_metadata_by_owner(const account_id_type owner, const nft_metadata_id_type lower_id, uint32_t limit) const {
return my->nft_get_metadata_by_owner(owner, lower_id, limit);
}
vector<nft_metadata_object> database_api_impl::nft_get_metadata_by_owner(const account_id_type owner, const nft_metadata_id_type lower_id, uint32_t limit) const {
FC_ASSERT(limit <= api_limit_nft_tokens,
"Number of queried nft metadata objects can not be greater than ${configured_limit}",
("configured_limit", api_limit_nft_tokens));
const auto &idx_nft = _db.get_index_type<nft_metadata_index>().indices().get<by_owner>();
auto idx_nft_range = idx_nft.equal_range(owner);
vector<nft_metadata_object> result;
result.reserve(limit);
auto itr = std::find_if(idx_nft_range.first, idx_nft_range.second, [&lower_id](const nft_metadata_object &obj) {
return !(obj.id.instance() < lower_id.instance);
});
while (limit-- && itr != idx_nft_range.second)
result.emplace_back(*itr++);
for (auto itr = idx_nft_range.first; itr != idx_nft_range.second; ++itr) {
result.push_back(*itr);
}
return result;
}
@ -3554,9 +3396,9 @@ void database_api_impl::handle_object_changed(bool force_notify, bool full_objec
/// pushing the future back / popping the prior future if it is complete.
/// if a connection hangs then this could get backed up and result in
/// a failure to exit cleanly.
// fc::async([capture_this,this,updates,market_broadcast_queue](){
// if( _subscribe_callback )
// _subscribe_callback( updates );
//fc::async([capture_this,this,updates,market_broadcast_queue](){
//if( _subscribe_callback )
// _subscribe_callback( updates );
for (auto id : ids) {
if (id.is<call_order_object>()) {

View file

@ -25,18 +25,19 @@
#include <graphene/app/database_api.hpp>
#include <graphene/chain/protocol/confidential.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/net/node.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/protocol/confidential.hpp>
#include <graphene/accounts_list/accounts_list_plugin.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
#include <graphene/elasticsearch/elasticsearch_plugin.hpp>
#include <graphene/affiliate_stats/affiliate_stats_api.hpp>
#include <graphene/bookie/bookie_api.hpp>
#include <graphene/debug_witness/debug_api.hpp>
#include <graphene/elasticsearch/elasticsearch_plugin.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
#include <graphene/net/node.hpp>
#include <fc/api.hpp>
#include <fc/crypto/elliptic.hpp>
@ -85,10 +86,10 @@ struct asset_holders {
};
/**
* @brief The history_api class implements the RPC API for account history
*
* This API contains methods to access account histories
*/
* @brief The history_api class implements the RPC API for account history
*
* This API contains methods to access account histories
*/
class history_api {
public:
history_api(application &app) :
@ -97,27 +98,27 @@ public:
}
/**
* @brief Get operations relevant to the specificed account
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
* @brief Get operations relevant to the specificed account
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_account_history(const std::string account_id_or_name,
operation_history_id_type stop = operation_history_id_type(),
unsigned limit = 100,
operation_history_id_type start = operation_history_id_type()) const;
/**
* @brief Get only asked operations relevant to the specified account
* @param account_id_or_name The account ID or name whose history should be queried
* @param operation_id The ID of the operation we want to get operations in the account( 0 = transfer , 1 = limit order create, ...)
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
* @brief Get only asked operations relevant to the specified account
* @param account_id_or_name The account ID or name whose history should be queried
* @param operation_id The ID of the operation we want to get operations in the account( 0 = transfer , 1 = limit order create, ...)
* @param stop ID of the earliest operation to retrieve
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start ID of the most recent operation to retrieve
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_account_history_operations(const std::string account_id_or_name,
int operation_id,
operation_history_id_type start = operation_history_id_type(),
@ -125,17 +126,17 @@ public:
unsigned limit = 100) const;
/**
* @breif Get operations relevant to the specified account referenced
* by an event numbering specific to the account. The current number of operations
* for the account can be found in the account statistics (or use 0 for start).
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop Sequence number of earliest operation. 0 is default and will
* query 'limit' number of operations.
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start Sequence number of the most recent operation to retrieve.
* 0 is default, which will start querying from the most recent operation.
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
* @breif Get operations relevant to the specified account referenced
* by an event numbering specific to the account. The current number of operations
* for the account can be found in the account statistics (or use 0 for start).
* @param account_id_or_name The account ID or name whose history should be queried
* @param stop Sequence number of earliest operation. 0 is default and will
* query 'limit' number of operations.
* @param limit Maximum number of operations to retrieve (must not exceed 100)
* @param start Sequence number of the most recent operation to retrieve.
* 0 is default, which will start querying from the most recent operation.
* @return A list of operations performed by account, ordered from most recent to oldest.
*/
vector<operation_history_object> get_relative_account_history(const std::string account_id_or_name,
uint32_t stop = 0,
unsigned limit = 100,
@ -156,8 +157,8 @@ private:
};
/**
* @brief Block api
*/
* @brief Block api
*/
class block_api {
public:
block_api(graphene::chain::database &db);
@ -170,8 +171,8 @@ private:
};
/**
* @brief The network_broadcast_api class allows broadcasting of transactions.
*/
* @brief The network_broadcast_api class allows broadcasting of transactions.
*/
class network_broadcast_api : public std::enable_shared_from_this<network_broadcast_api> {
public:
network_broadcast_api(application &a);
@ -186,36 +187,36 @@ public:
typedef std::function<void(variant /*transaction_confirmation*/)> confirmation_callback;
/**
* @brief Broadcast a transaction to the network
* @param trx The transaction to broadcast
*
* The transaction will be checked for validity in the local database prior to broadcasting. If it fails to
* apply locally, an error will be thrown and the transaction will not be broadcast.
*/
* @brief Broadcast a transaction to the network
* @param trx The transaction to broadcast
*
* The transaction will be checked for validity in the local database prior to broadcasting. If it fails to
* apply locally, an error will be thrown and the transaction will not be broadcast.
*/
void broadcast_transaction(const signed_transaction &trx);
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
void broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction &trx);
/** this version of broadcast transaction registers a callback method that will be called when the transaction is
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
fc::variant broadcast_transaction_synchronous(const signed_transaction &trx);
void broadcast_block(const signed_block &block);
/**
* @brief Not reflected, thus not accessible to API clients.
*
* This function is registered to receive the applied_block
* signal from the chain database when a block is received.
* It then dispatches callbacks to clients who have requested
* to be notified when a particular txid is included in a block.
*/
* @brief Not reflected, thus not accessible to API clients.
*
* This function is registered to receive the applied_block
* signal from the chain database when a block is received.
* It then dispatches callbacks to clients who have requested
* to be notified when a particular txid is included in a block.
*/
void on_applied_block(const signed_block &b);
private:
@ -225,60 +226,60 @@ private:
};
/**
* @brief The network_node_api class allows maintenance of p2p connections.
*/
* @brief The network_node_api class allows maintenance of p2p connections.
*/
class network_node_api {
public:
network_node_api(application &a);
/**
* @brief Return general network information, such as p2p port
*/
* @brief Return general network information, such as p2p port
*/
fc::variant_object get_info() const;
/**
* @brief add_node Connect to a new peer
* @param ep The IP/Port of the peer to connect to
*/
* @brief add_node Connect to a new peer
* @param ep The IP/Port of the peer to connect to
*/
void add_node(const fc::ip::endpoint &ep);
/**
* @brief Get status of all current connections to peers
*/
* @brief Get status of all current connections to peers
*/
std::vector<net::peer_status> get_connected_peers() const;
/**
* @brief Get advanced node parameters, such as desired and max
* number of connections
*/
* @brief Get advanced node parameters, such as desired and max
* number of connections
*/
fc::variant_object get_advanced_node_parameters() const;
/**
* @brief Set advanced node parameters, such as desired and max
* number of connections
* @param params a JSON object containing the name/value pairs for the parameters to set
*/
* @brief Set advanced node parameters, such as desired and max
* number of connections
* @param params a JSON object containing the name/value pairs for the parameters to set
*/
void set_advanced_node_parameters(const fc::variant_object &params);
/**
* @brief Return list of potential peers
*/
* @brief Return list of potential peers
*/
std::vector<net::potential_peer_record> get_potential_peers() const;
/**
* @brief Return list of pending transactions.
*/
* @brief Return list of pending transactions.
*/
map<transaction_id_type, signed_transaction> list_pending_transactions() const;
/**
* @brief Subscribes caller for notifications about pending transactions.
* @param callback a functional object which will be called when new transaction is created.
*/
* @brief Subscribes caller for notifications about pending transactions.
* @param callback a functional object which will be called when new transaction is created.
*/
void subscribe_to_pending_transactions(std::function<void(const variant &)> callback);
/**
* @brief Unsubscribes caller from notifications about pending transactions.
*/
* @brief Unsubscribes caller from notifications about pending transactions.
*/
void unsubscribe_from_pending_transactions();
private:
@ -289,34 +290,61 @@ private:
std::function<void(const variant &)> _on_pending_transaction;
};
class crypto_api {
public:
crypto_api();
fc::ecc::commitment_type blind(const fc::ecc::blind_factor_type &blind, uint64_t value);
fc::ecc::blind_factor_type blind_sum(const std::vector<blind_factor_type> &blinds_in, uint32_t non_neg);
bool verify_sum(const std::vector<commitment_type> &commits_in, const std::vector<commitment_type> &neg_commits_in, int64_t excess);
verify_range_result verify_range(const fc::ecc::commitment_type &commit, const std::vector<char> &proof);
std::vector<char> range_proof_sign(uint64_t min_value,
const commitment_type &commit,
const blind_factor_type &commit_blind,
const blind_factor_type &nonce,
int8_t base10_exp,
uint8_t min_bits,
uint64_t actual_value);
verify_range_proof_rewind_result verify_range_proof_rewind(const blind_factor_type &nonce,
const fc::ecc::commitment_type &commit,
const std::vector<char> &proof);
range_proof_info range_get_info(const std::vector<char> &proof);
};
/**
* @brief
*/
* @brief
*/
class asset_api {
public:
asset_api(graphene::app::application &app);
~asset_api();
/**
* @brief Get asset holders for a specific asset
* @param asset The specific asset id or symbol
* @param start The start index
* @param limit Maximum limit must not exceed 100
* @return A list of asset holders for the specified asset
*/
* @brief Get asset holders for a specific asset
* @param asset The specific asset id or symbol
* @param start The start index
* @param limit Maximum limit must not exceed 100
* @return A list of asset holders for the specified asset
*/
vector<account_asset_balance> get_asset_holders(std::string asset, uint32_t start, uint32_t limit) const;
/**
* @brief Get asset holders count for a specific asset
* @param asset The specific asset id or symbol
* @return Holders count for the specified asset
*/
* @brief Get asset holders count for a specific asset
* @param asset The specific asset id or symbol
* @return Holders count for the specified asset
*/
int get_asset_holders_count(std::string asset) const;
/**
* @brief Get all asset holders
* @return A list of all asset holders
*/
* @brief Get all asset holders
* @return A list of all asset holders
*/
vector<asset_holders> get_all_asset_holders() const;
uint32_t api_limit_get_asset_holders = 100;
@ -332,29 +360,30 @@ extern template class fc::api<graphene::app::block_api>;
extern template class fc::api<graphene::app::network_broadcast_api>;
extern template class fc::api<graphene::app::network_node_api>;
extern template class fc::api<graphene::app::history_api>;
extern template class fc::api<graphene::app::crypto_api>;
extern template class fc::api<graphene::app::asset_api>;
extern template class fc::api<graphene::debug_witness::debug_api>;
namespace graphene { namespace app {
/**
* @brief The login_api class implements the bottom layer of the RPC API
*
* All other APIs must be requested from this API.
*/
* @brief The login_api class implements the bottom layer of the RPC API
*
* All other APIs must be requested from this API.
*/
class login_api {
public:
login_api(application &a);
~login_api();
/**
* @brief Authenticate to the RPC server
* @param user Username to login with
* @param password Password to login with
* @return True if logged in successfully; false otherwise
*
* @note This must be called prior to requesting other APIs. Other APIs may not be accessible until the client
* has sucessfully authenticated.
*/
* @brief Authenticate to the RPC server
* @param user Username to login with
* @param password Password to login with
* @return True if logged in successfully; false otherwise
*
* @note This must be called prior to requesting other APIs. Other APIs may not be accessible until the client
* has sucessfully authenticated.
*/
bool login(const string &user, const string &password);
/// @brief Retrieve the network block API
fc::api<block_api> block() const;
@ -366,6 +395,8 @@ public:
fc::api<history_api> history() const;
/// @brief Retrieve the network node API
fc::api<network_node_api> network_node() const;
/// @brief Retrieve the cryptography API
fc::api<crypto_api> crypto() const;
/// @brief Retrieve the asset API
fc::api<asset_api> asset() const;
/// @brief Retrieve the debug API (if available)
@ -374,8 +405,6 @@ public:
fc::api<graphene::bookie::bookie_api> bookie() const;
/// @brief Retrieve the affiliate_stats API (if available)
fc::api<graphene::affiliate_stats::affiliate_stats_api> affiliate_stats() const;
/// @brief Retrieve the sidechain_api API (if available)
fc::api<graphene::peerplays_sidechain::sidechain_api> sidechain() const;
/// @brief Called to enable an API, not reflected.
void enable_api(const string &api_name);
@ -387,11 +416,11 @@ private:
optional<fc::api<network_broadcast_api>> _network_broadcast_api;
optional<fc::api<network_node_api>> _network_node_api;
optional<fc::api<history_api>> _history_api;
optional<fc::api<crypto_api>> _crypto_api;
optional<fc::api<asset_api>> _asset_api;
optional<fc::api<graphene::debug_witness::debug_api>> _debug_api;
optional<fc::api<graphene::bookie::bookie_api>> _bookie_api;
optional<fc::api<graphene::affiliate_stats::affiliate_stats_api>> _affiliate_stats_api;
optional<fc::api<graphene::peerplays_sidechain::sidechain_api>> _sidechain_api;
};
}} // namespace graphene::app
@ -444,6 +473,15 @@ FC_API(graphene::app::network_node_api,
(subscribe_to_pending_transactions)
(unsubscribe_from_pending_transactions))
FC_API(graphene::app::crypto_api,
(blind)
(blind_sum)
(verify_sum)
(verify_range)
(range_proof_sign)
(verify_range_proof_rewind)
(range_get_info))
FC_API(graphene::app::asset_api,
(get_asset_holders)
(get_asset_holders_count)
@ -456,10 +494,10 @@ FC_API(graphene::app::login_api,
(database)
(history)
(network_node)
(crypto)
(asset)
(debug)
(bookie)
(affiliate_stats)
(sidechain))
(affiliate_stats))
// clang-format on

View file

@ -39,7 +39,10 @@ class abstract_plugin;
class application {
public:
struct TESTING_MODE {};
application();
application(TESTING_MODE);
~application();
void set_program_options(boost::program_options::options_description &cli,

View file

@ -25,7 +25,7 @@
#include <graphene/app/full_account.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/chain/database.hpp>
@ -56,8 +56,8 @@
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/voters_info.hpp>
#include <graphene/chain/votes_info.hpp>
#include <graphene/chain/voters_info.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
@ -82,15 +82,6 @@ using namespace std;
class database_api_impl;
struct signed_block_with_info : public signed_block {
signed_block_with_info();
signed_block_with_info(const signed_block &block);
signed_block_with_info(const signed_block_with_info &block) = default;
block_id_type block_id;
public_key_type signing_key;
vector<transaction_id_type> transaction_ids;
};
struct order {
double price;
double quote;
@ -139,14 +130,6 @@ struct gpos_info {
share_type account_vested_balance;
};
struct version_info {
string version;
string git_revision;
string built;
string openssl;
string boost;
};
/**
* @brief The database_api class implements the RPC API for the chain database.
*
@ -198,10 +181,10 @@ public:
optional<block_header> get_block_header(uint32_t block_num) const;
/**
* @brief Retrieve multiple block header by block numbers
* @param block_num vector containing heights of the block whose header should be returned
* @return array of headers of the referenced blocks, or null if no matching block was found
*/
* @brief Retrieve multiple block header by block numbers
* @param block_num vector containing heights of the block whose header should be returned
* @return array of headers of the referenced blocks, or null if no matching block was found
*/
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums) const;
/**
@ -211,13 +194,6 @@ public:
*/
optional<signed_block> get_block(uint32_t block_num) const;
/**
* @brief Retrieve a full, signed block, with some extra info
* @param block_num Height of the block to be returned
* @return the referenced block, or null if no matching block was found
*/
optional<signed_block_with_info> get_block2(uint32_t block_num) const;
/**
* @brief Retrieve a list of signed blocks
* @param block_num_from start
@ -242,11 +218,6 @@ public:
// Globals //
/////////////
/**
* @brief Retrieve the @ref version_info associated with the witness node
*/
version_info get_version_info() const;
/**
* @brief Retrieve the @ref chain_property_object associated with the chain
*/
@ -279,12 +250,12 @@ public:
vector<vector<account_id_type>> get_key_references(vector<public_key_type> key) const;
/**
* Determine whether a textual representation of a public key
* (in Base-58 format) is *currently* linked
* to any *registered* (i.e. non-stealth) account on the blockchain
* @param public_key Public key
* @return Whether a public key is known
*/
* Determine whether a textual representation of a public key
* (in Base-58 format) is *currently* linked
* to any *registered* (i.e. non-stealth) account on the blockchain
* @param public_key Public key
* @return Whether a public key is known
*/
bool is_public_key_registered(string public_key) const;
//////////////
@ -691,32 +662,6 @@ public:
*/
uint64_t get_son_count() const;
/**
* @brief Get list of active sons
* @return List of active SONs
*/
flat_map<sidechain_type, vector<son_sidechain_info>> get_active_sons();
/**
* @brief Get list of active sons
* @param sidechain Sidechain type [bitcoin|ethereum|hive]
* @return List of active SONs
*/
vector<son_sidechain_info> get_active_sons_by_sidechain(sidechain_type sidechain);
/**
* @brief Get SON network status
* @return SON network status description for a given sidechain type
*/
map<sidechain_type, map<son_id_type, string>> get_son_network_status();
/**
* @brief Get SON network status
* @param sidechain Sidechain type [bitcoin|ethereum|hive]
* @return SON network status description for a given sidechain type
*/
map<son_id_type, string> get_son_network_status_by_sidechain(sidechain_type sidechain);
/////////////////////////
// SON Wallets //
/////////////////////////
@ -919,6 +864,15 @@ public:
*/
vector<proposal_object> get_proposed_transactions(const std::string account_id_or_name) const;
//////////////////////
// Blinded balances //
//////////////////////
/**
* @return the set of blinded balance objects by commitment ID
*/
vector<blinded_balance_object> get_blinded_balances(const flat_set<commitment_type> &commitments) const;
/////////////////
// Tournaments //
/////////////////
@ -1043,25 +997,14 @@ public:
* @brief Returns list of all available NTF's
* @return List of all available NFT's
*/
vector<nft_object> nft_get_all_tokens(const nft_id_type lower_id, uint32_t limit) const;
vector<nft_object> nft_get_all_tokens() const;
/**
* @brief Returns NFT's owned by owner
* @param owner NFT owner
* @param lower_id ID of the first NFT to return
* @param limit Maximum number of results to return
* @return List of NFT owned by owner
*/
vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner, const nft_id_type lower_id, uint32_t limit) const;
/**
* @brief Returns NFT metadata owned by owner
* @param owner NFT owner
* @param lower_id ID of the first NFT metadata to return
* @param limit Maximum number of results to return
* @return List of NFT owned by owner
*/
vector<nft_metadata_object> nft_get_metadata_by_owner(const account_id_type owner, const nft_metadata_id_type lower_id, uint32_t limit) const;
vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner) const;
//////////////////
// MARKET PLACE //
@ -1091,15 +1034,12 @@ extern template class fc::api<graphene::app::database_api>;
// clang-format off
FC_REFLECT_DERIVED(graphene::app::signed_block_with_info, (graphene::chain::signed_block), (block_id)(signing_key)(transaction_ids));
FC_REFLECT(graphene::app::order, (price)(quote)(base));
FC_REFLECT(graphene::app::order_book, (base)(quote)(bids)(asks));
FC_REFLECT(graphene::app::market_ticker, (base)(quote)(latest)(lowest_ask)(highest_bid)(percent_change)(base_volume)(quote_volume));
FC_REFLECT(graphene::app::market_volume, (base)(quote)(base_volume)(quote_volume));
FC_REFLECT(graphene::app::market_trade, (date)(price)(amount)(value));
FC_REFLECT(graphene::app::gpos_info, (vesting_factor)(award)(total_amount)(current_subperiod)(last_voted_time)(allowed_withdraw_amount)(account_vested_balance));
FC_REFLECT(graphene::app::version_info, (version)(git_revision)(built)(openssl)(boost));
FC_API(graphene::app::database_api,
// Objects
@ -1115,13 +1055,11 @@ FC_API(graphene::app::database_api,
(get_block_header)
(get_block_header_batch)
(get_block)
(get_block2)
(get_blocks)
(get_transaction)
(get_recent_transaction_by_id)
// Globals
(get_version_info)
(get_chain_properties)
(get_global_properties)
(get_config)
@ -1205,10 +1143,6 @@ FC_API(graphene::app::database_api,
(get_son_by_account)
(lookup_son_accounts)
(get_son_count)
(get_active_sons)
(get_active_sons_by_sidechain)
(get_son_network_status)
(get_son_network_status_by_sidechain)
// SON wallets
(get_active_son_wallet)
@ -1249,6 +1183,9 @@ FC_API(graphene::app::database_api,
// Proposed transactions
(get_proposed_transactions)
// Blinded balances
(get_blinded_balances)
// Tournaments
(get_tournaments_in_state)
(get_tournaments_by_state)
@ -1279,7 +1216,6 @@ FC_API(graphene::app::database_api,
(nft_token_of_owner_by_index)
(nft_get_all_tokens)
(nft_get_tokens_by_owner)
(nft_get_metadata_by_owner)
// Marketplace
(list_offers)

View file

@ -24,9 +24,11 @@
#pragma once
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/market_evaluator.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/proposal_object.hpp>
namespace graphene { namespace app {
using namespace graphene::chain;

View file

@ -23,7 +23,7 @@
*/
#include <graphene/app/plugin.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace app {

View file

@ -6,31 +6,33 @@ set_source_files_properties( "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain
add_dependencies( build_hardfork_hpp cat-parts )
file(GLOB HEADERS "include/graphene/chain/*.hpp")
file(GLOB PROTOCOL_HEADERS "include/graphene/chain/protocol/*.hpp")
list(APPEND HEADERS "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp")
file(GLOB CPP_FILES "*.cpp")
file(GLOB PROTOCOL_CPP_FILES "protocol/*.cpp")
#if( GRAPHENE_DISABLE_UNITY_BUILD )
list(FILTER CPP_FILES EXCLUDE REGEX "[/]database[.]cpp$")
#message ("--- ${CPP_FILES}")
message( STATUS "Graphene database unity build disabled" )
#else( GRAPHENE_DISABLE_UNITY_BUILD )
# list(FILTER CPP_FILES EXCLUDE REGEX ".*db_.*[.]cpp$")
# #message ("--- ${CPP_FILES}")
# set( GRAPHENE_DB_FILES
# database.cpp )
# message( STATUS "Graphene database unity build enabled" )
#endif( GRAPHENE_DISABLE_UNITY_BUILD )
add_library( graphene_chain
${CPP_FILES}
${PROTOCOL_CPP_FILES}
${HEADERS}
${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
)
set( GRAPHENE_CHAIN_FILES
${CPP_FILES}
${HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"
)
if (NOT ${GRAPHENE_BUILD_DYNAMIC_LIBRARIES})
add_library( graphene_chain ${GRAPHENE_CHAIN_FILES} )
else()
add_library( graphene_chain SHARED ${GRAPHENE_CHAIN_FILES} )
endif()
add_dependencies( graphene_chain build_hardfork_hpp )
target_link_libraries( graphene_chain graphene_db )
target_link_libraries( graphene_chain fc graphene_db graphene_protocol )
target_include_directories( graphene_chain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )
@ -46,4 +48,3 @@ INSTALL( TARGETS
ARCHIVE DESTINATION lib
)
INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/chain" )
INSTALL( FILES ${PROTOCOL_HEADERS} DESTINATION "include/graphene/chain/protocol" )

View file

@ -53,54 +53,7 @@ void verify_authority_accounts( const database& db, const authority& a )
}
}
// Overwrites the num_son values from the origin to the destination for those sidechains which are found in the origin.
// Keeps the values of num_son for the sidechains which are found in the destination, but not in the origin.
// Returns false if an error is detected.
bool merge_num_sons( flat_map<sidechain_type, uint16_t>& destination,
const flat_map<sidechain_type, uint16_t>& origin,
fc::optional<time_point_sec> head_block_time = {})
{
const auto active_sidechains = head_block_time.valid() ? active_sidechain_types(*head_block_time) : all_sidechain_types;
bool success = true;
for (const auto &ns : origin)
{
destination[ns.first] = ns.second;
if (active_sidechains.find(ns.first) == active_sidechains.end())
{
success = false;
}
}
return success;
}
flat_map<sidechain_type, uint16_t> count_SON_votes_per_sidechain( const flat_set<vote_id_type>& votes )
{
flat_map<sidechain_type, uint16_t> SON_votes_per_sidechain = account_options::ext::empty_num_son();
for (const auto &vote : votes)
{
switch (vote.type())
{
case vote_id_type::son_bitcoin:
SON_votes_per_sidechain[sidechain_type::bitcoin]++;
break;
case vote_id_type::son_hive:
SON_votes_per_sidechain[sidechain_type::hive]++;
break;
case vote_id_type::son_ethereum:
SON_votes_per_sidechain[sidechain_type::ethereum]++;
break;
default:
break;
}
}
return SON_votes_per_sidechain;
}
void verify_account_votes( const database& db, const account_options& options, fc::optional<account_object> account = {} )
void verify_account_votes( const database& db, const account_options& options )
{
// ensure account's votes satisfy requirements
// NB only the part of vote checking that requires chain state is here,
@ -109,47 +62,10 @@ void verify_account_votes( const database& db, const account_options& options, f
const auto& gpo = db.get_global_properties();
const auto& chain_params = gpo.parameters;
FC_ASSERT( db.find_object(options.voting_account), "Invalid proxy account specified." );
FC_ASSERT( options.num_witness <= chain_params.maximum_witness_count,
"Voted for more witnesses than currently allowed (${c})", ("c", chain_params.maximum_witness_count) );
FC_ASSERT( options.num_committee <= chain_params.maximum_committee_count,
"Voted for more committee members than currently allowed (${c})", ("c", chain_params.maximum_committee_count) );
FC_ASSERT( chain_params.extensions.value.maximum_son_count.valid() , "Invalid maximum son count" );
flat_map<sidechain_type, uint16_t> merged_num_sons = account_options::ext::empty_num_son();
// Merge with existing account if exists
if ( account.valid() && account->options.extensions.value.num_son.valid())
{
merge_num_sons( merged_num_sons, *account->options.extensions.value.num_son, db.head_block_time() );
}
// Apply update operation on top
if ( options.extensions.value.num_son.valid() )
{
merge_num_sons( merged_num_sons, *options.extensions.value.num_son, db.head_block_time() );
}
for(const auto& num_sons : merged_num_sons)
{
FC_ASSERT( num_sons.second <= *chain_params.extensions.value.maximum_son_count,
"Voted for more sons than currently allowed (${c})", ("c", *chain_params.extensions.value.maximum_son_count) );
}
// Count the votes for SONs and confirm that the account did not vote for less SONs than num_son
flat_map<sidechain_type, uint16_t> SON_votes_per_sidechain = count_SON_votes_per_sidechain(options.votes);
for (const auto& number_of_votes : SON_votes_per_sidechain)
{
// Number of votes of account_options are also checked in account_options::do_evaluate,
// but there we are checking the value before merging num_sons, so the values should be checked again
const auto sidechain = number_of_votes.first;
FC_ASSERT( number_of_votes.second >= merged_num_sons[sidechain],
"Voted for less sons than specified in num_son (votes ${v} < num_son ${ns}) for sidechain ${s}",
("v", number_of_votes.second) ("ns", merged_num_sons[sidechain]) ("s", sidechain) );
}
FC_ASSERT( db.find_object(options.voting_account), "Invalid proxy account specified." );
uint32_t max_vote_id = gpo.next_available_vote_id;
@ -263,13 +179,6 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
obj.owner = o.owner;
obj.active = o.active;
obj.options = o.options;
obj.options.extensions.value.num_son = account_options::ext::empty_num_son();
if ( o.options.extensions.value.num_son.valid() )
{
merge_num_sons( *obj.options.extensions.value.num_son, *o.options.extensions.value.num_son );
}
obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
s.owner = obj.id;
s.name = obj.name;
@ -305,7 +214,7 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
if( dynamic_properties.accounts_registered_this_interval % global_properties.parameters.accounts_per_fee_scale == 0
&& global_properties.parameters.account_fee_scale_bitshifts != 0 )
{
d.modify(global_properties, [&dynamic_properties](global_property_object& p) {
d.modify(global_properties, [](global_property_object& p) {
p.parameters.current_fees->get<account_create_operation>().basic_fee <<= p.parameters.account_fee_scale_bitshifts;
});
}
@ -369,7 +278,7 @@ void_result account_update_evaluator::do_evaluate( const account_update_operatio
acnt = &o.account(d);
if( o.new_options.valid() )
verify_account_votes( d, *o.new_options, *acnt );
verify_account_votes( d, *o.new_options );
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
@ -408,31 +317,7 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.active = *o.active;
a.top_n_control_flags = 0;
}
// New num_son structure initialized to 0
flat_map<sidechain_type, uint16_t> new_num_son = account_options::ext::empty_num_son();
// If num_son of existing object is valid, we should merge the existing data
if ( a.options.extensions.value.num_son.valid() )
{
merge_num_sons( new_num_son, *a.options.extensions.value.num_son );
}
// If num_son of the operation are valid, they should merge the existing data
if ( o.new_options )
{
const auto new_options = *o.new_options;
if ( new_options.extensions.value.num_son.valid() )
{
merge_num_sons( new_num_son, *new_options.extensions.value.num_son );
}
a.options = *o.new_options;
}
a.options.extensions.value.num_son = new_num_son;
if( o.new_options ) a.options = *o.new_options;
if( o.extensions.value.owner_special_authority.valid() )
{
a.owner_special_authority = *(o.extensions.value.owner_special_authority);

View file

@ -36,10 +36,10 @@ share_type cut_fee(share_type a, uint16_t p)
if( p == GRAPHENE_100_PERCENT )
return a;
fc::uint128 r(a.value);
fc::uint128_t r = a.value;
r *= p;
r /= GRAPHENE_100_PERCENT;
return r.to_uint64();
return r;
}
void account_balance_object::adjust_balance(const asset& delta)
@ -142,7 +142,12 @@ set<address> account_member_index::get_address_members(const account_object& a)c
return result;
}
void account_member_index::object_inserted(const object& obj)
void account_member_index::object_loaded(const object& obj)
{
object_created(obj);
}
void account_member_index::object_created(const object& obj)
{
assert( dynamic_cast<const account_object*>(&obj) ); // for debug only
const account_object& a = static_cast<const account_object&>(obj);
@ -256,7 +261,10 @@ void account_member_index::object_modified(const object& after)
}
void account_referrer_index::object_inserted( const object& obj )
void account_referrer_index::object_loaded( const object& obj )
{
}
void account_referrer_index::object_created( const object& obj )
{
}
void account_referrer_index::object_removed( const object& obj )
@ -272,7 +280,12 @@ void account_referrer_index::object_modified( const object& after )
const uint8_t balances_by_account_index::bits = 20;
const uint64_t balances_by_account_index::mask = (1ULL << balances_by_account_index::bits) - 1;
void balances_by_account_index::object_inserted( const object& obj )
void balances_by_account_index::object_loaded( const object& obj )
{
object_created(obj);
}
void balances_by_account_index::object_created( const object& obj )
{
const auto& abo = dynamic_cast< const account_balance_object& >( obj );
while( balances.size() < (abo.owner.instance.value >> bits) + 1 )

View file

@ -62,15 +62,15 @@ namespace graphene { namespace chain {
//ilog("Paying ${p} of ${P} for ${s} of ${r}", ("p",payout.to_uint64())("P",to_pay.value)("s",share)("r",remaining) );
remaining -= share;
}
FC_ASSERT( payout.to_uint64() <= to_pay );
FC_ASSERT( payout <= to_pay );
if( payout > 0 )
{
if ( accumulator.find(affiliate) == accumulator.end() )
accumulator[affiliate] = payout.to_uint64();
accumulator[affiliate] = payout;
else
accumulator[affiliate] += payout.to_uint64();
to_pay -= payout.to_uint64();
paid += payout.to_uint64();
accumulator[affiliate] += payout;
to_pay -= payout;
paid += payout;
}
}
FC_ASSERT( to_pay == 0 );

View file

@ -130,7 +130,7 @@ void asset_create_evaluator::pay_fee()
{
fee_is_odd = core_fee_paid.value & 1;
core_fee_paid -= core_fee_paid.value/2;
generic_evaluator::pay_fee();
consensus_evaluator::pay_fee();
}
object_id_type asset_create_evaluator::do_apply( const asset_create_operation& op )
@ -283,7 +283,7 @@ void lottery_asset_create_evaluator::pay_fee()
{
fee_is_odd = core_fee_paid.value & 1;
core_fee_paid -= core_fee_paid.value/2;
generic_evaluator::pay_fee();
consensus_evaluator::pay_fee();
}
object_id_type lottery_asset_create_evaluator::do_apply( const lottery_asset_create_operation& op )

View file

@ -38,10 +38,11 @@ share_type asset_bitasset_data_object::max_force_settlement_volume(share_type cu
if( options.maximum_force_settlement_volume == GRAPHENE_100_PERCENT )
return current_supply + force_settled_volume;
fc::uint128 volume = current_supply.value + force_settled_volume.value;
fc::uint128_t volume = current_supply.value;
volume += force_settled_volume.value;
volume *= options.maximum_force_settlement_volume;
volume /= GRAPHENE_100_PERCENT;
return volume.to_uint64();
return volume;
}
void asset_bitasset_data_object::update_median_feeds(time_point_sec current_time)

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include <graphene/chain/balance_evaluator.hpp>
#include <graphene/chain/pts_address.hpp>
#include <graphene/protocol/pts_address.hpp>
namespace graphene { namespace chain {

View file

@ -541,7 +541,7 @@ void betting_market_group_object::dispatch_new_status(database& db, betting_mark
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect betting_market_group_object to variant to properly reflect "state"
void to_variant(const graphene::chain::betting_market_group_object& betting_market_group_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -75,7 +75,7 @@ namespace mpl = boost::mpl;
amount_to_match_128 += backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION - 1;
amount_to_match_128 /= backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION;
}
return amount_to_match_128.to_uint64();
return amount_to_match_128;
}
share_type bet_object::get_approximate_matching_amount(bool round_up /* = false */) const
@ -466,7 +466,7 @@ void betting_market_object::on_canceled_event(database& db)
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect betting_market_object to variant to properly reflect "state"
void to_variant(const graphene::chain::betting_market_object& event_obj, fc::variant& v, uint32_t max_depth)
{
@ -493,3 +493,4 @@ namespace fc {
const_cast<int*>(event_obj.my->state_machine.current_state())[0] = (int)status;
}
} //end namespace fc

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include <graphene/chain/block_database.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <fc/io/raw.hpp>
namespace graphene { namespace chain {

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include <graphene/chain/protocol/buyback.hpp>
#include <graphene/protocol/buyback.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>

View file

@ -25,9 +25,8 @@
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/protocol/vote.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/vote.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>
namespace graphene { namespace chain {
@ -42,7 +41,7 @@ object_id_type committee_member_create_evaluator::do_apply( const committee_memb
{ try {
vote_id_type vote_id;
db().modify(db().get_global_properties(), [&vote_id](global_property_object& p) {
vote_id = get_next_vote_id(p, vote_id_type::committee);
vote_id = vote_id_type(vote_id_type::committee, p.next_available_vote_id++);
});
const auto& new_del_object = db().create<committee_member_object>( [&]( committee_member_object& obj ){

View file

@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/confidential.hpp>
#include <graphene/protocol/confidential.hpp>
#include <graphene/chain/confidential_evaluator.hpp>
#include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/database.hpp>
@ -33,163 +33,149 @@ namespace graphene { namespace chain {
void_result transfer_to_blind_evaluator::do_evaluate( const transfer_to_blind_operation& o )
{ try {
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME )
{
const auto& atype = o.amount.asset_id(d);
FC_ASSERT( atype.allow_confidential() );
FC_ASSERT( !atype.is_transfer_restricted() );
FC_ASSERT( !(atype.options.flags & white_list) );
const auto& d = db();
for( const auto& out : o.outputs )
{
for( const auto& a : out.owner.account_auths )
a.first(d); // verify all accounts exist and are valid
}
}
const auto& atype = o.amount.asset_id(db());
FC_ASSERT( atype.allow_confidential() );
FC_ASSERT( !atype.is_transfer_restricted() );
FC_ASSERT( !(atype.options.flags & white_list) );
return void_result();
for( const auto& out : o.outputs )
{
for( const auto& a : out.owner.account_auths )
a.first(d); // verify all accounts exist and are valid
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void_result transfer_to_blind_evaluator::do_apply( const transfer_to_blind_operation& o )
void_result transfer_to_blind_evaluator::do_apply( const transfer_to_blind_operation& o )
{ try {
if( db().head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
db().adjust_balance(o.from, -o.amount);
db().adjust_balance( o.from, -o.amount );
const auto &add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset
db().modify(add, [&](asset_dynamic_data_object &obj) {
obj.confidential_supply += o.amount.amount;
FC_ASSERT(obj.confidential_supply >= 0);
});
for (const auto &out : o.outputs) {
db().create<blinded_balance_object>([&](blinded_balance_object &obj) {
obj.asset_id = o.amount.asset_id;
obj.owner = out.owner;
obj.commitment = out.commitment;
});
}
}
return void_result();
const auto& add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset
db().modify( add, [&]( asset_dynamic_data_object& obj ){
obj.confidential_supply += o.amount.amount;
FC_ASSERT( obj.confidential_supply >= 0 );
});
for( const auto& out : o.outputs )
{
db().create<blinded_balance_object>( [&]( blinded_balance_object& obj ){
obj.asset_id = o.amount.asset_id;
obj.owner = out.owner;
obj.commitment = out.commitment;
});
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void transfer_to_blind_evaluator::pay_fee()
{
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
if (d.head_block_time() >= HARDFORK_563_TIME)
pay_fba_fee(fba_accumulator_id_transfer_to_blind);
else
generic_evaluator::pay_fee();
}
if( db().head_block_time() >= HARDFORK_563_TIME )
pay_fba_fee( fba_accumulator_id_transfer_to_blind );
else
consensus_evaluator::pay_fee();
}
void_result transfer_from_blind_evaluator::do_evaluate( const transfer_from_blind_operation& o )
{ try {
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
o.fee.asset_id(d); // verify fee is a legit asset
const auto &bbi = d.get_index_type<blinded_balance_index>();
const auto &cidx = bbi.indices().get<by_commitment>();
for (const auto &in : o.inputs) {
auto itr = cidx.find(in.commitment);
FC_ASSERT(itr != cidx.end());
FC_ASSERT(itr->asset_id == o.fee.asset_id);
FC_ASSERT(itr->owner == in.owner);
}
}
return void_result();
const auto& d = db();
o.fee.asset_id(d); // verify fee is a legit asset
const auto& bbi = d.get_index_type<blinded_balance_index>();
const auto& cidx = bbi.indices().get<by_commitment>();
for( const auto& in : o.inputs )
{
auto itr = cidx.find( in.commitment );
FC_ASSERT( itr != cidx.end() );
FC_ASSERT( itr->asset_id == o.fee.asset_id );
FC_ASSERT( itr->owner == in.owner );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void_result transfer_from_blind_evaluator::do_apply( const transfer_from_blind_operation& o )
void_result transfer_from_blind_evaluator::do_apply( const transfer_from_blind_operation& o )
{ try {
if( db().head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
db().adjust_balance(o.fee_payer(), o.fee);
db().adjust_balance(o.to, o.amount);
const auto &bbi = db().get_index_type<blinded_balance_index>();
const auto &cidx = bbi.indices().get<by_commitment>();
for (const auto &in : o.inputs) {
auto itr = cidx.find(in.commitment);
FC_ASSERT(itr != cidx.end());
db().remove(*itr);
}
const auto &add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset
db().modify(add, [&](asset_dynamic_data_object &obj) {
obj.confidential_supply -= o.amount.amount + o.fee.amount;
FC_ASSERT(obj.confidential_supply >= 0);
});
}
return void_result();
db().adjust_balance( o.fee_payer(), o.fee );
db().adjust_balance( o.to, o.amount );
const auto& bbi = db().get_index_type<blinded_balance_index>();
const auto& cidx = bbi.indices().get<by_commitment>();
for( const auto& in : o.inputs )
{
auto itr = cidx.find( in.commitment );
FC_ASSERT( itr != cidx.end() );
db().remove( *itr );
}
const auto& add = o.amount.asset_id(db()).dynamic_asset_data_id(db()); // verify fee is a legit asset
db().modify( add, [&]( asset_dynamic_data_object& obj ){
obj.confidential_supply -= o.amount.amount + o.fee.amount;
FC_ASSERT( obj.confidential_supply >= 0 );
});
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void transfer_from_blind_evaluator::pay_fee()
{
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
if (d.head_block_time() >= HARDFORK_563_TIME)
pay_fba_fee(fba_accumulator_id_transfer_from_blind);
else
generic_evaluator::pay_fee();
}
if( db().head_block_time() >= HARDFORK_563_TIME )
pay_fba_fee( fba_accumulator_id_transfer_from_blind );
else
consensus_evaluator::pay_fee();
}
void_result blind_transfer_evaluator::do_evaluate( const blind_transfer_operation& o )
{ try {
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
o.fee.asset_id(d); // verify fee is a legit asset
const auto &bbi = d.get_index_type<blinded_balance_index>();
const auto &cidx = bbi.indices().get<by_commitment>();
for (const auto &out : o.outputs) {
for (const auto &a : out.owner.account_auths)
a.first(d); // verify all accounts exist and are valid
}
for (const auto &in : o.inputs) {
auto itr = cidx.find(in.commitment);
GRAPHENE_ASSERT(itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment", in.commitment));
FC_ASSERT(itr->asset_id == o.fee.asset_id);
FC_ASSERT(itr->owner == in.owner);
}
}
return void_result();
const auto& d = db();
o.fee.asset_id(db()); // verify fee is a legit asset
const auto& bbi = db().get_index_type<blinded_balance_index>();
const auto& cidx = bbi.indices().get<by_commitment>();
for( const auto& out : o.outputs )
{
for( const auto& a : out.owner.account_auths )
a.first(d); // verify all accounts exist and are valid
}
for( const auto& in : o.inputs )
{
auto itr = cidx.find( in.commitment );
GRAPHENE_ASSERT( itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment",in.commitment) );
FC_ASSERT( itr->asset_id == o.fee.asset_id );
FC_ASSERT( itr->owner == in.owner );
}
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void_result blind_transfer_evaluator::do_apply( const blind_transfer_operation& o )
void_result blind_transfer_evaluator::do_apply( const blind_transfer_operation& o )
{ try {
if( db().head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
db().adjust_balance(o.fee_payer(), o.fee); // deposit the fee to the temp account
const auto &bbi = db().get_index_type<blinded_balance_index>();
const auto &cidx = bbi.indices().get<by_commitment>();
for (const auto &in : o.inputs) {
auto itr = cidx.find(in.commitment);
GRAPHENE_ASSERT(itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment", in.commitment));
db().remove(*itr);
}
for (const auto &out : o.outputs) {
db().create<blinded_balance_object>([&](blinded_balance_object &obj) {
obj.asset_id = o.fee.asset_id;
obj.owner = out.owner;
obj.commitment = out.commitment;
});
}
const auto &add = o.fee.asset_id(db()).dynamic_asset_data_id(db());
db().modify(add, [&](asset_dynamic_data_object &obj) {
obj.confidential_supply -= o.fee.amount;
FC_ASSERT(obj.confidential_supply >= 0);
});
}
return void_result();
db().adjust_balance( o.fee_payer(), o.fee ); // deposit the fee to the temp account
const auto& bbi = db().get_index_type<blinded_balance_index>();
const auto& cidx = bbi.indices().get<by_commitment>();
for( const auto& in : o.inputs )
{
auto itr = cidx.find( in.commitment );
GRAPHENE_ASSERT( itr != cidx.end(), blind_transfer_unknown_commitment, "", ("commitment",in.commitment) );
db().remove( *itr );
}
for( const auto& out : o.outputs )
{
db().create<blinded_balance_object>( [&]( blinded_balance_object& obj ){
obj.asset_id = o.fee.asset_id;
obj.owner = out.owner;
obj.commitment = out.commitment;
});
}
const auto& add = o.fee.asset_id(db()).dynamic_asset_data_id(db());
db().modify( add, [&]( asset_dynamic_data_object& obj ){
obj.confidential_supply -= o.fee.amount;
FC_ASSERT( obj.confidential_supply >= 0 );
});
return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
void blind_transfer_evaluator::pay_fee()
{
const auto& d = db();
if( d.head_block_time() < HARDFORK_SON_FOR_ETHEREUM_TIME ) {
if (d.head_block_time() >= HARDFORK_563_TIME)
pay_fba_fee(fba_accumulator_id_blind_transfer);
else
generic_evaluator::pay_fee();
}
if( db().head_block_time() >= HARDFORK_563_TIME )
pay_fba_fee( fba_accumulator_id_blind_transfer );
else
consensus_evaluator::pay_fee();
}
} } // graphene::chain

View file

@ -126,3 +126,4 @@ void_result delete_custom_account_authority_evaluator::do_apply(const custom_acc
} // namespace chain
} // namespace graphene

View file

@ -29,6 +29,8 @@
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/event_object.hpp>
#include <fc/log/logger.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/range/combine.hpp>
#include <boost/range/join.hpp>
@ -132,7 +134,7 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
bool group_was_canceled = resolutions.begin()->second == betting_market_resolution_type::cancel;
if (group_was_canceled)
modify(betting_market_group, [group_was_canceled,this](betting_market_group_object& betting_market_group_obj) {
modify(betting_market_group, [this](betting_market_group_object& betting_market_group_obj) {
betting_market_group_obj.on_canceled_event(*this, false); // this cancels the betting markets
});
else {
@ -149,7 +151,7 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
});
}
modify(betting_market_group, [group_was_canceled,this](betting_market_group_object& betting_market_group_obj) {
modify(betting_market_group, [this](betting_market_group_object& betting_market_group_obj) {
betting_market_group_obj.on_graded_event(*this);
});
}
@ -263,7 +265,7 @@ void database::settle_betting_market_group(const betting_market_group_object& be
share_type rake_amount;
if (net_profits.value > 0 && rake_account_id)
{
rake_amount = ((fc::uint128_t(net_profits.value) * rake_fee_percentage + GRAPHENE_100_PERCENT - 1) / GRAPHENE_100_PERCENT).to_uint64();
rake_amount = ((fc::uint128_t(net_profits.value) * rake_fee_percentage + GRAPHENE_100_PERCENT - 1) / GRAPHENE_100_PERCENT);
share_type affiliates_share;
if (rake_amount.value)
affiliates_share = payout_helper.payout( bettor_id, rake_amount );
@ -490,7 +492,7 @@ int match_bet(database& db, const bet_object& taker_bet, const bet_object& maker
payout_128 += taker_amount_to_match.value;
payout_128 *= GRAPHENE_BETTING_ODDS_PRECISION;
payout_128 /= maker_bet.back_or_lay == bet_type::back ? maker_amount_to_match.value : taker_amount_to_match.value;
assert(payout_128.to_uint64() == maker_bet.backer_multiplier);
assert(payout_128 == maker_bet.backer_multiplier);
}
#endif

View file

@ -26,24 +26,23 @@
#include <graphene/chain/db_with.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/chain/block_summary_object.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/db/object_database.hpp>
#include <fc/crypto/digest.hpp>
#include <boost/filesystem.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/protocol/betting_market.hpp>
#include <fc/crypto/digest.hpp>
#include <fc/thread/non_preemptable_scope_check.hpp>
namespace {
@ -162,13 +161,10 @@ void database::check_transaction_for_duplicated_operations(const signed_transact
existed_operations_digests.insert( proposed_operations_digests.begin(), proposed_operations_digests.end() );
});
for (auto& pending_transaction: _pending_tx)
{
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
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(pending_transaction);
existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end());
}
auto proposed_operations_digests = gather_proposed_operations_digests(trx);
@ -190,12 +186,7 @@ bool database::push_block(const signed_block& new_block, uint32_t skip)
bool result;
detail::with_skip_flags( *this, skip, [&]()
{
std::vector<processed_transaction> pending_tx = [this] {
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
return std::move(_pending_tx);
}();
detail::without_pending_transactions( *this, std::move(pending_tx),
detail::without_pending_transactions( *this, std::move(_pending_tx),
[&]()
{
result = _push_block(new_block);
@ -206,9 +197,6 @@ bool database::push_block(const signed_block& new_block, uint32_t skip)
bool database::_push_block(const signed_block& new_block)
{ try {
boost::filesystem::space_info si = boost::filesystem::space(get_data_dir());
FC_ASSERT((si.available) > 104857600, "Rejecting block due to low disk space"); // 104857600 bytes = 100 MB
uint32_t skip = get_node_properties().skip_flags;
const auto now = fc::time_point::now().sec_since_epoch();
@ -393,28 +381,20 @@ processed_transaction database::push_transaction( const signed_transaction& trx,
processed_transaction database::_push_transaction( const signed_transaction& trx )
{
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
// If this is the first transaction pushed after applying a block, start a new undo session.
// This allows us to quickly rewind to the clean state of the head block, in case a new block arrives.
{
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
if (!_pending_tx_session.valid()) {
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
_pending_tx_session = _undo_db.start_undo_session();
}
}
if( !_pending_tx_session.valid() )
_pending_tx_session = _undo_db.start_undo_session();
// Create a temporary undo session as a child of _pending_tx_session.
// The temporary session will be discarded by the destructor if
// _apply_transaction fails. If we make it to merge(), we
// apply the changes.
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
auto temp_session = _undo_db.start_undo_session();
auto processed_trx = _apply_transaction(trx);
{
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
_pending_tx.push_back(processed_trx);
}
auto processed_trx = _apply_transaction( trx );
_pending_tx.push_back(processed_trx);
// notify_changed_objects();
// The transaction applied successfully. Merge its changes into the pending block session.
@ -427,13 +407,13 @@ processed_transaction database::_push_transaction( const signed_transaction& trx
processed_transaction database::validate_transaction( const signed_transaction& trx )
{
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
auto session = _undo_db.start_undo_session();
return _apply_transaction( trx );
}
processed_transaction database::push_proposal(const proposal_object& proposal)
{ try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
transaction_evaluation_state eval_state(this);
eval_state._is_proposed_trx = true;
@ -456,12 +436,7 @@ processed_transaction database::push_proposal(const proposal_object& proposal)
{
for( size_t i=old_applied_ops_size,n=_applied_ops.size(); i<n; i++ )
{
if(_applied_ops[i].valid()) {
ilog("removing failed operation from applied_ops: ${op}", ("op", *(_applied_ops[i])));
}
else{
ilog("Can't remove failed operation from applied_ops (operation is not valid), op_id : ${op_id}", ("op_id", i));
}
ilog( "removing failed operation from applied_ops: ${op}", ("op", *(_applied_ops[i])) );
_applied_ops[i].reset();
}
}
@ -484,6 +459,7 @@ signed_block database::generate_block(
uint32_t skip /* = 0 */
)
{ try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
signed_block result;
detail::with_skip_flags( *this, skip, [&]()
{
@ -527,52 +503,47 @@ signed_block database::_generate_block(
// the value of the "when" variable is known, which means we need to
// re-apply pending transactions in this method.
//
{
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
_pending_tx_session.reset();
_pending_tx_session = _undo_db.start_undo_session();
}
_pending_tx_session.reset();
_pending_tx_session = _undo_db.start_undo_session();
uint64_t postponed_tx_count = 0;
// pop pending state (reset to head block state)
for( const processed_transaction& tx : _pending_tx )
{
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
for (const processed_transaction &tx : _pending_tx) {
size_t new_total_size = total_block_size + fc::raw::pack_size(tx);
size_t new_total_size = total_block_size + fc::raw::pack_size( tx );
// postpone transaction if it would make block too big
if (new_total_size >= maximum_block_size) {
postponed_tx_count++;
continue;
}
// postpone transaction if it would make block too big
if( new_total_size >= maximum_block_size )
{
postponed_tx_count++;
continue;
}
try {
auto temp_session = _undo_db.start_undo_session();
processed_transaction ptx = _apply_transaction(tx);
temp_session.merge();
try
{
auto temp_session = _undo_db.start_undo_session();
processed_transaction ptx = _apply_transaction( tx );
temp_session.merge();
// We have to recompute pack_size(ptx) because it may be different
// than pack_size(tx) (i.e. if one or more results increased
// their size)
total_block_size += fc::raw::pack_size(ptx);
pending_block.transactions.push_back(ptx);
} catch (const fc::exception &e) {
// Do nothing, transaction will not be re-applied
wlog("Transaction was not processed while generating block due to ${e}", ("e", e));
wlog("The transaction was ${t}", ("t", tx));
}
// We have to recompute pack_size(ptx) because it may be different
// than pack_size(tx) (i.e. if one or more results increased
// their size)
total_block_size += fc::raw::pack_size( ptx );
pending_block.transactions.push_back( ptx );
}
catch ( const fc::exception& e )
{
// Do nothing, transaction will not be re-applied
wlog( "Transaction was not processed while generating block due to ${e}", ("e", e) );
wlog( "The transaction was ${t}", ("t", tx) );
}
}
if( postponed_tx_count > 0 )
{
wlog( "Postponed ${n} transactions due to block size limit", ("n", postponed_tx_count) );
}
{
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
_pending_tx_session.reset();
}
_pending_tx_session.reset();
// We have temporarily broken the invariant that
// _pending_tx_session is the result of applying _pending_tx, as
@ -620,11 +591,8 @@ signed_block database::_generate_block(
*/
void database::pop_block()
{ try {
{
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
_pending_tx_session.reset();
}
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
_pending_tx_session.reset();
auto head_id = head_block_id();
optional<signed_block> head_block = fetch_block_by_id( head_id );
GRAPHENE_ASSERT( head_block.valid(), pop_empty_chain, "there are no blocks to pop" );
@ -638,8 +606,7 @@ void database::pop_block()
void database::clear_pending()
{ try {
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
assert( (_pending_tx.size() == 0) || _pending_tx_session.valid() );
_pending_tx.clear();
_pending_tx_session.reset();
@ -658,7 +625,7 @@ uint32_t database::push_applied_operation( const operation& op )
void database::set_applied_operation_result( uint32_t op_id, const operation_result& result )
{
assert( op_id < _applied_ops.size() );
if( _applied_ops[op_id].valid() )
if( _applied_ops[op_id] )
_applied_ops[op_id]->result = result;
else
{
@ -699,6 +666,7 @@ void database::apply_block( const signed_block& next_block, uint32_t skip )
void database::_apply_block( const signed_block& next_block )
{ try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
uint32_t next_block_num = next_block.block_num();
uint32_t skip = get_node_properties().skip_flags;
_applied_ops.clear();
@ -739,11 +707,8 @@ void database::_apply_block( const signed_block& next_block )
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) {
update_witness_schedule(next_block);
for(const auto& active_sons : global_props.active_sons) {
if(!active_sons.second.empty()) {
update_son_schedule(active_sons.first, next_block);
}
if(global_props.active_sons.size() > 0) {
update_son_schedule(next_block);
}
}
@ -758,7 +723,7 @@ void database::_apply_block( const signed_block& next_block )
check_ending_lotteries();
check_ending_nft_lotteries();
create_block_summary(next_block);
place_delayed_bets(); // must happen after update_global_dynamic_data() updates the time
clear_expired_transactions();
@ -776,15 +741,11 @@ void database::_apply_block( const signed_block& next_block )
// TODO: figure out if we could collapse this function into
// update_global_dynamic_data() as perhaps these methods only need
// to be called for header validation?
update_maintenance_flag( maint_needed );
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) {
update_witness_schedule();
for(const auto& active_sidechain_type : active_sidechain_types(dynamic_global_props.time)) {
if(global_props.active_sons.at(active_sidechain_type).size() > 0) {
update_son_schedule(active_sidechain_type);
}
if(global_props.active_sons.size() > 0) {
update_son_schedule();
}
}
@ -825,6 +786,7 @@ class undo_size_restorer {
processed_transaction database::_apply_transaction(const signed_transaction& trx)
{ try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
uint32_t skip = get_node_properties().skip_flags;
if( true || !(skip&skip_validate) ) /* issue #505 explains why this skip_flag is disabled */
@ -852,7 +814,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
return get_account_custom_authorities(id, op);
};
trx.verify_authority( chain_id, get_active, get_owner, get_custom,
true,
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(head_block_time()),
get_global_properties().parameters.max_authority_depth );
}
@ -865,7 +827,7 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
const auto& tapos_block_summary = block_summary_id_type( trx.ref_block_num )(*this);
//Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration
FC_ASSERT( trx.ref_block_prefix == tapos_block_summary.block_id._hash[1] );
FC_ASSERT( trx.ref_block_prefix == tapos_block_summary.block_id._hash[1].value() );
}
fc::time_point_sec now = head_block_time();
@ -878,8 +840,8 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
//Insert transaction into unique transactions database.
if( !(skip & skip_transaction_dupe_check) )
{
create<transaction_object>([&trx_id,&trx](transaction_object& transaction) {
transaction.trx_id = trx_id;
create<transaction_history_object>([&trx](transaction_history_object& transaction) {
transaction.trx_id = trx.id();
transaction.trx = trx;
});
}
@ -909,15 +871,26 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
operation_result database::apply_operation(transaction_evaluation_state& eval_state, const operation& op)
{ try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
int i_which = op.which();
uint64_t u_which = uint64_t( i_which );
FC_ASSERT( i_which >= 0, "Negative operation tag in operation ${op}", ("op",op) );
FC_ASSERT( u_which < _operation_evaluators.size(), "No registered evaluator for operation ${op}", ("op",op) );
unique_ptr<op_evaluator>& eval = _operation_evaluators[ u_which ];
FC_ASSERT( u_which < _consensus_operation_evaluators.size(), "No registered evaluator for operation ${op}", ("op",op) );
unique_ptr<op_evaluator>& eval = _consensus_operation_evaluators[ u_which ];
FC_ASSERT( eval, "No registered evaluator for operation ${op}", ("op",op) );
auto op_id = push_applied_operation( op );
auto result = eval->evaluate( eval_state, op, true );
set_applied_operation_result( op_id, result );
// Run third party evaluator chain. Check that they don't yield, and lock consensus databases while they run.
if (_third_party_operation_evaluators.size() > u_which && _third_party_operation_evaluators[u_which]) {
ASSERT_TASK_NOT_PREEMPTED();
_check_policy_1->lock();
_check_policy_2->lock();
_third_party_operation_evaluators[u_which]->evaluate( eval_state, op, true );
_check_policy_1->unlock();
_check_policy_2->unlock();
}
return result;
} FC_CAPTURE_AND_RETHROW( (op) ) }

View file

@ -113,13 +113,15 @@ std::vector<uint32_t> database::get_seeds( asset_id_type for_asset, uint8_t coun
{
FC_ASSERT( count_winners <= 64 );
std::string salted_string = std::string(_random_number_generator._seed) + std::to_string(for_asset.instance.value);
uint32_t* seeds = (uint32_t*)(fc::sha256::hash(salted_string)._hash);
auto seeds_hash = fc::sha256::hash(salted_string);
uint32_t* seeds = (uint32_t*)(seeds_hash._hash);
std::vector<uint32_t> result;
result.reserve(64);
for( int s = 0; s < 8; ++s ) {
uint32_t* sub_seeds = ( uint32_t* ) fc::sha256::hash( std::to_string( seeds[s] ) + std::to_string( for_asset.instance.value ) )._hash;
auto sub_seeds_hash = fc::sha256::hash(std::to_string(seeds[s]) + std::to_string(for_asset.instance.value));
uint32_t* sub_seeds = (uint32_t*) sub_seeds_hash._hash;
for( int ss = 0; ss < 8; ++ss ) {
result.push_back(sub_seeds[ss]);
}
@ -222,32 +224,18 @@ std::set<son_id_type> database::get_sons_to_be_deregistered()
for( auto& son : son_idx )
{
bool need_to_be_deregistered = true;
for(const auto& status : son.statuses)
if(son.status == son_status::in_maintenance)
{
const auto& sidechain = status.first;
if(status.second != son_status::in_maintenance)
need_to_be_deregistered = false;
auto& stats = son.statistics(*this);
if(need_to_be_deregistered)
// 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()))
{
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(stats.last_active_timestamp.contains(sidechain)) {
if (head_block_time() - stats.last_active_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time())) {
need_to_be_deregistered = false;
}
}
ret.insert(son.id);
}
}
if(need_to_be_deregistered)
{
ret.insert(son.id);
}
}
return ret;
}
@ -304,50 +292,28 @@ bool database::is_son_dereg_valid( son_id_type son_id )
return false;
}
bool status_son_dereg_valid = true;
for (const auto &active_sidechain_type : active_sidechain_types(head_block_time())) {
if(son->statuses.at(active_sidechain_type) != son_status::in_maintenance)
status_son_dereg_valid = false;
if(status_son_dereg_valid)
{
if(son->statistics(*this).last_active_timestamp.contains(active_sidechain_type)) {
if (head_block_time() - son->statistics(*this).last_active_timestamp.at(active_sidechain_type) < fc::seconds(get_global_properties().parameters.son_deregister_time())) {
status_son_dereg_valid = false;
}
}
}
}
return status_son_dereg_valid;
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( sidechain_type type, son_id_type son_id )
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()) {
if(son == son_idx.end())
{
return false;
}
const global_property_object& gpo = get_global_properties();
if(!gpo.active_sons.contains(type)) {
return false;
}
const auto& gpo_as = gpo.active_sons.at(type);
vector<son_id_type> active_son_ids;
active_son_ids.reserve(gpo_as.size());
std::transform(gpo_as.cbegin(), gpo_as.cend(),
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_sidechain_info& swi) {
[](const son_info& swi) {
return swi.son_id;
});
if(active_son_ids.empty()) {
return false;
}
auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), son_id);
return (it_son != active_son_ids.end());
}
@ -386,14 +352,23 @@ vector<uint64_t> database::get_random_numbers(uint64_t minimum, uint64_t maximum
bool database::is_asset_creation_allowed(const string &symbol)
{
time_point_sec now = head_block_time();
std::unordered_set<std::string> post_son_hf_symbols = {"ETH", "USDT", "BNB", "ADA", "DOGE", "XRP", "USDC", "DOT", "UNI", "BUSD", "BCH", "LTC", "SOL", "LINK", "MATIC", "THETA",
"WBTC", "XLM", "ICP", "DAI", "VET", "ETC", "TRX", "FIL", "XMR", "EGR", "EOS", "SHIB", "AAVE", "CRO", "ALGO", "AMP", "BTCB",
"BSV", "KLAY", "CAKE", "FTT", "LEO", "XTZ", "TFUEL", "MIOTA", "LUNA", "NEO", "ATOM", "MKR", "FEI", "WBNB", "UST", "AVAX",
"STEEM", "HIVE", "HBD", "SBD", "BTS"};
if (symbol == "BTC")
{
if (head_block_time() < HARDFORK_SON_TIME)
if (now < HARDFORK_SON_TIME)
return false;
}
if (post_son_hf_symbols.find(symbol) != post_son_hf_symbols.end())
{
if (now >= HARDFORK_SON_TIME)
return false;
}
return true;
}
}
}
} }

View file

@ -40,7 +40,7 @@
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp>
@ -104,7 +104,7 @@
#include <graphene/chain/sidechain_transaction_evaluator.hpp>
#include <graphene/chain/random_number_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <fc/uint128.hpp>
#include <fc/crypto/digest.hpp>
@ -152,8 +152,8 @@ const uint8_t operation_history_object::type_id;
const uint8_t proposal_object::space_id;
const uint8_t proposal_object::type_id;
const uint8_t transaction_object::space_id;
const uint8_t transaction_object::type_id;
const uint8_t transaction_history_object::space_id;
const uint8_t transaction_history_object::type_id;
const uint8_t vesting_balance_object::space_id;
const uint8_t vesting_balance_object::type_id;
@ -214,169 +214,132 @@ const uint8_t random_number_object::type_id;
void database::initialize_evaluators()
{
_operation_evaluators.resize(255);
register_evaluator<account_create_evaluator>();
register_evaluator<account_update_evaluator>();
register_evaluator<account_upgrade_evaluator>();
register_evaluator<account_whitelist_evaluator>();
register_evaluator<committee_member_create_evaluator>();
register_evaluator<committee_member_update_evaluator>();
register_evaluator<committee_member_update_global_parameters_evaluator>();
register_evaluator<custom_evaluator>();
register_evaluator<asset_create_evaluator>();
register_evaluator<asset_issue_evaluator>();
register_evaluator<asset_reserve_evaluator>();
register_evaluator<asset_update_evaluator>();
register_evaluator<asset_update_bitasset_evaluator>();
register_evaluator<asset_update_dividend_evaluator>();
register_evaluator<asset_update_feed_producers_evaluator>();
register_evaluator<asset_settle_evaluator>();
register_evaluator<asset_global_settle_evaluator>();
register_evaluator<assert_evaluator>();
register_evaluator<limit_order_create_evaluator>();
register_evaluator<limit_order_cancel_evaluator>();
register_evaluator<call_order_update_evaluator>();
register_evaluator<transfer_evaluator>();
register_evaluator<override_transfer_evaluator>();
register_evaluator<asset_fund_fee_pool_evaluator>();
register_evaluator<asset_publish_feeds_evaluator>();
register_evaluator<proposal_create_evaluator>();
register_evaluator<proposal_update_evaluator>();
register_evaluator<proposal_delete_evaluator>();
register_evaluator<vesting_balance_create_evaluator>();
register_evaluator<vesting_balance_withdraw_evaluator>();
register_evaluator<witness_create_evaluator>();
register_evaluator<witness_update_evaluator>();
register_evaluator<withdraw_permission_create_evaluator>();
register_evaluator<withdraw_permission_claim_evaluator>();
register_evaluator<withdraw_permission_update_evaluator>();
register_evaluator<withdraw_permission_delete_evaluator>();
register_evaluator<worker_create_evaluator>();
register_evaluator<balance_claim_evaluator>();
register_evaluator<transfer_to_blind_evaluator>();
register_evaluator<transfer_from_blind_evaluator>();
register_evaluator<blind_transfer_evaluator>();
register_evaluator<asset_claim_fees_evaluator>();
register_evaluator<sport_create_evaluator>();
register_evaluator<sport_update_evaluator>();
register_evaluator<sport_delete_evaluator>();
register_evaluator<event_group_create_evaluator>();
register_evaluator<event_group_update_evaluator>();
register_evaluator<event_group_delete_evaluator>();
register_evaluator<event_create_evaluator>();
register_evaluator<event_update_evaluator>();
register_evaluator<event_update_status_evaluator>();
register_evaluator<betting_market_rules_create_evaluator>();
register_evaluator<betting_market_rules_update_evaluator>();
register_evaluator<betting_market_group_create_evaluator>();
register_evaluator<betting_market_group_update_evaluator>();
register_evaluator<betting_market_create_evaluator>();
register_evaluator<betting_market_update_evaluator>();
register_evaluator<bet_place_evaluator>();
register_evaluator<bet_cancel_evaluator>();
register_evaluator<betting_market_group_resolve_evaluator>();
register_evaluator<betting_market_group_cancel_unmatched_bets_evaluator>();
register_evaluator<tournament_create_evaluator>();
register_evaluator<tournament_join_evaluator>();
register_evaluator<game_move_evaluator>();
register_evaluator<tournament_leave_evaluator>();
register_evaluator<lottery_asset_create_evaluator>();
register_evaluator<ticket_purchase_evaluator>();
register_evaluator<lottery_reward_evaluator>();
register_evaluator<lottery_end_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<nft_lottery_token_purchase_evaluator>();
register_evaluator<nft_lottery_reward_evaluator>();
register_evaluator<nft_lottery_end_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>();
register_evaluator<random_number_store_evaluator>();
}
void database::initialize_hardforks()
{
_hardfork_times.emplace_back(HARDFORK_357_TIME);
_hardfork_times.emplace_back(HARDFORK_359_TIME);
_hardfork_times.emplace_back(HARDFORK_385_TIME);
_hardfork_times.emplace_back(HARDFORK_409_TIME);
_hardfork_times.emplace_back(HARDFORK_413_TIME);
_hardfork_times.emplace_back(HARDFORK_415_TIME);
_hardfork_times.emplace_back(HARDFORK_416_TIME);
_hardfork_times.emplace_back(HARDFORK_419_TIME);
_hardfork_times.emplace_back(HARDFORK_436_TIME);
_hardfork_times.emplace_back(HARDFORK_445_TIME);
_hardfork_times.emplace_back(HARDFORK_453_TIME);
_hardfork_times.emplace_back(HARDFORK_480_TIME);
_hardfork_times.emplace_back(HARDFORK_483_TIME);
_hardfork_times.emplace_back(HARDFORK_516_TIME);
_hardfork_times.emplace_back(HARDFORK_533_TIME);
_hardfork_times.emplace_back(HARDFORK_538_TIME);
_hardfork_times.emplace_back(HARDFORK_555_TIME);
_hardfork_times.emplace_back(HARDFORK_563_TIME);
_hardfork_times.emplace_back(HARDFORK_572_TIME);
_hardfork_times.emplace_back(HARDFORK_599_TIME);
_hardfork_times.emplace_back(HARDFORK_607_TIME);
_hardfork_times.emplace_back(HARDFORK_613_TIME);
_hardfork_times.emplace_back(HARDFORK_615_TIME);
_hardfork_times.emplace_back(HARDFORK_999_TIME);
_hardfork_times.emplace_back(HARDFORK_1000_TIME);
_hardfork_times.emplace_back(HARDFORK_1001_TIME);
_hardfork_times.emplace_back(HARDFORK_5050_1_TIME);
_hardfork_times.emplace_back(HARDFORK_CORE_429_TIME);
_hardfork_times.emplace_back(HARDFORK_GPOS_TIME);
_hardfork_times.emplace_back(HARDFORK_NFT_TIME);
_hardfork_times.emplace_back(HARDFORK_SON_FOR_HIVE_TIME);
_hardfork_times.emplace_back(HARDFORK_SON_TIME);
_hardfork_times.emplace_back(HARDFORK_SON2_TIME);
_hardfork_times.emplace_back(HARDFORK_SON_FOR_ETHEREUM_TIME);
_hardfork_times.emplace_back(HARDFORK_SWEEPS_TIME);
std::sort(_hardfork_times.begin(), _hardfork_times.end());
_consensus_operation_evaluators.resize(255);
_third_party_operation_evaluators.resize(255);
register_consensus_evaluator<account_create_evaluator>();
register_consensus_evaluator<account_update_evaluator>();
register_consensus_evaluator<account_upgrade_evaluator>();
register_consensus_evaluator<account_whitelist_evaluator>();
register_consensus_evaluator<committee_member_create_evaluator>();
register_consensus_evaluator<committee_member_update_evaluator>();
register_consensus_evaluator<committee_member_update_global_parameters_evaluator>();
register_consensus_evaluator<custom_evaluator>();
register_consensus_evaluator<asset_create_evaluator>();
register_consensus_evaluator<asset_issue_evaluator>();
register_consensus_evaluator<asset_reserve_evaluator>();
register_consensus_evaluator<asset_update_evaluator>();
register_consensus_evaluator<asset_update_bitasset_evaluator>();
register_consensus_evaluator<asset_update_dividend_evaluator>();
register_consensus_evaluator<asset_update_feed_producers_evaluator>();
register_consensus_evaluator<asset_settle_evaluator>();
register_consensus_evaluator<asset_global_settle_evaluator>();
register_consensus_evaluator<assert_evaluator>();
register_consensus_evaluator<limit_order_create_evaluator>();
register_consensus_evaluator<limit_order_cancel_evaluator>();
register_consensus_evaluator<call_order_update_evaluator>();
register_consensus_evaluator<transfer_evaluator>();
register_consensus_evaluator<override_transfer_evaluator>();
register_consensus_evaluator<asset_fund_fee_pool_evaluator>();
register_consensus_evaluator<asset_publish_feeds_evaluator>();
register_consensus_evaluator<proposal_create_evaluator>();
register_consensus_evaluator<proposal_update_evaluator>();
register_consensus_evaluator<proposal_delete_evaluator>();
register_consensus_evaluator<vesting_balance_create_evaluator>();
register_consensus_evaluator<vesting_balance_withdraw_evaluator>();
register_consensus_evaluator<witness_create_evaluator>();
register_consensus_evaluator<witness_update_evaluator>();
register_consensus_evaluator<withdraw_permission_create_evaluator>();
register_consensus_evaluator<withdraw_permission_claim_evaluator>();
register_consensus_evaluator<withdraw_permission_update_evaluator>();
register_consensus_evaluator<withdraw_permission_delete_evaluator>();
register_consensus_evaluator<worker_create_evaluator>();
register_consensus_evaluator<balance_claim_evaluator>();
register_consensus_evaluator<transfer_to_blind_evaluator>();
register_consensus_evaluator<transfer_from_blind_evaluator>();
register_consensus_evaluator<blind_transfer_evaluator>();
register_consensus_evaluator<asset_claim_fees_evaluator>();
register_consensus_evaluator<sport_create_evaluator>();
register_consensus_evaluator<sport_update_evaluator>();
register_consensus_evaluator<sport_delete_evaluator>();
register_consensus_evaluator<event_group_create_evaluator>();
register_consensus_evaluator<event_group_update_evaluator>();
register_consensus_evaluator<event_group_delete_evaluator>();
register_consensus_evaluator<event_create_evaluator>();
register_consensus_evaluator<event_update_evaluator>();
register_consensus_evaluator<event_update_status_evaluator>();
register_consensus_evaluator<betting_market_rules_create_evaluator>();
register_consensus_evaluator<betting_market_rules_update_evaluator>();
register_consensus_evaluator<betting_market_group_create_evaluator>();
register_consensus_evaluator<betting_market_group_update_evaluator>();
register_consensus_evaluator<betting_market_create_evaluator>();
register_consensus_evaluator<betting_market_update_evaluator>();
register_consensus_evaluator<bet_place_evaluator>();
register_consensus_evaluator<bet_cancel_evaluator>();
register_consensus_evaluator<betting_market_group_resolve_evaluator>();
register_consensus_evaluator<betting_market_group_cancel_unmatched_bets_evaluator>();
register_consensus_evaluator<tournament_create_evaluator>();
register_consensus_evaluator<tournament_join_evaluator>();
register_consensus_evaluator<game_move_evaluator>();
register_consensus_evaluator<tournament_leave_evaluator>();
register_consensus_evaluator<lottery_asset_create_evaluator>();
register_consensus_evaluator<ticket_purchase_evaluator>();
register_consensus_evaluator<lottery_reward_evaluator>();
register_consensus_evaluator<lottery_end_evaluator>();
register_consensus_evaluator<sweeps_vesting_claim_evaluator>();
register_consensus_evaluator<create_custom_permission_evaluator>();
register_consensus_evaluator<update_custom_permission_evaluator>();
register_consensus_evaluator<delete_custom_permission_evaluator>();
register_consensus_evaluator<create_custom_account_authority_evaluator>();
register_consensus_evaluator<update_custom_account_authority_evaluator>();
register_consensus_evaluator<delete_custom_account_authority_evaluator>();
register_consensus_evaluator<offer_evaluator>();
register_consensus_evaluator<bid_evaluator>();
register_consensus_evaluator<cancel_offer_evaluator>();
register_consensus_evaluator<finalize_offer_evaluator>();
register_consensus_evaluator<nft_metadata_create_evaluator>();
register_consensus_evaluator<nft_metadata_update_evaluator>();
register_consensus_evaluator<nft_mint_evaluator>();
register_consensus_evaluator<nft_safe_transfer_from_evaluator>();
register_consensus_evaluator<nft_approve_evaluator>();
register_consensus_evaluator<nft_set_approval_for_all_evaluator>();
register_consensus_evaluator<account_role_create_evaluator>();
register_consensus_evaluator<account_role_update_evaluator>();
register_consensus_evaluator<account_role_delete_evaluator>();
register_consensus_evaluator<nft_lottery_token_purchase_evaluator>();
register_consensus_evaluator<nft_lottery_reward_evaluator>();
register_consensus_evaluator<nft_lottery_end_evaluator>();
register_consensus_evaluator<create_son_evaluator>();
register_consensus_evaluator<update_son_evaluator>();
register_consensus_evaluator<deregister_son_evaluator>();
register_consensus_evaluator<son_heartbeat_evaluator>();
register_consensus_evaluator<son_report_down_evaluator>();
register_consensus_evaluator<son_maintenance_evaluator>();
register_consensus_evaluator<recreate_son_wallet_evaluator>();
register_consensus_evaluator<update_son_wallet_evaluator>();
register_consensus_evaluator<create_son_wallet_deposit_evaluator>();
register_consensus_evaluator<process_son_wallet_deposit_evaluator>();
register_consensus_evaluator<create_son_wallet_withdraw_evaluator>();
register_consensus_evaluator<process_son_wallet_withdraw_evaluator>();
register_consensus_evaluator<add_sidechain_address_evaluator>();
register_consensus_evaluator<update_sidechain_address_evaluator>();
register_consensus_evaluator<delete_sidechain_address_evaluator>();
register_consensus_evaluator<sidechain_transaction_create_evaluator>();
register_consensus_evaluator<sidechain_transaction_sign_evaluator>();
register_consensus_evaluator<sidechain_transaction_send_evaluator>();
register_consensus_evaluator<sidechain_transaction_settle_evaluator>();
register_consensus_evaluator<random_number_store_evaluator>();
}
void database::initialize_indexes()
{
reset_indexes();
_undo_db.set_max_size( GRAPHENE_MIN_UNDO_HISTORY );
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
_undo_db.set_max_size(GRAPHENE_MIN_UNDO_HISTORY);
_check_policy_1 = allocate_object_space<database_lock_safety_check>(protocol_ids);
_check_policy_2 = allocate_object_space<database_lock_safety_check>(implementation_ids);
// No checks on API objects
allocate_object_space<null_safety_check>(api_ids);
FC_ASSERT(_check_policy_1 != nullptr && _check_policy_2 != nullptr, "Failed to allocate object spaces");
//Protocol object indexes
add_index< primary_index<asset_index, 13> >(); // 8192 assets per chunk
@ -464,6 +427,8 @@ void database::initialize_indexes()
add_index< primary_index<son_stats_index > >();
add_index< primary_index<random_number_index > >();
_check_policy_1->lock();
_check_policy_2->lock();
}
void database::init_genesis(const genesis_state_type& genesis_state)
@ -476,9 +441,8 @@ void database::init_genesis(const genesis_state_type& genesis_state)
FC_ASSERT(genesis_state.initial_active_witnesses <= genesis_state.initial_witness_candidates.size(),
"initial_active_witnesses is larger than the number of candidate witnesses.");
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
_undo_db.disable();
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
struct auth_inhibitor {
auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags)
{ db.node_properties().skip_flags |= skip_authority_check; }
@ -726,7 +690,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
p.time = genesis_state.initial_timestamp;
p.dynamic_flags = 0;
p.witness_budget = 0;
p.recent_slots_filled = fc::uint128::max_value();
p.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
});
create<global_betting_statistics_object>([&](global_betting_statistics_object& betting_statistics) {
betting_statistics.number_of_active_events = 0;
@ -949,7 +913,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
for( const auto& handout : genesis_state.initial_balances )
{
const auto asset_id = get_asset_id(handout.asset_symbol);
create<balance_object>([&handout,&get_asset_id,total_allocation,asset_id](balance_object& b) {
create<balance_object>([&handout,total_allocation,asset_id](balance_object& b) {
b.balance = asset(handout.amount, asset_id);
b.owner = handout.owner;
});
@ -1095,7 +1059,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
_wso.last_scheduling_block = 0;
_wso.recent_slots_filled = fc::uint128::max_value();
_wso.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
// for shuffled
for( const witness_id_type& wid : get_global_properties().active_witnesses )
@ -1104,9 +1068,8 @@ void database::init_genesis(const genesis_state_type& genesis_state)
FC_ASSERT( _p_witness_schedule_obj->id == witness_schedule_id_type() );
// Initialize witness schedule
#ifndef NDEBUG
const son_schedule_object& ssobitcoin =
const son_schedule_object& sso =
#endif
create<son_schedule_object>([&](son_schedule_object& _sso)
{
@ -1115,64 +1078,24 @@ void database::init_genesis(const genesis_state_type& genesis_state)
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
auto init_bitcoin_sons = get_global_properties().active_sons.at(sidechain_type::bitcoin);
auto init_witnesses = get_global_properties().active_witnesses;
_sso.scheduler = son_scheduler();
_sso.scheduler._min_token_count = std::max(int(init_bitcoin_sons.size()) / 2, 1);
_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();
_sso.recent_slots_filled = std::numeric_limits<fc::uint128_t>::max();
});
assert( ssobitcoin.id == son_schedule_id_type(get_son_schedule_id(sidechain_type::bitcoin)) );
#ifndef NDEBUG
const son_schedule_object& ssoethereum =
#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_ethereum_sons = get_global_properties().active_sons.at(sidechain_type::ethereum);
_sso.scheduler = son_scheduler();
_sso.scheduler._min_token_count = std::max(int(init_ethereum_sons.size()) / 2, 1);
_sso.last_scheduling_block = 0;
_sso.recent_slots_filled = fc::uint128::max_value();
});
assert( ssoethereum.id == son_schedule_id_type(get_son_schedule_id(sidechain_type::ethereum)) );
#ifndef NDEBUG
const son_schedule_object& ssohive =
#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_hive_sons = get_global_properties().active_sons.at(sidechain_type::hive);
_sso.scheduler = son_scheduler();
_sso.scheduler._min_token_count = std::max(int(init_hive_sons.size()) / 2, 1);
_sso.last_scheduling_block = 0;
_sso.recent_slots_filled = fc::uint128::max_value();
});
assert( ssohive.id == son_schedule_id_type(get_son_schedule_id(sidechain_type::hive)) );
assert( sso.id == son_schedule_id_type() );
// Enable fees
modify(get_global_properties(), [&genesis_state](global_property_object& p) {
p.parameters.current_fees = genesis_state.initial_parameters.current_fees;
});
// Create FBA counters
create<fba_accumulator_object>([&]( fba_accumulator_object& acc )
{

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,8 @@
#include <graphene/chain/special_authority_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/nft_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <fc/io/fstream.hpp>
@ -39,12 +40,14 @@
namespace graphene { namespace chain {
database::database() :
_random_number_generator(fc::ripemd160().data())
database::database(bool allow_testing_edits) :
_random_number_generator(fc::ripemd160().data()),
_allow_safety_check_bypass(allow_testing_edits)
{
if (allow_testing_edits)
elog("UNIT TESTING MODE ENABLED -- NOT FOR PRODUCTION USE");
initialize_indexes();
initialize_evaluators();
initialize_hardforks();
}
database::~database()

View file

@ -575,10 +575,10 @@ asset database::calculate_market_fee( const asset_object& trade_asset, const ass
if( trade_asset.options.market_fee_percent == 0 )
return trade_asset.amount(0);
fc::uint128 a(trade_amount.amount.value);
fc::uint128_t a(trade_amount.amount.value);
a *= trade_asset.options.market_fee_percent;
a /= GRAPHENE_100_PERCENT;
asset percent_fee = trade_asset.amount(a.to_uint64());
asset percent_fee = trade_asset.amount(a);
if( percent_fee.amount > trade_asset.options.max_market_fee )
percent_fee.amount = trade_asset.options.max_market_fee;

View file

@ -24,11 +24,11 @@
#include <fc/container/flat.hpp>
#include <graphene/protocol/authority.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/protocol/transaction.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/protocol/authority.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/transaction.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/confidential_object.hpp>
@ -39,14 +39,17 @@
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/vesting_balance_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/impacted.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/sidechain_address_object.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/offer_object.hpp>
#include <graphene/chain/nft_object.hpp>
using namespace fc;
using namespace graphene::chain;
@ -203,10 +206,27 @@ struct get_impacted_account_visitor
_impacted.insert( op.issuer );
}
//! We don't use this operations
void operator()( const transfer_to_blind_operation& op ){}
void operator()( const blind_transfer_operation& op ){}
void operator()( const transfer_from_blind_operation& op ){}
void operator()( const transfer_to_blind_operation& op )
{
_impacted.insert( op.from );
for( const auto& out : op.outputs )
add_authority_accounts( _impacted, out.owner );
}
void operator()( const blind_transfer_operation& op )
{
for( const auto& in : op.inputs )
add_authority_accounts( _impacted, in.owner );
for( const auto& out : op.outputs )
add_authority_accounts( _impacted, out.owner );
}
void operator()( const transfer_from_blind_operation& op )
{
_impacted.insert( op.to );
for( const auto& in : op.inputs )
add_authority_accounts( _impacted, in.owner );
}
void operator()( const asset_settle_cancel_operation& op )
{
@ -433,7 +453,6 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
{
case null_object_type:
case base_object_type:
case OBJECT_TYPE_COUNT:
return;
case account_object_type:{
accounts.insert( obj->id );
@ -476,11 +495,7 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
transaction_get_impacted_accounts( aobj->proposed_transaction, accounts,
ignore_custom_operation_required_auths);
break;
} case operation_history_object_type:{
const auto& aobj = dynamic_cast<const operation_history_object*>(obj);
assert( aobj != nullptr );
operation_get_impacted_accounts( aobj->op, accounts,
ignore_custom_operation_required_auths);
} case reserved0_object_type:{
break;
} case withdraw_permission_object_type:{
const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj);
@ -501,7 +516,85 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case balance_object_type:{
/** these are free from any accounts */
break;
} case account_role_type:{
} case tournament_object_type:{
auto aobj = dynamic_cast<const tournament_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->creator);
accounts.insert(aobj->options.whitelist.begin(), aobj->options.whitelist.end());
break;
} case tournament_details_object_type:{
auto aobj = dynamic_cast<const tournament_details_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->registered_players.begin(), aobj->registered_players.end());
std::transform(aobj->payers.begin(), aobj->payers.end(), std::inserter(accounts, accounts.end()),
[](const auto& pair) { return pair.first; });
std::for_each(aobj->players_payers.begin(), aobj->players_payers.end(),
[&accounts](const auto& pair) {
accounts.insert(pair.first);
accounts.insert(pair.second);
});
break;
} case match_object_type:{
auto aobj = dynamic_cast<const match_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->players.begin(), aobj->players.end());
std::for_each(aobj->game_winners.begin(), aobj->game_winners.end(),
[&accounts](const auto& set) { accounts.insert(set.begin(), set.end()); });
accounts.insert(aobj->match_winners.begin(), aobj->match_winners.end());
break;
} case game_object_type:{
auto aobj = dynamic_cast<const game_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->players.begin(), aobj->players.end());
accounts.insert(aobj->winners.begin(), aobj->winners.end());
break;
} case sport_object_type:
break;
case event_group_object_type:
break;
case event_object_type:
break;
case betting_market_rules_object_type:
break;
case betting_market_group_object_type:
break;
case betting_market_object_type:
break;
case bet_object_type:{
auto aobj = dynamic_cast<const bet_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->bettor_id);
break;
} case custom_permission_object_type:{
auto aobj = dynamic_cast<const custom_permission_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->account);
add_authority_accounts(accounts, aobj->auth);
break;
} case custom_account_authority_object_type:
break;
case offer_object_type:{
auto aobj = dynamic_cast<const offer_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->issuer);
if (aobj->bidder.valid())
accounts.insert(*aobj->bidder);
break;
} case nft_metadata_object_type:{
auto aobj = dynamic_cast<const nft_metadata_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->owner);
if (aobj->revenue_partner.valid())
accounts.insert(*aobj->revenue_partner);
break;
} case nft_object_type:{
auto aobj = dynamic_cast<const nft_object*>(obj);
assert(aobj != nullptr);
accounts.insert(aobj->owner);
accounts.insert(aobj->approved);
accounts.insert(aobj->approved_operators.begin(), aobj->approved_operators.end());
break;
} case account_role_object_type:{
const auto& aobj = dynamic_cast<const account_role_object*>(obj);
assert( aobj != nullptr );
accounts.insert( aobj->owner );
@ -512,6 +605,8 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
assert( aobj != nullptr );
accounts.insert( aobj->son_account );
break;
} case son_proposal_object_type:{
break;
} case son_wallet_object_type:{
break;
} case son_wallet_deposit_object_type:{
@ -541,9 +636,9 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break;
case impl_reserved0_object_type:
break;
case impl_asset_dynamic_data_type:
case impl_asset_dynamic_data_object_type:
break;
case impl_asset_bitasset_data_type:
case impl_asset_bitasset_data_object_type:
break;
case impl_account_balance_object_type:{
const auto& aobj = dynamic_cast<const account_balance_object*>(obj);
@ -555,11 +650,11 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
assert( aobj != nullptr );
accounts.insert( aobj->owner );
break;
} case impl_transaction_object_type:{
const auto& aobj = dynamic_cast<const transaction_object*>(obj);
assert( aobj != nullptr );
} case impl_transaction_history_object_type:{
const auto& aobj = dynamic_cast<const transaction_history_object*>(obj);
FC_ASSERT( aobj != nullptr );
transaction_get_impacted_accounts( aobj->trx, accounts,
ignore_custom_operation_required_auths);
ignore_custom_operation_required_auths );
break;
} case impl_blinded_balance_object_type:{
const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj);
@ -569,7 +664,7 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break;
} case impl_block_summary_object_type:
break;
case impl_account_transaction_history_object_type:
case impl_reserved1_object_type:
break;
case impl_chain_property_object_type:
break;
@ -583,11 +678,62 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break;
case impl_fba_accumulator_object_type:
break;
case impl_asset_dividend_data_object_type:{
const auto& aobj = dynamic_cast<const asset_dividend_data_object*>(obj);
assert( aobj != nullptr );
accounts.insert(aobj->dividend_distribution_account);
break;
} case impl_pending_dividend_payout_balance_for_holder_object_type:{
const auto& aobj = dynamic_cast<const pending_dividend_payout_balance_for_holder_object*>(obj);
assert( aobj != nullptr );
accounts.insert(aobj->owner);
break;
} case impl_total_distributed_dividend_balance_object_type:
break;
case impl_betting_market_position_object_type:{
const auto& aobj = dynamic_cast<const betting_market_position_object*>(obj);
assert( aobj != nullptr );
accounts.insert(aobj->bettor_id);
break;
} case impl_global_betting_statistics_object_type:
break;
case impl_lottery_balance_object_type:
break;
case impl_sweeps_vesting_balance_object_type:{
const auto& aobj = dynamic_cast<const sweeps_vesting_balance_object*>(obj);
assert( aobj != nullptr );
accounts.insert(aobj->owner);
break;
} case impl_offer_history_object_type:{
const auto& aobj = dynamic_cast<const offer_history_object*>(obj);
assert( aobj != nullptr );
accounts.insert(aobj->issuer);
if (aobj->bidder.valid())
accounts.insert(*aobj->bidder);
break;
} case impl_son_statistics_object_type: {
break;
} case impl_son_schedule_object_type: {
break;
}
case impl_nft_lottery_balance_object_type:
break;
default:
break;
}
} else if( obj->id.space() == api_ids ) {
switch( (api_object_type)obj->id.type() )
{
case graphene::chain::api_operation_history_object_type: {
const auto& aobj = dynamic_cast<const operation_history_object*>(obj);
assert( aobj != nullptr );
operation_get_impacted_accounts( aobj->op, accounts,
ignore_custom_operation_required_auths);
break;
}
case api_account_transaction_history_object_type:
break;
}
}
} // end get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts )
@ -608,6 +754,7 @@ void database::notify_changed_objects()
if( _undo_db.enabled() )
{
const auto& head_undo = _undo_db.head();
auto chain_time = head_block_time();
// New
if( !new_objects.empty() )
@ -619,7 +766,8 @@ void database::notify_changed_objects()
new_ids.push_back(item);
auto obj = find_object(item);
if(obj != nullptr)
get_relevant_accounts(obj, new_accounts_impacted, true);
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)
@ -633,7 +781,8 @@ void database::notify_changed_objects()
for( const auto& item : head_undo.old_values )
{
changed_ids.push_back(item.first);
get_relevant_accounts(item.second.get(), changed_accounts_impacted, true);
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)
@ -650,7 +799,8 @@ void database::notify_changed_objects()
removed_ids.emplace_back( item.first );
auto obj = item.second.get();
removed.emplace_back( obj );
get_relevant_accounts(obj, removed_accounts_impacted, true);
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)

View file

@ -35,13 +35,11 @@
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/son_proposal_object.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/uint128.hpp>
#include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace chain {
@ -156,7 +154,8 @@ void database::clear_expired_transactions()
{ try {
//Look for expired transactions in the deduplication list, and remove them.
//Transactions must have expired by at least two forking windows in order to be removed.
auto& transaction_idx = static_cast<transaction_index&>(get_mutable_index(implementation_ids, impl_transaction_object_type));
auto& transaction_idx = static_cast<transaction_index&>(get_mutable_index(implementation_ids,
impl_transaction_history_object_type));
const auto& dedupe_index = transaction_idx.indices().get<by_expiration>();
while( (!dedupe_index.empty()) && (head_block_time() > dedupe_index.begin()->trx.expiration) )
transaction_idx.remove(*dedupe_index.begin());
@ -427,7 +426,7 @@ void database::clear_expired_orders()
auto& pays = order.balance;
auto receives = (order.balance * mia.current_feed.settlement_price);
receives.amount = (fc::uint128_t(receives.amount.value) *
(GRAPHENE_100_PERCENT - mia.options.force_settlement_offset_percent) / GRAPHENE_100_PERCENT).to_uint64();
(GRAPHENE_100_PERCENT - mia.options.force_settlement_offset_percent) / GRAPHENE_100_PERCENT);
assert(receives <= order.balance * mia.current_feed.settlement_price);
price settlement_price = pays / receives;

View file

@ -22,12 +22,14 @@
* THE SOFTWARE.
*/
#include <graphene/protocol/son_info.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_info.hpp>
#include <fc/popcount.hpp>
namespace graphene { namespace chain {
@ -74,32 +76,21 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
return wid;
}
unsigned_int database::get_son_schedule_id( sidechain_type type )const
{
static const map<sidechain_type, unsigned_int> schedule_map = {
{ sidechain_type::bitcoin, 0 },
{ sidechain_type::ethereum, 1 },
{ sidechain_type::hive, 2 }
};
return schedule_map.at(type);
}
son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num )const
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(get_son_schedule_id(type))(*this);
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(get_son_schedule_id(type))(*this);
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)
@ -200,39 +191,36 @@ void database::update_witness_schedule()
}
}
void database::update_son_schedule(sidechain_type type)
void database::update_son_schedule()
{
const son_schedule_object& sso = son_schedule_id_type()(*this);
const global_property_object& gpo = get_global_properties();
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(type)));
if( gpo.active_sons.at(type).size() != 0 &&
head_block_num() % gpo.active_sons.at(type).size() == 0)
if( head_block_num() % gpo.active_sons.size() == 0 )
{
modify( sidechain_sso, [&]( son_schedule_object& _sso )
modify( sso, [&]( son_schedule_object& _sso )
{
_sso.current_shuffled_sons.clear();
_sso.current_shuffled_sons.reserve( gpo.active_sons.at(type).size() );
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
for ( const auto &w : gpo.active_sons.at(type) ) {
_sso.current_shuffled_sons.push_back(w.son_id);
}
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)
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;
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]);
uint32_t j = i + k%jmax;
std::swap( _sso.current_shuffled_sons[i],
_sso.current_shuffled_sons[j] );
}
});
}
@ -281,7 +269,7 @@ void database::update_witness_schedule(const signed_block& next_block)
modify(wso, [&](witness_schedule_object& _wso)
{
_wso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(wso.rng_seed.data, _wso.slots_since_genesis);
witness_scheduler_rng rng(wso.rng_seed.data(), _wso.slots_since_genesis);
_wso.scheduler._min_token_count = std::max(int(gpo.active_witnesses.size()) / 2, 1);
@ -318,15 +306,13 @@ void database::update_witness_schedule(const signed_block& next_block)
idump( ( double(total_time/1000000.0)/calls) );
}
void database::update_son_schedule(sidechain_type type, const signed_block& next_block)
void database::update_son_schedule(const signed_block& next_block)
{
auto start = fc::time_point::now();
#ifndef NDEBUG
const son_schedule_object& sso = get(son_schedule_id_type());
#endif
const global_property_object& gpo = get_global_properties();
const uint32_t schedule_needs_filled = gpo.active_sons.at(type).size();
const uint32_t schedule_slot = get_slot_at_time(next_block.timestamp);
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
@ -335,49 +321,48 @@ void database::update_son_schedule(sidechain_type type, const signed_block& next
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() );
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(type)));
son_id_type first_son;
bool slot_is_near = sidechain_sso.scheduler.get_slot( schedule_slot-1, first_son );
son_id_type son_id;
modify(sidechain_sso, [&](son_schedule_object& _sso)
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.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.at(type).size()) / 2, 1);
_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_id) )
{
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);
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;
@ -408,12 +393,12 @@ uint32_t database::witness_participation_rate()const
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
return uint64_t(GRAPHENE_100_PERCENT) * dpo.recent_slots_filled.popcount() / 128;
return uint64_t(GRAPHENE_100_PERCENT) * fc::popcount(dpo.recent_slots_filled) / 128;
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM)
{
const witness_schedule_object& wso = get_witness_schedule_object();
return uint64_t(GRAPHENE_100_PERCENT) * wso.recent_slots_filled.popcount() / 128;
return uint64_t(GRAPHENE_100_PERCENT) * fc::popcount(wso.recent_slots_filled) / 128;
}
return 0;
}

View file

@ -33,14 +33,12 @@
#include <graphene/chain/fba_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/market_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <fc/uint128.hpp>
#include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace chain {
database& generic_evaluator::db()const { return trx_state->db(); }
database& consensus_evaluator::db()const { return trx_state->db(); }
operation_result generic_evaluator::start_evaluate( transaction_evaluation_state& eval_state, const operation& op, bool apply )
operation_result consensus_evaluator::start_evaluate( transaction_evaluation_state& eval_state, const operation& op, bool apply )
{ try {
trx_state = &eval_state;
//check_required_authorities(op);
@ -50,7 +48,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
return result;
} FC_CAPTURE_AND_RETHROW() }
void generic_evaluator::prepare_fee(account_id_type account_id, asset fee)
void consensus_evaluator::prepare_fee(account_id_type account_id, asset fee)
{
const database& d = db();
fee_from_account = fee;
@ -79,7 +77,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
}
}
void generic_evaluator::convert_fee()
void consensus_evaluator::convert_fee()
{
if( !trx_state->skip_fee ) {
if( fee_asset->get_id() != asset_id_type() )
@ -92,7 +90,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
}
}
void generic_evaluator::pay_fee()
void consensus_evaluator::pay_fee()
{ try {
if( !trx_state->skip_fee ) {
database& d = db();
@ -104,13 +102,13 @@ database& generic_evaluator::db()const { return trx_state->db(); }
}
} FC_CAPTURE_AND_RETHROW() }
void generic_evaluator::pay_fba_fee( uint64_t fba_id )
void consensus_evaluator::pay_fba_fee( uint64_t fba_id )
{
database& d = db();
const fba_accumulator_object& fba = d.get< fba_accumulator_object >( fba_accumulator_id_type( fba_id ) );
if( !fba.is_configured(d) )
{
generic_evaluator::pay_fee();
consensus_evaluator::pay_fee();
return;
}
d.modify( fba, [&]( fba_accumulator_object& _fba )
@ -119,16 +117,16 @@ database& generic_evaluator::db()const { return trx_state->db(); }
} );
}
share_type generic_evaluator::calculate_fee_for_operation(const operation& op) const
share_type consensus_evaluator::calculate_fee_for_operation(const operation& op) const
{
return db().current_fee_schedule().calculate_fee( op ).amount;
}
void generic_evaluator::db_adjust_balance(const account_id_type& fee_payer, asset fee_from_account)
void consensus_evaluator::db_adjust_balance(const account_id_type& fee_payer, asset fee_from_account)
{
db().adjust_balance(fee_payer, fee_from_account);
}
object_id_type generic_evaluator::get_relative_id( object_id_type rel_id )const
object_id_type consensus_evaluator::get_relative_id( object_id_type rel_id )const
{
if (!is_relative(rel_id))
FC_THROW("get_relative_id() called for non-relative id ${id}", ("id", rel_id));

View file

@ -29,6 +29,7 @@
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
namespace graphene { namespace chain {

View file

@ -47,7 +47,7 @@ namespace graphene { namespace chain {
};
} }
FC_REFLECT_ENUM(graphene::chain::event_state,
FC_REFLECT_ENUM(graphene::chain::event_state,
(upcoming)
(frozen_upcoming)
(in_progress)
@ -61,12 +61,12 @@ namespace graphene { namespace chain {
namespace msm = boost::msm;
namespace mpl = boost::mpl;
namespace
namespace
{
// Events -- most events happen when the witnesses publish an event_update operation with a new
// status, so if they publish an event with the status set to `frozen`, we'll generate a `frozen_event`
struct upcoming_event
struct upcoming_event
{
database& db;
upcoming_event(database& db) : db(db) {}
@ -76,12 +76,12 @@ namespace graphene { namespace chain {
database& db;
in_progress_event(database& db) : db(db) {}
};
struct frozen_event
struct frozen_event
{
database& db;
frozen_event(database& db) : db(db) {}
};
struct finished_event
struct finished_event
{
database& db;
finished_event(database& db) : db(db) {}
@ -104,7 +104,7 @@ namespace graphene { namespace chain {
betting_market_group_resolved_event(database& db, betting_market_group_id_type resolved_group, bool was_canceled) : db(db), resolved_group(resolved_group), was_canceled(was_canceled) {}
};
// event triggered when a betting market group is closed. When we get this,
// event triggered when a betting market group is closed. When we get this,
// if all child betting market groups are closed, transition to finished
struct betting_market_group_closed_event
{
@ -127,7 +127,7 @@ namespace graphene { namespace chain {
void on_entry(const upcoming_event& event, event_state_machine_& fsm) {
dlog("event ${id} -> upcoming", ("id", fsm.event_obj->id));
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(fsm.event_obj->id)))
try
{
@ -147,7 +147,7 @@ namespace graphene { namespace chain {
void on_entry(const in_progress_event& event, event_state_machine_& fsm) {
dlog("event ${id} -> in_progress", ("id", fsm.event_obj->id));
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(fsm.event_obj->id)))
try
{
@ -203,7 +203,7 @@ namespace graphene { namespace chain {
void freeze_betting_market_groups(const frozen_event& event) {
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
{
try
@ -222,7 +222,7 @@ namespace graphene { namespace chain {
void close_all_betting_market_groups(const finished_event& event) {
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
{
try
@ -241,7 +241,7 @@ namespace graphene { namespace chain {
void cancel_all_betting_market_groups(const canceled_event& event) {
auto& betting_market_group_index = event.db.template get_index_type<betting_market_group_object_index>().indices().template get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
event.db.modify(betting_market_group, [&event](betting_market_group_object& betting_market_group_obj) {
betting_market_group_obj.on_canceled_event(event.db, true);
@ -252,15 +252,15 @@ namespace graphene { namespace chain {
bool all_betting_market_groups_are_closed(const betting_market_group_closed_event& event)
{
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
if (betting_market_group.id != event.closed_group)
{
betting_market_group_status status = betting_market_group.get_status();
if (status != betting_market_group_status::closed &&
status != betting_market_group_status::graded &&
status != betting_market_group_status::re_grading &&
status != betting_market_group_status::settled &&
if (status != betting_market_group_status::closed &&
status != betting_market_group_status::graded &&
status != betting_market_group_status::re_grading &&
status != betting_market_group_status::settled &&
status != betting_market_group_status::canceled)
return false;
}
@ -276,7 +276,7 @@ namespace graphene { namespace chain {
if (event_obj->at_least_one_betting_market_group_settled)
return false;
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id)))
if (betting_market_group.id != event.resolved_group)
if (betting_market_group.get_status() != betting_market_group_status::canceled)
@ -290,7 +290,7 @@ namespace graphene { namespace chain {
event_obj->at_least_one_betting_market_group_settled = true;
auto& betting_market_group_index = event.db.get_index_type<betting_market_group_object_index>().indices().get<by_event_id>();
for (const betting_market_group_object& betting_market_group :
for (const betting_market_group_object& betting_market_group :
boost::make_iterator_range(betting_market_group_index.equal_range(event_obj->id))) {
if (betting_market_group.id != event.resolved_group) {
betting_market_group_status status = betting_market_group.get_status();
@ -344,6 +344,7 @@ namespace graphene { namespace chain {
{
FC_THROW_EXCEPTION(graphene::chain::no_transition, "No transition");
}
template <class Fsm>
void no_transition(canceled_event const& e, Fsm&, int state)
{
@ -371,7 +372,7 @@ namespace graphene { namespace chain {
{
}
event_object::event_object(const event_object& rhs) :
event_object::event_object(const event_object& rhs) :
graphene::db::abstract_object<event_object>(rhs),
name(rhs.name),
season(rhs.season),
@ -407,7 +408,7 @@ namespace graphene { namespace chain {
}
namespace {
bool verify_event_status_constants()
{
unsigned error_count = 0;
@ -442,19 +443,19 @@ namespace graphene { namespace chain {
dlog("Event status constants are correct");
else
wlog("There were ${count} errors in the event status constants", ("count", error_count));
return error_count == 0;
}
} // end anonymous namespace
event_status event_object::get_status() const
{
static bool state_constants_are_correct = verify_event_status_constants();
(void)&state_constants_are_correct;
event_state state = (event_state)my->state_machine.current_state()[0];
ddump((state));
switch (state)
{
case event_state::upcoming:
@ -522,8 +523,8 @@ namespace graphene { namespace chain {
my->state_machine.process_event(betting_market_group_closed_event(db, closed_group));
}
// These are the only statuses that can be explicitly set by witness operations. The missing
// status, 'settled', is automatically set when all of the betting market groups have
// These are the only statuses that can be explicitly set by witness operations. The missing
// status, 'settled', is automatically set when all of the betting market groups have
// settled/canceled
void event_object::dispatch_new_status(database& db, event_status new_status)
{
@ -532,16 +533,16 @@ namespace graphene { namespace chain {
on_upcoming_event(db);
break;
case event_status::in_progress: // by witnesses when the event starts
on_in_progress_event(db);
on_in_progress_event(db);
break;
case event_status::frozen: // by witnesses when the event needs to be frozen
on_frozen_event(db);
on_frozen_event(db);
break;
case event_status::finished: // by witnesses when the event is complete
on_finished_event(db);
on_finished_event(db);
break;
case event_status::canceled: // by witnesses to cancel the event
on_canceled_event(db);
on_canceled_event(db);
break;
default:
FC_THROW("Status ${new_status} cannot be explicitly set", ("new_status", new_status));
@ -550,7 +551,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect event_object to variant to properly reflect "state"
void to_variant(const graphene::chain::event_object& event_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2019 BitShares Blockchain Foundation, and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/internal_exceptions.hpp>
namespace graphene { namespace chain {
// Internal exceptions
FC_IMPLEMENT_DERIVED_EXCEPTION( internal_exception, graphene::chain::chain_exception, 3990000, "internal exception" )
GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_max_auth_exceeded, 1, "Exceeds max authority fan-out" )
GRAPHENE_IMPLEMENT_INTERNAL_EXCEPTION( verify_auth_account_not_found, 2, "Auth account not found" )
// Public exceptions
FC_IMPLEMENT_EXCEPTION( chain_exception, 3000000, "blockchain exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000, "database query exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000, "block validation exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000, "operation validation exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000, "operation evaluation exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000, "utility method exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000, "undo database exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000, "unlinkable block" )
FC_IMPLEMENT_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000, "black swan" )
FC_IMPLEMENT_DERIVED_EXCEPTION( plugin_exception, chain_exception, 3100000, "plugin exception" )
FC_IMPLEMENT_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006, "insufficient feeds" )
FC_IMPLEMENT_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001, "there are no blocks to pop" )
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( to_account_not_whitelisted, transfer, 2, "owner mismatch" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( restricted_transfer_asset, transfer, 3, "restricted transfer asset" )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( limit_order_cancel );
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( call_order_update );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unfilled_margin_call, call_order_update, 1, "Updating call order would trigger a margin call that cannot be fully filled" )
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_create );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_create, 1, "Exceeds max authority fan-out" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_create, 2, "Auth account not found" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_incorrect_issuer, account_create, 3, "Incorrect issuer specified for account" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_already_exists, account_create, 4, "Cannot create buyback for asset which already has buyback" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( buyback_too_many_markets, account_create, 5, "Too many buyback markets" )
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_update );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( max_auth_exceeded, account_update, 1, "Exceeds max authority fan-out" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( auth_account_not_found, account_update, 2, "Auth account not found" )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_whitelist );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_upgrade );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( account_transfer );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_bitasset );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_feed_producers );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_issue );
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_reserve );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( invalid_on_mia, asset_reserve, 1, "invalid on mia" )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_fund_fee_pool );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_settle );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_global_settle );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_publish_feed );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( committee_member_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( witness_create );
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_create );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_required, proposal_create, 1, "review_period required" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( review_period_insufficient, proposal_create, 2, "review_period insufficient" )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_update );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( proposal_delete );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_update );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_claim );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( withdraw_permission_delete );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( fill_order );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( global_parameters_update );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( vesting_balance_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( vesting_balance_withdraw );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( worker_create );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( custom );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( assert );
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( balance_claim );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( claimed_too_often, balance_claim, 1, "balance claimed too often" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( invalid_claim_amount, balance_claim, 2, "invalid claim amount" )
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( owner_mismatch, balance_claim, 3, "owner mismatch" )
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( override_transfer );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( not_permitted, override_transfer, 1, "not permitted" )
GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( blind_transfer );
GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" );
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( transfer_from_blind_operation )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_claim_fees_operation )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( bid_collateral_operation )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_claim_pool_operation )
//GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( asset_update_issuer_operation )
#define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \
catch( const cause_type& e ) \
{ throw( effect_type( e.what(), e.get_log() ) ); }
} } // graphene::chain

View file

@ -23,7 +23,7 @@
*/
#include <graphene/chain/fork_database.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace chain {
fork_database::fork_database()

View file

@ -547,7 +547,7 @@ namespace graphene { namespace chain {
} } // graphene::chain
namespace fc {
namespace fc {
// Manually reflect game_object to variant to properly reflect "state"
void to_variant(const graphene::chain::game_object& game_obj, fc::variant& v, uint32_t max_depth)
{

View file

@ -24,8 +24,8 @@
#include <graphene/chain/genesis_state.hpp>
// these are required to serialize a genesis_state
#include <graphene/chain/protocol/fee_schedule.hpp>
// this is required to serialize a genesis_state
#include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace chain {

View file

@ -24,7 +24,7 @@
#include <graphene/chain/get_config.hpp>
#include <graphene/chain/config.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/types.hpp>
namespace graphene { namespace chain {
@ -74,7 +74,6 @@ fc::variant_object get_config()
result[ "GRAPHENE_MAX_COLLATERAL_RATIO" ] = GRAPHENE_MAX_COLLATERAL_RATIO;
result[ "GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO" ] = GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO;
result[ "GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO" ] = GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO;
result[ "GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC" ] = GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC;
result[ "GRAPHENE_DEFAULT_MAX_WITNESSES" ] = GRAPHENE_DEFAULT_MAX_WITNESSES;
result[ "GRAPHENE_DEFAULT_MAX_COMMITTEE" ] = GRAPHENE_DEFAULT_MAX_COMMITTEE;
result[ "GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC" ] = GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC;

View file

@ -0,0 +1,10 @@
// #210 Check authorities on custom_operation
#ifndef HARDFORK_CORE_210_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_CORE_210_TIME (fc::time_point_sec::from_iso_string("2021-01-01T00:00:00"))
#else
#define HARDFORK_CORE_210_TIME (fc::time_point_sec::from_iso_string("2030-01-01T00:00:00")) // (Not yet scheduled)
#endif
// 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

@ -1,3 +1,4 @@
// The value should be harmonized with the protcol constant named GPOS_PERIOD_START
#ifndef HARDFORK_GPOS_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_GPOS_TIME (fc::time_point_sec::from_iso_string("2020-01-06T01:00:00"))

View file

@ -1,7 +0,0 @@
#ifndef HARDFORK_HOTFIX_2024_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_HOTFIX_2024_TIME (fc::time_point_sec::from_iso_string("2023-12-20T00:00:00"))
#else
#define HARDFORK_HOTFIX_2024_TIME (fc::time_point_sec::from_iso_string("2023-12-20T00:00:00"))
#endif
#endif

View file

@ -1,7 +0,0 @@
#ifndef HARDFORK_SIDECHAIN_DELETE_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_SIDECHAIN_DELETE_TIME (fc::time_point_sec::from_iso_string("2022-11-16T02:00:00"))
#else
#define HARDFORK_SIDECHAIN_DELETE_TIME (fc::time_point_sec::from_iso_string("2022-11-16T02:00:00"))
#endif
#endif

View file

@ -1,7 +0,0 @@
#ifndef HARDFORK_SON_FOR_ETHEREUM_TIME
#ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-07-17T12:00:00"))
#else
#define HARDFORK_SON_FOR_ETHEREUM_TIME (fc::time_point_sec::from_iso_string("2023-10-24T12:00:00"))
#endif
#endif

View file

@ -27,7 +27,7 @@
namespace graphene { namespace chain {
class account_create_evaluator : public evaluator<account_create_evaluator>
class account_create_evaluator : public fee_handling_evaluator<account_create_evaluator>
{
public:
typedef account_create_operation operation_type;
@ -36,7 +36,7 @@ public:
object_id_type do_apply( const account_create_operation& o ) ;
};
class account_update_evaluator : public evaluator<account_update_evaluator>
class account_update_evaluator : public fee_handling_evaluator<account_update_evaluator>
{
public:
typedef account_update_operation operation_type;
@ -47,7 +47,7 @@ public:
const account_object* acnt;
};
class account_upgrade_evaluator : public evaluator<account_upgrade_evaluator>
class account_upgrade_evaluator : public fee_handling_evaluator<account_upgrade_evaluator>
{
public:
typedef account_upgrade_operation operation_type;
@ -58,7 +58,7 @@ public:
const account_object* account;
};
class account_whitelist_evaluator : public evaluator<account_whitelist_evaluator>
class account_whitelist_evaluator : public fee_handling_evaluator<account_whitelist_evaluator>
{
public:
typedef account_whitelist_operation operation_type;

View file

@ -22,13 +22,15 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/account.hpp>
#include <graphene/chain/types.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
class database;
class account_object;
class vesting_balance_object;
/**
* @class account_statistics_object
@ -321,7 +323,8 @@ namespace graphene { namespace chain {
};
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_loaded( const object& obj ) override;
virtual void object_created( 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;
@ -352,7 +355,8 @@ namespace graphene { namespace chain {
class account_referrer_index : public secondary_index
{
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_loaded( const object& obj ) override;
virtual void object_created( 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;
@ -393,7 +397,8 @@ namespace graphene { namespace chain {
class balances_by_account_index : public secondary_index
{
public:
virtual void object_inserted( const object& obj ) override;
virtual void object_loaded( const object& obj ) override;
virtual void object_created( 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;
@ -541,6 +546,10 @@ namespace graphene { namespace chain {
}}
MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_balance_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_statistics_object)
FC_REFLECT_DERIVED( graphene::chain::account_object,
(graphene::db::object),
(membership_expiration_date)(registrar)(referrer)(lifetime_referrer)

View file

@ -2,12 +2,12 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/protocol/types.hpp>
namespace graphene { namespace chain {
class account_role_create_evaluator : public evaluator<account_role_create_evaluator>
class account_role_create_evaluator : public fee_handling_evaluator<account_role_create_evaluator>
{
public:
typedef account_role_create_operation operation_type;
@ -15,7 +15,7 @@ namespace graphene { namespace chain {
object_id_type do_apply( const account_role_create_operation& o );
};
class account_role_update_evaluator : public evaluator<account_role_update_evaluator>
class account_role_update_evaluator : public fee_handling_evaluator<account_role_update_evaluator>
{
public:
typedef account_role_update_operation operation_type;
@ -23,7 +23,7 @@ namespace graphene { namespace chain {
void_result do_apply( const account_role_update_operation& o );
};
class account_role_delete_evaluator : public evaluator<account_role_delete_evaluator>
class account_role_delete_evaluator : public fee_handling_evaluator<account_role_delete_evaluator>
{
public:
typedef account_role_delete_operation operation_type;

View file

@ -1,5 +1,5 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -13,7 +13,7 @@ namespace graphene
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = account_role_type;
static const uint8_t type_id = account_role_object_type;
account_id_type owner;
std::string name;
@ -45,5 +45,7 @@ namespace graphene
} // namespace chain
} // namespace graphene
MAP_OBJECT_ID_TO_TYPE(graphene::chain::account_role_object)
FC_REFLECT_DERIVED(graphene::chain::account_role_object, (graphene::db::object),
(owner)(name)(metadata)(allowed_operations)(whitelisted_accounts)(valid_to))

View file

@ -23,8 +23,8 @@
*/
#pragma once
#include <graphene/chain/protocol/asset.hpp>
#include <graphene/chain/protocol/affiliate.hpp>
#include <graphene/protocol/asset.hpp>
#include <graphene/protocol/affiliate.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/tournament_object.hpp>

View file

@ -22,13 +22,13 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene { namespace chain {
class assert_evaluator : public evaluator<assert_evaluator>
class assert_evaluator : public fee_handling_evaluator<assert_evaluator>
{
public:
typedef assert_operation operation_type;

View file

@ -22,13 +22,13 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene { namespace chain {
class asset_create_evaluator : public evaluator<asset_create_evaluator>
class asset_create_evaluator : public fee_handling_evaluator<asset_create_evaluator>
{
public:
typedef asset_create_operation operation_type;
@ -44,7 +44,7 @@ namespace graphene { namespace chain {
bool fee_is_odd;
};
class lottery_asset_create_evaluator : public evaluator<lottery_asset_create_evaluator>
class lottery_asset_create_evaluator : public fee_handling_evaluator<lottery_asset_create_evaluator>
{
public:
typedef lottery_asset_create_operation operation_type;
@ -60,7 +60,7 @@ namespace graphene { namespace chain {
bool fee_is_odd;
};
class asset_issue_evaluator : public evaluator<asset_issue_evaluator>
class asset_issue_evaluator : public fee_handling_evaluator<asset_issue_evaluator>
{
public:
typedef asset_issue_operation operation_type;
@ -71,7 +71,7 @@ namespace graphene { namespace chain {
const account_object* to_account = nullptr;
};
class asset_reserve_evaluator : public evaluator<asset_reserve_evaluator>
class asset_reserve_evaluator : public fee_handling_evaluator<asset_reserve_evaluator>
{
public:
typedef asset_reserve_operation operation_type;
@ -83,7 +83,7 @@ namespace graphene { namespace chain {
};
class asset_update_evaluator : public evaluator<asset_update_evaluator>
class asset_update_evaluator : public fee_handling_evaluator<asset_update_evaluator>
{
public:
typedef asset_update_operation operation_type;
@ -94,7 +94,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_update = nullptr;
};
class asset_update_bitasset_evaluator : public evaluator<asset_update_bitasset_evaluator>
class asset_update_bitasset_evaluator : public fee_handling_evaluator<asset_update_bitasset_evaluator>
{
public:
typedef asset_update_bitasset_operation operation_type;
@ -105,7 +105,7 @@ namespace graphene { namespace chain {
const asset_bitasset_data_object* bitasset_to_update = nullptr;
};
class asset_update_dividend_evaluator : public evaluator<asset_update_dividend_evaluator>
class asset_update_dividend_evaluator : public fee_handling_evaluator<asset_update_dividend_evaluator>
{
public:
typedef asset_update_dividend_operation operation_type;
@ -117,7 +117,7 @@ namespace graphene { namespace chain {
const asset_dividend_data_object* asset_dividend_data_to_update = nullptr;
};
class asset_update_feed_producers_evaluator : public evaluator<asset_update_feed_producers_evaluator>
class asset_update_feed_producers_evaluator : public fee_handling_evaluator<asset_update_feed_producers_evaluator>
{
public:
typedef asset_update_feed_producers_operation operation_type;
@ -128,7 +128,7 @@ namespace graphene { namespace chain {
const asset_bitasset_data_object* bitasset_to_update = nullptr;
};
class asset_fund_fee_pool_evaluator : public evaluator<asset_fund_fee_pool_evaluator>
class asset_fund_fee_pool_evaluator : public fee_handling_evaluator<asset_fund_fee_pool_evaluator>
{
public:
typedef asset_fund_fee_pool_operation operation_type;
@ -139,7 +139,7 @@ namespace graphene { namespace chain {
const asset_dynamic_data_object* asset_dyn_data = nullptr;
};
class asset_global_settle_evaluator : public evaluator<asset_global_settle_evaluator>
class asset_global_settle_evaluator : public fee_handling_evaluator<asset_global_settle_evaluator>
{
public:
typedef asset_global_settle_operation operation_type;
@ -149,7 +149,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_settle = nullptr;
};
class asset_settle_evaluator : public evaluator<asset_settle_evaluator>
class asset_settle_evaluator : public fee_handling_evaluator<asset_settle_evaluator>
{
public:
typedef asset_settle_operation operation_type;
@ -160,7 +160,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_settle = nullptr;
};
class asset_publish_feeds_evaluator : public evaluator<asset_publish_feeds_evaluator>
class asset_publish_feeds_evaluator : public fee_handling_evaluator<asset_publish_feeds_evaluator>
{
public:
typedef asset_publish_feed_operation operation_type;
@ -171,7 +171,7 @@ namespace graphene { namespace chain {
std::map<std::pair<asset_id_type,asset_id_type>,price_feed> median_feed_values;
};
class asset_claim_fees_evaluator : public evaluator<asset_claim_fees_evaluator>
class asset_claim_fees_evaluator : public fee_handling_evaluator<asset_claim_fees_evaluator>
{
public:
typedef asset_claim_fees_operation operation_type;

View file

@ -22,11 +22,10 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/chain/protocol/asset_ops.hpp>
#include <graphene/protocol/asset_ops.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/types.hpp>
/**
* @defgroup prediction_market Prediction Market
@ -39,6 +38,9 @@
*/
namespace graphene { namespace chain {
class account_object;
class asset_bitasset_data_object;
class asset_dividend_data_object;
class database;
class transaction_evaluation_state;
using namespace graphene::db;
@ -59,7 +61,7 @@ namespace graphene { namespace chain {
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_asset_dynamic_data_type;
static const uint8_t type_id = impl_asset_dynamic_data_object_type;
/// The number of shares currently in existence
share_type current_supply;
@ -111,13 +113,13 @@ namespace graphene { namespace chain {
string amount_to_string(share_type amount)const;
/// Convert an asset to a textual representation, i.e. "123.45"
string amount_to_string(const asset& amount)const
{ FC_ASSERT(amount.asset_id == id); return amount_to_string(amount.amount); }
{ FC_ASSERT(amount.asset_id == get_id()); return amount_to_string(amount.amount); }
/// Convert an asset to a textual representation with symbol, i.e. "123.45 USD"
string amount_to_pretty_string(share_type amount)const
{ return amount_to_string(amount) + " " + symbol; }
/// Convert an asset to a textual representation with symbol, i.e. "123.45 USD"
string amount_to_pretty_string(const asset &amount)const
{ FC_ASSERT(amount.asset_id == id); return amount_to_pretty_string(amount.amount); }
{ FC_ASSERT(amount.asset_id == get_id()); return amount_to_pretty_string(amount.amount); }
uint32_t get_issuer_num()const
{ return issuer.instance.value; }
@ -197,7 +199,7 @@ namespace graphene { namespace chain {
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_asset_bitasset_data_type;
static const uint8_t type_id = impl_asset_bitasset_data_object_type;
/// The asset this object belong to
asset_id_type asset_id;
@ -375,7 +377,7 @@ namespace graphene { namespace chain {
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_asset_dividend_data_type;
static const uint8_t type_id = impl_asset_dividend_data_object_type;
/// The tunable options for Dividend-paying assets are stored in this field.
dividend_asset_options options;
@ -419,7 +421,7 @@ namespace graphene { namespace chain {
{
public:
static const uint8_t space_id = implementation_ids;
static const uint8_t type_id = impl_distributed_dividend_balance_data_type;
static const uint8_t type_id = impl_total_distributed_dividend_balance_object_type;
asset_id_type dividend_holder_asset_type;
asset_id_type dividend_payout_asset_type;
@ -518,6 +520,14 @@ namespace graphene { namespace chain {
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_dynamic_data_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_bitasset_data_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::asset_dividend_data_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::total_distributed_dividend_balance_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::lottery_balance_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::sweeps_vesting_balance_object)
FC_REFLECT_DERIVED( graphene::chain::asset_dynamic_data_object, (graphene::db::object),
(current_supply)(sweeps_tickets_sold)(confidential_supply)(accumulated_fees)(fee_pool) )

View file

@ -23,7 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/transaction.hpp>
#include <graphene/protocol/transaction.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/balance_object.hpp>
#include <graphene/chain/evaluator.hpp>
@ -31,7 +31,7 @@
namespace graphene { namespace chain {
class balance_claim_evaluator : public evaluator<balance_claim_evaluator>
class balance_claim_evaluator : public fee_handling_evaluator<balance_claim_evaluator>
{
public:
typedef balance_claim_operation operation_type;

View file

@ -71,6 +71,8 @@ namespace graphene { namespace chain {
using balance_index = generic_index<balance_object, balance_multi_index_type>;
} }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::balance_object)
FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object),
(owner)(balance)(vesting_policy)(last_claim_date) )

View file

@ -23,13 +23,13 @@
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene { namespace chain {
class betting_market_rules_create_evaluator : public evaluator<betting_market_rules_create_evaluator>
class betting_market_rules_create_evaluator : public fee_handling_evaluator<betting_market_rules_create_evaluator>
{
public:
typedef betting_market_rules_create_operation operation_type;
@ -38,7 +38,7 @@ namespace graphene { namespace chain {
object_id_type do_apply( const betting_market_rules_create_operation& o );
};
class betting_market_rules_update_evaluator : public evaluator<betting_market_rules_update_evaluator>
class betting_market_rules_update_evaluator : public fee_handling_evaluator<betting_market_rules_update_evaluator>
{
public:
typedef betting_market_rules_update_operation operation_type;
@ -49,7 +49,7 @@ namespace graphene { namespace chain {
const betting_market_rules_object* _rules;
};
class betting_market_group_create_evaluator : public evaluator<betting_market_group_create_evaluator>
class betting_market_group_create_evaluator : public fee_handling_evaluator<betting_market_group_create_evaluator>
{
public:
typedef betting_market_group_create_operation operation_type;
@ -61,7 +61,7 @@ namespace graphene { namespace chain {
betting_market_rules_id_type _rules_id;
};
class betting_market_group_update_evaluator : public evaluator<betting_market_group_update_evaluator>
class betting_market_group_update_evaluator : public fee_handling_evaluator<betting_market_group_update_evaluator>
{
public:
typedef betting_market_group_update_operation operation_type;
@ -73,7 +73,7 @@ namespace graphene { namespace chain {
const betting_market_group_object* _betting_market_group;
};
class betting_market_create_evaluator : public evaluator<betting_market_create_evaluator>
class betting_market_create_evaluator : public fee_handling_evaluator<betting_market_create_evaluator>
{
public:
typedef betting_market_create_operation operation_type;
@ -84,7 +84,7 @@ namespace graphene { namespace chain {
betting_market_group_id_type _group_id;
};
class betting_market_update_evaluator : public evaluator<betting_market_update_evaluator>
class betting_market_update_evaluator : public fee_handling_evaluator<betting_market_update_evaluator>
{
public:
typedef betting_market_update_operation operation_type;
@ -96,7 +96,7 @@ namespace graphene { namespace chain {
betting_market_group_id_type _group_id;
};
class bet_place_evaluator : public evaluator<bet_place_evaluator>
class bet_place_evaluator : public fee_handling_evaluator<bet_place_evaluator>
{
public:
typedef bet_place_operation operation_type;
@ -111,7 +111,7 @@ namespace graphene { namespace chain {
share_type _stake_plus_fees;
};
class bet_cancel_evaluator : public evaluator<bet_cancel_evaluator>
class bet_cancel_evaluator : public fee_handling_evaluator<bet_cancel_evaluator>
{
public:
typedef bet_cancel_operation operation_type;
@ -122,7 +122,7 @@ namespace graphene { namespace chain {
const bet_object* _bet_to_cancel;
};
class betting_market_group_resolve_evaluator : public evaluator<betting_market_group_resolve_evaluator>
class betting_market_group_resolve_evaluator : public fee_handling_evaluator<betting_market_group_resolve_evaluator>
{
public:
typedef betting_market_group_resolve_operation operation_type;
@ -133,7 +133,7 @@ namespace graphene { namespace chain {
const betting_market_group_object* _betting_market_group;
};
class betting_market_group_cancel_unmatched_bets_evaluator : public evaluator<betting_market_group_cancel_unmatched_bets_evaluator>
class betting_market_group_cancel_unmatched_bets_evaluator : public fee_handling_evaluator<betting_market_group_cancel_unmatched_bets_evaluator>
{
public:
typedef betting_market_group_cancel_unmatched_bets_operation operation_type;

View file

@ -23,11 +23,15 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/protocol/betting_market.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <sstream>
namespace graphene { namespace chain {
@ -35,7 +39,7 @@ namespace graphene { namespace chain {
class betting_market_group_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::betting_market_object& betting_market_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::betting_market_object& betting_market_obj, uint32_t max_depth = 1);
void to_variant(const graphene::chain::betting_market_group_object& betting_market_group_obj, fc::variant& v, uint32_t max_depth = 1);
@ -44,7 +48,7 @@ namespace fc {
namespace graphene { namespace chain {
FC_DECLARE_EXCEPTION(no_transition, 100000, "Invalid state transition");
FC_DECLARE_EXCEPTION(no_transition, 100000);
class database;
struct by_event_id;
@ -625,9 +629,10 @@ typedef multi_index_container<
typedef generic_index<betting_market_position_object, betting_market_position_multi_index_type> betting_market_position_index;
template<typename Stream>
inline Stream& operator<<( Stream& s, const betting_market_object& betting_market_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<betting_market_object> >(s, betting_market_obj);
@ -647,7 +652,7 @@ inline Stream& operator<<( Stream& s, const betting_market_object& betting_marke
}
template<typename Stream>
inline Stream& operator>>( Stream& s, betting_market_object& betting_market_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<betting_market_object> >(s, betting_market_obj);
fc::raw::unpack(s, betting_market_obj.id);
@ -661,14 +666,14 @@ inline Stream& operator>>( Stream& s, betting_market_object& betting_market_obj
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
betting_market_obj.unpack_impl(stream);
return s;
}
template<typename Stream>
inline Stream& operator<<( Stream& s, const betting_market_group_object& betting_market_group_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<betting_market_group_object> >(s, betting_market_group_obj);
@ -691,7 +696,7 @@ inline Stream& operator<<( Stream& s, const betting_market_group_object& betting
}
template<typename Stream>
inline Stream& operator>>( Stream& s, betting_market_group_object& betting_market_group_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<betting_market_group_object> >(s, betting_market_group_obj);
fc::raw::unpack(s, betting_market_group_obj.id);
@ -709,113 +714,22 @@ inline Stream& operator>>( Stream& s, betting_market_group_object& betting_marke
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
betting_market_group_obj.unpack_impl(stream);
return s;
}
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::betting_market_rules_object, (graphene::db::object), (name)(description) )
MAP_OBJECT_ID_TO_TYPE(graphene::chain::betting_market_rules_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::betting_market_group_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::betting_market_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::bet_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::betting_market_position_object)
FC_REFLECT_DERIVED( graphene::chain::betting_market_rules_object, (graphene::db::object), (name)(description) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_group_object, (graphene::db::object), (description)(event_id)(rules_id)(asset_id)(total_matched_bets_amount)(never_in_play)(delay_before_settling)(settling_time) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_object, (graphene::db::object), (group_id)(description)(payout_condition)(resolution) )
FC_REFLECT_DERIVED( graphene::chain::bet_object, (graphene::db::object), (bettor_id)(betting_market_id)(amount_to_bet)(backer_multiplier)(back_or_lay)(end_of_delay) )
FC_REFLECT_DERIVED( graphene::chain::betting_market_position_object, (graphene::db::object), (bettor_id)(betting_market_id)(pay_if_payout_condition)(pay_if_not_payout_condition)(pay_if_canceled)(pay_if_not_canceled)(fees_collected) )
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::betting_market_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::betting_market_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::betting_market_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::betting_market_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::betting_market_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::betting_market_object> {
static const char *name() {
return "graphene::chain::betting_market_object";
}
};
template <>
struct reflector<graphene::chain::betting_market_object> {
typedef graphene::chain::betting_market_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc
namespace fc {
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::betting_market_group_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::betting_market_group_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::betting_market_group_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::betting_market_group_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::betting_market_group_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw:detail
template <>
struct get_typename<graphene::chain::betting_market_group_object> {
static const char *name() {
return "graphene::chain::betting_market_group_object";
}
};
template <>
struct reflector<graphene::chain::betting_market_group_object> {
typedef graphene::chain::betting_market_group_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -23,12 +23,13 @@
*/
#pragma once
#include <fstream>
#include <graphene/chain/protocol/block.hpp>
#include <graphene/protocol/block.hpp>
#include <fc/filesystem.hpp>
namespace graphene { namespace chain {
class index_entry;
struct index_entry;
using namespace graphene::protocol;
class block_database
{

View file

@ -22,7 +22,8 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
namespace graphene { namespace chain {
@ -48,6 +49,7 @@ namespace graphene { namespace chain {
} }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::block_summary_object)
FC_REFLECT_DERIVED( graphene::chain::block_summary_object, (graphene::db::object), (block_id) )

View file

@ -22,7 +22,9 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
@ -67,6 +69,8 @@ class budget_record_object : public graphene::db::abstract_object<budget_record_
} }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::budget_record_object)
FC_REFLECT(graphene::chain::budget_record,
(time_since_last_budget)
(from_initial_reserve)

View file

@ -23,7 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/buyback.hpp>
#include <graphene/protocol/buyback.hpp>
namespace graphene { namespace chain {

View file

@ -23,7 +23,8 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -64,6 +65,8 @@ typedef generic_index< buyback_object, buyback_multi_index_type > buyback_index;
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::buyback_object)
FC_REFLECT_DERIVED( graphene::chain::buyback_object, (graphene::db::object), (asset_to_buy) )
GRAPHENE_EXTERNAL_SERIALIZATION( extern, graphene::chain::buyback_object )

View file

@ -24,6 +24,7 @@
#pragma once
#include <graphene/chain/immutable_chain_parameters.hpp>
#include <graphene/chain/types.hpp>
namespace graphene { namespace chain {
@ -42,6 +43,8 @@ class chain_property_object : public abstract_object<chain_property_object>
} }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::chain_property_object)
FC_REFLECT_DERIVED( graphene::chain::chain_property_object, (graphene::db::object),
(chain_id)
(immutable_parameters)

View file

@ -24,10 +24,11 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/global_property_object.hpp>
namespace graphene { namespace chain {
class committee_member_create_evaluator : public evaluator<committee_member_create_evaluator>
class committee_member_create_evaluator : public fee_handling_evaluator<committee_member_create_evaluator>
{
public:
typedef committee_member_create_operation operation_type;
@ -36,7 +37,7 @@ namespace graphene { namespace chain {
object_id_type do_apply( const committee_member_create_operation& o );
};
class committee_member_update_evaluator : public evaluator<committee_member_update_evaluator>
class committee_member_update_evaluator : public fee_handling_evaluator<committee_member_update_evaluator>
{
public:
typedef committee_member_update_operation operation_type;
@ -45,7 +46,7 @@ namespace graphene { namespace chain {
void_result do_apply( const committee_member_update_operation& o );
};
class committee_member_update_global_parameters_evaluator : public evaluator<committee_member_update_global_parameters_evaluator>
class committee_member_update_global_parameters_evaluator : public fee_handling_evaluator<committee_member_update_global_parameters_evaluator>
{
public:
typedef committee_member_update_global_parameters_operation operation_type;

View file

@ -22,9 +22,10 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/protocol/vote.hpp>
#include <graphene/chain/types.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
@ -71,6 +72,7 @@ namespace graphene { namespace chain {
using committee_member_index = generic_index<committee_member_object, committee_member_multi_index_type>;
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::committee_member_object)
FC_REFLECT_DERIVED( graphene::chain::committee_member_object, (graphene::db::object),
(committee_member_account)(vote_id)(total_votes)(url) )

View file

@ -23,14 +23,11 @@
*/
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/types.hpp>
namespace graphene { namespace chain {
struct transfer_to_blind_operation;
struct transfer_from_blind_operation;
struct blind_transfer_operation;
class transfer_to_blind_evaluator : public evaluator<transfer_to_blind_evaluator>
class transfer_to_blind_evaluator : public fee_handling_evaluator<transfer_to_blind_evaluator>
{
public:
typedef transfer_to_blind_operation operation_type;
@ -41,7 +38,7 @@ class transfer_to_blind_evaluator : public evaluator<transfer_to_blind_evaluator
virtual void pay_fee() override;
};
class transfer_from_blind_evaluator : public evaluator<transfer_from_blind_evaluator>
class transfer_from_blind_evaluator : public fee_handling_evaluator<transfer_from_blind_evaluator>
{
public:
typedef transfer_from_blind_operation operation_type;
@ -52,7 +49,7 @@ class transfer_from_blind_evaluator : public evaluator<transfer_from_blind_evalu
virtual void pay_fee() override;
};
class blind_transfer_evaluator : public evaluator<blind_transfer_evaluator>
class blind_transfer_evaluator : public fee_handling_evaluator<blind_transfer_evaluator>
{
public:
typedef blind_transfer_operation operation_type;

View file

@ -23,8 +23,8 @@
*/
#pragma once
#include <graphene/chain/protocol/authority.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/authority.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/db/generic_index.hpp>
@ -65,6 +65,7 @@ typedef generic_index<blinded_balance_object, blinded_balance_object_multi_index
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::blinded_balance_object)
FC_REFLECT_DERIVED( graphene::chain::blinded_balance_object, (graphene::db::object),
(commitment)(asset_id)(owner) )

View file

@ -23,242 +23,16 @@
*/
#pragma once
#ifdef BUILD_PEERPLAYS_TESTNET
#define GRAPHENE_SYMBOL "TEST"
#define GRAPHENE_ADDRESS_PREFIX "TEST"
#else
#define GRAPHENE_SYMBOL "PPY"
#define GRAPHENE_ADDRESS_PREFIX "PPY"
#endif
#define GRAPHENE_MIN_ACCOUNT_NAME_LENGTH 1
#define GRAPHENE_MAX_ACCOUNT_NAME_LENGTH 63
#define GRAPHENE_MIN_ASSET_SYMBOL_LENGTH 3
#define GRAPHENE_MAX_ASSET_SYMBOL_LENGTH 16
#define GRAPHENE_MAX_SHARE_SUPPLY int64_t(1000000000000000ll)
#define GRAPHENE_MAX_PAY_RATE 10000 /* 100% */
#define GRAPHENE_MAX_SIG_CHECK_DEPTH 2
/**
* Don't allow the committee_members to publish a limit that would
* make the network unable to operate.
*/
#define GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT 1024
#define GRAPHENE_MIN_BLOCK_INTERVAL 1 /* seconds */
#define GRAPHENE_MAX_BLOCK_INTERVAL 30 /* seconds */
#define GRAPHENE_DEFAULT_BLOCK_INTERVAL 3 /* seconds */
#define GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE 2048
#define GRAPHENE_DEFAULT_MAX_BLOCK_SIZE (GRAPHENE_DEFAULT_MAX_TRANSACTION_SIZE*GRAPHENE_DEFAULT_BLOCK_INTERVAL*200000)
#define GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION (60*60*24) // seconds, aka: 1 day
#define GRAPHENE_DEFAULT_MAINTENANCE_INTERVAL (60*60*24) // seconds, aka: 1 day
#define GRAPHENE_DEFAULT_MAINTENANCE_SKIP_SLOTS 3 // number of slots to skip for maintenance interval
#include <graphene/protocol/config.hpp>
#define GRAPHENE_MIN_UNDO_HISTORY 10
#define GRAPHENE_MAX_UNDO_HISTORY 10000
#define GRAPHENE_MIN_BLOCK_SIZE_LIMIT (GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT*5) // 5 transactions per block
#define GRAPHENE_MIN_TRANSACTION_EXPIRATION_LIMIT (GRAPHENE_MAX_BLOCK_INTERVAL * 5) // 5 transactions per block
#define GRAPHENE_BLOCKCHAIN_PRECISION uint64_t( 100000 )
#define GRAPHENE_MAX_NESTED_OBJECTS (200)
#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS 5
#define GRAPHENE_DEFAULT_TRANSFER_FEE (1*GRAPHENE_BLOCKCHAIN_PRECISION)
#define GRAPHENE_MAX_INSTANCE_ID (uint64_t(-1)>>16)
/** percentage fields are fixed point with a denominator of 10,000 */
#define GRAPHENE_100_PERCENT 10000
#define GRAPHENE_1_PERCENT (GRAPHENE_100_PERCENT/100)
/** NOTE: making this a power of 2 (say 2^15) would greatly accelerate fee calcs */
#define GRAPHENE_MAX_MARKET_FEE_PERCENT GRAPHENE_100_PERCENT
#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_DELAY (60*60*24) ///< 1 day
#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_OFFSET 0 ///< 1%
#define GRAPHENE_DEFAULT_FORCE_SETTLEMENT_MAX_VOLUME (20* GRAPHENE_1_PERCENT) ///< 20%
#define GRAPHENE_DEFAULT_PRICE_FEED_LIFETIME (60*60*24) ///< 1 day
#define GRAPHENE_MAX_FEED_PRODUCERS 200
#define GRAPHENE_DEFAULT_MAX_AUTHORITY_MEMBERSHIP 10
#define GRAPHENE_DEFAULT_MAX_ASSET_WHITELIST_AUTHORITIES 10
#define GRAPHENE_DEFAULT_MAX_ASSET_FEED_PUBLISHERS 10
/**
* These ratios are fixed point numbers with a denominator of GRAPHENE_COLLATERAL_RATIO_DENOM, the
* minimum maitenance collateral is therefore 1.001x and the default
* maintenance ratio is 1.75x
*/
///@{
#define GRAPHENE_COLLATERAL_RATIO_DENOM 1000
#define GRAPHENE_MIN_COLLATERAL_RATIO 1001 ///< lower than this could result in divide by 0
#define GRAPHENE_MAX_COLLATERAL_RATIO 32000 ///< higher than this is unnecessary and may exceed int16 storage
#define GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO 1750 ///< Call when collateral only pays off 175% the debt
#define GRAPHENE_DEFAULT_MAX_SHORT_SQUEEZE_RATIO 1500 ///< Stop calling when collateral only pays off 150% of the debt
///@}
#define GRAPHENE_DEFAULT_MARGIN_PERIOD_SEC (30*60*60*24)
#define GRAPHENE_DEFAULT_MIN_WITNESS_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_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_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_LIFETIME_REFERRER_PERCENT_OF_FEE (30*GRAPHENE_1_PERCENT)
#define GRAPHENE_DEFAULT_MAX_BULK_DISCOUNT_PERCENT (50*GRAPHENE_1_PERCENT)
#define GRAPHENE_DEFAULT_BULK_DISCOUNT_THRESHOLD_MIN ( GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(1000) )
#define GRAPHENE_DEFAULT_BULK_DISCOUNT_THRESHOLD_MAX ( GRAPHENE_DEFAULT_BULK_DISCOUNT_THRESHOLD_MIN*int64_t(100) )
#define GRAPHENE_DEFAULT_CASHBACK_VESTING_PERIOD_SEC (60*60*24*365) ///< 1 year
#define GRAPHENE_DEFAULT_CASHBACK_VESTING_THRESHOLD (GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(100))
#define GRAPHENE_DEFAULT_BURN_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT)
#define GRAPHENE_WITNESS_PAY_PERCENT_PRECISION (1000000000)
#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1
#define GRAPHENE_DEFAULT_FEE_LIQUIDATION_THRESHOLD GRAPHENE_BLOCKCHAIN_PRECISION * 100;
#define GRAPHENE_DEFAULT_ACCOUNTS_PER_FEE_SCALE 1000
#define GRAPHENE_DEFAULT_ACCOUNT_FEE_SCALE_BITSHIFTS 4
#define GRAPHENE_DEFAULT_MAX_BUYBACK_MARKETS 4
#define GRAPHENE_MAX_WORKER_NAME_LENGTH 63
#define GRAPHENE_MAX_URL_LENGTH 127
#define GRAPHENE_WITNESS_SHUFFLED_ALGORITHM 0
#define GRAPHENE_WITNESS_SCHEDULED_ALGORITHM 1
// counter initialization values used to derive near and far future seeds for shuffling witnesses
// we use the fractional bits of sqrt(2) in hex
#define GRAPHENE_NEAR_SCHEDULE_CTR_IV ( (uint64_t( 0x6a09 ) << 0x30) \
| (uint64_t( 0xe667 ) << 0x20) \
| (uint64_t( 0xf3bc ) << 0x10) \
| (uint64_t( 0xc908 ) ) )
// and the fractional bits of sqrt(3) in hex
#define GRAPHENE_FAR_SCHEDULE_CTR_IV ( (uint64_t( 0xbb67 ) << 0x30) \
| (uint64_t( 0xae85 ) << 0x20) \
| (uint64_t( 0x84ca ) << 0x10) \
| (uint64_t( 0xa73b ) ) )
// counter used to determine bits of entropy
// must be less than or equal to secret_hash_type::data_length()
#define GRAPHENE_RNG_SEED_LENGTH (160 / 8)
/**
* every second, the fraction of burned core asset which cycles is
* GRAPHENE_CORE_ASSET_CYCLE_RATE / (1 << GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS)
*/
#define GRAPHENE_CORE_ASSET_CYCLE_RATE 17
#define GRAPHENE_CORE_ASSET_CYCLE_RATE_BITS 32
#define GRAPHENE_DEFAULT_WITNESS_PAY_PER_BLOCK (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t( 10) )
#define GRAPHENE_DEFAULT_WITNESS_PAY_VESTING_SECONDS (60*60*24)
#define GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY (GRAPHENE_BLOCKCHAIN_PRECISION * int64_t(500) * 1000 )
#define GRAPHENE_DEFAULT_MINIMUM_FEEDS 7
#define GRAPHENE_MAX_INTEREST_APR uint16_t( 10000 )
#define GRAPHENE_CURRENT_DB_VERSION "PPY2.5"
#define GRAPHENE_DEFAULT_MIN_SON_COUNT (5)
#define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4
#define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3
#define GRAPHENE_CURRENT_DB_VERSION "PPY2.5"
#define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT)
/**
* Reserved Account IDs with special meaning
*/
///@{
/// Represents the current committee members, two-week review period
#define GRAPHENE_COMMITTEE_ACCOUNT (graphene::chain::account_id_type(0))
/// Represents the current witnesses
#define GRAPHENE_WITNESS_ACCOUNT (graphene::chain::account_id_type(1))
/// Represents the current committee members
#define GRAPHENE_RELAXED_COMMITTEE_ACCOUNT (graphene::chain::account_id_type(2))
/// Represents the canonical account with NO authority (nobody can access funds in null account)
#define GRAPHENE_NULL_ACCOUNT (graphene::chain::account_id_type(3))
/// Represents the canonical account with WILDCARD authority (anybody can access funds in temp account)
#define GRAPHENE_TEMP_ACCOUNT (graphene::chain::account_id_type(4))
/// Represents the canonical account for specifying you will vote directly (as opposed to a proxy)
#define GRAPHENE_PROXY_TO_SELF_ACCOUNT (graphene::chain::account_id_type(5))
///
#define GRAPHENE_RAKE_FEE_ACCOUNT_ID (graphene::chain::account_id_type(6))
/// Sentinel value used in the scheduler.
#define GRAPHENE_NULL_WITNESS (graphene::chain::witness_id_type(0))
///@}
#define GRAPHENE_FBA_STEALTH_DESIGNATED_ASSET (asset_id_type(743))
#define GRAPHENE_DEFAULT_RAKE_FEE_PERCENTAGE (3*GRAPHENE_1_PERCENT)
/**
* Betting-related constants.
*
* We store bet multipliers as fixed-precision uint32_t. These values are
* the maximum power-of-ten bet we can have on a "symmetric" market:
* (decimal) 1.0001 - 10001
* (fractional) 1:10000 - 10000:1
*/
///@{
/// betting odds (multipliers) are stored as fixed-precision, divide by this to get the actual multiplier
#define GRAPHENE_BETTING_ODDS_PRECISION 10000
/// the smallest bet multiplier we will accept
#define GRAPHENE_BETTING_MIN_MULTIPLIER 10001
/// the largest bet multiplier we will accept
#define GRAPHENE_BETTING_MAX_MULTIPLIER 100010000
///@}
#define GRAPHENE_DEFAULT_MIN_BET_MULTIPLIER 10100
#define GRAPHENE_DEFAULT_MAX_BET_MULTIPLIER 10000000
#define GRAPHENE_DEFAULT_PERMITTED_BETTING_ODDS_INCREMENTS { { 20000, 100}, /* <= 2: 0.01 */ \
{ 30000, 200}, /* <= 3: 0.02 */ \
{ 40000, 500}, /* <= 4: 0.05 */ \
{ 60000, 1000}, /* <= 6: 0.10 */ \
{ 100000, 2000}, /* <= 10: 0.20 */ \
{ 200000, 5000}, /* <= 20: 0.50 */ \
{ 300000, 10000}, /* <= 30: 1.00 */ \
{ 500000, 20000}, /* <= 50: 2.00 */ \
{ 1000000, 50000}, /* <= 100: 5.00 */ \
{ 10000000, 100000} } /* <= 1000: 10.00 */
#define GRAPHENE_DEFAULT_BETTING_PERCENT_FEE (2 * GRAPHENE_1_PERCENT)
#define GRAPHENE_DEFAULT_LIVE_BETTING_DELAY_TIME 5 // seconds
#define GRAPHENE_MAX_NESTED_OBJECTS (200)
#define TOURNAMENT_MIN_ROUND_DELAY 0
#define TOURNAMENT_MAX_ROUND_DELAY 600
#define TOURNAMENT_MIN_TIME_PER_COMMIT_MOVE 0
#define TOURNAMENT_MAN_TIME_PER_COMMIT_MOVE 600
#define TOURNAMENT_MIN_TIME_PER_REVEAL_MOVE 0
#define TOURNAMENT_MAX_TIME_PER_REVEAL_MOVE 600
#define TOURNAMENT_DEFAULT_RAKE_FEE_PERCENTAGE (3*GRAPHENE_1_PERCENT)
#define TOURNAMENT_MINIMAL_RAKE_FEE_PERCENTAGE (1*GRAPHENE_1_PERCENT)
#define TOURNAMENT_MAXIMAL_RAKE_FEE_PERCENTAGE (20*GRAPHENE_1_PERCENT)
#define TOURNAMENT_MAXIMAL_REGISTRATION_DEADLINE (60*60*24*30) // seconds, 30 days
#define TOURNAMENT_MAX_NUMBER_OF_WINS 100
#define TOURNAMENT_MAX_PLAYERS_NUMBER 256
#define TOURNAMENT_MAX_WHITELIST_LENGTH 1000
#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 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_ASSET (graphene::chain::asset_id_type(0))
#define SWEEPS_VESTING_BALANCE_MULTIPLIER 100000000
#define SWEEPS_ACCUMULATOR_ACCOUNT (graphene::chain::account_id_type(0))
#define GPOS_PERIOD (60*60*24*30*6) // 6 months
#define GPOS_SUBPERIOD (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

@ -1,13 +1,14 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
#include <graphene/protocol/custom_account_authority.hpp>
namespace graphene
{
namespace chain
{
class create_custom_account_authority_evaluator : public evaluator<create_custom_account_authority_evaluator>
class create_custom_account_authority_evaluator : public fee_handling_evaluator<create_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_create_operation operation_type;
@ -16,7 +17,7 @@ public:
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>
class update_custom_account_authority_evaluator : public fee_handling_evaluator<update_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_update_operation operation_type;
@ -25,7 +26,7 @@ public:
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>
class delete_custom_account_authority_evaluator : public fee_handling_evaluator<delete_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_delete_operation operation_type;
@ -35,4 +36,5 @@ public:
};
} // namespace chain
} // namespace graphene
} // namespace graphene

View file

@ -1,5 +1,6 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -23,7 +24,6 @@ namespace graphene { namespace chain {
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<
@ -51,5 +51,8 @@ namespace graphene { namespace chain {
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::custom_account_authority_object)
FC_REFLECT_DERIVED( graphene::chain::custom_account_authority_object, (graphene::db::object),
(permission_id)(operation_type)(valid_from)(valid_to) )
(permission_id)(operation_type)(valid_from)(valid_to) )

View file

@ -22,13 +22,13 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
namespace graphene { namespace chain {
class custom_evaluator : public evaluator<custom_evaluator>
class custom_evaluator : public fee_handling_evaluator<custom_evaluator>
{
public:
typedef custom_operation operation_type;

View file

@ -1,13 +1,15 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_permission.hpp>
#include <graphene/protocol/custom_permission.hpp>
namespace graphene
{
namespace chain
{
class create_custom_permission_evaluator : public evaluator<create_custom_permission_evaluator>
class create_custom_permission_evaluator : public fee_handling_evaluator<create_custom_permission_evaluator>
{
public:
typedef custom_permission_create_operation operation_type;
@ -16,7 +18,7 @@ public:
object_id_type do_apply(const custom_permission_create_operation &o);
};
class update_custom_permission_evaluator : public evaluator<update_custom_permission_evaluator>
class update_custom_permission_evaluator : public fee_handling_evaluator<update_custom_permission_evaluator>
{
public:
typedef custom_permission_update_operation operation_type;
@ -25,7 +27,7 @@ public:
object_id_type do_apply(const custom_permission_update_operation &o);
};
class delete_custom_permission_evaluator : public evaluator<delete_custom_permission_evaluator>
class delete_custom_permission_evaluator : public fee_handling_evaluator<delete_custom_permission_evaluator>
{
public:
typedef custom_permission_delete_operation operation_type;
@ -35,4 +37,5 @@ public:
};
} // namespace chain
} // namespace graphene
} // namespace graphene

View file

@ -1,5 +1,9 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/protocol/authority.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -25,7 +29,6 @@ namespace graphene { namespace chain {
authority auth;
};
struct by_id;
struct by_account_and_permission;
using custom_permission_multi_index_type = multi_index_container<
custom_permission_object,
@ -45,5 +48,8 @@ namespace graphene { namespace chain {
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::custom_permission_object)
FC_REFLECT_DERIVED( graphene::chain::custom_permission_object, (graphene::db::object),
(account)(permission_name)(auth) )
(account)(permission_name)(auth) )

View file

@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/node_property_object.hpp>
#include <graphene/chain/account_object.hpp>
@ -30,18 +31,20 @@
#include <graphene/chain/block_database.hpp>
#include <graphene/chain/genesis_state.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/db/object_database.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/simple_index.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/protocol.hpp>
#include <graphene/protocol/sidechain_defs.hpp>
#include <fc/signals.hpp>
#include <fc/crypto/hash_ctr_rng.hpp>
#include <graphene/chain/protocol/protocol.hpp>
#include <graphene/chain/sidechain_defs.hpp>
#include <fc/log/logger.hpp>
#include <map>
@ -51,6 +54,15 @@ namespace graphene { namespace chain {
using graphene::db::object;
class op_evaluator;
class transaction_evaluation_state;
class proposal_object;
class operation_history_object;
class chain_property_object;
class witness_schedule_object;
class witness_object;
class force_settlement_object;
class limit_order_object;
class call_order_object;
class account_role_object;
struct budget_record;
@ -63,11 +75,9 @@ namespace graphene { namespace chain {
public:
//////////////////// db_management.cpp ////////////////////
database();
database(bool allow_testing_edits = false);
~database();
std::vector<fc::time_point_sec> _hardfork_times;
enum validation_steps
{
skip_nothing = 0,
@ -245,16 +255,7 @@ namespace graphene { namespace chain {
witness_id_type get_scheduled_witness(uint32_t slot_num)const;
/**
* @brief Get son schedule id for the given sidechain_type.
*
* type sidechain_type we getting schedule.
*
* returns Id of the schedule object.
*/
unsigned_int get_son_schedule_id(sidechain_type type)const;
/**
* @brief Get the bitcoin or hive son scheduled for block production in a slot.
* @brief Get the son scheduled for block production in a slot.
*
* slot_num always corresponds to a time in the future.
*
@ -267,7 +268,7 @@ namespace graphene { namespace chain {
*
* Passing slot_num == 0 returns GRAPHENE_NULL_WITNESS
*/
son_id_type get_scheduled_son(sidechain_type type, uint32_t slot_num)const;
son_id_type get_scheduled_son(uint32_t slot_num)const;
/**
* Get the time at which the given slot occurs.
@ -292,8 +293,8 @@ namespace graphene { namespace chain {
vector<witness_id_type> get_near_witness_schedule()const;
void update_witness_schedule();
void update_witness_schedule(const signed_block& next_block);
void update_son_schedule(sidechain_type type);
void update_son_schedule(sidechain_type type, 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_ending_lotteries();
@ -322,7 +323,7 @@ namespace graphene { namespace chain {
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( sidechain_type type, son_id_type son_id );
bool is_son_active( son_id_type son_id );
bool is_asset_creation_allowed(const string& symbol);
time_point_sec head_block_time()const;
@ -343,15 +344,52 @@ namespace graphene { namespace chain {
void initialize_evaluators();
/// Reset the object graph in-memory
void initialize_indexes();
void initialize_hardforks();
void init_genesis(const genesis_state_type& genesis_state = genesis_state_type());
/**
* @brief Register a new third party evaluator to the evaluator chain for its operation type
* @tparam EvaluatorType An evaluator type which will be used to evaluate its declared operation type
* @return Returns a handle for the newly added evaluator which can be used to delete it later.
*
* This method registers a new third party evaluator type with the database. The evaluator specifies an
* operation type which it should be used to evaluate. A third party evaluator is an evaluator which belongs
* to code which is not part of official blockchain consensus. Consensus evaluators can only be added by the
* blockchain database itself. The evaluator will be instantiated each time an operaton of the appropriate
* type is processed and used to evaluate the operation.
*
* This method may be called more than once with multiple evaluator types for a given operation type. When
* multiple evaluator types are registered for a given operation type, they will all execute in the order of
* registration. Values returned by third party evaluators will be ignored.
*
* IMPORTANT: Third party evaluators must observe certain rules of etiquette:
* - No exceptions. Exceptions indicate the operation is invalid, and only consensus code can declare an
* operation invalid. Third party evaluators should not throw exceptions.
* - No yielding. Evaluators run as part of the core consensus pathway, and must not yield, to preserve the
* guarantees of consistency of the database.
* - Fast execution. Evaluators must be quick. If heavy processing is necessary, defer it until after the
* core consensus pathway has finished execution.
*/
template<typename EvaluatorType>
void register_evaluator()
op_evaluator::evaluator_handle register_third_party_evaluator()
{
_operation_evaluators[
operation::tag<typename EvaluatorType::operation_type>::value].reset( new op_evaluator_impl<EvaluatorType>() );
return register_evaluator<EvaluatorType, true>(_third_party_operation_evaluators);
}
/**
* @brief Delete a third party evaluator
* @param handle The evaluator handle for the evaluator to delete, as returned by @ref register_evaluator
*
* Third party evaluators, or evaluators registered by non-consensus code for a given operation type, can be
* deleted so that they no longer execute when operations of the relevant type are processed.
*
* If it may be desired to delete an evaluator, retain the evaluator handle obtained when the evaluator was
* initially registered and when it is necessary to delete the evaluator, pass the handle to this function.
*
* The evaluator will have been deleted by the time this function returns.
*/
void delete_third_party_evaluator(op_evaluator::evaluator_handle&& handle)
{
delete_evaluator(_third_party_operation_evaluators, std::move(handle));
}
//////////////////// db_balance.cpp ////////////////////
@ -416,6 +454,12 @@ namespace graphene { namespace chain {
void debug_dump();
void apply_debug_updates();
void debug_update( const fc::variant_object& update );
template<typename Action>
auto bypass_safety_checks(Action&& action) {
FC_ASSERT(_allow_safety_check_bypass, "Safety check bypass disallowed.");
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
return action();
}
//////////////////// db_market.cpp ////////////////////
@ -512,7 +556,7 @@ namespace graphene { namespace chain {
*/
/// Enable or disable tracking of votes of standby witnesses and committee members
inline void enable_standby_votes_tracking(bool enable) { _track_standby_votes = enable; }
protected:
protected:
//Mark pop_undo() as protected -- we do not want outside calling pop_undo(); it should call pop_block() instead
void pop_undo() { object_database::pop_undo(); }
void notify_applied_block( const signed_block& block );
@ -520,19 +564,50 @@ namespace graphene { namespace chain {
void notify_changed_objects();
private:
std::mutex _pending_tx_session_mutex;
optional<undo_database::session> _pending_tx_session;
vector< unique_ptr<op_evaluator> > _operation_evaluators;
vector< unique_ptr<op_evaluator> > _third_party_operation_evaluators;
vector< unique_ptr<op_evaluator> > _consensus_operation_evaluators;
template<typename EvaluatorType, bool DiscardExceptions>
op_evaluator::evaluator_handle register_evaluator(vector<unique_ptr<op_evaluator>>& registry) {
auto op_tag = operation::tag<typename EvaluatorType::operation_type>::value;
FC_ASSERT(registry.size() > (size_t)op_tag,
"Cannot register evaluator for operation type ${T}: operation type is too large.",
("T", op_tag));
auto& eval_ptr = registry[op_tag];
if (eval_ptr == nullptr) {
eval_ptr = std::make_unique<op_evaluator_impl<EvaluatorType, DiscardExceptions>>();
return {eval_ptr.get(), op_tag};
} else {
auto new_evaluator = std::make_unique<op_evaluator_impl<EvaluatorType, DiscardExceptions>>();
return eval_ptr->append_evaluator(std::move(new_evaluator));
}
}
template<typename EvaluatorType>
op_evaluator::evaluator_handle register_consensus_evaluator() {
return register_evaluator<EvaluatorType, false>(_consensus_operation_evaluators);
}
void delete_evaluator(vector<unique_ptr<op_evaluator>>& registry, op_evaluator::evaluator_handle&& handle)
{
if ((uint64_t)handle.get_operation_type() < registry.size()) {
auto& eval_ptr = registry[handle.get_operation_type()];
if (eval_ptr.get() == handle.pointer)
eval_ptr = eval_ptr->take_next();
else
eval_ptr->delete_evaluator(std::move(handle));
}
}
void delete_consensus_evaluator(op_evaluator::evaluator_handle&& handle)
{
delete_evaluator(_consensus_operation_evaluators, std::move(handle));
}
template<class Index>
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(size_t count)const;
template<class Index>
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(sidechain_type sidechain, size_t count)const;
//////////////////// db_block.cpp ////////////////////
public:
public:
// these were formerly private, but they have a fairly well-defined API, so let's make them public
void apply_block( const signed_block& next_block, uint32_t skip = skip_nothing );
processed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
@ -579,22 +654,19 @@ namespace graphene { namespace chain {
void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const;
void process_budget();
void pay_workers( share_type& budget );
void pay_sons_before_hf_ethereum();
void pay_sons_after_hf_ethereum();
void pay_sons();
void perform_son_tasks();
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
void update_active_witnesses();
void update_active_committee_members();
void update_son_metrics( const flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons );
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 flat_map<sidechain_type, vector<son_sidechain_info> >& curr_active_sons,
const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons );
void update_son_wallet( const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons );
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 hotfix_2024();
public:
double calculate_vesting_factor(const account_object& stake_account);
@ -605,7 +677,6 @@ namespace graphene { namespace chain {
///@}
///@}
std::mutex _pending_tx_mutex;
vector< processed_transaction > _pending_tx;
fork_database _fork_db;
@ -633,17 +704,11 @@ namespace graphene { namespace chain {
uint16_t _current_op_in_trx = 0;
uint32_t _current_virtual_op = 0;
vector<uint64_t> _vote_tally_buffer;
vector<uint64_t> _witness_count_histogram_buffer;
vector<uint64_t> _committee_count_histogram_buffer;
flat_map<sidechain_type, vector<uint64_t> > _son_count_histogram_buffer = []{
flat_map<sidechain_type, vector<uint64_t> > son_count_histogram_buffer;
for(const auto& active_sidechain_type : all_sidechain_types){
son_count_histogram_buffer[active_sidechain_type] = vector<uint64_t>{};
}
return son_count_histogram_buffer;
}();
uint64_t _total_voting_stake;
vector<uint64_t> _vote_tally_buffer;
vector<uint64_t> _witness_count_histogram_buffer;
vector<uint64_t> _committee_count_histogram_buffer;
vector<uint64_t> _son_count_histogram_buffer;
uint64_t _total_voting_stake;
flat_map<uint32_t,block_id_type> _checkpoints;
@ -676,6 +741,13 @@ namespace graphene { namespace chain {
const chain_property_object* _p_chain_property_obj = nullptr;
const witness_schedule_object* _p_witness_schedule_obj = nullptr;
///@}
/// Whether or not to allow safety check bypassing (for unit testing only)
bool _allow_safety_check_bypass;
/// Safety check policy for object space 1
database_lock_safety_check* _check_policy_1 = nullptr;
/// Safety check policy for object space 2
database_lock_safety_check* _check_policy_2 = nullptr;
};
namespace detail

View file

@ -24,19 +24,22 @@
#pragma once
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
namespace graphene { namespace chain {
class database;
struct signed_transaction;
class generic_evaluator;
class consensus_evaluator;
class transaction_evaluation_state;
class account_object;
class account_statistics_object;
class asset_object;
class asset_dynamic_data_object;
class generic_evaluator
class consensus_evaluator
{
public:
virtual ~generic_evaluator(){}
virtual ~consensus_evaluator(){}
virtual int get_type()const = 0;
virtual operation_result start_evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply);
@ -119,24 +122,88 @@ namespace graphene { namespace chain {
class op_evaluator
{
protected:
unique_ptr<op_evaluator> next_evaluator;
public:
class evaluator_handle {
// Move-only semantics, and only friends can construct
evaluator_handle(const op_evaluator* pointer, operation::tag_type type)
: pointer(pointer), operation_type(type) {}
evaluator_handle(const evaluator_handle&) = delete;
evaluator_handle& operator=(const evaluator_handle&) = delete;
friend class database;
friend class op_evaluator;
template<typename, bool>
friend class op_evaluator_impl;
// Pointer to the handled evaluator
const op_evaluator* pointer;
// Tag of the handled evaluator
operation::tag_type operation_type;
public:
evaluator_handle(evaluator_handle&&) = default;
evaluator_handle& operator=(evaluator_handle&&) = default;
operation::tag_type get_operation_type() const { return operation_type; }
};
virtual ~op_evaluator(){}
virtual evaluator_handle append_evaluator(unique_ptr<op_evaluator> next_evaluator) = 0;
std::unique_ptr<op_evaluator> take_next() { return std::move(next_evaluator); }
virtual void delete_evaluator(evaluator_handle&& handle) {
FC_ASSERT(handle.pointer != this, "Cannot delete first element of evaluator chain!");
if (next_evaluator.get() == handle.pointer)
// Next evaluator in chain is the one to delete. Move its next pointer into ours, and unique_ptr will delete the one that's going away.
next_evaluator = next_evaluator->take_next();
else if (next_evaluator != nullptr)
next_evaluator->delete_evaluator(std::move(handle));
else
elog("ERROR: Attempted to delete evaluator, but did not find referenced evaluator in the chain");
}
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply) = 0;
};
template<typename T>
template<typename T, bool DiscardExceptions>
class op_evaluator_impl : public op_evaluator
{
public:
virtual evaluator_handle append_evaluator(unique_ptr<op_evaluator> next_evaluator) override {
if (this->next_evaluator == nullptr) {
this->next_evaluator = std::move(next_evaluator);
return evaluator_handle(this->next_evaluator.get(), operation::tag<typename T::operation_type>::value);
} else {
return this->next_evaluator->append_evaluator(std::move(next_evaluator));
}
}
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply = true) override
{
T eval;
return eval.start_evaluate(eval_state, op, apply);
operation_result result;
try {
T eval;
result = eval.start_evaluate(eval_state, op, apply);
} catch (fc::exception_ptr e) {
if (DiscardExceptions)
elog("ERROR: Third party evaluator threw an exception. Discarding.", ("exception", e));
else
throw;
} catch (...) {
if (DiscardExceptions)
elog("ERROR: Third party evaluator threw an unknown exception type. Discarding.");
else
throw;
}
if (this->next_evaluator != nullptr)
this->next_evaluator->evaluate(eval_state, op, apply);
return result;
}
};
template<typename DerivedEvaluator>
class evaluator : public generic_evaluator
class fee_handling_evaluator : public consensus_evaluator
{
public:
virtual int get_type()const override { return operation::tag<typename DerivedEvaluator::operation_type>::value; }
@ -174,4 +241,32 @@ namespace graphene { namespace chain {
return result;
}
};
template<typename DerivedEvaluator>
class third_party_evaluator {
protected:
transaction_evaluation_state* trx_state = nullptr;
database& db() {
FC_ASSERT(trx_state != nullptr, "Cannot get database: evaluator not initialized");
return trx_state->db();
}
public:
operation_result start_evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply) {
trx_state = &eval_state;
using Operation = typename DerivedEvaluator::operation_type;
Operation specific_operation = op.get<Operation>();
DerivedEvaluator& specific_evaluator = static_cast<DerivedEvaluator&>(*this);
operation_result result;
result = specific_evaluator.do_evaluate(specific_operation);
if (apply)
result = specific_evaluator.do_apply(specific_operation);
return result;
}
};
} }

View file

@ -23,13 +23,15 @@
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/protocol/operations.hpp>
namespace graphene { namespace chain {
class event_create_evaluator : public evaluator<event_create_evaluator>
class event_create_evaluator : public fee_handling_evaluator<event_create_evaluator>
{
public:
typedef event_create_operation operation_type;
@ -40,7 +42,7 @@ namespace graphene { namespace chain {
event_group_id_type event_group_id;
};
class event_update_evaluator : public evaluator<event_update_evaluator>
class event_update_evaluator : public fee_handling_evaluator<event_update_evaluator>
{
public:
typedef event_update_operation operation_type;
@ -51,7 +53,7 @@ namespace graphene { namespace chain {
event_group_id_type event_group_id;
};
class event_update_status_evaluator : public evaluator<event_update_status_evaluator>
class event_update_status_evaluator : public fee_handling_evaluator<event_update_status_evaluator>
{
public:
typedef event_update_status_operation operation_type;

View file

@ -23,7 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp>
@ -31,7 +31,7 @@ namespace graphene { namespace chain {
class event_group_object;
class event_group_create_evaluator : public evaluator<event_group_create_evaluator>
class event_group_create_evaluator : public fee_handling_evaluator<event_group_create_evaluator>
{
public:
typedef event_group_create_operation operation_type;
@ -43,7 +43,7 @@ namespace graphene { namespace chain {
sport_id_type sport_id;
};
class event_group_update_evaluator : public evaluator<event_group_update_evaluator>
class event_group_update_evaluator : public fee_handling_evaluator<event_group_update_evaluator>
{
public:
typedef event_group_update_operation operation_type;
@ -55,7 +55,7 @@ namespace graphene { namespace chain {
sport_id_type sport_id;
};
class event_group_delete_evaluator : public evaluator<event_group_delete_evaluator>
class event_group_delete_evaluator : public fee_handling_evaluator<event_group_delete_evaluator>
{
public:
typedef event_group_delete_operation operation_type;

View file

@ -23,9 +23,11 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain {
@ -58,4 +60,6 @@ typedef multi_index_container<
typedef generic_index<event_group_object, event_group_object_multi_index_type> event_group_object_index;
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::event_group_object)
FC_REFLECT_DERIVED( graphene::chain::event_group_object, (graphene::db::object), (name)(sport_id) )

View file

@ -23,19 +23,22 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/protocol/event.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/event.hpp>
#include <sstream>
#include <boost/multi_index/composite_key.hpp>
#include <sstream>
namespace graphene { namespace chain {
class event_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::event_object& event_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::event_object& event_obj, uint32_t max_depth = 1);
} //end namespace fc
@ -56,7 +59,7 @@ class event_object : public graphene::db::abstract_object< event_object >
event_object& operator=(const event_object& rhs);
internationalized_string_type name;
internationalized_string_type season;
optional<time_point_sec> start_time;
@ -114,7 +117,7 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
template<typename Stream>
inline Stream& operator<<( Stream& s, const event_object& event_obj )
{
{
fc_elog(fc::logger::get("event"), "In event_obj to_raw");
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
@ -137,7 +140,7 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
}
template<typename Stream>
inline Stream& operator>>( Stream& s, event_object& event_obj )
{
{
fc_elog(fc::logger::get("event"), "In event_obj from_raw");
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<event_object> >(s, event_obj);
@ -154,57 +157,13 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
event_obj.unpack_impl(stream);
return s;
}
} } // graphene::chain
namespace fc {
MAP_OBJECT_ID_TO_TYPE(graphene::chain::event_object)
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::event_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
FC_REFLECT_DERIVED(graphene::chain::event_object, (graphene::db::object),
(name)(season)(start_time)(event_group_id)(at_least_one_betting_market_group_settled)(scores))
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::event_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::event_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::event_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::event_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::event_object> {
static const char *name() {
return "graphene::chain::event_object";
}
};
template <>
struct reflector<graphene::chain::event_object> {
typedef graphene::chain::event_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -25,7 +25,10 @@
#include <boost/exception/diagnostic_information.hpp>
#include <fc/exception/exception.hpp>
#include <graphene/chain/protocol/protocol.hpp>
#include <graphene/protocol/exceptions.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/operations.hpp>
#include <graphene/chain/types.hpp>
#define GRAPHENE_ASSERT( expr, exc_type, FORMAT, ... ) \
FC_MULTILINE_MACRO_BEGIN \
@ -33,15 +36,26 @@
FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \
FC_MULTILINE_MACRO_END
#define GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _validate_exception, \
graphene::chain::operation_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \
) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \
graphene::chain::operation_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \
)
#define GRAPHENE_IMPLEMENT_OP_BASE_EXCEPTIONS( op_name ) \
FC_IMPLEMENT_DERIVED_EXCEPTION( \
op_name ## _validate_exception, \
graphene::chain::operation_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation validation exception" \
) \
FC_DECLARE_DERIVED_EXCEPTION( \
FC_IMPLEMENT_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \
graphene::chain::operation_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value, \
@ -50,6 +64,14 @@
#define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
graphene::chain::op_name ## _validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum \
)
#define GRAPHENE_IMPLEMENT_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_IMPLEMENT_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
graphene::chain::op_name ## _validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \
@ -59,6 +81,14 @@
#define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
graphene::chain::op_name ## _evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum \
)
#define GRAPHENE_IMPLEMENT_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_IMPLEMENT_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
graphene::chain::op_name ## _evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \
@ -91,30 +121,21 @@
namespace graphene { namespace chain {
FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" )
FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, graphene::chain::chain_exception, 3010000, "database query exception" )
FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, graphene::chain::chain_exception, 3020000, "block validation exception" )
FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, graphene::chain::chain_exception, 3030000, "transaction validation exception" )
FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, graphene::chain::chain_exception, 3040000, "operation validation exception" )
FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, graphene::chain::chain_exception, 3050000, "operation evaluation exception" )
FC_DECLARE_DERIVED_EXCEPTION( utility_exception, graphene::chain::chain_exception, 3060000, "utility method exception" )
FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, graphene::chain::chain_exception, 3070000, "undo database exception" )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, graphene::chain::chain_exception, 3080000, "unlinkable block" )
FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, graphene::chain::chain_exception, 3090000, "black swan" )
FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, graphene::chain::chain_exception, 3100000, "plugin exception" )
FC_DECLARE_EXCEPTION( chain_exception, 3000000 )
FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000 )
FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000 )
FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, chain_exception, 3030000 )
FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000 )
FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000 )
FC_DECLARE_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000 )
FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000 )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000 )
FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000 )
FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, chain_exception, 3100000 )
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_active_auth, graphene::chain::transaction_exception, 3030001, "missing required active authority" )
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_owner_auth, graphene::chain::transaction_exception, 3030002, "missing required owner authority" )
FC_DECLARE_DERIVED_EXCEPTION( tx_missing_other_auth, graphene::chain::transaction_exception, 3030003, "missing required other authority" )
FC_DECLARE_DERIVED_EXCEPTION( tx_irrelevant_sig, graphene::chain::transaction_exception, 3030004, "irrelevant signature included" )
FC_DECLARE_DERIVED_EXCEPTION( tx_duplicate_sig, graphene::chain::transaction_exception, 3030005, "duplicate signature included" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_approval, graphene::chain::transaction_exception, 3030006, "committee account cannot directly approve transaction" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::transaction_exception, 3030007, "insufficient fee" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, chain_exception, 37006 )
FC_DECLARE_DERIVED_EXCEPTION( invalid_pts_address, graphene::chain::utility_exception, 3060001, "invalid pts address" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::chain_exception, 37006, "insufficient feeds" )
FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, graphene::chain::undo_database_exception, 3070001, "there are no blocks to pop" )
FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001 )
GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer );
GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" )
@ -185,93 +206,11 @@ namespace graphene { namespace chain {
GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( blind_transfer );
GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" );
/*
FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" )
FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" )
FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" )
FC_DECLARE_DERIVED_EXCEPTION( unsupported_chain_operation, graphene::chain::chain_exception, 30005, "unsupported chain operation" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_transaction, graphene::chain::chain_exception, 30006, "unknown transaction" )
FC_DECLARE_DERIVED_EXCEPTION( duplicate_transaction, graphene::chain::chain_exception, 30007, "duplicate transaction" )
FC_DECLARE_DERIVED_EXCEPTION( zero_amount, graphene::chain::chain_exception, 30008, "zero amount" )
FC_DECLARE_DERIVED_EXCEPTION( zero_price, graphene::chain::chain_exception, 30009, "zero price" )
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_self, graphene::chain::chain_exception, 30010, "asset divide by self" )
FC_DECLARE_DERIVED_EXCEPTION( asset_divide_by_zero, graphene::chain::chain_exception, 30011, "asset divide by zero" )
FC_DECLARE_DERIVED_EXCEPTION( new_database_version, graphene::chain::chain_exception, 30012, "new database version" )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block, graphene::chain::chain_exception, 30013, "unlinkable block" )
FC_DECLARE_DERIVED_EXCEPTION( price_out_of_range, graphene::chain::chain_exception, 30014, "price out of range" )
FC_DECLARE_DERIVED_EXCEPTION( block_numbers_not_sequential, graphene::chain::chain_exception, 30015, "block numbers not sequential" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_previous_block_id, graphene::chain::chain_exception, 30016, "invalid previous block" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_time, graphene::chain::chain_exception, 30017, "invalid block time" )
FC_DECLARE_DERIVED_EXCEPTION( time_in_past, graphene::chain::chain_exception, 30018, "time is in the past" )
FC_DECLARE_DERIVED_EXCEPTION( time_in_future, graphene::chain::chain_exception, 30019, "time is in the future" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_block_digest, graphene::chain::chain_exception, 30020, "invalid block digest" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_committee_member_signee, graphene::chain::chain_exception, 30021, "invalid committee_member signee" )
FC_DECLARE_DERIVED_EXCEPTION( failed_checkpoint_verification, graphene::chain::chain_exception, 30022, "failed checkpoint verification" )
FC_DECLARE_DERIVED_EXCEPTION( wrong_chain_id, graphene::chain::chain_exception, 30023, "wrong chain id" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_block, graphene::chain::chain_exception, 30024, "unknown block" )
FC_DECLARE_DERIVED_EXCEPTION( block_older_than_undo_history, graphene::chain::chain_exception, 30025, "block is older than our undo history allows us to process" )
FC_DECLARE_EXCEPTION( evaluation_error, 31000, "Evaluation Error" )
FC_DECLARE_DERIVED_EXCEPTION( negative_deposit, graphene::chain::evaluation_error, 31001, "negative deposit" )
FC_DECLARE_DERIVED_EXCEPTION( not_a_committee_member, graphene::chain::evaluation_error, 31002, "not a committee_member" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_balance_record, graphene::chain::evaluation_error, 31003, "unknown balance record" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_funds, graphene::chain::evaluation_error, 31004, "insufficient funds" )
FC_DECLARE_DERIVED_EXCEPTION( missing_signature, graphene::chain::evaluation_error, 31005, "missing signature" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_claim_password, graphene::chain::evaluation_error, 31006, "invalid claim password" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_withdraw_condition, graphene::chain::evaluation_error, 31007, "invalid withdraw condition" )
FC_DECLARE_DERIVED_EXCEPTION( negative_withdraw, graphene::chain::evaluation_error, 31008, "negative withdraw" )
FC_DECLARE_DERIVED_EXCEPTION( not_an_active_committee_member, graphene::chain::evaluation_error, 31009, "not an active committee_member" )
FC_DECLARE_DERIVED_EXCEPTION( expired_transaction, graphene::chain::evaluation_error, 31010, "expired transaction" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_transaction_expiration, graphene::chain::evaluation_error, 31011, "invalid transaction expiration" )
FC_DECLARE_DERIVED_EXCEPTION( oversized_transaction, graphene::chain::evaluation_error, 31012, "transaction exceeded the maximum transaction size" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_account_name, graphene::chain::evaluation_error, 32001, "invalid account name" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_id, graphene::chain::evaluation_error, 32002, "unknown account id" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_account_name, graphene::chain::evaluation_error, 32003, "unknown account name" )
FC_DECLARE_DERIVED_EXCEPTION( missing_parent_account_signature, graphene::chain::evaluation_error, 32004, "missing parent account signature" )
FC_DECLARE_DERIVED_EXCEPTION( parent_account_retracted, graphene::chain::evaluation_error, 32005, "parent account retracted" )
FC_DECLARE_DERIVED_EXCEPTION( account_expired, graphene::chain::evaluation_error, 32006, "account expired" )
FC_DECLARE_DERIVED_EXCEPTION( account_already_registered, graphene::chain::evaluation_error, 32007, "account already registered" )
FC_DECLARE_DERIVED_EXCEPTION( account_key_in_use, graphene::chain::evaluation_error, 32008, "account key already in use" )
FC_DECLARE_DERIVED_EXCEPTION( account_retracted, graphene::chain::evaluation_error, 32009, "account retracted" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_parent_account_name, graphene::chain::evaluation_error, 32010, "unknown parent account name" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_committee_member_slate, graphene::chain::evaluation_error, 32011, "unknown committee_member slate" )
FC_DECLARE_DERIVED_EXCEPTION( too_may_committee_members_in_slate, graphene::chain::evaluation_error, 32012, "too many committee_members in slate" )
FC_DECLARE_DERIVED_EXCEPTION( pay_balance_remaining, graphene::chain::evaluation_error, 32013, "pay balance remaining" )
FC_DECLARE_DERIVED_EXCEPTION( not_a_committee_member_signature, graphene::chain::evaluation_error, 33002, "not committee_members signature" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_precision, graphene::chain::evaluation_error, 35001, "invalid precision" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_symbol, graphene::chain::evaluation_error, 35002, "invalid asset symbol" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_id, graphene::chain::evaluation_error, 35003, "unknown asset id" )
FC_DECLARE_DERIVED_EXCEPTION( asset_symbol_in_use, graphene::chain::evaluation_error, 35004, "asset symbol in use" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_amount, graphene::chain::evaluation_error, 35005, "invalid asset amount" )
FC_DECLARE_DERIVED_EXCEPTION( negative_issue, graphene::chain::evaluation_error, 35006, "negative issue" )
FC_DECLARE_DERIVED_EXCEPTION( over_issue, graphene::chain::evaluation_error, 35007, "over issue" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_asset_symbol, graphene::chain::evaluation_error, 35008, "unknown asset symbol" )
FC_DECLARE_DERIVED_EXCEPTION( asset_id_in_use, graphene::chain::evaluation_error, 35009, "asset id in use" )
FC_DECLARE_DERIVED_EXCEPTION( not_user_issued, graphene::chain::evaluation_error, 35010, "not user issued" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_asset_name, graphene::chain::evaluation_error, 35011, "invalid asset name" )
FC_DECLARE_DERIVED_EXCEPTION( committee_member_vote_limit, graphene::chain::evaluation_error, 36001, "committee_member_vote_limit" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_fee, graphene::chain::evaluation_error, 36002, "insufficient fee" )
FC_DECLARE_DERIVED_EXCEPTION( negative_fee, graphene::chain::evaluation_error, 36003, "negative fee" )
FC_DECLARE_DERIVED_EXCEPTION( missing_deposit, graphene::chain::evaluation_error, 36004, "missing deposit" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_relay_fee, graphene::chain::evaluation_error, 36005, "insufficient relay fee" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_market, graphene::chain::evaluation_error, 37001, "invalid market" )
FC_DECLARE_DERIVED_EXCEPTION( unknown_market_order, graphene::chain::evaluation_error, 37002, "unknown market order" )
FC_DECLARE_DERIVED_EXCEPTION( shorting_base_shares, graphene::chain::evaluation_error, 37003, "shorting base shares" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_collateral, graphene::chain::evaluation_error, 37004, "insufficient collateral" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_depth, graphene::chain::evaluation_error, 37005, "insufficient depth" )
FC_DECLARE_DERIVED_EXCEPTION( insufficient_feeds, graphene::chain::evaluation_error, 37006, "insufficient feeds" )
FC_DECLARE_DERIVED_EXCEPTION( invalid_feed_price, graphene::chain::evaluation_error, 37007, "invalid feed price" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_overflow, graphene::chain::evaluation_error, 38001, "price multiplication overflow" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_underflow, graphene::chain::evaluation_error, 38002, "price multiplication underflow" )
FC_DECLARE_DERIVED_EXCEPTION( price_multiplication_undefined, graphene::chain::evaluation_error, 38003, "price multiplication undefined product 0*inf" )
*/
//GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer_from_blind_operation )
//GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_fees_operation )
//GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( bid_collateral_operation )
//GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_pool_operation )
//GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_update_issuer_operation )
#define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \
catch( const cause_type& e ) \

View file

@ -23,7 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/types.hpp>
namespace graphene { namespace chain {

View file

@ -23,7 +23,7 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -49,6 +49,8 @@ class fba_accumulator_object : public graphene::db::abstract_object< fba_accumul
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::fba_accumulator_object)
FC_REFLECT_DERIVED( graphene::chain::fba_accumulator_object, (graphene::db::object),
(accumulated_fba_fees)(designated_asset) )

View file

@ -22,7 +22,9 @@
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/protocol/block.hpp>
#include <graphene/protocol/block.hpp>
#include <graphene/chain/types.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>

View file

@ -24,16 +24,23 @@
#pragma once
#include <graphene/chain/rock_paper_scissors.hpp>
#include <graphene/db/object.hpp>
#include <graphene/protocol/tournament.hpp>
#include <graphene/db/flat_index.hpp>
#include <graphene/db/generic_index.hpp>
#include <fc/crypto/hex.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <sstream>
namespace graphene { namespace chain {
class game_object;
} }
namespace fc {
namespace fc {
void to_variant(const graphene::chain::game_object& game_obj, fc::variant& v, uint32_t max_depth = 1);
void from_variant(const fc::variant& v, graphene::chain::game_object& game_obj, uint32_t max_depth = 1);
} //end namespace fc
@ -80,7 +87,7 @@ namespace graphene { namespace chain {
void on_move(database& db, const game_move_operation& op);
void on_timeout(database& db);
void start_game(database& db, const std::vector<account_id_type>& players);
// serialization functions:
// for serializing to raw, go through a temporary sstream object to avoid
// having to implement serialization in the header file
@ -114,7 +121,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator<<( Stream& s, const game_object& game_obj )
{
{
// pack all fields exposed in the header in the usual way
// instead of calling the derived pack, just serialize the one field in the base class
// fc::raw::pack<Stream, const graphene::db::abstract_object<game_object> >(s, game_obj);
@ -136,7 +143,7 @@ namespace graphene { namespace chain {
template<typename Stream>
inline Stream& operator>>( Stream& s, game_object& game_obj )
{
{
// unpack all fields exposed in the header in the usual way
//fc::raw::unpack<Stream, graphene::db::abstract_object<game_object> >(s, game_obj);
fc::raw::unpack(s, game_obj.id);
@ -151,63 +158,21 @@ namespace graphene { namespace chain {
fc::raw::unpack(s, stringified_stream);
std::istringstream stream(stringified_stream);
game_obj.unpack_impl(stream);
return s;
}
} }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::game_object)
FC_REFLECT_ENUM(graphene::chain::game_state,
(game_in_progress)
(expecting_commit_moves)
(expecting_reveal_moves)
(game_complete))
namespace fc {
//FC_REFLECT_TYPENAME(graphene::chain::game_object) // manually serialized
FC_REFLECT_DERIVED(graphene::chain::game_object, (graphene::db::object), (players))
template<>
template<>
inline void if_enum<fc::false_type>::from_variant(const variant &vo, graphene::chain::game_object &v, uint32_t max_depth) {
from_variant(vo, v, max_depth);
}
template<>
template<>
inline void if_enum<fc::false_type>::to_variant(const graphene::chain::game_object &v, variant &vo, uint32_t max_depth) {
to_variant(v, vo, max_depth);
}
namespace raw { namespace detail {
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<size_t> &s, const graphene::chain::game_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::pack(fc::datastream<char*> &s, const graphene::chain::game_object &v, uint32_t) {
s << v;
}
template<>
template<>
inline void if_enum<fc::false_type>::unpack(fc::datastream<const char*> &s, graphene::chain::game_object &v, uint32_t) {
s >> v;
}
} } // namespace fc::raw::detail
template <>
struct get_typename<graphene::chain::game_object> {
static const char *name() {
return "graphene::chain::game_object";
}
};
template <>
struct reflector<graphene::chain::game_object> {
typedef graphene::chain::game_object type;
typedef fc::true_type is_defined;
typedef fc::false_type is_enum;
};
} // namespace fc

View file

@ -23,9 +23,9 @@
*/
#pragma once
#include <graphene/chain/protocol/address.hpp>
#include <graphene/chain/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/protocol/address.hpp>
#include <graphene/protocol/chain_parameters.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/chain/immutable_chain_parameters.hpp>
#include <fc/crypto/sha256.hpp>

View file

@ -30,3 +30,4 @@ namespace graphene { namespace chain {
fc::variant_object get_config();
} } // graphene::chain

View file

@ -23,7 +23,8 @@
*/
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
@ -49,4 +50,6 @@ typedef generic_index<global_betting_statistics_object, global_betting_statistic
} } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::global_betting_statistics_object)
FC_REFLECT_DERIVED( graphene::chain::global_betting_statistics_object, (graphene::db::object), (number_of_active_events)(total_amount_staked) )

View file

@ -24,10 +24,12 @@
#pragma once
#include <fc/uint128.hpp>
#include <graphene/chain/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/son_sidechain_info.hpp>
#include <graphene/protocol/chain_parameters.hpp>
#include <graphene/protocol/son_info.hpp>
#include <graphene/chain/types.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/db/object.hpp>
namespace graphene { namespace chain {
@ -49,18 +51,10 @@ namespace graphene { namespace chain {
chain_parameters parameters;
optional<chain_parameters> pending_parameters;
uint32_t next_available_vote_id = 0;
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_map<sidechain_type, vector<son_sidechain_info> > active_sons = []() // updated once per maintenance interval
{
flat_map<sidechain_type, vector<son_sidechain_info> > active_sons;
for(const auto& active_sidechain_type : all_sidechain_types)
{
active_sons[active_sidechain_type] = vector<son_sidechain_info>();
}
return active_sons;
}();
uint32_t next_available_vote_id = 0;
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
vector<son_info> active_sons; // updated once per maintenance interval
// n.b. witness scheduling is done by witness_schedule object
};
@ -97,8 +91,6 @@ namespace graphene { namespace chain {
* every time a block is found it decreases by
* RECENTLY_MISSED_COUNT_DECREMENT. It is
* never less than 0.
*
* If the recently_missed_count hits 2*UNDO_HISTORY then no new blocks may be pushed.
*/
uint32_t recently_missed_count = 0;
@ -138,8 +130,10 @@ namespace graphene { namespace chain {
};
}}
MAP_OBJECT_ID_TO_TYPE(graphene::chain::dynamic_global_property_object)
MAP_OBJECT_ID_TO_TYPE(graphene::chain::global_property_object)
FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object),
(random)
(head_block_number)
(head_block_id)
(time)

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