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

4
.gitignore vendored
View file

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

View file

@ -8,11 +8,8 @@ include:
stages: stages:
- build - build
- test - test
- dockerize
- python-test
- deploy
build-mainnet: build:
stage: build stage: build
script: script:
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc - rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc
@ -22,7 +19,7 @@ build-mainnet:
- mkdir build - mkdir build
- cd build - cd build
- cmake -DCMAKE_BUILD_TYPE=Release .. - cmake -DCMAKE_BUILD_TYPE=Release ..
- make -j$(nproc) - make -j4
artifacts: artifacts:
untracked: true untracked: true
paths: paths:
@ -32,140 +29,28 @@ build-mainnet:
tags: tags:
- builder - builder
test-mainnet: dockerize:
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:
stage: build 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: script:
- rm -rf .git/modules/docs .git/modules/libraries/fc ./docs ./libraries/fc - docker build -t $IMAGE .
- git submodule sync - docker push $IMAGE
- 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
tags: tags:
- builder - builder
when: manual
timeout: 3h
deploy-testnet: test:
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:
stage: test stage: test
dependencies: dependencies:
- build-testnet - build
script: script:
- ./build/libraries/fc/tests/all_tests
- ./build/tests/betting_test --log_level=message - ./build/tests/betting_test --log_level=message
- ./build/tests/chain_test --log_level=message - ./build/tests/chain_test --log_level=message
- ./build/tests/cli_test --log_level=message - ./build/tests/cli_test --log_level=message
tags: tags:
- builder - 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"] [submodule "libraries/fc"]
path = libraries/fc path = libraries/fc
url = https://gitlab.com/PBSA/tools-libs/peerplays-fc.git url = https://gitlab.com/PBSA/tools-libs/peerplays-fc.git
branch = develop branch = dapp-support
ignore = dirty ignore = dirty

View file

@ -8,6 +8,15 @@ set( CLI_CLIENT_EXECUTABLE_NAME graphene_client )
set( GUI_CLIENT_EXECUTABLE_NAME Peerplays ) set( GUI_CLIENT_EXECUTABLE_NAME Peerplays )
set( CUSTOM_URL_SCHEME "gcs" ) set( CUSTOM_URL_SCHEME "gcs" )
set( INSTALLER_APP_ID "68ad7005-8eee-49c9-95ce-9eed97e5b347" ) 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 # http://stackoverflow.com/a/18369825
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
@ -22,37 +31,6 @@ endif()
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules" ) 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 # function to help with cUrl
macro(FIND_CURL) macro(FIND_CURL)
if (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB) if (NOT WIN32 AND NOT APPLE AND CURL_STATICLIB)
@ -119,7 +97,12 @@ LIST(APPEND BOOST_COMPONENTS thread
unit_test_framework unit_test_framework
context context
locale) 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 ) IF( WIN32 )
SET(BOOST_ROOT $ENV{BOOST_ROOT}) SET(BOOST_ROOT $ENV{BOOST_ROOT})
@ -173,11 +156,11 @@ else( WIN32 ) # Apple AND Linux
if( APPLE ) if( APPLE )
# Apple Specific Options Here # Apple Specific Options Here
message( STATUS "Configuring Peerplays on OS X" ) 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 ) else( APPLE )
# Linux Specific Options Here # Linux Specific Options Here
message( STATUS "Configuring Peerplays on Linux" ) 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( rt_library rt )
#set( pthread_library pthread) #set( pthread_library pthread)
set(CMAKE_LINKER_FLAGS "-pthread" CACHE STRING "Linker Flags" FORCE) set(CMAKE_LINKER_FLAGS "-pthread" CACHE STRING "Linker Flags" FORCE)

View file

@ -1,4 +1,5 @@
FROM ubuntu:20.04 FROM ubuntu:20.04
MAINTAINER PeerPlays Blockchain Standards Association
#=============================================================================== #===============================================================================
# Ubuntu setup # Ubuntu setup
@ -10,33 +11,35 @@ RUN \
apt-utils \ apt-utils \
autoconf \ autoconf \
bash \ bash \
bison \
build-essential \ build-essential \
ca-certificates \ ca-certificates \
cmake \
dnsutils \ dnsutils \
doxygen \
expect \ expect \
flex \
git \ git \
graphviz \ graphviz \
libboost1.67-all-dev \
libbz2-dev \ libbz2-dev \
libcurl4-openssl-dev \ libcurl4-openssl-dev \
libncurses-dev \ libncurses-dev \
libreadline-dev \
libsnappy-dev \ libsnappy-dev \
libssl-dev \ libssl-dev \
libtool \ libtool \
libzip-dev \ libzip-dev \
libzmq3-dev \
locales \ locales \
lsb-release \
mc \ mc \
nano \ nano \
net-tools \ net-tools \
ntp \ ntp \
openssh-server \ openssh-server \
pkg-config \ pkg-config \
perl \
python3 \ python3 \
python3-jinja2 \ python3-jinja2 \
sudo \ sudo \
systemd-coredump \
wget wget
ENV HOME /home/peerplays ENV HOME /home/peerplays
@ -50,127 +53,12 @@ RUN echo 'peerplays:peerplays' | chpasswd
# SSH # SSH
EXPOSE 22 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 # Peerplays setup
#=============================================================================== #===============================================================================
WORKDIR /home/peerplays/
## Clone Peerplays ## Clone Peerplays
#RUN \ #RUN \
# git clone https://gitlab.com/PBSA/peerplays.git && \ # git clone https://gitlab.com/PBSA/peerplays.git && \
@ -186,8 +74,6 @@ ADD . peerplays
# Configure Peerplays # Configure Peerplays
RUN \ RUN \
cd peerplays && \ cd peerplays && \
git submodule update --init --recursive && \
git log --oneline -n 5 && \
mkdir build && \ mkdir build && \
cd build && \ cd build && \
cmake -DCMAKE_BUILD_TYPE=Release .. cmake -DCMAKE_BUILD_TYPE=Release ..
@ -201,8 +87,8 @@ WORKDIR /home/peerplays/peerplays-network
# Setup Peerplays runimage # Setup Peerplays runimage
RUN \ RUN \
ln -s /home/peerplays/src/peerplays/build/programs/cli_wallet/cli_wallet ./ && \ ln -s /home/peerplays/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/witness_node/witness_node ./
RUN ./witness_node --create-genesis-json genesis.json && \ RUN ./witness_node --create-genesis-json genesis.json && \
rm 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 # 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:
Following dependencies are needed for a clean install of Ubuntu 20.04 and Ubuntu 18.04:
``` ```
sudo apt-get install \ sudo apt-get install \
autoconf bash bison build-essential ca-certificates dnsutils expect flex git \ apt-utils autoconf bash build-essential ca-certificates cmake dnsutils \
graphviz libbz2-dev libcurl4-openssl-dev libncurses-dev libpcre3-dev \ doxygen expect git graphviz libboost1.67-all-dev libbz2-dev libcurl4-openssl-dev \
libsnappy-dev libsodium-dev libssl-dev libtool libzip-dev locales lsb-release \ libncurses-dev libreadline-dev libsnappy-dev libssl-dev libtool libzip-dev \
mc nano net-tools ntp openssh-server pkg-config python3 python3-jinja2 sudo \ libzmq3-dev locales mc nano net-tools ntp openssh-server pkg-config perl \
systemd-coredump wget 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: ## Building Peerplays
```
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
```
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 git clone https://gitlab.com/PBSA/peerplays.git
cd peerplays cd peerplays
git submodule update --init --recursive git submodule update --init --recursive
# If you want to build Mainnet node # If you want to build Mainnet node
cmake -DCMAKE_BUILD_TYPE=Release cmake -DCMAKE_BUILD_TYPE=Release
# If you want to build Testnet node # If you want to build Testnet node
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 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) 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 ## Docker images
Install docker, and add current user to docker group. Install docker, and add current user to docker group.
@ -146,36 +54,15 @@ sudo usermod -a -G docker $USER
docker pull datasecuritynode/peerplays:latest docker pull datasecuritynode/peerplays:latest
``` ```
### Building docker images manually ### Building docker image manually
``` ```
# Checkout the code # Build docker image (from the project root, must be a docker group member)
git clone https://gitlab.com/PBSA/peerplays.git docker build -t peerplays .
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 .
``` ```
### Start docker image ### Start docker image
``` ```
# Start docker image, using Ubuntu 20.04 base docker start peerplays
docker run peerplays:latest
# Start docker image, using Ubuntu 18.04 base
docker run peerplays-18-04:latest
``` ```
Rest of the instructions on starting the chain remains same. 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/app -regex ".*[c|h]pp" | xargs clang-format -i
find ./libraries/chain/hardfork.d -regex ".*hf" | 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 ./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( fc )
add_subdirectory( net ) add_subdirectory( net )
add_subdirectory( plugins ) add_subdirectory( plugins )
add_subdirectory( sha3 )
add_subdirectory( time )
add_subdirectory( utilities ) add_subdirectory( utilities )
add_subdirectory( wallet ) 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 # 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 target_link_libraries( graphene_app
PUBLIC graphene_net graphene_utilities PUBLIC graphene_chain 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 ) 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 target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
@ -43,7 +44,7 @@ add_library( graphene_plugin
) )
target_link_libraries( graphene_plugin target_link_libraries( graphene_plugin
PUBLIC graphene_net graphene_utilities ) PUBLIC graphene_chain graphene_net graphene_utilities )
target_include_directories( graphene_plugin target_include_directories( graphene_plugin
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

View file

@ -29,14 +29,16 @@
#include <graphene/chain/confidential_object.hpp> #include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/get_config.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/market_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/transaction_history_object.hpp>
#include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/transaction_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp> #include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/worker_object.hpp> #include <graphene/chain/worker_object.hpp>
#include <graphene/utilities/key_conversion.hpp> #include <graphene/utilities/key_conversion.hpp>
#include <fc/crypto/base64.hpp>
#include <fc/crypto/hex.hpp> #include <fc/crypto/hex.hpp>
#include <fc/rpc/api_connection.hpp> #include <fc/rpc/api_connection.hpp>
#include <fc/thread/future.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_broadcast_api>;
template class fc::api<graphene::app::network_node_api>; template class fc::api<graphene::app::network_node_api>;
template class fc::api<graphene::app::history_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::app::asset_api>;
template class fc::api<graphene::debug_witness::debug_api>; template class fc::api<graphene::debug_witness::debug_api>;
template class fc::api<graphene::app::login_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); _history_api = std::make_shared<history_api>(_app);
} else if (api_name == "network_node_api") { } else if (api_name == "network_node_api") {
_network_node_api = std::make_shared<network_node_api>(std::ref(_app)); _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") { } else if (api_name == "asset_api") {
_asset_api = std::make_shared<asset_api>(_app); _asset_api = std::make_shared<asset_api>(_app);
} else if (api_name == "debug_api") { } 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 // can only enable this API if the plugin was loaded
if (_app.get_plugin("affiliate_stats")) if (_app.get_plugin("affiliate_stats"))
_affiliate_stats_api = std::make_shared<graphene::affiliate_stats::affiliate_stats_api>(std::ref(_app)); _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; return;
} }
@ -145,7 +146,7 @@ void network_broadcast_api::on_applied_block(const signed_block &b) {
if (itr != _callbacks.end()) { if (itr != _callbacks.end()) {
auto block_num = b.block_num(); auto block_num = b.block_num();
auto &callback = _callbacks.find(id)->second; 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}, callback(fc::variant(transaction_confirmation{id, block_num, trx_num, trx},
GRAPHENE_MAX_NESTED_OBJECTS)); 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) { fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction &trx) {
_app.chain_database()->check_transaction_for_duplicated_operations(trx); _app.chain_database()->check_transaction_for_duplicated_operations(trx);
fc::promise<fc::variant>::ptr prom(new fc::promise<fc::variant>()); fc::promise<fc::variant>::ptr prom(fc::promise<fc::variant>::create());
broadcast_transaction_with_callback([=](const fc::variant &v) { broadcast_transaction_with_callback([=](const fc::variant &v) {
prom->set_value(v); prom->set_value(v);
}, },
@ -286,6 +287,11 @@ fc::api<history_api> login_api::history() const {
return *_history_api; 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::api<asset_api> login_api::asset() const {
FC_ASSERT(_asset_api); FC_ASSERT(_asset_api);
return *_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; 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 { 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()); FC_ASSERT(_app.chain_database());
const auto &db = *_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)) 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::asset_api(graphene::app::application &app) : asset_api::asset_api(graphene::app::application &app) :
_app(app), _app(app),

View file

@ -26,8 +26,10 @@
#include <graphene/app/application.hpp> #include <graphene/app/application.hpp>
#include <graphene/app/plugin.hpp> #include <graphene/app/plugin.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/db_with.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/genesis_state.hpp>
#include <graphene/protocol/fee_schedule.hpp>
#include <graphene/protocol/types.hpp>
#include <graphene/egenesis/egenesis.hpp> #include <graphene/egenesis/egenesis.hpp>
@ -48,7 +50,6 @@
#include <boost/range/algorithm/reverse.hpp> #include <boost/range/algorithm/reverse.hpp>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <atomic>
#include <iostream> #include <iostream>
#include <fc/log/file_appender.hpp> #include <fc/log/file_appender.hpp>
@ -108,7 +109,6 @@ public:
fc::optional<fc::temp_file> _lock_file; fc::optional<fc::temp_file> _lock_file;
bool _is_block_producer = false; bool _is_block_producer = false;
bool _force_validate = false; bool _force_validate = false;
std::atomic_bool _running{true};
void reset_p2p_node(const fc::path &data_dir) { void reset_p2p_node(const fc::path &data_dir) {
try { try {
@ -117,20 +117,27 @@ public:
_p2p_network->load_configuration(data_dir / "p2p"); _p2p_network->load_configuration(data_dir / "p2p");
_p2p_network->set_node_delegate(this); _p2p_network->set_node_delegate(this);
vector<string> all_seeds;
if (_options->count("seed-node")) { if (_options->count("seed-node")) {
auto seeds = _options->at("seed-node").as<vector<string>>(); 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")) { if (_options->count("seed-nodes")) {
auto seeds_str = _options->at("seed-nodes").as<string>(); auto seeds_str = _options->at("seed-nodes").as<string>();
auto seeds = fc::json::from_string(seeds_str).as<vector<string>>(2); 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 : seeds) {
}
for (const string &endpoint_string : all_seeds) {
try { try {
std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string); std::vector<fc::ip::endpoint> endpoints = resolve_string_to_ip_endpoints(endpoint_string);
for (const fc::ip::endpoint &endpoint : endpoints) { for (const fc::ip::endpoint &endpoint : endpoints) {
@ -142,6 +149,37 @@ public:
("e", e.to_detail_string())("endpoint", endpoint_string)); ("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));
}
}
}
if (_options->count("p2p-endpoint")) if (_options->count("p2p-endpoint"))
_p2p_network->listen_on_endpoint(fc::ip::endpoint::from_string(_options->at("p2p-endpoint").as<string>()), true); _p2p_network->listen_on_endpoint(fc::ip::endpoint::from_string(_options->at("p2p-endpoint").as<string>()), true);
@ -253,6 +291,10 @@ public:
_self(self), _self(self),
_chain_db(std::make_shared<chain::database>()) { _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() { ~application_impl() {
} }
@ -270,10 +312,10 @@ public:
auto initial_state = [this] { auto initial_state = [this] {
ilog("Initializing database..."); ilog("Initializing database...");
if (_options->count("genesis-json")) { 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_file( _options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>( 20 );
genesis_state_type genesis = fc::json::from_string(genesis_str).as<genesis_state_type>(20); std::string genesis_str = fc::json::to_string(genesis) + "\n";
bool modified_genesis = false; bool modified_genesis = false;
if (_options->count("genesis-timestamp")) { 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>(); genesis.initial_timestamp = fc::time_point_sec(fc::time_point::now()) + genesis.initial_parameters.block_interval + _options->at("genesis-timestamp").as<uint32_t>();
@ -362,9 +404,9 @@ public:
wild_access.allowed_apis.push_back("database_api"); wild_access.allowed_apis.push_back("database_api");
wild_access.allowed_apis.push_back("network_broadcast_api"); wild_access.allowed_apis.push_back("network_broadcast_api");
wild_access.allowed_apis.push_back("history_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("bookie_api");
wild_access.allowed_apis.push_back("affiliate_stats_api"); wild_access.allowed_apis.push_back("affiliate_stats_api");
wild_access.allowed_apis.push_back("sidechain_api");
_apiaccess.permission_map["*"] = wild_access; _apiaccess.permission_map["*"] = wild_access;
} }
@ -413,12 +455,6 @@ public:
*/ */
virtual bool handle_block(const graphene::net::block_message &blk_msg, bool sync_mode, virtual bool handle_block(const graphene::net::block_message &blk_msg, bool sync_mode,
std::vector<fc::uint160_t> &contained_transaction_message_ids) override { 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 { try {
auto latency = fc::time_point::now() - blk_msg.block.timestamp; auto latency = fc::time_point::now() - blk_msg.block.timestamp;
FC_ASSERT((latency.count() / 1000) > -5000, "Rejecting block with timestamp in the future"); FC_ASSERT((latency.count() / 1000) > -5000, "Rejecting block with timestamp in the future");
@ -733,7 +769,7 @@ public:
low_block_num += (true_high_block_num - low_block_num + 2) / 2; low_block_num += (true_high_block_num - low_block_num + 2) / 2;
} while (low_block_num <= high_block_num); } while (low_block_num <= high_block_num);
// idump((synopsis)); //idump((synopsis));
return synopsis; return synopsis;
} }
FC_CAPTURE_AND_RETHROW() FC_CAPTURE_AND_RETHROW()
@ -764,10 +800,6 @@ public:
FC_CAPTURE_AND_RETHROW((block_id)) 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). * 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() * If we don't know about the block, returns time_point_sec::min()
@ -821,6 +853,10 @@ 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() { application::~application() {
if (my->_p2p_network) { if (my->_p2p_network) {
my->_p2p_network->close(); my->_p2p_network->close();
@ -833,24 +869,9 @@ application::~application() {
void application::set_program_options(boost::program_options::options_description &cli, void application::set_program_options(boost::program_options::options_description &cli,
boost::program_options::options_description &cfg) const { 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()("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-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()("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-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"); 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,7 +938,6 @@ void application::initialize(const fc::path &data_dir, const boost::program_opti
wanted.insert("accounts_list"); wanted.insert("accounts_list");
wanted.insert("affiliate_stats"); 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"); wanted.insert("bookie");
@ -950,7 +970,7 @@ void application::startup() {
} }
std::shared_ptr<abstract_plugin> application::get_plugin(const string &name) const { 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 { bool application::is_plugin_enabled(const string &name) const {
@ -997,7 +1017,6 @@ void application::shutdown_plugins() {
return; return;
} }
void application::shutdown() { void application::shutdown() {
my->_running.store(false);
if (my->_p2p_network) if (my->_p2p_network)
my->_p2p_network->close(); my->_p2p_network->close();
if (my->_chain_db) 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) { bpo::variables_map &options) {
deduplicator dedup; deduplicator dedup;
bpo::options_description unique_options("Graphene Witness Node"); 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); const boost::shared_ptr<bpo::option_description> od = dedup.next(opt);
if (!od) if (!od)
continue; 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); deduplicator dedup(modify_option_defaults);
std::ofstream out_cfg(config_ini_path.preferred_string()); std::ofstream out_cfg(config_ini_path.preferred_string());
std::string plugin_header_surrounding(78, '='); std::string plugin_header_surrounding( 78, '=' );
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); const boost::shared_ptr<bpo::option_description> od = dedup.next(opt);
if (!od) if (!od)
continue; continue;

View file

@ -23,13 +23,14 @@
*/ */
#include <graphene/app/database_api.hpp> #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> #include <fc/bloom_filter.hpp>
@ -37,7 +38,6 @@
#include <fc/rpc/api_connection.hpp> #include <fc/rpc/api_connection.hpp>
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <boost/rational.hpp> #include <boost/rational.hpp>
@ -55,33 +55,30 @@ template class fc::api<graphene::app::database_api>;
namespace graphene { namespace app { namespace graphene { namespace app {
template <class T> template<class T>
optional<T> maybe_id(const string &name_or_id) { optional<T> maybe_id( const string& name_or_id )
if (std::isdigit(name_or_id.front())) { {
try { if( std::isdigit( name_or_id.front() ) )
{
try
{
return fc::variant(name_or_id, 1).as<T>(1); 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>(); return optional<T>();
} }
std::string object_id_to_string(object_id_type id) { 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 = fc::to_string(id.space())
+ "." + fc::to_string(id.type())
+ "." + fc::to_string(id.instance());
return object_id; 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> { class database_api_impl : public std::enable_shared_from_this<database_api_impl> {
public: public:
database_api_impl(graphene::chain::database &db); database_api_impl(graphene::chain::database &db);
@ -100,12 +97,10 @@ public:
optional<block_header> get_block_header(uint32_t block_num) const; 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; 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> 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; 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; processed_transaction get_transaction(uint32_t block_num, uint32_t trx_in_block) const;
// Globals // Globals
version_info get_version_info() const;
chain_property_object get_chain_properties() const; chain_property_object get_chain_properties() const;
global_property_object get_global_properties() const; global_property_object get_global_properties() const;
fc::variant_object get_config() 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; 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; map<string, son_id_type> lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const;
uint64_t get_son_count() 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 // SON wallets
optional<son_wallet_object> get_active_son_wallet(); optional<son_wallet_object> get_active_son_wallet();
@ -223,16 +214,17 @@ public:
// Votes // Votes
vector<variant> lookup_vote_ids(const vector<vote_id_type> &votes) const; 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; vector<vote_id_type> get_votes_ids(const string &account_name_or_id) const;
template <typename IndexType, typename Tag> template<typename IndexType, typename Tag>
vector<variant> get_votes_objects(const vector<vote_id_type> &votes, unsigned int variant_max_depth = 1) const { 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"); {
static_assert( std::is_base_of<index,IndexType>::value, "Type must be an index type" );
vector<variant> result; vector<variant> result;
const auto &idx = _db.get_index_type<IndexType>().indices().template get<Tag>(); const auto &idx = _db.get_index_type<IndexType>().indices().template get<Tag>();
for (auto id : votes) { for (auto id : votes) {
auto itr = idx.find(id); auto itr = idx.find(id);
if (itr != idx.end()) if (itr != idx.end())
result.emplace_back(variant(*itr, variant_max_depth)); result.emplace_back(variant(*itr,variant_max_depth));
} }
return result; return result;
} }
@ -253,6 +245,9 @@ public:
// Proposed transactions // Proposed transactions
vector<proposal_object> get_proposed_transactions(const std::string account_id_or_name) const; 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 // Tournaments
vector<tournament_object> get_tournaments_in_state(tournament_state state, uint32_t limit) const; 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); 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; 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_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; 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_all_tokens() 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_object> nft_get_tokens_by_owner(const account_id_type owner) 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;
// Marketplace // Marketplace
vector<offer_object> list_offers(const offer_id_type lower_id, uint32_t limit) const; 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_limit_orders_by_account = 101;
uint32_t api_limit_get_order_book = 50; uint32_t api_limit_get_order_book = 50;
uint32_t api_limit_all_offers_count = 100; 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_accounts = 1000;
uint32_t api_limit_lookup_witness_accounts = 1000; uint32_t api_limit_lookup_witness_accounts = 1000;
uint32_t api_limit_lookup_committee_member_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 = 100;
uint32_t api_limit_get_trade_history_by_sequence = 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, const account_object *get_account_from_string(const std::string &name_or_id,
bool throw_if_not_found = true) const; bool throw_if_not_found = true) const;
const asset_object *get_asset_from_string(const std::string &symbol_or_id, 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 { fc::variants database_api_impl::get_objects(const vector<object_id_type> &ids) const {
if (_subscribe_callback) { if (_subscribe_callback) {
for (auto id : ids) { 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; 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; continue;
this->subscribe_to_item(id); 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) { 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; _subscribe_callback = cb;
_notify_remove_create = notify_remove_create; _notify_remove_create = notify_remove_create;
_subscribed_accounts.clear(); _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); 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 { 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); 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 { chain_property_object database_api::get_chain_properties() const {
return my->get_chain_properties(); 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(); 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 // // 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 &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 &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 &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_idx = _db.get_index_type<son_index>().indices().get<by_vote_id>();
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>();
vector<variant> result; vector<variant> result;
result.reserve(votes.size()); 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: { case vote_id_type::committee: {
auto itr = committee_idx.find(id); auto itr = committee_idx.find(id);
if (itr != committee_idx.end()) 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 else
result.emplace_back(variant()); result.emplace_back(variant());
break; break;
@ -2205,7 +2090,7 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
case vote_id_type::witness: { case vote_id_type::witness: {
auto itr = witness_idx.find(id); auto itr = witness_idx.find(id);
if (itr != witness_idx.end()) 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 else
result.emplace_back(variant()); result.emplace_back(variant());
break; break;
@ -2213,45 +2098,26 @@ vector<variant> database_api_impl::lookup_vote_ids(const vector<vote_id_type> &v
case vote_id_type::worker: { case vote_id_type::worker: {
auto itr = for_worker_idx.find(id); auto itr = for_worker_idx.find(id);
if (itr != for_worker_idx.end()) { if (itr != for_worker_idx.end()) {
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe. result.emplace_back(variant(*itr, 1));
// If we want to extract the balance object inside,
// need to increase this value
} else { } else {
auto itr = against_worker_idx.find(id); auto itr = against_worker_idx.find(id);
if (itr != against_worker_idx.end()) { if (itr != against_worker_idx.end()) {
result.emplace_back(variant(*itr, 4)); // Depth of worker_object is 3, add 1 here to be safe. result.emplace_back(variant(*itr, 1));
// If we want to extract the balance object inside,
// need to increase this value
} else { } else {
result.emplace_back(variant()); result.emplace_back(variant());
} }
} }
break; break;
} }
case vote_id_type::son_bitcoin: { case vote_id_type::son: {
auto itr = son_bictoin_idx.find(id); auto itr = son_idx.find(id);
if (itr != son_bictoin_idx.end()) if (itr != son_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())
result.emplace_back(variant(*itr, 5)); result.emplace_back(variant(*itr, 5));
else else
result.emplace_back(variant()); result.emplace_back(variant());
break; break;
} }
case vote_id_type::VOTE_TYPE_COUNT: case vote_id_type::VOTE_TYPE_COUNT:
break; // supress unused enum value warnings break; // supress unused enum value warnings
default: 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); const account_object *account = get_account_from_string(account_name_or_id);
//! Iterate throug votes and fill vector //! Iterate throug votes and fill vector
for (const auto &vote : account->options.votes) { for( const auto& vote : account->options.votes )
{
result.emplace_back(vote); 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 database_api_impl::get_votes(const string &account_name_or_id) const {
votes_info result; votes_info result;
const auto votes_ids = get_votes_ids(account_name_or_id); 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& 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& 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& 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& against_worker_ids = get_votes_objects<worker_index, by_vote_against>(votes_ids);
const auto son_ids = [this, &votes_ids]() { const auto& son_ids = get_votes_objects<son_index, by_vote_id>(votes_ids, 5);
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;
}();
//! Fill votes info //! Fill votes info
if (!committee_ids.empty()) { if(!committee_ids.empty()) {
vector<votes_info_object> votes_for_committee_members; vector< votes_info_object<committee_member_id_type> > votes_for_committee_members;
votes_for_committee_members.reserve(committee_ids.size()); votes_for_committee_members.reserve(committee_ids.size());
for (const auto &committee : committee_ids) { for (const auto &committee : committee_ids) {
const auto &committee_obj = committee.as<committee_member_object>(2); 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); result.votes_for_committee_members = std::move(votes_for_committee_members);
} }
if (!witness_ids.empty()) { if(!witness_ids.empty()) {
vector<votes_info_object> votes_for_witnesses; vector< votes_info_object<witness_id_type> > votes_for_witnesses;
votes_for_witnesses.reserve(witness_ids.size()); votes_for_witnesses.reserve(witness_ids.size());
for (const auto &witness : witness_ids) { for (const auto &witness : witness_ids) {
const auto &witness_obj = witness.as<witness_object>(2); 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); result.votes_for_witnesses = std::move(votes_for_witnesses);
} }
if (!for_worker_ids.empty()) { if(!for_worker_ids.empty()) {
vector<votes_info_object> votes_for_workers; vector< votes_info_object<worker_id_type> > votes_for_workers;
votes_for_workers.reserve(for_worker_ids.size()); votes_for_workers.reserve(for_worker_ids.size());
for (const auto &for_worker : for_worker_ids) { for (const auto &for_worker : for_worker_ids) {
const auto &for_worker_obj = for_worker.as<worker_object>(2); 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); result.votes_for_workers = std::move(votes_for_workers);
} }
if (!against_worker_ids.empty()) { if(!against_worker_ids.empty()) {
vector<votes_info_object> votes_against_workers; vector< votes_info_object<worker_id_type> > votes_against_workers;
votes_against_workers.reserve(against_worker_ids.size()); votes_against_workers.reserve(against_worker_ids.size());
for (const auto &against_worker : against_worker_ids) { for (const auto &against_worker : against_worker_ids) {
const auto &against_worker_obj = against_worker.as<worker_object>(2); 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); result.votes_against_workers = std::move(votes_against_workers);
} }
if (!son_ids.empty()) { if(!son_ids.empty()) {
flat_map<sidechain_type, vector<votes_info_object>> votes_for_sons; vector< votes_info_object<son_id_type> > votes_for_sons;
for (const auto &son_sidechain_ids : son_ids) { votes_for_sons.reserve(son_ids.size());
const auto &sidechain = son_sidechain_ids.first; for (const auto &son : son_ids) {
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); const auto &son_obj = son.as<son_object>(6);
if (son_obj.get_sidechain_vote_id(sidechain).valid()) { votes_for_sons.emplace_back(votes_info_object<son_id_type>{son_obj.vote_id, son_obj.id.instance()});
votes_for_sons[sidechain].emplace_back(votes_info_object{*son_obj.get_sidechain_vote_id(sidechain), son_obj.id});
}
}
} }
result.votes_for_sons = std::move(votes_for_sons); 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; vector<account_object> result;
//! We search all accounts that have voted for this vote_id //! 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>(); const auto& account_index = _db.get_index_type<graphene::chain::account_index>().indices().get<by_id>();
for (const auto &account : account_index) { for( const auto& account: account_index )
if (account.options.votes.count(vote_id) != 0) {
if(account.options.votes.count(vote_id) != 0)
result.emplace_back(account); 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; std::string owner_account_id;
//! Check if we have account by name //! Check if we have account by name
const auto &account_object = get_account_by_name(account_name_or_id); const auto& account_object = get_account_by_name(account_name_or_id);
if (account_object) { if(account_object) {
//! It is account //! 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; owner_account_found = true;
} else { }
else {
//! Check if we have account id //! Check if we have account id
const auto &account_id = maybe_id<account_id_type>(account_name_or_id); const auto& account_id = maybe_id<account_id_type>(account_name_or_id);
if (account_id) { if(account_id) {
//! It may be account id //! It may be account id
const auto &account_objects = get_accounts({account_name_or_id}); const auto& account_objects = get_accounts({account_name_or_id});
if (!account_objects.empty()) { if(!account_objects.empty()){
const auto &account_object = account_objects.front(); const auto& account_object = account_objects.front();
if (account_object) { if(account_object) {
//! It is 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; owner_account_found = true;
} }
} }
} else { }
else {
//! Check if we have committee member id //! Check if we have committee member id
const auto &committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id); const auto& committee_member_id = maybe_id<committee_member_id_type>(account_name_or_id);
if (committee_member_id) { if(committee_member_id) {
//! It may be committee member id //! It may be committee member id
const auto &committee_member_objects = get_committee_members({*committee_member_id}); const auto& committee_member_objects = get_committee_members({*committee_member_id});
if (!committee_member_objects.empty()) { if(!committee_member_objects.empty()){
const auto &committee_member_object = committee_member_objects.front(); const auto& committee_member_object = committee_member_objects.front();
if (committee_member_object) { if(committee_member_object) {
//! It is 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; owner_account_found = true;
} }
} }
} else { }
else {
//! Check if we have witness id //! Check if we have witness id
const auto &witness_id = maybe_id<witness_id_type>(account_name_or_id); const auto& witness_id = maybe_id<witness_id_type>(account_name_or_id);
if (witness_id) { if(witness_id) {
//! It may be witness id //! It may be witness id
const auto &witness_objects = get_witnesses({*witness_id}); const auto& witness_objects = get_witnesses({*witness_id});
if (!witness_objects.empty()) { if(!witness_objects.empty()){
const auto &witness_object = witness_objects.front(); const auto& witness_object = witness_objects.front();
if (witness_object) { if(witness_object) {
//! It is 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; owner_account_found = true;
} }
} }
} else { }
else {
//! Check if we have worker id //! Check if we have worker id
const auto &worker_id = maybe_id<worker_id_type>(account_name_or_id); const auto& worker_id = maybe_id<worker_id_type>(account_name_or_id);
if (worker_id) { if(worker_id) {
//! It may be worker id //! It may be worker id
const auto &worker_objects = get_workers({*worker_id}); const auto& worker_objects = get_workers({*worker_id});
if (!worker_objects.empty()) { if(!worker_objects.empty()){
const auto &worker_object = worker_objects.front(); const auto& worker_object = worker_objects.front();
if (worker_object) { if(worker_object) {
//! It is 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; owner_account_found = true;
} }
} }
} else { }
else {
//! Check if we have son id //! Check if we have son id
const auto &son_id = maybe_id<son_id_type>(account_name_or_id); const auto& son_id = maybe_id<son_id_type>(account_name_or_id);
if (son_id) { if(son_id) {
//! It may be son id //! It may be son id
const auto &son_objects = get_sons({*son_id}); const auto& son_objects = get_sons({*son_id});
if (!son_objects.empty()) { if(!son_objects.empty()){
const auto &son_object = son_objects.front(); const auto& son_object = son_objects.front();
if (son_object) { if(son_object) {
//! It is 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; 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 //! 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)); 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 //! Fill voters_info
const auto &committee_member_object = get_committee_member_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& witness_object = get_witness_by_account(owner_account_id);
const auto &worker_objects = get_workers_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& son_object = get_son_by_account(owner_account_id);
//! Info for committee member voters //! Info for committee member voters
if (committee_member_object) { if(committee_member_object) {
const auto &committee_member_voters = get_voters_by_id(committee_member_object->vote_id); const auto& committee_member_voters = get_voters_by_id(committee_member_object->vote_id);
voters_info_object voters_for_committee_member; voters_info_object voters_for_committee_member;
voters_for_committee_member.vote_id = committee_member_object->vote_id; voters_for_committee_member.vote_id = committee_member_object->vote_id;
voters_for_committee_member.voters.reserve(committee_member_voters.size()); 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()); voters_for_committee_member.voters.emplace_back(voter.get_id());
} }
result.voters_for_committee_member = std::move(voters_for_committee_member); result.voters_for_committee_member = std::move(voters_for_committee_member);
} }
//! Info for witness voters //! Info for witness voters
if (witness_object) { if(witness_object) {
const auto &witness_voters = get_voters_by_id(witness_object->vote_id); const auto& witness_voters = get_voters_by_id(witness_object->vote_id);
voters_info_object voters_for_witness; voters_info_object voters_for_witness;
voters_for_witness.vote_id = witness_object->vote_id; voters_for_witness.vote_id = witness_object->vote_id;
voters_for_witness.voters.reserve(witness_voters.size()); 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()); voters_for_witness.voters.emplace_back(voter.get_id());
} }
result.voters_for_witness = std::move(voters_for_witness); result.voters_for_witness = std::move(voters_for_witness);
} }
//! Info for worker voters //! 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_for_workers(worker_objects.size());
vector<voters_info_object> voters_against_workers(worker_objects.size()); vector<voters_info_object> voters_against_workers(worker_objects.size());
for (const auto &worker_object : worker_objects) { 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 //! Info for son voters
if (son_object) { if(son_object) {
flat_map<sidechain_type, voters_info_object> voters_for_son; const auto& son_voters = get_voters_by_id(son_object->vote_id);
for (const auto &vote_id : son_object->sidechain_vote_ids) { voters_info_object voters_for_son;
const auto &son_voters = get_voters_by_id(vote_id.second); voters_for_son.vote_id = son_object->vote_id;
voters_info_object voters_for_sidechain_son; voters_for_son.voters.reserve(son_voters.size());
voters_for_sidechain_son.vote_id = vote_id.second; for(const auto& voter: son_voters) {
voters_for_sidechain_son.voters.reserve(son_voters.size()); voters_for_son.voters.emplace_back(voter.get_id());
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);
} }
result.voters_for_son = std::move(voters_for_son); 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; 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 // // 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 { 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; gpos_info result;
result.vesting_factor = _db.calculate_vesting_factor(account(_db)); 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; 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); 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, 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()) if (balance.balance.amount > 0 && balance.balance_type == vesting_balance_type::gpos && balance.balance.asset_id == asset_id_type())
account_vbos.emplace_back(balance); 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 { 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>(); const auto &idx_nft_md = _db.get_index_type<nft_metadata_index>().indices().get<by_id>();
return idx_nft.count(nft_metadata_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 { 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 {}; return {};
} }
vector<nft_object> database_api::nft_get_all_tokens(const nft_id_type lower_id, uint32_t limit) const { vector<nft_object> database_api::nft_get_all_tokens() const {
return my->nft_get_all_tokens(lower_id, limit); 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 { vector<nft_object> database_api_impl::nft_get_all_tokens() 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));
const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_id>(); const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_id>();
vector<nft_object> result; vector<nft_object> result;
result.reserve(limit); for (auto itr = idx_nft.begin(); itr != idx_nft.end(); ++itr) {
auto itr = idx_nft.lower_bound(lower_id); result.push_back(*itr);
while (limit-- && itr != idx_nft.end()) }
result.emplace_back(*itr++);
return result; 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 { vector<nft_object> database_api::nft_get_tokens_by_owner(const account_id_type owner) const {
return my->nft_get_tokens_by_owner(owner, lower_id, limit); 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 { vector<nft_object> database_api_impl::nft_get_tokens_by_owner(const account_id_type owner) 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));
const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_owner>(); const auto &idx_nft = _db.get_index_type<nft_index>().indices().get<by_owner>();
auto idx_nft_range = idx_nft.equal_range(owner); auto idx_nft_range = idx_nft.equal_range(owner);
vector<nft_object> result; vector<nft_object> result;
result.reserve(limit); for (auto itr = idx_nft_range.first; itr != idx_nft_range.second; ++itr) {
auto itr = std::find_if(idx_nft_range.first, idx_nft_range.second, [&lower_id](const nft_object &obj) { result.push_back(*itr);
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++);
return result; return result;
} }
@ -3554,8 +3396,8 @@ 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. /// 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 /// if a connection hangs then this could get backed up and result in
/// a failure to exit cleanly. /// a failure to exit cleanly.
// fc::async([capture_this,this,updates,market_broadcast_queue](){ //fc::async([capture_this,this,updates,market_broadcast_queue](){
// if( _subscribe_callback ) //if( _subscribe_callback )
// _subscribe_callback( updates ); // _subscribe_callback( updates );
for (auto id : ids) { for (auto id : ids) {

View file

@ -25,18 +25,19 @@
#include <graphene/app/database_api.hpp> #include <graphene/app/database_api.hpp>
#include <graphene/chain/protocol/confidential.hpp> #include <graphene/protocol/types.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/confidential.hpp>
#include <graphene/net/node.hpp>
#include <graphene/accounts_list/accounts_list_plugin.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/affiliate_stats/affiliate_stats_api.hpp>
#include <graphene/bookie/bookie_api.hpp> #include <graphene/bookie/bookie_api.hpp>
#include <graphene/debug_witness/debug_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/net/node.hpp>
#include <graphene/peerplays_sidechain/sidechain_api.hpp>
#include <fc/api.hpp> #include <fc/api.hpp>
#include <fc/crypto/elliptic.hpp> #include <fc/crypto/elliptic.hpp>
@ -289,6 +290,33 @@ private:
std::function<void(const variant &)> _on_pending_transaction; 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
*/ */
@ -332,6 +360,7 @@ 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_broadcast_api>;
extern template class fc::api<graphene::app::network_node_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::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::app::asset_api>;
extern template class fc::api<graphene::debug_witness::debug_api>; extern template class fc::api<graphene::debug_witness::debug_api>;
@ -366,6 +395,8 @@ public:
fc::api<history_api> history() const; fc::api<history_api> history() const;
/// @brief Retrieve the network node API /// @brief Retrieve the network node API
fc::api<network_node_api> network_node() const; fc::api<network_node_api> network_node() const;
/// @brief Retrieve the cryptography API
fc::api<crypto_api> crypto() const;
/// @brief Retrieve the asset API /// @brief Retrieve the asset API
fc::api<asset_api> asset() const; fc::api<asset_api> asset() const;
/// @brief Retrieve the debug API (if available) /// @brief Retrieve the debug API (if available)
@ -374,8 +405,6 @@ public:
fc::api<graphene::bookie::bookie_api> bookie() const; fc::api<graphene::bookie::bookie_api> bookie() const;
/// @brief Retrieve the affiliate_stats API (if available) /// @brief Retrieve the affiliate_stats API (if available)
fc::api<graphene::affiliate_stats::affiliate_stats_api> affiliate_stats() const; 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. /// @brief Called to enable an API, not reflected.
void enable_api(const string &api_name); 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_broadcast_api>> _network_broadcast_api;
optional<fc::api<network_node_api>> _network_node_api; optional<fc::api<network_node_api>> _network_node_api;
optional<fc::api<history_api>> _history_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<asset_api>> _asset_api;
optional<fc::api<graphene::debug_witness::debug_api>> _debug_api; optional<fc::api<graphene::debug_witness::debug_api>> _debug_api;
optional<fc::api<graphene::bookie::bookie_api>> _bookie_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::affiliate_stats::affiliate_stats_api>> _affiliate_stats_api;
optional<fc::api<graphene::peerplays_sidechain::sidechain_api>> _sidechain_api;
}; };
}} // namespace graphene::app }} // namespace graphene::app
@ -444,6 +473,15 @@ FC_API(graphene::app::network_node_api,
(subscribe_to_pending_transactions) (subscribe_to_pending_transactions)
(unsubscribe_from_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, FC_API(graphene::app::asset_api,
(get_asset_holders) (get_asset_holders)
(get_asset_holders_count) (get_asset_holders_count)
@ -456,10 +494,10 @@ FC_API(graphene::app::login_api,
(database) (database)
(history) (history)
(network_node) (network_node)
(crypto)
(asset) (asset)
(debug) (debug)
(bookie) (bookie)
(affiliate_stats) (affiliate_stats))
(sidechain))
// clang-format on // clang-format on

View file

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

View file

@ -25,7 +25,7 @@
#include <graphene/app/full_account.hpp> #include <graphene/app/full_account.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/types.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
@ -56,8 +56,8 @@
#include <graphene/chain/custom_permission_object.hpp> #include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/nft_object.hpp> #include <graphene/chain/nft_object.hpp>
#include <graphene/chain/offer_object.hpp> #include <graphene/chain/offer_object.hpp>
#include <graphene/chain/voters_info.hpp>
#include <graphene/chain/votes_info.hpp> #include <graphene/chain/votes_info.hpp>
#include <graphene/chain/voters_info.hpp>
#include <graphene/market_history/market_history_plugin.hpp> #include <graphene/market_history/market_history_plugin.hpp>
@ -82,15 +82,6 @@ using namespace std;
class database_api_impl; 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 { struct order {
double price; double price;
double quote; double quote;
@ -139,14 +130,6 @@ struct gpos_info {
share_type account_vested_balance; 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. * @brief The database_api class implements the RPC API for the chain database.
* *
@ -211,13 +194,6 @@ public:
*/ */
optional<signed_block> get_block(uint32_t block_num) const; 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 * @brief Retrieve a list of signed blocks
* @param block_num_from start * @param block_num_from start
@ -242,11 +218,6 @@ public:
// Globals // // 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 * @brief Retrieve the @ref chain_property_object associated with the chain
*/ */
@ -691,32 +662,6 @@ public:
*/ */
uint64_t get_son_count() const; 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 // // SON Wallets //
///////////////////////// /////////////////////////
@ -919,6 +864,15 @@ public:
*/ */
vector<proposal_object> get_proposed_transactions(const std::string account_id_or_name) const; 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 // // Tournaments //
///////////////// /////////////////
@ -1043,25 +997,14 @@ public:
* @brief Returns list of all available NTF's * @brief Returns list of all available NTF's
* @return List of all available NFT'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 * @brief Returns NFT's owned by owner
* @param owner NFT 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 * @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; vector<nft_object> nft_get_tokens_by_owner(const account_id_type owner) 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;
////////////////// //////////////////
// MARKET PLACE // // MARKET PLACE //
@ -1091,15 +1034,12 @@ extern template class fc::api<graphene::app::database_api>;
// clang-format off // 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, (price)(quote)(base));
FC_REFLECT(graphene::app::order_book, (base)(quote)(bids)(asks)); 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_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_volume, (base)(quote)(base_volume)(quote_volume));
FC_REFLECT(graphene::app::market_trade, (date)(price)(amount)(value)); 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::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, FC_API(graphene::app::database_api,
// Objects // Objects
@ -1115,13 +1055,11 @@ FC_API(graphene::app::database_api,
(get_block_header) (get_block_header)
(get_block_header_batch) (get_block_header_batch)
(get_block) (get_block)
(get_block2)
(get_blocks) (get_blocks)
(get_transaction) (get_transaction)
(get_recent_transaction_by_id) (get_recent_transaction_by_id)
// Globals // Globals
(get_version_info)
(get_chain_properties) (get_chain_properties)
(get_global_properties) (get_global_properties)
(get_config) (get_config)
@ -1205,10 +1143,6 @@ FC_API(graphene::app::database_api,
(get_son_by_account) (get_son_by_account)
(lookup_son_accounts) (lookup_son_accounts)
(get_son_count) (get_son_count)
(get_active_sons)
(get_active_sons_by_sidechain)
(get_son_network_status)
(get_son_network_status_by_sidechain)
// SON wallets // SON wallets
(get_active_son_wallet) (get_active_son_wallet)
@ -1249,6 +1183,9 @@ FC_API(graphene::app::database_api,
// Proposed transactions // Proposed transactions
(get_proposed_transactions) (get_proposed_transactions)
// Blinded balances
(get_blinded_balances)
// Tournaments // Tournaments
(get_tournaments_in_state) (get_tournaments_in_state)
(get_tournaments_by_state) (get_tournaments_by_state)
@ -1279,7 +1216,6 @@ FC_API(graphene::app::database_api,
(nft_token_of_owner_by_index) (nft_token_of_owner_by_index)
(nft_get_all_tokens) (nft_get_all_tokens)
(nft_get_tokens_by_owner) (nft_get_tokens_by_owner)
(nft_get_metadata_by_owner)
// Marketplace // Marketplace
(list_offers) (list_offers)

View file

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

View file

@ -23,7 +23,7 @@
*/ */
#include <graphene/app/plugin.hpp> #include <graphene/app/plugin.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace app { 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 ) add_dependencies( build_hardfork_hpp cat-parts )
file(GLOB HEADERS "include/graphene/chain/*.hpp") 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 CPP_FILES "*.cpp")
file(GLOB PROTOCOL_CPP_FILES "protocol/*.cpp")
#if( GRAPHENE_DISABLE_UNITY_BUILD ) #if( GRAPHENE_DISABLE_UNITY_BUILD )
list(FILTER CPP_FILES EXCLUDE REGEX "[/]database[.]cpp$") list(FILTER CPP_FILES EXCLUDE REGEX "[/]database[.]cpp$")
#message ("--- ${CPP_FILES}") #message ("--- ${CPP_FILES}")
message( STATUS "Graphene database unity build disabled" ) message( STATUS "Graphene database unity build disabled" )
#else( GRAPHENE_DISABLE_UNITY_BUILD ) #else( GRAPHENE_DISABLE_UNITY_BUILD )
# list(FILTER CPP_FILES EXCLUDE REGEX ".*db_.*[.]cpp$") # set( GRAPHENE_DB_FILES
# #message ("--- ${CPP_FILES}") # database.cpp )
# message( STATUS "Graphene database unity build enabled" ) # message( STATUS "Graphene database unity build enabled" )
#endif( GRAPHENE_DISABLE_UNITY_BUILD ) #endif( GRAPHENE_DISABLE_UNITY_BUILD )
add_library( graphene_chain set( GRAPHENE_CHAIN_FILES
${CPP_FILES} ${CPP_FILES}
${PROTOCOL_CPP_FILES}
${HEADERS} ${HEADERS}
${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" "${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 ) 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 target_include_directories( graphene_chain
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" ) PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )
@ -46,4 +48,3 @@ INSTALL( TARGETS
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib
) )
INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/chain" ) 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. void verify_account_votes( const database& db, const account_options& options )
// 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 = {} )
{ {
// ensure account's votes satisfy requirements // ensure account's votes satisfy requirements
// NB only the part of vote checking that requires chain state is here, // 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& gpo = db.get_global_properties();
const auto& chain_params = gpo.parameters; 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, FC_ASSERT( options.num_witness <= chain_params.maximum_witness_count,
"Voted for more witnesses than currently allowed (${c})", ("c", 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, 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) ); "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." ); FC_ASSERT( db.find_object(options.voting_account), "Invalid proxy account specified." );
uint32_t max_vote_id = gpo.next_available_vote_id; 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.owner = o.owner;
obj.active = o.active; obj.active = o.active;
obj.options = o.options; 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){ obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
s.owner = obj.id; s.owner = obj.id;
s.name = obj.name; 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 if( dynamic_properties.accounts_registered_this_interval % global_properties.parameters.accounts_per_fee_scale == 0
&& global_properties.parameters.account_fee_scale_bitshifts != 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; 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); acnt = &o.account(d);
if( o.new_options.valid() ) if( o.new_options.valid() )
verify_account_votes( d, *o.new_options, *acnt ); verify_account_votes( d, *o.new_options );
return void_result(); return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) } } 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.active = *o.active;
a.top_n_control_flags = 0; a.top_n_control_flags = 0;
} }
if( o.new_options ) a.options = *o.new_options;
// 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.extensions.value.owner_special_authority.valid() ) if( o.extensions.value.owner_special_authority.valid() )
{ {
a.owner_special_authority = *(o.extensions.value.owner_special_authority); 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 ) if( p == GRAPHENE_100_PERCENT )
return a; return a;
fc::uint128 r(a.value); fc::uint128_t r = a.value;
r *= p; r *= p;
r /= GRAPHENE_100_PERCENT; r /= GRAPHENE_100_PERCENT;
return r.to_uint64(); return r;
} }
void account_balance_object::adjust_balance(const asset& delta) 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; 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 assert( dynamic_cast<const account_object*>(&obj) ); // for debug only
const account_object& a = static_cast<const account_object&>(obj); 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 ) 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 uint8_t balances_by_account_index::bits = 20;
const uint64_t balances_by_account_index::mask = (1ULL << balances_by_account_index::bits) - 1; 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 ); const auto& abo = dynamic_cast< const account_balance_object& >( obj );
while( balances.size() < (abo.owner.instance.value >> bits) + 1 ) 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) ); //ilog("Paying ${p} of ${P} for ${s} of ${r}", ("p",payout.to_uint64())("P",to_pay.value)("s",share)("r",remaining) );
remaining -= share; remaining -= share;
} }
FC_ASSERT( payout.to_uint64() <= to_pay ); FC_ASSERT( payout <= to_pay );
if( payout > 0 ) if( payout > 0 )
{ {
if ( accumulator.find(affiliate) == accumulator.end() ) if ( accumulator.find(affiliate) == accumulator.end() )
accumulator[affiliate] = payout.to_uint64(); accumulator[affiliate] = payout;
else else
accumulator[affiliate] += payout.to_uint64(); accumulator[affiliate] += payout;
to_pay -= payout.to_uint64(); to_pay -= payout;
paid += payout.to_uint64(); paid += payout;
} }
} }
FC_ASSERT( to_pay == 0 ); 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; fee_is_odd = core_fee_paid.value & 1;
core_fee_paid -= core_fee_paid.value/2; 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 ) 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; fee_is_odd = core_fee_paid.value & 1;
core_fee_paid -= core_fee_paid.value/2; 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 ) 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 ) if( options.maximum_force_settlement_volume == GRAPHENE_100_PERCENT )
return current_supply + force_settled_volume; 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 *= options.maximum_force_settlement_volume;
volume /= GRAPHENE_100_PERCENT; volume /= GRAPHENE_100_PERCENT;
return volume.to_uint64(); return volume;
} }
void asset_bitasset_data_object::update_median_feeds(time_point_sec current_time) void asset_bitasset_data_object::update_median_feeds(time_point_sec current_time)

View file

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

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 - 1;
amount_to_match_128 /= backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION; 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 share_type bet_object::get_approximate_matching_amount(bool round_up /* = false */) const
@ -493,3 +493,4 @@ namespace fc {
const_cast<int*>(event_obj.my->state_machine.current_state())[0] = (int)status; const_cast<int*>(event_obj.my->state_machine.current_state())[0] = (int)status;
} }
} //end namespace fc } //end namespace fc

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,6 +29,8 @@
#include <graphene/chain/betting_market_object.hpp> #include <graphene/chain/betting_market_object.hpp>
#include <graphene/chain/event_object.hpp> #include <graphene/chain/event_object.hpp>
#include <fc/log/logger.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <boost/range/combine.hpp> #include <boost/range/combine.hpp>
#include <boost/range/join.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; bool group_was_canceled = resolutions.begin()->second == betting_market_resolution_type::cancel;
if (group_was_canceled) 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 betting_market_group_obj.on_canceled_event(*this, false); // this cancels the betting markets
}); });
else { 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); 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; share_type rake_amount;
if (net_profits.value > 0 && rake_account_id) 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; share_type affiliates_share;
if (rake_amount.value) if (rake_amount.value)
affiliates_share = payout_helper.payout( bettor_id, rake_amount ); 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 += taker_amount_to_match.value;
payout_128 *= GRAPHENE_BETTING_ODDS_PRECISION; 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; 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 #endif

View file

@ -26,24 +26,23 @@
#include <graphene/chain/db_with.hpp> #include <graphene/chain/db_with.hpp>
#include <graphene/chain/hardfork.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/block_summary_object.hpp>
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/operation_history_object.hpp> #include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/proposal_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/witness_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/exceptions.hpp> #include <graphene/chain/exceptions.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/witness_schedule_object.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 { namespace {
@ -162,14 +161,11 @@ void database::check_transaction_for_duplicated_operations(const signed_transact
existed_operations_digests.insert( proposed_operations_digests.begin(), proposed_operations_digests.end() ); 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); auto proposed_operations_digests = gather_proposed_operations_digests(pending_transaction);
existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end()); existed_operations_digests.insert(proposed_operations_digests.begin(), proposed_operations_digests.end());
} }
}
auto proposed_operations_digests = gather_proposed_operations_digests(trx); auto proposed_operations_digests = gather_proposed_operations_digests(trx);
for (auto& digest: proposed_operations_digests) for (auto& digest: proposed_operations_digests)
@ -190,12 +186,7 @@ bool database::push_block(const signed_block& new_block, uint32_t skip)
bool result; bool result;
detail::with_skip_flags( *this, skip, [&]() detail::with_skip_flags( *this, skip, [&]()
{ {
std::vector<processed_transaction> pending_tx = [this] { detail::without_pending_transactions( *this, std::move(_pending_tx),
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),
[&]() [&]()
{ {
result = _push_block(new_block); 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) bool database::_push_block(const signed_block& new_block)
{ try { { 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; uint32_t skip = get_node_properties().skip_flags;
const auto now = fc::time_point::now().sec_since_epoch(); 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 ) 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. // 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. // This allows us to quickly rewind to the clean state of the head block, in case a new block arrives.
{ if( !_pending_tx_session.valid() )
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(); _pending_tx_session = _undo_db.start_undo_session();
}
}
// Create a temporary undo session as a child of _pending_tx_session. // Create a temporary undo session as a child of _pending_tx_session.
// The temporary session will be discarded by the destructor if // The temporary session will be discarded by the destructor if
// _apply_transaction fails. If we make it to merge(), we // _apply_transaction fails. If we make it to merge(), we
// apply the changes. // apply the changes.
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex};
auto temp_session = _undo_db.start_undo_session(); auto temp_session = _undo_db.start_undo_session();
auto processed_trx = _apply_transaction(trx); auto processed_trx = _apply_transaction( trx );
{
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex};
_pending_tx.push_back(processed_trx); _pending_tx.push_back(processed_trx);
}
// notify_changed_objects(); // notify_changed_objects();
// The transaction applied successfully. Merge its changes into the pending block session. // 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 ) 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(); auto session = _undo_db.start_undo_session();
return _apply_transaction( trx ); return _apply_transaction( trx );
} }
processed_transaction database::push_proposal(const proposal_object& proposal) processed_transaction database::push_proposal(const proposal_object& proposal)
{ try { { try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
transaction_evaluation_state eval_state(this); transaction_evaluation_state eval_state(this);
eval_state._is_proposed_trx = true; 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++ ) 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])) );
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));
}
_applied_ops[i].reset(); _applied_ops[i].reset();
} }
} }
@ -484,6 +459,7 @@ signed_block database::generate_block(
uint32_t skip /* = 0 */ uint32_t skip /* = 0 */
) )
{ try { { try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
signed_block result; signed_block result;
detail::with_skip_flags( *this, skip, [&]() 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 // the value of the "when" variable is known, which means we need to
// re-apply pending transactions in this method. // 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.reset();
_pending_tx_session = _undo_db.start_undo_session(); _pending_tx_session = _undo_db.start_undo_session();
}
uint64_t postponed_tx_count = 0; uint64_t postponed_tx_count = 0;
// pop pending state (reset to head block state) // 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}; size_t new_total_size = total_block_size + fc::raw::pack_size( tx );
for (const processed_transaction &tx : _pending_tx) {
size_t new_total_size = total_block_size + fc::raw::pack_size(tx);
// postpone transaction if it would make block too big // postpone transaction if it would make block too big
if (new_total_size >= maximum_block_size) { if( new_total_size >= maximum_block_size )
{
postponed_tx_count++; postponed_tx_count++;
continue; continue;
} }
try { try
{
auto temp_session = _undo_db.start_undo_session(); auto temp_session = _undo_db.start_undo_session();
processed_transaction ptx = _apply_transaction(tx); processed_transaction ptx = _apply_transaction( tx );
temp_session.merge(); temp_session.merge();
// We have to recompute pack_size(ptx) because it may be different // We have to recompute pack_size(ptx) because it may be different
// than pack_size(tx) (i.e. if one or more results increased // than pack_size(tx) (i.e. if one or more results increased
// their size) // their size)
total_block_size += fc::raw::pack_size(ptx); total_block_size += fc::raw::pack_size( ptx );
pending_block.transactions.push_back(ptx); pending_block.transactions.push_back( ptx );
} catch (const fc::exception &e) { }
catch ( const fc::exception& e )
{
// Do nothing, transaction will not be re-applied // Do nothing, transaction will not be re-applied
wlog("Transaction was not processed while generating block due to ${e}", ("e", e)); wlog( "Transaction was not processed while generating block due to ${e}", ("e", e) );
wlog("The transaction was ${t}", ("t", tx)); wlog( "The transaction was ${t}", ("t", tx) );
} }
} }
}
if( postponed_tx_count > 0 ) if( postponed_tx_count > 0 )
{ {
wlog( "Postponed ${n} transactions due to block size limit", ("n", postponed_tx_count) ); 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 // We have temporarily broken the invariant that
// _pending_tx_session is the result of applying _pending_tx, as // _pending_tx_session is the result of applying _pending_tx, as
@ -620,11 +591,8 @@ signed_block database::_generate_block(
*/ */
void database::pop_block() void database::pop_block()
{ try { { try {
{ scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
_pending_tx_session.reset(); _pending_tx_session.reset();
}
auto head_id = head_block_id(); auto head_id = head_block_id();
optional<signed_block> head_block = fetch_block_by_id( head_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" ); 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() void database::clear_pending()
{ try { { try {
const std::lock_guard<std::mutex> pending_tx_lock{_pending_tx_mutex}; scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
const std::lock_guard<std::mutex> pending_tx_session_lock{_pending_tx_session_mutex};
assert( (_pending_tx.size() == 0) || _pending_tx_session.valid() ); assert( (_pending_tx.size() == 0) || _pending_tx_session.valid() );
_pending_tx.clear(); _pending_tx.clear();
_pending_tx_session.reset(); _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 ) void database::set_applied_operation_result( uint32_t op_id, const operation_result& result )
{ {
assert( op_id < _applied_ops.size() ); assert( op_id < _applied_ops.size() );
if( _applied_ops[op_id].valid() ) if( _applied_ops[op_id] )
_applied_ops[op_id]->result = result; _applied_ops[op_id]->result = result;
else 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 ) void database::_apply_block( const signed_block& next_block )
{ try { { try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
uint32_t next_block_num = next_block.block_num(); uint32_t next_block_num = next_block.block_num();
uint32_t skip = get_node_properties().skip_flags; uint32_t skip = get_node_properties().skip_flags;
_applied_ops.clear(); _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) { if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM) {
update_witness_schedule(next_block); update_witness_schedule(next_block);
if(global_props.active_sons.size() > 0) {
for(const auto& active_sons : global_props.active_sons) { update_son_schedule(next_block);
if(!active_sons.second.empty()) {
update_son_schedule(active_sons.first, next_block);
}
} }
} }
@ -776,15 +741,11 @@ void database::_apply_block( const signed_block& next_block )
// TODO: figure out if we could collapse this function into // TODO: figure out if we could collapse this function into
// update_global_dynamic_data() as perhaps these methods only need // update_global_dynamic_data() as perhaps these methods only need
// to be called for header validation? // to be called for header validation?
update_maintenance_flag( maint_needed ); update_maintenance_flag( maint_needed );
if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) { if (global_props.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) {
update_witness_schedule(); update_witness_schedule();
if(global_props.active_sons.size() > 0) {
for(const auto& active_sidechain_type : active_sidechain_types(dynamic_global_props.time)) { update_son_schedule();
if(global_props.active_sons.at(active_sidechain_type).size() > 0) {
update_son_schedule(active_sidechain_type);
}
} }
} }
@ -825,6 +786,7 @@ class undo_size_restorer {
processed_transaction database::_apply_transaction(const signed_transaction& trx) processed_transaction database::_apply_transaction(const signed_transaction& trx)
{ try { { try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
uint32_t skip = get_node_properties().skip_flags; uint32_t skip = get_node_properties().skip_flags;
if( true || !(skip&skip_validate) ) /* issue #505 explains why this skip_flag is disabled */ 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); return get_account_custom_authorities(id, op);
}; };
trx.verify_authority( chain_id, get_active, get_owner, get_custom, 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 ); 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); 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 //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(); 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. //Insert transaction into unique transactions database.
if( !(skip & skip_transaction_dupe_check) ) if( !(skip & skip_transaction_dupe_check) )
{ {
create<transaction_object>([&trx_id,&trx](transaction_object& transaction) { create<transaction_history_object>([&trx](transaction_history_object& transaction) {
transaction.trx_id = trx_id; transaction.trx_id = trx.id();
transaction.trx = trx; 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) operation_result database::apply_operation(transaction_evaluation_state& eval_state, const operation& op)
{ try { { try {
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
int i_which = op.which(); int i_which = op.which();
uint64_t u_which = uint64_t( i_which ); uint64_t u_which = uint64_t( i_which );
FC_ASSERT( i_which >= 0, "Negative operation tag in operation ${op}", ("op",op) ); 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) ); FC_ASSERT( u_which < _consensus_operation_evaluators.size(), "No registered evaluator for operation ${op}", ("op",op) );
unique_ptr<op_evaluator>& eval = _operation_evaluators[ u_which ]; unique_ptr<op_evaluator>& eval = _consensus_operation_evaluators[ u_which ];
FC_ASSERT( eval, "No registered evaluator for operation ${op}", ("op",op) ); FC_ASSERT( eval, "No registered evaluator for operation ${op}", ("op",op) );
auto op_id = push_applied_operation( op ); auto op_id = push_applied_operation( op );
auto result = eval->evaluate( eval_state, op, true ); auto result = eval->evaluate( eval_state, op, true );
set_applied_operation_result( op_id, result ); 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; return result;
} FC_CAPTURE_AND_RETHROW( (op) ) } } 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 ); FC_ASSERT( count_winners <= 64 );
std::string salted_string = std::string(_random_number_generator._seed) + std::to_string(for_asset.instance.value); 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; std::vector<uint32_t> result;
result.reserve(64); result.reserve(64);
for( int s = 0; s < 8; ++s ) { 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 ) { for( int ss = 0; ss < 8; ++ss ) {
result.push_back(sub_seeds[ss]); result.push_back(sub_seeds[ss]);
} }
@ -222,33 +224,19 @@ std::set<son_id_type> database::get_sons_to_be_deregistered()
for( auto& son : son_idx ) for( auto& son : son_idx )
{ {
bool need_to_be_deregistered = true; if(son.status == son_status::in_maintenance)
for(const auto& status : son.statuses)
{ {
const auto& sidechain = status.first; auto& stats = son.statistics(*this);
if(status.second != son_status::in_maintenance)
need_to_be_deregistered = false;
if(need_to_be_deregistered)
{
auto stats = son.statistics(*this);
// TODO : We need to add a function that returns if we can deregister SON // 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 // 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 // is needed for release of funds from the PW
if(stats.last_active_timestamp.contains(sidechain)) { if(head_block_time() - stats.last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time()))
if (head_block_time() - stats.last_active_timestamp.at(sidechain) < fc::seconds(get_global_properties().parameters.son_deregister_time())) {
need_to_be_deregistered = false;
}
}
}
}
if(need_to_be_deregistered)
{ {
ret.insert(son.id); ret.insert(son.id);
} }
} }
}
return ret; return ret;
} }
@ -304,50 +292,28 @@ bool database::is_son_dereg_valid( son_id_type son_id )
return false; return false;
} }
bool status_son_dereg_valid = true; return (son->status == son_status::in_maintenance &&
for (const auto &active_sidechain_type : active_sidechain_types(head_block_time())) { (head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_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;
} }
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 >(); const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
auto son = son_idx.find( son_id ); auto son = son_idx.find( son_id );
if(son == son_idx.end()) { if(son == son_idx.end())
{
return false; return false;
} }
const global_property_object& gpo = get_global_properties(); 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; vector<son_id_type> active_son_ids;
active_son_ids.reserve(gpo_as.size()); active_son_ids.reserve(gpo.active_sons.size());
std::transform(gpo_as.cbegin(), gpo_as.cend(), std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
std::inserter(active_son_ids, active_son_ids.end()), std::inserter(active_son_ids, active_son_ids.end()),
[](const son_sidechain_info& swi) { [](const son_info& swi) {
return swi.son_id; 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); auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), son_id);
return (it_son != active_son_ids.end()); 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) 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 (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 false;
} }
return true; return true;
} }
} } }
}

View file

@ -40,7 +40,7 @@
#include <graphene/chain/operation_history_object.hpp> #include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/proposal_object.hpp> #include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/special_authority_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/vesting_balance_object.hpp>
#include <graphene/chain/withdraw_permission_object.hpp> #include <graphene/chain/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
@ -104,7 +104,7 @@
#include <graphene/chain/sidechain_transaction_evaluator.hpp> #include <graphene/chain/sidechain_transaction_evaluator.hpp>
#include <graphene/chain/random_number_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/uint128.hpp>
#include <fc/crypto/digest.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::space_id;
const uint8_t proposal_object::type_id; const uint8_t proposal_object::type_id;
const uint8_t transaction_object::space_id; const uint8_t transaction_history_object::space_id;
const uint8_t transaction_object::type_id; const uint8_t transaction_history_object::type_id;
const uint8_t vesting_balance_object::space_id; const uint8_t vesting_balance_object::space_id;
const uint8_t vesting_balance_object::type_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() void database::initialize_evaluators()
{ {
_operation_evaluators.resize(255); _consensus_operation_evaluators.resize(255);
register_evaluator<account_create_evaluator>(); _third_party_operation_evaluators.resize(255);
register_evaluator<account_update_evaluator>(); register_consensus_evaluator<account_create_evaluator>();
register_evaluator<account_upgrade_evaluator>(); register_consensus_evaluator<account_update_evaluator>();
register_evaluator<account_whitelist_evaluator>(); register_consensus_evaluator<account_upgrade_evaluator>();
register_evaluator<committee_member_create_evaluator>(); register_consensus_evaluator<account_whitelist_evaluator>();
register_evaluator<committee_member_update_evaluator>(); register_consensus_evaluator<committee_member_create_evaluator>();
register_evaluator<committee_member_update_global_parameters_evaluator>(); register_consensus_evaluator<committee_member_update_evaluator>();
register_evaluator<custom_evaluator>(); register_consensus_evaluator<committee_member_update_global_parameters_evaluator>();
register_evaluator<asset_create_evaluator>(); register_consensus_evaluator<custom_evaluator>();
register_evaluator<asset_issue_evaluator>(); register_consensus_evaluator<asset_create_evaluator>();
register_evaluator<asset_reserve_evaluator>(); register_consensus_evaluator<asset_issue_evaluator>();
register_evaluator<asset_update_evaluator>(); register_consensus_evaluator<asset_reserve_evaluator>();
register_evaluator<asset_update_bitasset_evaluator>(); register_consensus_evaluator<asset_update_evaluator>();
register_evaluator<asset_update_dividend_evaluator>(); register_consensus_evaluator<asset_update_bitasset_evaluator>();
register_evaluator<asset_update_feed_producers_evaluator>(); register_consensus_evaluator<asset_update_dividend_evaluator>();
register_evaluator<asset_settle_evaluator>(); register_consensus_evaluator<asset_update_feed_producers_evaluator>();
register_evaluator<asset_global_settle_evaluator>(); register_consensus_evaluator<asset_settle_evaluator>();
register_evaluator<assert_evaluator>(); register_consensus_evaluator<asset_global_settle_evaluator>();
register_evaluator<limit_order_create_evaluator>(); register_consensus_evaluator<assert_evaluator>();
register_evaluator<limit_order_cancel_evaluator>(); register_consensus_evaluator<limit_order_create_evaluator>();
register_evaluator<call_order_update_evaluator>(); register_consensus_evaluator<limit_order_cancel_evaluator>();
register_evaluator<transfer_evaluator>(); register_consensus_evaluator<call_order_update_evaluator>();
register_evaluator<override_transfer_evaluator>(); register_consensus_evaluator<transfer_evaluator>();
register_evaluator<asset_fund_fee_pool_evaluator>(); register_consensus_evaluator<override_transfer_evaluator>();
register_evaluator<asset_publish_feeds_evaluator>(); register_consensus_evaluator<asset_fund_fee_pool_evaluator>();
register_evaluator<proposal_create_evaluator>(); register_consensus_evaluator<asset_publish_feeds_evaluator>();
register_evaluator<proposal_update_evaluator>(); register_consensus_evaluator<proposal_create_evaluator>();
register_evaluator<proposal_delete_evaluator>(); register_consensus_evaluator<proposal_update_evaluator>();
register_evaluator<vesting_balance_create_evaluator>(); register_consensus_evaluator<proposal_delete_evaluator>();
register_evaluator<vesting_balance_withdraw_evaluator>(); register_consensus_evaluator<vesting_balance_create_evaluator>();
register_evaluator<witness_create_evaluator>(); register_consensus_evaluator<vesting_balance_withdraw_evaluator>();
register_evaluator<witness_update_evaluator>(); register_consensus_evaluator<witness_create_evaluator>();
register_evaluator<withdraw_permission_create_evaluator>(); register_consensus_evaluator<witness_update_evaluator>();
register_evaluator<withdraw_permission_claim_evaluator>(); register_consensus_evaluator<withdraw_permission_create_evaluator>();
register_evaluator<withdraw_permission_update_evaluator>(); register_consensus_evaluator<withdraw_permission_claim_evaluator>();
register_evaluator<withdraw_permission_delete_evaluator>(); register_consensus_evaluator<withdraw_permission_update_evaluator>();
register_evaluator<worker_create_evaluator>(); register_consensus_evaluator<withdraw_permission_delete_evaluator>();
register_evaluator<balance_claim_evaluator>(); register_consensus_evaluator<worker_create_evaluator>();
register_evaluator<transfer_to_blind_evaluator>(); register_consensus_evaluator<balance_claim_evaluator>();
register_evaluator<transfer_from_blind_evaluator>(); register_consensus_evaluator<transfer_to_blind_evaluator>();
register_evaluator<blind_transfer_evaluator>(); register_consensus_evaluator<transfer_from_blind_evaluator>();
register_evaluator<asset_claim_fees_evaluator>(); register_consensus_evaluator<blind_transfer_evaluator>();
register_evaluator<sport_create_evaluator>(); register_consensus_evaluator<asset_claim_fees_evaluator>();
register_evaluator<sport_update_evaluator>(); register_consensus_evaluator<sport_create_evaluator>();
register_evaluator<sport_delete_evaluator>(); register_consensus_evaluator<sport_update_evaluator>();
register_evaluator<event_group_create_evaluator>(); register_consensus_evaluator<sport_delete_evaluator>();
register_evaluator<event_group_update_evaluator>(); register_consensus_evaluator<event_group_create_evaluator>();
register_evaluator<event_group_delete_evaluator>(); register_consensus_evaluator<event_group_update_evaluator>();
register_evaluator<event_create_evaluator>(); register_consensus_evaluator<event_group_delete_evaluator>();
register_evaluator<event_update_evaluator>(); register_consensus_evaluator<event_create_evaluator>();
register_evaluator<event_update_status_evaluator>(); register_consensus_evaluator<event_update_evaluator>();
register_evaluator<betting_market_rules_create_evaluator>(); register_consensus_evaluator<event_update_status_evaluator>();
register_evaluator<betting_market_rules_update_evaluator>(); register_consensus_evaluator<betting_market_rules_create_evaluator>();
register_evaluator<betting_market_group_create_evaluator>(); register_consensus_evaluator<betting_market_rules_update_evaluator>();
register_evaluator<betting_market_group_update_evaluator>(); register_consensus_evaluator<betting_market_group_create_evaluator>();
register_evaluator<betting_market_create_evaluator>(); register_consensus_evaluator<betting_market_group_update_evaluator>();
register_evaluator<betting_market_update_evaluator>(); register_consensus_evaluator<betting_market_create_evaluator>();
register_evaluator<bet_place_evaluator>(); register_consensus_evaluator<betting_market_update_evaluator>();
register_evaluator<bet_cancel_evaluator>(); register_consensus_evaluator<bet_place_evaluator>();
register_evaluator<betting_market_group_resolve_evaluator>(); register_consensus_evaluator<bet_cancel_evaluator>();
register_evaluator<betting_market_group_cancel_unmatched_bets_evaluator>(); register_consensus_evaluator<betting_market_group_resolve_evaluator>();
register_evaluator<tournament_create_evaluator>(); register_consensus_evaluator<betting_market_group_cancel_unmatched_bets_evaluator>();
register_evaluator<tournament_join_evaluator>(); register_consensus_evaluator<tournament_create_evaluator>();
register_evaluator<game_move_evaluator>(); register_consensus_evaluator<tournament_join_evaluator>();
register_evaluator<tournament_leave_evaluator>(); register_consensus_evaluator<game_move_evaluator>();
register_evaluator<lottery_asset_create_evaluator>(); register_consensus_evaluator<tournament_leave_evaluator>();
register_evaluator<ticket_purchase_evaluator>(); register_consensus_evaluator<lottery_asset_create_evaluator>();
register_evaluator<lottery_reward_evaluator>(); register_consensus_evaluator<ticket_purchase_evaluator>();
register_evaluator<lottery_end_evaluator>(); register_consensus_evaluator<lottery_reward_evaluator>();
register_evaluator<sweeps_vesting_claim_evaluator>(); register_consensus_evaluator<lottery_end_evaluator>();
register_evaluator<create_custom_permission_evaluator>(); register_consensus_evaluator<sweeps_vesting_claim_evaluator>();
register_evaluator<update_custom_permission_evaluator>(); register_consensus_evaluator<create_custom_permission_evaluator>();
register_evaluator<delete_custom_permission_evaluator>(); register_consensus_evaluator<update_custom_permission_evaluator>();
register_evaluator<create_custom_account_authority_evaluator>(); register_consensus_evaluator<delete_custom_permission_evaluator>();
register_evaluator<update_custom_account_authority_evaluator>(); register_consensus_evaluator<create_custom_account_authority_evaluator>();
register_evaluator<delete_custom_account_authority_evaluator>(); register_consensus_evaluator<update_custom_account_authority_evaluator>();
register_evaluator<offer_evaluator>(); register_consensus_evaluator<delete_custom_account_authority_evaluator>();
register_evaluator<bid_evaluator>(); register_consensus_evaluator<offer_evaluator>();
register_evaluator<cancel_offer_evaluator>(); register_consensus_evaluator<bid_evaluator>();
register_evaluator<finalize_offer_evaluator>(); register_consensus_evaluator<cancel_offer_evaluator>();
register_evaluator<nft_metadata_create_evaluator>(); register_consensus_evaluator<finalize_offer_evaluator>();
register_evaluator<nft_metadata_update_evaluator>(); register_consensus_evaluator<nft_metadata_create_evaluator>();
register_evaluator<nft_mint_evaluator>(); register_consensus_evaluator<nft_metadata_update_evaluator>();
register_evaluator<nft_safe_transfer_from_evaluator>(); register_consensus_evaluator<nft_mint_evaluator>();
register_evaluator<nft_approve_evaluator>(); register_consensus_evaluator<nft_safe_transfer_from_evaluator>();
register_evaluator<nft_set_approval_for_all_evaluator>(); register_consensus_evaluator<nft_approve_evaluator>();
register_evaluator<account_role_create_evaluator>(); register_consensus_evaluator<nft_set_approval_for_all_evaluator>();
register_evaluator<account_role_update_evaluator>(); register_consensus_evaluator<account_role_create_evaluator>();
register_evaluator<account_role_delete_evaluator>(); register_consensus_evaluator<account_role_update_evaluator>();
register_evaluator<nft_lottery_token_purchase_evaluator>(); register_consensus_evaluator<account_role_delete_evaluator>();
register_evaluator<nft_lottery_reward_evaluator>(); register_consensus_evaluator<nft_lottery_token_purchase_evaluator>();
register_evaluator<nft_lottery_end_evaluator>(); register_consensus_evaluator<nft_lottery_reward_evaluator>();
register_evaluator<create_son_evaluator>(); register_consensus_evaluator<nft_lottery_end_evaluator>();
register_evaluator<update_son_evaluator>(); register_consensus_evaluator<create_son_evaluator>();
register_evaluator<deregister_son_evaluator>(); register_consensus_evaluator<update_son_evaluator>();
register_evaluator<son_heartbeat_evaluator>(); register_consensus_evaluator<deregister_son_evaluator>();
register_evaluator<son_report_down_evaluator>(); register_consensus_evaluator<son_heartbeat_evaluator>();
register_evaluator<son_maintenance_evaluator>(); register_consensus_evaluator<son_report_down_evaluator>();
register_evaluator<recreate_son_wallet_evaluator>(); register_consensus_evaluator<son_maintenance_evaluator>();
register_evaluator<update_son_wallet_evaluator>(); register_consensus_evaluator<recreate_son_wallet_evaluator>();
register_evaluator<create_son_wallet_deposit_evaluator>(); register_consensus_evaluator<update_son_wallet_evaluator>();
register_evaluator<process_son_wallet_deposit_evaluator>(); register_consensus_evaluator<create_son_wallet_deposit_evaluator>();
register_evaluator<create_son_wallet_withdraw_evaluator>(); register_consensus_evaluator<process_son_wallet_deposit_evaluator>();
register_evaluator<process_son_wallet_withdraw_evaluator>(); register_consensus_evaluator<create_son_wallet_withdraw_evaluator>();
register_evaluator<add_sidechain_address_evaluator>(); register_consensus_evaluator<process_son_wallet_withdraw_evaluator>();
register_evaluator<update_sidechain_address_evaluator>(); register_consensus_evaluator<add_sidechain_address_evaluator>();
register_evaluator<delete_sidechain_address_evaluator>(); register_consensus_evaluator<update_sidechain_address_evaluator>();
register_evaluator<sidechain_transaction_create_evaluator>(); register_consensus_evaluator<delete_sidechain_address_evaluator>();
register_evaluator<sidechain_transaction_sign_evaluator>(); register_consensus_evaluator<sidechain_transaction_create_evaluator>();
register_evaluator<sidechain_transaction_send_evaluator>(); register_consensus_evaluator<sidechain_transaction_sign_evaluator>();
register_evaluator<sidechain_transaction_settle_evaluator>(); register_consensus_evaluator<sidechain_transaction_send_evaluator>();
register_evaluator<random_number_store_evaluator>(); register_consensus_evaluator<sidechain_transaction_settle_evaluator>();
} register_consensus_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());
} }
void database::initialize_indexes() void database::initialize_indexes()
{ {
reset_indexes(); reset_indexes();
_undo_db.set_max_size( GRAPHENE_MIN_UNDO_HISTORY );
const std::lock_guard<std::mutex> undo_db_lock{_undo_db_mutex}; _check_policy_1 = allocate_object_space<database_lock_safety_check>(protocol_ids);
_undo_db.set_max_size(GRAPHENE_MIN_UNDO_HISTORY); _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 //Protocol object indexes
add_index< primary_index<asset_index, 13> >(); // 8192 assets per chunk 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<son_stats_index > >();
add_index< primary_index<random_number_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) 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(), FC_ASSERT(genesis_state.initial_active_witnesses <= genesis_state.initial_witness_candidates.size(),
"initial_active_witnesses is larger than the number of candidate witnesses."); "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(); _undo_db.disable();
scoped_database_unlocker unlocker(*_check_policy_1, *_check_policy_2);
struct auth_inhibitor { struct auth_inhibitor {
auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags) auth_inhibitor(database& db) : db(db), old_flags(db.node_properties().skip_flags)
{ db.node_properties().skip_flags |= skip_authority_check; } { 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.time = genesis_state.initial_timestamp;
p.dynamic_flags = 0; p.dynamic_flags = 0;
p.witness_budget = 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) { create<global_betting_statistics_object>([&](global_betting_statistics_object& betting_statistics) {
betting_statistics.number_of_active_events = 0; 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 ) for( const auto& handout : genesis_state.initial_balances )
{ {
const auto asset_id = get_asset_id(handout.asset_symbol); 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.balance = asset(handout.amount, asset_id);
b.owner = handout.owner; b.owner = handout.owner;
}); });
@ -1095,7 +1059,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
_wso.last_scheduling_block = 0; _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 shuffled
for( const witness_id_type& wid : get_global_properties().active_witnesses ) 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() ); FC_ASSERT( _p_witness_schedule_obj->id == witness_schedule_id_type() );
// Initialize witness schedule // Initialize witness schedule
#ifndef NDEBUG #ifndef NDEBUG
const son_schedule_object& ssobitcoin = const son_schedule_object& sso =
#endif #endif
create<son_schedule_object>([&](son_schedule_object& _sso) 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); 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 = 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.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)) ); assert( sso.id == son_schedule_id_type() );
#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)) );
// Enable fees // Enable fees
modify(get_global_properties(), [&genesis_state](global_property_object& p) { modify(get_global_properties(), [&genesis_state](global_property_object& p) {
p.parameters.current_fees = genesis_state.initial_parameters.current_fees; p.parameters.current_fees = genesis_state.initial_parameters.current_fees;
}); });
// Create FBA counters // Create FBA counters
create<fba_accumulator_object>([&]( fba_accumulator_object& acc ) 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/special_authority_object.hpp>
#include <graphene/chain/operation_history_object.hpp> #include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/nft_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> #include <fc/io/fstream.hpp>
@ -39,12 +40,14 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
database::database() : database::database(bool allow_testing_edits) :
_random_number_generator(fc::ripemd160().data()) _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_indexes();
initialize_evaluators(); initialize_evaluators();
initialize_hardforks();
} }
database::~database() 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 ) if( trade_asset.options.market_fee_percent == 0 )
return trade_asset.amount(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 *= trade_asset.options.market_fee_percent;
a /= GRAPHENE_100_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 ) if( percent_fee.amount > trade_asset.options.max_market_fee )
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 <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/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/withdraw_permission_object.hpp>
#include <graphene/chain/worker_object.hpp> #include <graphene/chain/worker_object.hpp>
#include <graphene/chain/confidential_object.hpp> #include <graphene/chain/confidential_object.hpp>
@ -39,14 +39,17 @@
#include <graphene/chain/proposal_object.hpp> #include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/operation_history_object.hpp> #include <graphene/chain/operation_history_object.hpp>
#include <graphene/chain/vesting_balance_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/impacted.hpp>
#include <graphene/chain/hardfork.hpp> #include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp> #include <graphene/chain/account_object.hpp>
#include <graphene/chain/account_role_object.hpp> #include <graphene/chain/account_role_object.hpp>
#include <graphene/chain/son_object.hpp> #include <graphene/chain/son_object.hpp>
#include <graphene/chain/sidechain_address_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 fc;
using namespace graphene::chain; using namespace graphene::chain;
@ -203,10 +206,27 @@ struct get_impacted_account_visitor
_impacted.insert( op.issuer ); _impacted.insert( op.issuer );
} }
//! We don't use this operations void operator()( const transfer_to_blind_operation& op )
void operator()( const transfer_to_blind_operation& op ){} {
void operator()( const blind_transfer_operation& op ){} _impacted.insert( op.from );
void operator()( const transfer_from_blind_operation& op ){} 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 ) 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 null_object_type:
case base_object_type: case base_object_type:
case OBJECT_TYPE_COUNT:
return; return;
case account_object_type:{ case account_object_type:{
accounts.insert( obj->id ); 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, transaction_get_impacted_accounts( aobj->proposed_transaction, accounts,
ignore_custom_operation_required_auths); ignore_custom_operation_required_auths);
break; break;
} case operation_history_object_type:{ } case reserved0_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; break;
} case withdraw_permission_object_type:{ } case withdraw_permission_object_type:{
const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj); const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj);
@ -501,7 +516,85 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case balance_object_type:{ } case balance_object_type:{
/** these are free from any accounts */ /** these are free from any accounts */
break; break;
} case account_role_type:{ } 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); const auto& aobj = dynamic_cast<const account_role_object*>(obj);
assert( aobj != nullptr ); assert( aobj != nullptr );
accounts.insert( aobj->owner ); accounts.insert( aobj->owner );
@ -512,6 +605,8 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
assert( aobj != nullptr ); assert( aobj != nullptr );
accounts.insert( aobj->son_account ); accounts.insert( aobj->son_account );
break; break;
} case son_proposal_object_type:{
break;
} case son_wallet_object_type:{ } case son_wallet_object_type:{
break; break;
} case son_wallet_deposit_object_type:{ } case son_wallet_deposit_object_type:{
@ -541,9 +636,9 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break; break;
case impl_reserved0_object_type: case impl_reserved0_object_type:
break; break;
case impl_asset_dynamic_data_type: case impl_asset_dynamic_data_object_type:
break; break;
case impl_asset_bitasset_data_type: case impl_asset_bitasset_data_object_type:
break; break;
case impl_account_balance_object_type:{ case impl_account_balance_object_type:{
const auto& aobj = dynamic_cast<const account_balance_object*>(obj); 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 ); assert( aobj != nullptr );
accounts.insert( aobj->owner ); accounts.insert( aobj->owner );
break; break;
} case impl_transaction_object_type:{ } case impl_transaction_history_object_type:{
const auto& aobj = dynamic_cast<const transaction_object*>(obj); const auto& aobj = dynamic_cast<const transaction_history_object*>(obj);
assert( aobj != nullptr ); FC_ASSERT( aobj != nullptr );
transaction_get_impacted_accounts( aobj->trx, accounts, transaction_get_impacted_accounts( aobj->trx, accounts,
ignore_custom_operation_required_auths); ignore_custom_operation_required_auths );
break; break;
} case impl_blinded_balance_object_type:{ } case impl_blinded_balance_object_type:{
const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj); const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj);
@ -569,7 +664,7 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break; break;
} case impl_block_summary_object_type: } case impl_block_summary_object_type:
break; break;
case impl_account_transaction_history_object_type: case impl_reserved1_object_type:
break; break;
case impl_chain_property_object_type: case impl_chain_property_object_type:
break; break;
@ -583,11 +678,62 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
break; break;
case impl_fba_accumulator_object_type: case impl_fba_accumulator_object_type:
break; 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: case impl_nft_lottery_balance_object_type:
break; break;
default: default:
break; 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 ) } // 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() ) if( _undo_db.enabled() )
{ {
const auto& head_undo = _undo_db.head(); const auto& head_undo = _undo_db.head();
auto chain_time = head_block_time();
// New // New
if( !new_objects.empty() ) if( !new_objects.empty() )
@ -619,7 +766,8 @@ void database::notify_changed_objects()
new_ids.push_back(item); new_ids.push_back(item);
auto obj = find_object(item); auto obj = find_object(item);
if(obj != nullptr) if(obj != nullptr)
get_relevant_accounts(obj, new_accounts_impacted, 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) 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 ) for( const auto& item : head_undo.old_values )
{ {
changed_ids.push_back(item.first); changed_ids.push_back(item.first);
get_relevant_accounts(item.second.get(), changed_accounts_impacted, 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) 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 ); removed_ids.emplace_back( item.first );
auto obj = item.second.get(); auto obj = item.second.get();
removed.emplace_back( obj ); removed.emplace_back( obj );
get_relevant_accounts(obj, removed_accounts_impacted, 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) 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/proposal_object.hpp>
#include <graphene/chain/son_proposal_object.hpp> #include <graphene/chain/son_proposal_object.hpp>
#include <graphene/chain/tournament_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/withdraw_permission_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/protocol/fee_schedule.hpp>
#include <fc/uint128.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -156,7 +154,8 @@ void database::clear_expired_transactions()
{ try { { try {
//Look for expired transactions in the deduplication list, and remove them. //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. //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>(); const auto& dedupe_index = transaction_idx.indices().get<by_expiration>();
while( (!dedupe_index.empty()) && (head_block_time() > dedupe_index.begin()->trx.expiration) ) while( (!dedupe_index.empty()) && (head_block_time() > dedupe_index.begin()->trx.expiration) )
transaction_idx.remove(*dedupe_index.begin()); transaction_idx.remove(*dedupe_index.begin());
@ -427,7 +426,7 @@ void database::clear_expired_orders()
auto& pays = order.balance; auto& pays = order.balance;
auto receives = (order.balance * mia.current_feed.settlement_price); auto receives = (order.balance * mia.current_feed.settlement_price);
receives.amount = (fc::uint128_t(receives.amount.value) * 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); assert(receives <= order.balance * mia.current_feed.settlement_price);
price settlement_price = pays / receives; price settlement_price = pays / receives;

View file

@ -22,12 +22,14 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <graphene/protocol/son_info.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/witness_object.hpp> #include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp> #include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/son_object.hpp> #include <graphene/chain/son_object.hpp>
#include <graphene/chain/son_info.hpp>
#include <fc/popcount.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -74,32 +76,21 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
return wid; return wid;
} }
unsigned_int database::get_son_schedule_id( sidechain_type type )const son_id_type database::get_scheduled_son( uint32_t slot_num )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 sid; son_id_type sid;
const global_property_object& gpo = get_global_properties(); const global_property_object& gpo = get_global_properties();
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM) if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{ {
const dynamic_global_property_object& dpo = get_dynamic_global_properties(); 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; uint64_t current_aslot = dpo.current_aslot + slot_num;
return sso.current_shuffled_sons[ current_aslot % sso.current_shuffled_sons.size() ]; return sso.current_shuffled_sons[ current_aslot % sso.current_shuffled_sons.size() ];
} }
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM && if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 ) 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 // ask the near scheduler who goes in the given slot
bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid); bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid);
if(! slot_is_near) 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 global_property_object& gpo = get_global_properties();
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(type))); if( head_block_num() % gpo.active_sons.size() == 0 )
if( gpo.active_sons.at(type).size() != 0 &&
head_block_num() % gpo.active_sons.at(type).size() == 0)
{ {
modify( sidechain_sso, [&]( son_schedule_object& _sso ) modify( sso, [&]( son_schedule_object& _sso )
{ {
_sso.current_shuffled_sons.clear(); _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) ) { for( const son_info& w : gpo.active_sons )
_sso.current_shuffled_sons.push_back(w.son_id); _sso.current_shuffled_sons.push_back( w.son_id );
}
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32; 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 /// High performance random generator
/// http://xorshift.di.unimi.it/ /// 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 >> 12);
k ^= (k << 25); k ^= (k << 25);
k ^= (k >> 27); k ^= (k >> 27);
k *= 2685821657736338717ULL; k *= 2685821657736338717ULL;
uint32_t jmax = _sso.current_shuffled_sons.size() - i; uint32_t jmax = _sso.current_shuffled_sons.size() - i;
uint32_t j = i + k % jmax; uint32_t j = i + k%jmax;
std::swap(_sso.current_shuffled_sons[i], std::swap( _sso.current_shuffled_sons[i],
_sso.current_shuffled_sons[j]); _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) modify(wso, [&](witness_schedule_object& _wso)
{ {
_wso.slots_since_genesis += schedule_slot; _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); _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) ); 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(); 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 global_property_object& gpo = get_global_properties();
const uint32_t schedule_needs_filled = gpo.active_sons.at(type).size(); const son_schedule_object& sso = get(son_schedule_id_type());
const uint32_t schedule_slot = get_slot_at_time(next_block.timestamp); 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 // We shouldn't be able to generate _pending_block with timestamp
// in the past, and incoming blocks from the network with timestamp // in the past, and incoming blocks from the network with timestamp
@ -335,22 +321,22 @@ void database::update_son_schedule(sidechain_type type, const signed_block& next
assert( schedule_slot > 0 ); 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(); const dynamic_global_property_object& dpo = get_dynamic_global_properties();
assert( dpo.random.data_size() == witness_scheduler_rng::seed_length ); assert( dpo.random.data_size() == witness_scheduler_rng::seed_length );
assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() ); 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))); modify(sso, [&](son_schedule_object& _sso)
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)
{ {
_sso.slots_since_genesis += schedule_slot; _sso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(_sso.rng_seed.data, _sso.slots_since_genesis); 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 ) if( slot_is_near )
{ {
@ -367,7 +353,7 @@ void database::update_son_schedule(sidechain_type type, const signed_block& next
{ {
_sso.scheduler.reset_schedule( first_son ); _sso.scheduler.reset_schedule( first_son );
} }
while( !_sso.scheduler.get_slot(schedule_needs_filled, son_id) ) while( !_sso.scheduler.get_slot(schedule_needs_filled, son) )
{ {
if( _sso.scheduler.produce_schedule(rng) & emit_turn ) if( _sso.scheduler.produce_schedule(rng) & emit_turn )
memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size()); memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size());
@ -377,7 +363,6 @@ void database::update_son_schedule(sidechain_type type, const signed_block& next
(_sso.recent_slots_filled << 1) (_sso.recent_slots_filled << 1)
+ 1) << (schedule_slot - 1); + 1) << (schedule_slot - 1);
}); });
auto end = fc::time_point::now(); auto end = fc::time_point::now();
static uint64_t total_time = 0; static uint64_t total_time = 0;
static uint64_t calls = 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) if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{ {
const dynamic_global_property_object& dpo = get_dynamic_global_properties(); 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) if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM)
{ {
const witness_schedule_object& wso = get_witness_schedule_object(); 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; return 0;
} }

View file

@ -33,14 +33,12 @@
#include <graphene/chain/fba_object.hpp> #include <graphene/chain/fba_object.hpp>
#include <graphene/chain/committee_member_object.hpp> #include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/market_evaluator.hpp> #include <graphene/chain/market_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/protocol/fee_schedule.hpp>
#include <fc/uint128.hpp>
namespace graphene { namespace chain { 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 { { try {
trx_state = &eval_state; trx_state = &eval_state;
//check_required_authorities(op); //check_required_authorities(op);
@ -50,7 +48,7 @@ database& generic_evaluator::db()const { return trx_state->db(); }
return result; return result;
} FC_CAPTURE_AND_RETHROW() } } 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(); const database& d = db();
fee_from_account = fee; 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( !trx_state->skip_fee ) {
if( fee_asset->get_id() != asset_id_type() ) 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 { { try {
if( !trx_state->skip_fee ) { if( !trx_state->skip_fee ) {
database& d = db(); database& d = db();
@ -104,13 +102,13 @@ database& generic_evaluator::db()const { return trx_state->db(); }
} }
} FC_CAPTURE_AND_RETHROW() } } 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(); database& d = db();
const fba_accumulator_object& fba = d.get< fba_accumulator_object >( fba_accumulator_id_type( fba_id ) ); const fba_accumulator_object& fba = d.get< fba_accumulator_object >( fba_accumulator_id_type( fba_id ) );
if( !fba.is_configured(d) ) if( !fba.is_configured(d) )
{ {
generic_evaluator::pay_fee(); consensus_evaluator::pay_fee();
return; return;
} }
d.modify( fba, [&]( fba_accumulator_object& _fba ) 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; 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); 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)) if (!is_relative(rel_id))
FC_THROW("get_relative_id() called for non-relative id ${id}", ("id", 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/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp> #include <graphene/chain/is_authorized_asset.hpp>
#include <graphene/chain/global_betting_statistics_object.hpp> #include <graphene/chain/global_betting_statistics_object.hpp>
#include <graphene/chain/betting_market_object.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {

View file

@ -344,6 +344,7 @@ namespace graphene { namespace chain {
{ {
FC_THROW_EXCEPTION(graphene::chain::no_transition, "No transition"); FC_THROW_EXCEPTION(graphene::chain::no_transition, "No transition");
} }
template <class Fsm> template <class Fsm>
void no_transition(canceled_event const& e, Fsm&, int state) void no_transition(canceled_event const& e, Fsm&, int state)
{ {

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/fork_database.hpp>
#include <graphene/chain/exceptions.hpp> #include <graphene/chain/exceptions.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/protocol/fee_schedule.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
fork_database::fork_database() fork_database::fork_database()

View file

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

View file

@ -24,7 +24,7 @@
#include <graphene/chain/get_config.hpp> #include <graphene/chain/get_config.hpp>
#include <graphene/chain/config.hpp> #include <graphene/chain/config.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/types.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -74,7 +74,6 @@ fc::variant_object get_config()
result[ "GRAPHENE_MAX_COLLATERAL_RATIO" ] = GRAPHENE_MAX_COLLATERAL_RATIO; result[ "GRAPHENE_MAX_COLLATERAL_RATIO" ] = GRAPHENE_MAX_COLLATERAL_RATIO;
result[ "GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO" ] = GRAPHENE_DEFAULT_MAINTENANCE_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_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_WITNESSES" ] = GRAPHENE_DEFAULT_MAX_WITNESSES;
result[ "GRAPHENE_DEFAULT_MAX_COMMITTEE" ] = GRAPHENE_DEFAULT_MAX_COMMITTEE; result[ "GRAPHENE_DEFAULT_MAX_COMMITTEE" ] = GRAPHENE_DEFAULT_MAX_COMMITTEE;
result[ "GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC" ] = GRAPHENE_DEFAULT_MAX_PROPOSAL_LIFETIME_SEC; 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 #ifndef HARDFORK_GPOS_TIME
#ifdef BUILD_PEERPLAYS_TESTNET #ifdef BUILD_PEERPLAYS_TESTNET
#define HARDFORK_GPOS_TIME (fc::time_point_sec::from_iso_string("2020-01-06T01:00:00")) #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 { 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: public:
typedef account_create_operation operation_type; typedef account_create_operation operation_type;
@ -36,7 +36,7 @@ public:
object_id_type do_apply( const account_create_operation& o ) ; 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: public:
typedef account_update_operation operation_type; typedef account_update_operation operation_type;
@ -47,7 +47,7 @@ public:
const account_object* acnt; 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: public:
typedef account_upgrade_operation operation_type; typedef account_upgrade_operation operation_type;
@ -58,7 +58,7 @@ public:
const account_object* account; 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: public:
typedef account_whitelist_operation operation_type; typedef account_whitelist_operation operation_type;

View file

@ -22,13 +22,15 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/db/generic_index.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> #include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
class database; class database;
class account_object;
class vesting_balance_object;
/** /**
* @class account_statistics_object * @class account_statistics_object
@ -321,7 +323,8 @@ namespace graphene { namespace chain {
}; };
public: 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 object_removed( const object& obj ) override;
virtual void about_to_modify( const object& before ) override; virtual void about_to_modify( const object& before ) override;
virtual void object_modified( const object& after ) override; virtual void object_modified( const object& after ) override;
@ -352,7 +355,8 @@ namespace graphene { namespace chain {
class account_referrer_index : public secondary_index class account_referrer_index : public secondary_index
{ {
public: 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 object_removed( const object& obj ) override;
virtual void about_to_modify( const object& before ) override; virtual void about_to_modify( const object& before ) override;
virtual void object_modified( const object& after ) 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 class balances_by_account_index : public secondary_index
{ {
public: 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 object_removed( const object& obj ) override;
virtual void about_to_modify( const object& before ) override; virtual void about_to_modify( const object& before ) override;
virtual void object_modified( const object& after ) 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, FC_REFLECT_DERIVED( graphene::chain::account_object,
(graphene::db::object), (graphene::db::object),
(membership_expiration_date)(registrar)(referrer)(lifetime_referrer) (membership_expiration_date)(registrar)(referrer)(lifetime_referrer)

View file

@ -2,12 +2,12 @@
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/types.hpp>
namespace graphene { namespace chain { 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: public:
typedef account_role_create_operation operation_type; 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 ); 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: public:
typedef account_role_update_operation operation_type; 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 ); 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: public:
typedef account_role_delete_operation operation_type; typedef account_role_delete_operation operation_type;

View file

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

View file

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

View file

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

View file

@ -22,13 +22,13 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
namespace graphene { namespace chain { 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: public:
typedef asset_create_operation operation_type; typedef asset_create_operation operation_type;
@ -44,7 +44,7 @@ namespace graphene { namespace chain {
bool fee_is_odd; 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: public:
typedef lottery_asset_create_operation operation_type; typedef lottery_asset_create_operation operation_type;
@ -60,7 +60,7 @@ namespace graphene { namespace chain {
bool fee_is_odd; 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: public:
typedef asset_issue_operation operation_type; typedef asset_issue_operation operation_type;
@ -71,7 +71,7 @@ namespace graphene { namespace chain {
const account_object* to_account = nullptr; 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: public:
typedef asset_reserve_operation operation_type; 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: public:
typedef asset_update_operation operation_type; typedef asset_update_operation operation_type;
@ -94,7 +94,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_update = nullptr; 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: public:
typedef asset_update_bitasset_operation operation_type; typedef asset_update_bitasset_operation operation_type;
@ -105,7 +105,7 @@ namespace graphene { namespace chain {
const asset_bitasset_data_object* bitasset_to_update = nullptr; 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: public:
typedef asset_update_dividend_operation operation_type; 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; 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: public:
typedef asset_update_feed_producers_operation operation_type; 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; 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: public:
typedef asset_fund_fee_pool_operation operation_type; 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; 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: public:
typedef asset_global_settle_operation operation_type; typedef asset_global_settle_operation operation_type;
@ -149,7 +149,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_settle = nullptr; 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: public:
typedef asset_settle_operation operation_type; typedef asset_settle_operation operation_type;
@ -160,7 +160,7 @@ namespace graphene { namespace chain {
const asset_object* asset_to_settle = nullptr; 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: public:
typedef asset_publish_feed_operation operation_type; 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; 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: public:
typedef asset_claim_fees_operation operation_type; typedef asset_claim_fees_operation operation_type;

View file

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

View file

@ -23,7 +23,7 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/transaction.hpp> #include <graphene/protocol/transaction.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/balance_object.hpp> #include <graphene/chain/balance_object.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
@ -31,7 +31,7 @@
namespace graphene { namespace chain { 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: public:
typedef balance_claim_operation operation_type; 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>; 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), FC_REFLECT_DERIVED( graphene::chain::balance_object, (graphene::db::object),
(owner)(balance)(vesting_policy)(last_claim_date) ) (owner)(balance)(vesting_policy)(last_claim_date) )

View file

@ -23,13 +23,13 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
namespace graphene { namespace chain { 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: public:
typedef betting_market_rules_create_operation operation_type; 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 ); 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: public:
typedef betting_market_rules_update_operation operation_type; typedef betting_market_rules_update_operation operation_type;
@ -49,7 +49,7 @@ namespace graphene { namespace chain {
const betting_market_rules_object* _rules; 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: public:
typedef betting_market_group_create_operation operation_type; typedef betting_market_group_create_operation operation_type;
@ -61,7 +61,7 @@ namespace graphene { namespace chain {
betting_market_rules_id_type _rules_id; 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: public:
typedef betting_market_group_update_operation operation_type; typedef betting_market_group_update_operation operation_type;
@ -73,7 +73,7 @@ namespace graphene { namespace chain {
const betting_market_group_object* _betting_market_group; 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: public:
typedef betting_market_create_operation operation_type; typedef betting_market_create_operation operation_type;
@ -84,7 +84,7 @@ namespace graphene { namespace chain {
betting_market_group_id_type _group_id; 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: public:
typedef betting_market_update_operation operation_type; typedef betting_market_update_operation operation_type;
@ -96,7 +96,7 @@ namespace graphene { namespace chain {
betting_market_group_id_type _group_id; 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: public:
typedef bet_place_operation operation_type; typedef bet_place_operation operation_type;
@ -111,7 +111,7 @@ namespace graphene { namespace chain {
share_type _stake_plus_fees; 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: public:
typedef bet_cancel_operation operation_type; typedef bet_cancel_operation operation_type;
@ -122,7 +122,7 @@ namespace graphene { namespace chain {
const bet_object* _bet_to_cancel; 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: public:
typedef betting_market_group_resolve_operation operation_type; typedef betting_market_group_resolve_operation operation_type;
@ -133,7 +133,7 @@ namespace graphene { namespace chain {
const betting_market_group_object* _betting_market_group; 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: public:
typedef betting_market_group_cancel_unmatched_bets_operation operation_type; typedef betting_market_group_cancel_unmatched_bets_operation operation_type;

View file

@ -23,11 +23,15 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/protocol/betting_market.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/composite_key.hpp>
#include <sstream> #include <sstream>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -44,7 +48,7 @@ namespace fc {
namespace graphene { namespace chain { namespace graphene { namespace chain {
FC_DECLARE_EXCEPTION(no_transition, 100000, "Invalid state transition"); FC_DECLARE_EXCEPTION(no_transition, 100000);
class database; class database;
struct by_event_id; struct by_event_id;
@ -625,6 +629,7 @@ typedef multi_index_container<
typedef generic_index<betting_market_position_object, betting_market_position_multi_index_type> betting_market_position_index; typedef generic_index<betting_market_position_object, betting_market_position_multi_index_type> betting_market_position_index;
template<typename Stream> template<typename Stream>
inline Stream& operator<<( Stream& s, const betting_market_object& betting_market_obj ) inline Stream& operator<<( Stream& s, const betting_market_object& betting_market_obj )
{ {
@ -712,110 +717,19 @@ inline Stream& operator>>( Stream& s, betting_market_group_object& betting_marke
return s; return s;
} }
} } // graphene::chain } } // 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::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) ) 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 #pragma once
#include <fstream> #include <fstream>
#include <graphene/chain/protocol/block.hpp> #include <graphene/protocol/block.hpp>
#include <fc/filesystem.hpp> #include <fc/filesystem.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
class index_entry; struct index_entry;
using namespace graphene::protocol;
class block_database class block_database
{ {

View file

@ -22,7 +22,8 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
namespace graphene { namespace chain { 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) ) FC_REFLECT_DERIVED( graphene::chain::block_summary_object, (graphene::db::object), (block_id) )

View file

@ -22,7 +22,9 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #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 <graphene/db/generic_index.hpp>
namespace graphene { namespace chain { 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, FC_REFLECT(graphene::chain::budget_record,
(time_since_last_budget) (time_since_last_budget)
(from_initial_reserve) (from_initial_reserve)

View file

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

View file

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

View file

@ -24,6 +24,7 @@
#pragma once #pragma once
#include <graphene/chain/immutable_chain_parameters.hpp> #include <graphene/chain/immutable_chain_parameters.hpp>
#include <graphene/chain/types.hpp>
namespace graphene { namespace chain { 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), FC_REFLECT_DERIVED( graphene::chain::chain_property_object, (graphene::db::object),
(chain_id) (chain_id)
(immutable_parameters) (immutable_parameters)

View file

@ -24,10 +24,11 @@
#pragma once #pragma once
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/committee_member_object.hpp> #include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/global_property_object.hpp>
namespace graphene { namespace chain { 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: public:
typedef committee_member_create_operation operation_type; 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 ); 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: public:
typedef committee_member_update_operation operation_type; 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 ); 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: public:
typedef committee_member_update_global_parameters_operation operation_type; typedef committee_member_update_global_parameters_operation operation_type;

View file

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

View file

@ -23,14 +23,11 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/types.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
struct transfer_to_blind_operation; class transfer_to_blind_evaluator : public fee_handling_evaluator<transfer_to_blind_evaluator>
struct transfer_from_blind_operation;
struct blind_transfer_operation;
class transfer_to_blind_evaluator : public evaluator<transfer_to_blind_evaluator>
{ {
public: public:
typedef transfer_to_blind_operation operation_type; 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; 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: public:
typedef transfer_from_blind_operation operation_type; 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; 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: public:
typedef blind_transfer_operation operation_type; typedef blind_transfer_operation operation_type;

View file

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

View file

@ -23,242 +23,16 @@
*/ */
#pragma once #pragma once
#ifdef BUILD_PEERPLAYS_TESTNET #include <graphene/protocol/config.hpp>
#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
#define GRAPHENE_MIN_UNDO_HISTORY 10 #define GRAPHENE_MIN_UNDO_HISTORY 10
#define GRAPHENE_MAX_UNDO_HISTORY 10000 #define GRAPHENE_MAX_UNDO_HISTORY 10000
#define GRAPHENE_MIN_BLOCK_SIZE_LIMIT (GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT*5) // 5 transactions per block #define GRAPHENE_MAX_NESTED_OBJECTS (200)
#define GRAPHENE_MIN_TRANSACTION_EXPIRATION_LIMIT (GRAPHENE_MAX_BLOCK_INTERVAL * 5) // 5 transactions per block
#define GRAPHENE_BLOCKCHAIN_PRECISION uint64_t( 100000 )
#define GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS 5 #define GRAPHENE_CURRENT_DB_VERSION "PPY2.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_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_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4
#define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 #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 #pragma once
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
#include <graphene/protocol/custom_account_authority.hpp>
namespace graphene namespace graphene
{ {
namespace chain 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: public:
typedef custom_account_authority_create_operation operation_type; 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); 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: public:
typedef custom_account_authority_update_operation operation_type; 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); 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: public:
typedef custom_account_authority_delete_operation operation_type; typedef custom_account_authority_delete_operation operation_type;
@ -36,3 +37,4 @@ public:
} // namespace chain } // namespace chain
} // namespace graphene } // namespace graphene

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
@ -23,7 +24,6 @@ namespace graphene { namespace chain {
time_point_sec valid_to; time_point_sec valid_to;
}; };
struct by_id;
struct by_permission_and_op; struct by_permission_and_op;
struct by_expiration; struct by_expiration;
using custom_account_authority_multi_index_type = multi_index_container< using custom_account_authority_multi_index_type = multi_index_container<
@ -51,5 +51,8 @@ namespace graphene { namespace chain {
} } // graphene::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), 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. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
class custom_evaluator : public evaluator<custom_evaluator> class custom_evaluator : public fee_handling_evaluator<custom_evaluator>
{ {
public: public:
typedef custom_operation operation_type; typedef custom_operation operation_type;

View file

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

View file

@ -1,5 +1,9 @@
#pragma once #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/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
@ -25,7 +29,6 @@ namespace graphene { namespace chain {
authority auth; authority auth;
}; };
struct by_id;
struct by_account_and_permission; struct by_account_and_permission;
using custom_permission_multi_index_type = multi_index_container< using custom_permission_multi_index_type = multi_index_container<
custom_permission_object, custom_permission_object,
@ -45,5 +48,8 @@ namespace graphene { namespace chain {
} } // graphene::chain } } // graphene::chain
MAP_OBJECT_ID_TO_TYPE(graphene::chain::custom_permission_object)
FC_REFLECT_DERIVED( graphene::chain::custom_permission_object, (graphene::db::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. * THE SOFTWARE.
*/ */
#pragma once #pragma once
#include <graphene/chain/global_property_object.hpp> #include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/node_property_object.hpp> #include <graphene/chain/node_property_object.hpp>
#include <graphene/chain/account_object.hpp> #include <graphene/chain/account_object.hpp>
@ -30,18 +31,20 @@
#include <graphene/chain/block_database.hpp> #include <graphene/chain/block_database.hpp>
#include <graphene/chain/genesis_state.hpp> #include <graphene/chain/genesis_state.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/betting_market_object.hpp>
#include <graphene/db/object_database.hpp> #include <graphene/db/object_database.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
#include <graphene/db/simple_index.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/signals.hpp>
#include <fc/crypto/hash_ctr_rng.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 <fc/log/logger.hpp>
#include <map> #include <map>
@ -51,6 +54,15 @@ namespace graphene { namespace chain {
using graphene::db::object; using graphene::db::object;
class op_evaluator; class op_evaluator;
class transaction_evaluation_state; 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; struct budget_record;
@ -63,11 +75,9 @@ namespace graphene { namespace chain {
public: public:
//////////////////// db_management.cpp //////////////////// //////////////////// db_management.cpp ////////////////////
database(); database(bool allow_testing_edits = false);
~database(); ~database();
std::vector<fc::time_point_sec> _hardfork_times;
enum validation_steps enum validation_steps
{ {
skip_nothing = 0, skip_nothing = 0,
@ -245,16 +255,7 @@ namespace graphene { namespace chain {
witness_id_type get_scheduled_witness(uint32_t slot_num)const; witness_id_type get_scheduled_witness(uint32_t slot_num)const;
/** /**
* @brief Get son schedule id for the given sidechain_type. * @brief Get the son scheduled for block production in a slot.
*
* 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.
* *
* slot_num always corresponds to a time in the future. * 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 * 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. * 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; vector<witness_id_type> get_near_witness_schedule()const;
void update_witness_schedule(); void update_witness_schedule();
void update_witness_schedule(const signed_block& next_block); void update_witness_schedule(const signed_block& next_block);
void update_son_schedule(sidechain_type type); void update_son_schedule();
void update_son_schedule(sidechain_type type, const signed_block& next_block); void update_son_schedule(const signed_block& next_block);
void check_lottery_end_by_participants( asset_id_type asset_id ); void check_lottery_end_by_participants( asset_id_type asset_id );
void check_ending_lotteries(); void check_ending_lotteries();
@ -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 ); 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 ); 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_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); bool is_asset_creation_allowed(const string& symbol);
time_point_sec head_block_time()const; time_point_sec head_block_time()const;
@ -343,15 +344,52 @@ namespace graphene { namespace chain {
void initialize_evaluators(); void initialize_evaluators();
/// Reset the object graph in-memory /// Reset the object graph in-memory
void initialize_indexes(); void initialize_indexes();
void initialize_hardforks();
void init_genesis(const genesis_state_type& genesis_state = genesis_state_type()); 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> template<typename EvaluatorType>
void register_evaluator() op_evaluator::evaluator_handle register_third_party_evaluator()
{ {
_operation_evaluators[ return register_evaluator<EvaluatorType, true>(_third_party_operation_evaluators);
operation::tag<typename EvaluatorType::operation_type>::value].reset( new op_evaluator_impl<EvaluatorType>() ); }
/**
* @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 //////////////////// //////////////////// db_balance.cpp ////////////////////
@ -416,6 +454,12 @@ namespace graphene { namespace chain {
void debug_dump(); void debug_dump();
void apply_debug_updates(); void apply_debug_updates();
void debug_update( const fc::variant_object& update ); 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 //////////////////// //////////////////// db_market.cpp ////////////////////
@ -520,16 +564,47 @@ namespace graphene { namespace chain {
void notify_changed_objects(); void notify_changed_objects();
private: private:
std::mutex _pending_tx_session_mutex;
optional<undo_database::session> _pending_tx_session; 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> template<class Index>
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(size_t count)const; 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 //////////////////// //////////////////// db_block.cpp ////////////////////
public: public:
@ -579,22 +654,19 @@ namespace graphene { namespace chain {
void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const; void initialize_budget_record( fc::time_point_sec now, budget_record& rec )const;
void process_budget(); void process_budget();
void pay_workers( share_type& budget ); void pay_workers( share_type& budget );
void pay_sons_before_hf_ethereum(); void pay_sons();
void pay_sons_after_hf_ethereum();
void perform_son_tasks(); void perform_son_tasks();
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props); void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
void update_active_witnesses(); void update_active_witnesses();
void update_active_committee_members(); void update_active_committee_members();
void update_son_metrics( const 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 update_active_sons();
void remove_son_proposal( const proposal_object& proposal ); 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_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 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, void update_son_statuses( const vector<son_info>& cur_active_sons, const vector<son_info>& new_active_sons );
const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons ); void update_son_wallet( const vector<son_info>& new_active_sons );
void update_son_wallet( const flat_map<sidechain_type, vector<son_sidechain_info> >& new_active_sons );
void update_worker_votes(); void update_worker_votes();
void hotfix_2024();
public: public:
double calculate_vesting_factor(const account_object& stake_account); 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; vector< processed_transaction > _pending_tx;
fork_database _fork_db; fork_database _fork_db;
@ -636,13 +707,7 @@ namespace graphene { namespace chain {
vector<uint64_t> _vote_tally_buffer; vector<uint64_t> _vote_tally_buffer;
vector<uint64_t> _witness_count_histogram_buffer; vector<uint64_t> _witness_count_histogram_buffer;
vector<uint64_t> _committee_count_histogram_buffer; vector<uint64_t> _committee_count_histogram_buffer;
flat_map<sidechain_type, vector<uint64_t> > _son_count_histogram_buffer = []{ 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; uint64_t _total_voting_stake;
flat_map<uint32_t,block_id_type> _checkpoints; 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 chain_property_object* _p_chain_property_obj = nullptr;
const witness_schedule_object* _p_witness_schedule_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 namespace detail

View file

@ -24,19 +24,22 @@
#pragma once #pragma once
#include <graphene/chain/exceptions.hpp> #include <graphene/chain/exceptions.hpp>
#include <graphene/chain/transaction_evaluation_state.hpp> #include <graphene/chain/transaction_evaluation_state.hpp>
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
class database; class database;
struct signed_transaction; class consensus_evaluator;
class generic_evaluator;
class transaction_evaluation_state; 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: public:
virtual ~generic_evaluator(){} virtual ~consensus_evaluator(){}
virtual int get_type()const = 0; virtual int get_type()const = 0;
virtual operation_result start_evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply); 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 class op_evaluator
{ {
protected:
unique_ptr<op_evaluator> next_evaluator;
public: 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 ~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; 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 class op_evaluator_impl : public op_evaluator
{ {
public: 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 virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply = true) override
{ {
operation_result result;
try {
T eval; T eval;
return eval.start_evaluate(eval_state, op, apply); 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> template<typename DerivedEvaluator>
class evaluator : public generic_evaluator class fee_handling_evaluator : public consensus_evaluator
{ {
public: public:
virtual int get_type()const override { return operation::tag<typename DerivedEvaluator::operation_type>::value; } virtual int get_type()const override { return operation::tag<typename DerivedEvaluator::operation_type>::value; }
@ -174,4 +241,32 @@ namespace graphene { namespace chain {
return result; 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 #pragma once
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/evaluator.hpp> #include <graphene/chain/evaluator.hpp>
#include <graphene/chain/database.hpp> #include <graphene/chain/database.hpp>
#include <graphene/chain/event_object.hpp>
#include <graphene/protocol/operations.hpp>
namespace graphene { namespace chain { 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: public:
typedef event_create_operation operation_type; typedef event_create_operation operation_type;
@ -40,7 +42,7 @@ namespace graphene { namespace chain {
event_group_id_type event_group_id; 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: public:
typedef event_update_operation operation_type; typedef event_update_operation operation_type;
@ -51,7 +53,7 @@ namespace graphene { namespace chain {
event_group_id_type event_group_id; 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: public:
typedef event_update_status_operation operation_type; typedef event_update_status_operation operation_type;

View file

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

View file

@ -23,9 +23,11 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
#include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/composite_key.hpp>
namespace graphene { namespace chain { 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; typedef generic_index<event_group_object, event_group_object_multi_index_type> event_group_object_index;
} } // graphene::chain } } // 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) ) FC_REFLECT_DERIVED( graphene::chain::event_group_object, (graphene::db::object), (name)(sport_id) )

View file

@ -23,14 +23,17 @@
*/ */
#pragma once #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/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
#include <graphene/chain/protocol/event.hpp>
#include <sstream>
#include <boost/multi_index/composite_key.hpp> #include <boost/multi_index/composite_key.hpp>
#include <sstream>
namespace graphene { namespace chain { namespace graphene { namespace chain {
class event_object; class event_object;
} } } }
@ -159,52 +162,8 @@ typedef generic_index<event_object, event_object_multi_index_type> event_object_
} }
} } // graphene::chain } } // graphene::chain
namespace fc { MAP_OBJECT_ID_TO_TYPE(graphene::chain::event_object)
template<> FC_REFLECT_DERIVED(graphene::chain::event_object, (graphene::db::object),
template<> (name)(season)(start_time)(event_group_id)(at_least_one_betting_market_group_settled)(scores))
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);
}
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 <boost/exception/diagnostic_information.hpp>
#include <fc/exception/exception.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, ... ) \ #define GRAPHENE_ASSERT( expr, exc_type, FORMAT, ... ) \
FC_MULTILINE_MACRO_BEGIN \ FC_MULTILINE_MACRO_BEGIN \
@ -33,15 +36,26 @@
FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \ FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \
FC_MULTILINE_MACRO_END FC_MULTILINE_MACRO_END
#define GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \ #define GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \
FC_DECLARE_DERIVED_EXCEPTION( \ 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, \ op_name ## _validate_exception, \
graphene::chain::operation_validate_exception, \ graphene::chain::operation_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value, \ 3040000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation validation exception" \ #op_name "_operation validation exception" \
) \ ) \
FC_DECLARE_DERIVED_EXCEPTION( \ FC_IMPLEMENT_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \ op_name ## _evaluate_exception, \
graphene::chain::operation_evaluate_exception, \ graphene::chain::operation_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value, \ 3050000 + 100 * operation::tag< op_name ## _operation >::value, \
@ -50,6 +64,14 @@
#define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ #define GRAPHENE_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \ 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, \ op_name ## _ ## exc_name, \
graphene::chain::op_name ## _validate_exception, \ graphene::chain::op_name ## _validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \ 3040000 + 100 * operation::tag< op_name ## _operation >::value \
@ -59,6 +81,14 @@
#define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \ #define GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \ 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, \ op_name ## _ ## exc_name, \
graphene::chain::op_name ## _evaluate_exception, \ graphene::chain::op_name ## _evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \ 3050000 + 100 * operation::tag< op_name ## _operation >::value \
@ -91,30 +121,21 @@
namespace graphene { namespace chain { namespace graphene { namespace chain {
FC_DECLARE_EXCEPTION( chain_exception, 3000000, "blockchain exception" ) FC_DECLARE_EXCEPTION( chain_exception, 3000000 )
FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, graphene::chain::chain_exception, 3010000, "database query exception" ) FC_DECLARE_DERIVED_EXCEPTION( database_query_exception, chain_exception, 3010000 )
FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, graphene::chain::chain_exception, 3020000, "block validation exception" ) FC_DECLARE_DERIVED_EXCEPTION( block_validate_exception, chain_exception, 3020000 )
FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, graphene::chain::chain_exception, 3030000, "transaction validation exception" ) FC_DECLARE_DERIVED_EXCEPTION( transaction_exception, chain_exception, 3030000 )
FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, graphene::chain::chain_exception, 3040000, "operation validation exception" ) FC_DECLARE_DERIVED_EXCEPTION( operation_validate_exception, chain_exception, 3040000 )
FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, graphene::chain::chain_exception, 3050000, "operation evaluation exception" ) FC_DECLARE_DERIVED_EXCEPTION( operation_evaluate_exception, chain_exception, 3050000 )
FC_DECLARE_DERIVED_EXCEPTION( utility_exception, graphene::chain::chain_exception, 3060000, "utility method exception" ) FC_DECLARE_DERIVED_EXCEPTION( utility_exception, chain_exception, 3060000 )
FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, graphene::chain::chain_exception, 3070000, "undo database exception" ) FC_DECLARE_DERIVED_EXCEPTION( undo_database_exception, chain_exception, 3070000 )
FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, graphene::chain::chain_exception, 3080000, "unlinkable block" ) FC_DECLARE_DERIVED_EXCEPTION( unlinkable_block_exception, chain_exception, 3080000 )
FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, graphene::chain::chain_exception, 3090000, "black swan" ) FC_DECLARE_DERIVED_EXCEPTION( black_swan_exception, chain_exception, 3090000 )
FC_DECLARE_DERIVED_EXCEPTION( plugin_exception, graphene::chain::chain_exception, 3100000, "plugin exception" ) 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( insufficient_feeds, chain_exception, 37006 )
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( invalid_pts_address, graphene::chain::utility_exception, 3060001, "invalid pts address" ) FC_DECLARE_DERIVED_EXCEPTION( pop_empty_chain, undo_database_exception, 3070001 )
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" )
GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer ); GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer );
GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( from_account_not_whitelisted, transfer, 1, "owner mismatch" ) 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_BASE_EXCEPTIONS( blind_transfer );
GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" ); GRAPHENE_DECLARE_OP_EVALUATE_EXCEPTION( unknown_commitment, blind_transfer, 1, "Attempting to claim an unknown prior commitment" );
/* //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( transfer_from_blind_operation )
FC_DECLARE_DERIVED_EXCEPTION( addition_overflow, graphene::chain::chain_exception, 30002, "addition overflow" ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_fees_operation )
FC_DECLARE_DERIVED_EXCEPTION( subtraction_overflow, graphene::chain::chain_exception, 30003, "subtraction overflow" ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( bid_collateral_operation )
FC_DECLARE_DERIVED_EXCEPTION( asset_type_mismatch, graphene::chain::chain_exception, 30004, "asset/price mismatch" ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_claim_pool_operation )
FC_DECLARE_DERIVED_EXCEPTION( unsupported_chain_operation, graphene::chain::chain_exception, 30005, "unsupported chain operation" ) //GRAPHENE_DECLARE_OP_BASE_EXCEPTIONS( asset_update_issuer_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" )
*/
#define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \ #define GRAPHENE_RECODE_EXC( cause_type, effect_type ) \
catch( const cause_type& e ) \ catch( const cause_type& e ) \

View file

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

View file

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

View file

@ -22,7 +22,9 @@
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#pragma once #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_container.hpp>
#include <boost/multi_index/member.hpp> #include <boost/multi_index/member.hpp>

View file

@ -24,9 +24,16 @@
#pragma once #pragma once
#include <graphene/chain/rock_paper_scissors.hpp> #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 <graphene/db/generic_index.hpp>
#include <fc/crypto/hex.hpp> #include <fc/crypto/hex.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <sstream> #include <sstream>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -154,60 +161,18 @@ namespace graphene { namespace chain {
return s; return s;
} }
} } } }
MAP_OBJECT_ID_TO_TYPE(graphene::chain::game_object)
FC_REFLECT_ENUM(graphene::chain::game_state, FC_REFLECT_ENUM(graphene::chain::game_state,
(game_in_progress) (game_in_progress)
(expecting_commit_moves) (expecting_commit_moves)
(expecting_reveal_moves) (expecting_reveal_moves)
(game_complete)) (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 #pragma once
#include <graphene/chain/protocol/address.hpp> #include <graphene/protocol/address.hpp>
#include <graphene/chain/protocol/chain_parameters.hpp> #include <graphene/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/chain/immutable_chain_parameters.hpp> #include <graphene/chain/immutable_chain_parameters.hpp>
#include <fc/crypto/sha256.hpp> #include <fc/crypto/sha256.hpp>

View file

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

View file

@ -23,7 +23,8 @@
*/ */
#pragma once #pragma once
#include <graphene/chain/protocol/types.hpp> #include <graphene/chain/types.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp> #include <graphene/db/generic_index.hpp>
@ -49,4 +50,6 @@ typedef generic_index<global_betting_statistics_object, global_betting_statistic
} } // graphene::chain } } // 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) ) 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 #pragma once
#include <fc/uint128.hpp> #include <fc/uint128.hpp>
#include <graphene/chain/protocol/chain_parameters.hpp> #include <graphene/protocol/chain_parameters.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/son_info.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/son_sidechain_info.hpp> #include <graphene/chain/types.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/db/object.hpp> #include <graphene/db/object.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -52,15 +54,7 @@ namespace graphene { namespace chain {
uint32_t next_available_vote_id = 0; uint32_t next_available_vote_id = 0;
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
flat_map<sidechain_type, vector<son_sidechain_info> > active_sons = []() // updated once per maintenance interval vector<son_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;
}();
// n.b. witness scheduling is done by witness_schedule object // 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 * every time a block is found it decreases by
* RECENTLY_MISSED_COUNT_DECREMENT. It is * RECENTLY_MISSED_COUNT_DECREMENT. It is
* never less than 0. * 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; 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), FC_REFLECT_DERIVED( graphene::chain::dynamic_global_property_object, (graphene::db::object),
(random)
(head_block_number) (head_block_number)
(head_block_id) (head_block_id)
(time) (time)

View file

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

View file

@ -24,9 +24,9 @@
#pragma once #pragma once
#include <fc/container/flat.hpp> #include <fc/container/flat.hpp>
#include <graphene/chain/protocol/operations.hpp> #include <graphene/protocol/operations.hpp>
#include <graphene/chain/protocol/transaction.hpp> #include <graphene/protocol/transaction.hpp>
#include <graphene/chain/protocol/types.hpp> #include <graphene/protocol/types.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {

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