GithubHelp home page GithubHelp logo

steemit / steem Goto Github PK

View Code? Open in Web Editor NEW
1.9K 224.0 785.0 30.79 MB

The blockchain for Smart Media Tokens (SMTs) and decentralized applications.

Home Page: https://steem.com

License: Other

CMake 2.99% C++ 86.69% Perl 0.07% Python 4.84% Shell 0.79% Max 0.24% C 3.24% HTML 0.97% Dockerfile 0.16% Jinja 0.03%
steemit steem blockchain p2p-node social-network cpp

steem's Introduction

Steem - The Blockchain That Will Tokenize The Web

Welcome to the official repository for Steem, the blockchain that will revolutionize the web, and soon the blockchain for Smart Media Tokens!

Steem is the first blockchain which introduced the "Proof of Brain" social consensus algorithm for token allocation.

Being one of the most actively developed blockchain projects currently in existence, it's become fertile soil for entrepreneurial pursuits. It has also become home for many cryptocurrency centric projects.

Steem aims to be the preferred blockchain for dApp development with Smart Media Tokens at its core. With SMTs, everyone can leverage the power of Steem.

Originally, Steem was announced on the Bitcointalk forum prior to the start of any mining. (Steem is currently not mineable)

Documents

Advantages

  • Free Transactions (Resource Credits = Freemium Model)
  • Fast Block Confirmations (3 seconds)
  • Time Delay Security (Vested Steem & Savings)
  • Hierarchical Role Based Permissions (Keys)
  • Integrated Token Allocation
  • Smart Media Tokens (soon)
  • Lowest Entry-Barrier for User Adoption in the market
  • Dozens of dApps already built on Steem and many more to come

Technical Details

  • Currency symbol STEEM
  • SBD - Steem's very own stable coin with a one-way peg
  • Delegated Proof-of-Stake Consensus (DPOS)
  • 10% APR inflation narrowing to 1% APR over 20 years
    • 75% of inflation to "Proof of Brain" social consensus algorithm.
    • 15% of inflation to stakeholders.
    • 10% of inflation to block producers.

Installation

Getting started with Steem is fairly simple. You can either choose to use docker-images, build with docker manually or build from source directly. All steps have been documented and while many different OS are supported, the easiest one is Ubuntu 16.04.

Quickstart

Just want to get up and running quickly? We have pre-built Docker images for your convenience. More details are in our Quickstart Guide.

Building

We strongly recommend using one of our pre-built Docker images or using Docker to build Steem. Both of these processes are described in the Quickstart Guide.

But if you would still like to build from source, we also have build instructions for Linux (Ubuntu LTS) and macOS.

Dockerized P2P Node

To run a p2p node (ca. 2GB of memory is required at the moment):

docker run \
    -d -p 2001:2001 -p 8090:8090 --name steemd-default \
    steemit/steem

docker logs -f steemd-default  # follow along

Dockerized Full Node

To run a node with all the data (e.g. for supporting a content website) ca. 14GB of memory, and growing, is required:

docker run \
    --env USE_WAY_TOO_MUCH_RAM=1 --env USE_FULL_WEB_NODE=1 \
    -d -p 2001:2001 -p 8090:8090 --name steemd-full \
    steemit/steem

docker logs -f steemd-full

CLI Wallet

We provide a basic cli wallet for interfacing with steemd. The wallet is self-documented via command line help. The node you connect to via the cli wallet needs to be running the account_by_key_api, condenser_api, and needs to be configured to accept WebSocket connections via webserver-ws-endpoint.

Testing

See doc/devs/testing.md for test build targets and info on how to use lcov to check code test coverage.

Configuration

Config File

Run steemd once to generate a data directory and config file. The default location is witness_node_data_dir. Kill steemd. It won't do anything without seed nodes. If you want to modify the config to your liking, we have two example configs used in the docker images. ( consensus node, full node ) All options will be present in the default config file and there may be more options needing to be changed from the docker configs (some of the options actually used in images are configured via command line).

Seed Nodes

A list of some seed nodes to get you started can be found in doc/seednodes.txt.

This same file is baked into the docker images and can be overridden by setting STEEMD_SEED_NODES in the container environment at docker run time to a whitespace delimited list of seed nodes (with port).

Environment variables

There are quite a few environment variables that can be set to run steemd in different ways:

  • USE_WAY_TOO_MUCH_RAM - if set to true, steemd starts a 'full node'
  • USE_FULL_WEB_NODE - if set to true, a default config file will be used that enables a full set of API's and associated plugins.
  • USE_NGINX_FRONTEND - if set to true, this will enable an NGINX reverse proxy in front of steemd that proxies WebSocket requests to steemd. This will also enable a custom healthcheck at the path '/health' that lists how many seconds away from current blockchain time your node is. It will return a '200' if it's less than 60 seconds away from being synced.
  • USE_MULTICORE_READONLY - if set to true, this will enable steemd in multiple reader mode to take advantage of multiple cores (if available). Read requests are handled by the read-only nodes and write requests are forwarded back to the single 'writer' node automatically. NGINX load balances all requests to the reader nodes, 4 per available core. This setting is still considered experimental and may have trouble with some API calls until further development is completed.
  • HOME - set this to the path where you want steemd to store it's data files (block log, shared memory, config file, etc). By default /var/lib/steemd is used and exists inside the docker container. If you want to use a different mount point (like a ramdisk, or a different drive) then you may want to set this variable to map the volume to your docker container.

PaaS mode

Steemd now supports a PaaS mode (platform as a service) that currently works with Amazon's Elastic Beanstalk service. It can be launched using the following environment variables:

  • USE_PAAS - if set to true, steemd will launch in a format that works with AWS EB. Containers will exit upon failure so that they can be relaunched automatically by ECS. This mode assumes USE_WAY_TOO_MUCH_RAM and USE_FULL_WEB_NODE, they do not need to be also set.
  • S3_BUCKET - set this to the name of the S3 bucket where you will store shared memory files for steemd in Amazon S3. They will be stored compressed in bz2 format with the file name blockchain-$VERSION-latest.tar.bz2, where $VERSION is the release number followed by the git short commit hash stored in each docker image at /etc/steemdversion.
  • SYNC_TO_S3 - if set to true, the node will function to only generate shared memory files and upload them to the specified S3 bucket. This makes fast deployments and autoscaling for steemd possible.

System Requirements

For a full web node, you need at least 110GB of disk space available. Steemd uses a memory mapped file which currently holds 56GB of data and by default is set to use up to 80GB. The block log of the blockchain itself is a little over 27GB. It's highly recommended to run steemd on a fast disk such as an SSD or by placing the shared memory files in a ramdisk and using the --shared-file-dir=/path command line option to specify where. At least 16GB of memory is required for a full web node. Seed nodes (p2p mode) can run with as little as 4GB of memory with a 24 GB state file. Any CPU with decent single core performance should be sufficient. Steemd is constantly growing. As of August 2017, these numbers were accurate, but you may find you need more disk space to run a full node. We are also constantly working on optimizing Steem's use of disk space.

On Linux use the following Virtual Memory configuration for the initial sync and subsequent replays. It is not needed for normal operation.

echo    75 | sudo tee /proc/sys/vm/dirty_background_ratio
echo  1000 | sudo tee /proc/sys/vm/dirty_expire_centisecs
echo    80 | sudo tee /proc/sys/vm/dirty_ratio
echo 30000 | sudo tee /proc/sys/vm/dirty_writeback_centisecs

No Support & No Warranty

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.

steem's People

Contributors

abitmore avatar arhag avatar ausbitbank avatar bytemaster avatar dkedzierski avatar emfrias avatar gandalf-the-grey avatar jnordberg avatar joticajulian avatar jredbeard avatar kiwonik avatar mariusz-trela avatar mkochanowicz avatar mvandeberg avatar natebrune avatar piem avatar rajatsteemit avatar relativityboy avatar revflash avatar roadscape avatar scottsallinen avatar sgerbino avatar sneak avatar syvb avatar theoreticalbts avatar timcliff avatar vogel76 avatar wkedz avatar wkedzierski avatar youkaicountry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

steem's Issues

Create delete_comment operation

This operation will enable any comment that has no replies to be deleted by the author.

This is a superior alternative to leaving the database and permlink space polluted with content no one wants. It will still exist on the block chain history.

[HARDFORK] Withdraw Vesting cannot be set to 0

Currently the withdraw_vesting operation never allows the withdraw rate to be set back to 0. The current work around is to set it to 0.000001 VESTS, but this will generate unwanted transaction history / behavior for users.

Attack to steal SP using active authority only

I think updating the witness account to a new block signing key only requires active authority. This is a security concern because of how much power the block signing key has. An attacker that wants to steal a user's SP and has access to their active keys needs to:

  1. If the victim doesn't have enough votes already, the attacker uses some of their own SP to vote for the victim.
  2. The attacker predicts ahead of time roughly when the account will be scheduled as a runner-up witness. This is possible to do fairly accurately (ignoring large vote changes). Also, the attacker can err on predicting too early as much as they want with the only disadvantage being that the victim may be aware of compromise sooner.
  3. A reasonable amount of time before when the account is scheduled to be a runner-up witness, the attacker changes the victim's block signing key to one the attacker controls.
  4. The attacker intentionally double signs blocks under the victim's name and at the same time submits a proof of double sign to collect the victim's SP as a reward. It isn't guaranteed that the attacker will receive the reward, but the chances are good enough.

Alternative strategies to the above are:

  • If the user has enough votes to vote the victim into top 19, they don't need to make the predictions in step 2. They only need to signal to the victim that their account was compromised for less than 66 seconds before they are able to successfully finish their attack.
  • If the attacker has little voting power and doesn't want to wait too long for the victim to be a runner-up witness, the attacker may find it faster to instead solve a PoW under the victim's name (this also only requires active authority). For typical mining queue lengths (100), this means that the attacker signals to the victim that their account was compromised for less than 107 minutes before they are able to successfully finish their attack.

One potential fix for this problem is to allow providing a block_signing_key in the witness_update_operation to be optional (if none specified, the blockchain would just keep the previous signing key), and if a block_signing_key is specified, the blockchain would require the transaction containing the witness_update_operation to be signed by the owner authority of the corresponding account.

The problem with the above fix is that requires monitoring scripts that work by automatically detecting and switching over redundant block-signing witness nodes (by changing the block signing key) to keep the owner private key in the servers running the monitoring nodes. While signing keys currently give holders power over an account that owner authorities do not have (namely stealing SP as described in the above attack), it is also true that owner authorities have power over an account that signing key holders do not have (e.g. owning the account name). So a more elegant fix would be to take the above fix and modify it so that a witness_update_operation that changes the block signing key can also be validated by being included in a transaction signed by the current signing key (this won't mess up double signing proofs will it?). That way monitoring and switch-over management nodes need to hold all potential signing keys rather than the owner keys (those same keys are all necessarily on online servers anyway). And the user gets to keep their owner keys in cold storage where they belong.

Diluting influence of votes cast prior to HARDFORK_1 by 1,000,000 times?

If I understand what happened with the 1,000,000:1 SP change correctly, I believe it means that anyone who upvoted/downvoted a comment prior to HARDFORK_1 will have 1/1,000,000th the influence of someone voting after HARDFORK_1. Also, the vote retallying in HARDFORK_2 only adjusts votes for witnesses and not votes for comments, so that doesn't fix this issue either.

If I am correct in my understanding, doesn't that mean, to be fair to those who have voted already, a future hardfork prior to July 4th will be needed to retally the comment votes correctly (by multiplying the abs_rshares in this line by 1,000,000 for votes created prior to HARDFORK_1)?

Witness virtual scheduling issue

Current issues:

  1. if a witness is voted out of top 19, it will never be scheduled for time sharing (unless mass votes change?)
  2. if a running up witness went into miner queue, after come out, it will probably be on the top of running up queue for quite some rounds.

Please check my patch abitmore@24e8185 for possible fix.

Todo:

  1. add hard fork logic
  2. review adjust_witness_votes() to identify potential issues
  3. optimization against finding in a vector

Since I have no much time right now, please make your own decision on what's the best way to fix.

Serialization of UTF-8 characters

I am trying to allow UTF-8 encoded posting in piston. However I fail
to understand how the serialization in steem/fc works and why it is
encoded that way. Unless I am doing something wrong, the UTF-8 encoding
code by made more efficiency.

Steem does the following (the script 7532303236 comes from a valid
transaction constructed via cli_wallet):

from binascii import hexlify, unhexlify
>>> unhexlify("7532303236")
b'u2026'
>>> print("\u2026")
'โ€ฆ'

That's 5 bytes for a single UTF-8 character.

The same utf-8 character in python

>>> "โ€ฆ".encode('ascii', 'backslashreplace')
b'\\u2026'
>>> hexlify(b'\\u2026')
b'5c7532303236'      (note the extra 5c (backslash) at the beginning)

Can be encoded in only 3 bytes:

>>> hexlify(bytes("โ€ฆ", "utf-8"))
b'e280a6'
>>> print(unhexlify("e280a6").decode('utf-8'))
'โ€ฆ'

If I wanted to get python working with steem and UTF-8 characters, why
is your serialized code missing the escape backslash?

hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS

After the HARDFORK_4, the witness node will close itself with an Assert Exception if not started with --replay.

Assert Exception
hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS: Chain knows of more hardforks than configuration

1310495ms th_a       main.cpp:164                  main                 ] starting node
1311433ms th_a       database.cpp:95               open                 ] 10 assert_exception: Assert Exception
hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS: Chain knows of more hardforks than configuration
    {}
    th_a  database.cpp:2516 init_hardforks
1311433ms th_a       database.cpp:95               open                 ] data_dir: /home/bhuz/steem/programs/steemd/witness_node_data_dir/blockchain 
1311434ms th_a       application.cpp:353           startup              ] 10 assert_exception: Assert Exception
hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS: Chain knows of more hardforks than configuration
    {}
    th_a  database.cpp:2516 init_hardforks
rethrow
    {"data_dir":"/home/bhuz/steem/programs/steemd/witness_node_data_dir/blockchain"}
    th_a  database.cpp:95 open
1311434ms th_a       application.cpp:869           startup              ] 10 assert_exception: Assert Exception
hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS: Chain knows of more hardforks than configuration
    {}
    th_a  database.cpp:2516 init_hardforks
rethrow
    {"data_dir":"/home/bhuz/steem/programs/steemd/witness_node_data_dir/blockchain"}
    th_a  database.cpp:95 open
rethrow
    {}
    th_a  application.cpp:353 startup
1311434ms th_a       main.cpp:195                  main                 ] Exiting with error:
10 assert_exception: Assert Exception
hardforks.last_hardfork <= STEEMIT_NUM_HARDFORKS: Chain knows of more hardforks than configuration
    {}
    th_a  database.cpp:2516 init_hardforks
rethrow
    {"data_dir":"/home/bhuz/steem/programs/steemd/witness_node_data_dir/blockchain"}
    th_a  database.cpp:95 open
rethrow
    {}
    th_a  application.cpp:353 startup

update_witness_schedule issue?

According to the code, the logic in update_witness_schedule() executes every 21 blocks.

  • With this code, 21 elected witnesses and 1 time sharing witness are pushed;
  • with this code, one pow witness is pushed;

So in total 23 witnesses are pushed into the active_witnesses list, after shuffled, only the first 21 will produce blocks in this round (the last 2 won't have chance due to reschedule).

Am I missing something?

error when trying update_witness

ran

update_witness "steempty" "fmooo/steemd-docker" STM8LoQjQqJHvotqBo7HjnqmUbFW9oJ2theyqonzUd9DdJ7YYHsvD {"account_creation_fee":"100.000 STEEM","maximum_block_size":131072,"sbd_interest_rate":1000} true

also tried {} instead of the json

error

0 exception: unspecified
10 assert_exception: Assert Exception
o.fee >= std::max( asset( (STEEMIT_PRODUCER_APR * db().get_dynamic_global_properties().virtual_supply.amount.value) / (100*STEEMIT_BLOCKS_PER_YEAR), STEEM_SYMBOL), STEEMIT_MIN_PRODUCER_REWARD ):

Transfer VESTS

This feature was originally mentioned as an item in #8.

  • allow transfer of VESTS from one account to another
    • requires owner authority
    • requires the full balance to be transferred
    • verify votes update properly
    • receiving account has voting power as the min of 2 accounts
    • receiving account has bandwidth as sum of 2 accounts
    • account creation fee is destroyed

The goal behind this change was to allow centralization of VESTS for users. It also has the side effect of allowing VESTS to traded/sold but with severe drawbacks that STEEM does not have. Note the full balance of VESTS needs to be transferred. There currently exist many miner accounts with vesting balances <= 1.000000 VESTS. A market may exist to sell these VESTS, but in a short period of time those VESTS are going to be centralized into fewer accounts. The market demand for such large vesting balances will be small. Long term this change would be a simple way to users to transfer their funds and reputation to a new account or cash out immediately to another user wishing to enter the market or increase their power.

Immediately we realized we needed to add some consequences to such a transaction as both bandwidth and effective voting power are determined by the account's vesting balance and are both scarce resources. We determined summing the average bandwidths of both accounts and setting the voting power to the minimum of both accounts was sufficient to prevent exploiting this operation to increase access to these resources.

However, we came across another side effect that was not so easy to fix. The ability to transfer VESTS makes account creation free and enables severe name squatting. Consider the following scenario:

  • Alice creates the account "Bob" with the fee of 100.000 STEEM.
  • Alice transfers the VESTS from Bob back to herself retaining her original balance, but as VESTS.
  • Repeat until all of Alice's STEEM is held as VESTS.

Obviously, there needs to be some other restriction on the transferring of VESTS to prevent such abuse.

We have been brainstorming some ideas but have yet to come to a good solution. All of the ideas add a level of complication that indicates we have not arrived at a good solution yet. Because of this we are postponing the addition of this feature until we can iron out all the kinks.

HARDFORK - Precision on VESTS is insufficient for long-term use.

The VESTS symbol has a precision of 0.000001 which will be unable to accurately represent the result of converting 0.001 STEEM to VESTS once the ratio of total_vesting_fund_steem to total_vesting_shares reaches 1000. Rounding errors start having an impact much sooner.

We estimate that rounding errors will become an issue in as little as 6 months.

The solution is to increase the precision of VESTS by a factor of 1000000. It can be achieved by instantaneously multiplying all VESTS on the network by 1M on the hard-fork block and thereafter require the higher precision version of VESTS for all withdraw_vesting operations.

Values that need to be multiplied include:

  1. global_property_object::total_vesting_shares
  2. account::vesting_shares
  3. account::vesting_withdraw_rate

Additionally all places that use vesting_shares to derive additional computations which includes:

  1. bandwidth measurement
  2. reward shares
  3. witness voting

In all of these places, the additional precision required for VESTS is not nearly as relevant because they all depend upon % of total VESTS rather than absolute vests. So long as the calculated rshares retains the same magnitude of precision before and after the hard fork it should have relatively little impact.

Short Term Impact

If left unchanged then converting small amounts of STEEM to VESTS will result in increasingly large rounding errors. This will have the largest impact on:

  1. block producers and miners converting 1.000 STEEM at a time to VESTS
  2. content producers and curators earning small amounts of STEEM that get converted to VESTS

Questions to Ponder

How long will a precision of .000000000001 be sufficient for VESTS?

Rounding errors start having a measurable impact once the ratio of total_vesting_fund_steem to total_vesting_shares crosses 1M. This should happen once the STEEM supply crosses 1,000,000,000,000.000. The STEEM supply grows at about 500,000,000 STEEM per year initially and in the long term grows by 113% per year. This means that in as little as 10 years the STEEM supply could reach a point where VESTS precision is in trouble.

How will JavaScript represent total_vesting_shares?

1,000,000.000000000000 VESTS will require 2^60 bits which cannot be represented as an integer in JS (limit 2^53). This means it will have to be approximated in JS causing rounding errors in the user interface.

Should we implement a reverse-stock-split?

A reverse stock split will require the following:

  1. a block interval that is long enough to iterate over all accounts and update all balances
  2. support from all exchanges
  3. an update of all price feeds
  4. individuals with an odd balance will lose .001 STEEM.
  5. an update of price history to reflect the split.

The reverse-stock-split is the only long-term sustainable solution otherwise the number of bits required to represent balances will grow by 1.13 bits per year. The network needs 39 bits after 1 year, crosses 53 bits within just 10 years and outgrows 64 bits in less than 20 years.

The protocol as a whole can remain valid (not requiring changes to transaction structure) so long as users transact in STEEM amounts less than 64 bits. This maximum transaction size will shrink to 1% of all STEEM in less than 5 years after the 64 bit limit is hit.

Other options include:

  1. adopting some deterministic floating point - will still introduce rounding errors
  2. adopting 256 bit integers should allow the network to live for 100+ years

In the interest of keeping all numbers on a "human scale" implementing a 4:1 reverse-stock-split every 4 years should should keep all numbers within a friendly territory until the market has changed enough to justify an entire protocol upgrade. It has the added benefit of giving us over 3 years to implement.

0 bandwidth?

Looks like the rounding issue has taken effects already? With Current rate 31:1, new miners are now unable to convert STEEM to VESTS due to available bandwidth = 0.

  "vesting_shares": "0.031210 VESTS",
  "vesting_withdraw_rate": "0.000000 VESTS",
  "next_vesting_withdrawal": "1969-12-31T23:59:59",
  "withdrawn": 0,
  "to_withdraw": 0,
  "proxied_vsf_votes": 0,
  "average_bandwidth": 0,
  "lifetime_bandwidth": 0,
  "last_bandwidth_update": "1970-01-01T00:00:00",
  "average_market_bandwidth": 0,
  "last_market_bandwidth_update": "1970-01-01T00:00:00",
  "last_post": "1970-01-01T00:00:00"

//content is copied from #1

Plugin Operations

We are adding a system that will allow plugins to define their own set of operations which will be implemented through custom ops. These ops will use the same validate/apply convention as core operations. More details will come as the system is developed. The currently implemented private_message_plugin will be the first plugin to use these ops and will also be enabled in this hardfork.

Witness Version Communication

In hardfork 0_5_0 we will be adding some witness meta communication on the blockchain. We envision several uses for such a protocol, but we are going to start with something simple, and useful. Witnesses will begin broadcasting their Steem version on block production. This version is going to be used to enhance the current hardforking logic by triggering a hardfork when a super majority of witnesses have updated their nodes. This will allow us to release hardforks in a more reliable and speedy manner, specifically when we need to push emergency hardforks.

Request for pop blocks operation in debug_node_api

Ideally the debug_node_api would have a debug_pop_blocks method that will essentially "reverse time" and act like a block was never generated or pushed.

I found live debugging code to be a miserable experience because of the lack of this operation. I would realize after I had already generated blocks that I really wanted to know the state of the database some blocks ago. But I had no way to undo other than clearing the blockchain and starting all over again from an earlier snapshot that I copied in my filesystem. This slowed down my debugging process considerably.

Changing votes for witnesses does not adjust virtual_position and other related variables

See the lines that modify the witness votes here in account_witness_vote_evaluator::do_apply.

That code modifies the votes directly but does not make the necessary updates to virtual_position, virtual_last_update, and virtual_scheduled_time as is normally done here.

That means witnesses will incorrectly be using their old speeds in the virtual race to determine the runner-up witness, at least until the next time adjust_witness_votes is called on an account who happens to be voting for (either directly or via proxies) that particular witness.

Forking issue with 0.4.1: uniqueness constraint is violated

It's reported that 0.4.0 nodes are rejecting certain blocks produced by 0.4.1 node. Logs are here:

3480470ms th_a       steem_evaluator.cpp:569       do_apply             ] 10 assert_exception: Assert Exception
insert_result.second: Could not create object! Most likely a uniqueness constraint is violated.
    {}
    th_a  generic_index.hpp:63 create
3480470ms th_a       steem_evaluator.cpp:569       do_apply             ] o: {"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}
3480470ms th_a       database.cpp:1930             _apply_block         ] 10 assert_exception: Assert Exception
insert_result.second: Could not create object! Most likely a uniqueness constraint is violated.
    {}
    th_a  generic_index.hpp:63 create
rethrow
    {"o":{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}}
    th_a  steem_evaluator.cpp:569 do_apply

    {}
    th_a  evaluator.cpp:18 start_evaluate

    {}
    th_a  database.cpp:2075 apply_operation

    {"op":["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]}
    th_a  database.cpp:2056 _apply_transaction

    {"trx":{"ref_block_num":10724,"ref_block_prefix":3414704619,"expiration":"2016-05-10T08:58:06","operations":[["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]],"extensions":[],"signatures":[1f53abd8989022e6cceeb6690e41defdb5fbb3e5bcfec19992c0e32b3df6294aac2004f04fb2f799c9aa38579d89f16f3fe3fdea2aa934d6e73ca1aa5a5e2b2790"]}}
    th_a  database.cpp:2060 _apply_transaction
3480471ms th_a       database.cpp:558              _push_block          ] Failed to push new block:
10 assert_exception: Assert Exception
insert_result.second: Could not create object! Most likely a uniqueness constraint is violated.
    {}
    th_a  generic_index.hpp:63 create
rethrow
    {"o":{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}}
    th_a  steem_evaluator.cpp:569 do_apply

    {}
    th_a  evaluator.cpp:18 start_evaluate

    {}
    th_a  database.cpp:2075 apply_operation

    {"op":["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]}
    th_a  database.cpp:2056 _apply_transaction

    {"trx":{"ref_block_num":10724,"ref_block_prefix":3414704619,"expiration":"2016-05-10T08:58:06","operations":[["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]],"extensions":[],"signatures":["1f53abd8989022e6cceeb6690e41defdb5fbb3e5bcfec19992c0e32b3df6294aac2004f04fb2f799c9aa38579d89f16f3fe3fdea2aa934d6e73ca1aa5a5e2b2790"]}}
    th_a  database.cpp:2060 _apply_transaction
rethrow
    {}
    th_a  database.cpp:1930 _apply_block
3480471ms th_a       application.cpp:446           handle_block         ] Error when pushing block:
10 assert_exception: Assert Exception
insert_result.second: Could not create object! Most likely a uniqueness constraint is violated.
    {}
    th_a  generic_index.hpp:63 create
rethrow
    {"o":{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}}
    th_a  steem_evaluator.cpp:569 do_apply

    {}
    th_a  evaluator.cpp:18 start_evaluate

    {}
    th_a  database.cpp:2075 apply_operation

    {"op":["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]}
    th_a  database.cpp:2056 _apply_transaction

    {"trx":{"ref_block_num":10724,"ref_block_prefix":3414704619,"expiration":"2016-05-10T08:58:06","operations":[["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]],"extensions":[],"signatures":["1f53abd8989022e6cceeb6690e41defdb5fbb3e5bcfec19992c0e32b3df6294aac2004f04fb2f799c9aa38579d89f16f3fe3fdea2aa934d6e73ca1aa5a5e2b2790"]}}
    th_a  database.cpp:2060 _apply_transaction
rethrow
    {}
    th_a  database.cpp:1930 _apply_block

    {"new_block":{"previous":"001429e6d124925975b23c21c40d4150d37c45a2","timestamp":"2016-05-10T08:58:00","witness":"bitcube","transaction_merkle_root":"f7d0f8066a4615068e4e2e88be07d21b5ec59032","extensions":[],"witness_signature":"1f10ec56a5e53cfbf7d289c2931d7e151c4a1d1e9f4d4c97be55d9a424ece877076a67a180708b4ea80bf1783039798125e1b493d1926a42f1d2273891236230c4","transactions":[{"ref_block_num":10724,"ref_block_prefix":3414704619,"expiration":"2016-05-10T08:58:06","operations":[["vote",{"voter":"liondani","author":"liondani","permlink":"steem-a-blockchain-based-social-media-platform","weight":10000}]],"extensions":[],"signatures":["1f53abd8989022e6cceeb6690e41defdb5fbb3e5bcfec19992c0e32b3df6294aac2004f04fb2f799c9aa38579d89f16f3fe3fdea2aa934d6e73ca1aa5a5e2b2790"]}]}}
    th_a  database.cpp:564 _push_block

Error - segmentation fault - malloc_consolidate

This has happened a few times, usually 24-48 hours apart, finally caught it in gdb. This node powers steemd.com, a basic chain explorer. Server: Ubuntu 14.04 64bit.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff5c2e700 (LWP 32196)]
0x00007ffff6a30845 in malloc_consolidate (av=av@entry=0x7fffe8000020) at malloc.c:4165
4165    malloc.c: No such file or directory.
(gdb) bt
#0  0x00007ffff6a30845 in malloc_consolidate (av=av@entry=0x7fffe8000020) at malloc.c:4165
#1  0x00007ffff6a31df8 in _int_malloc (av=0x7fffe8000020, bytes=20128) at malloc.c:3423
#2  0x00007ffff6a347b0 in __GI___libc_malloc (bytes=20128) at malloc.c:2891
#3  0x00007ffff72f1dad in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x0000000000b46552 in websocketpp::endpoint<websocketpp::connection<fc::http::detail::asio_with_stub_log_and_deflate>, fc::http::detail::asio_with_stub_log_and_deflate>::create_connection() ()
#5  0x0000000000b46de5 in websocketpp::server<fc::http::detail::asio_with_stub_log_and_deflate>::start_accept(std::error_code&) ()
#6  0x0000000000b470b7 in websocketpp::server<fc::http::detail::asio_with_stub_log_and_deflate>::handle_accept(std::shared_ptr<websocketpp::connection<fc::http::detail::asio_with_stub_log_and_deflate> >, std::error_code const&) ()
#7  0x0000000000ac7c55 in std::_Function_handler<void (std::error_code const&), std::_Bind<std::_Mem_fn<void (websocketpp::server<fc::http::detail::asio_with_stub_log_and_deflate>::*)(std::shared_ptr<websocketpp::connection<fc::http::detail::asio_with_stub_log_and_deflate> >, std::error_code const&)> (websocketpp::server<fc::http::detail::asio_with_stub_log_and_deflate>*, std::shared_ptr<websocketpp::connection<fc::http::detail::asio_with_stub_log_and_deflate> >, std::_Placeholder<1>)> >::_M_invoke(std::_Any_data const&, std::error_code const&) ()
#8  0x0000000000b34b9c in websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::handle_accept(std::function<void (std::error_code const&)>, boost::system::error_code const&) ()
#9  0x0000000000b4e24d in void boost::asio::detail::strand_service::dispatch<boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::system::error_code> >(boost::asio::detail::strand_service::strand_impl*&, boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::system::error_code>&) ()
#10 0x0000000000b4e567 in void boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>::operator()<boost::system::error_code>(boost::system::error_code const&) ()
#11 0x0000000000b4e729 in boost::asio::detail::completion_handler<boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#12 0x0000000000b4e96f in void boost::asio::detail::strand_service::dispatch<boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> > >(boost::asio::detail::strand_service::strand_impl*&, boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> >&) ()
#13 0x0000000000b4ebaf in boost::asio::detail::reactive_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, boost::asio::ip::tcp, boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>::*)(std::function<void (std::error_code const&)>, boost::system::error_code const&)> (websocketpp::transport::asio::endpoint<fc::http::detail::asio_with_stub_log_and_deflate::transport_config>*, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running> >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#14 0x0000000000aba4a0 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#15 0x0000000000b5be1b in fc::asio::default_io_service_scope::default_io_service_scope()::{lambda()#1}::operator()() const ()
#16 0x0000000000c6567a in thread_proxy ()
#17 0x00007ffff7bc4182 in start_thread (arg=0x7ffff5c2e700) at pthread_create.c:312
#18 0x00007ffff6aac47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Allow Removal of up vote.

If someone makes a mistake while voting or their posting key is compromised, this operation will allow that vote to be removed resulting in the pending payout "as if it never happened".

When a vote is removed, the rshares earned by the vote are removed from the post and the voter loses any share of the voting rewards due them. They cannot vote again or change their vote.

Error - double free or corruption

First time I've seen this particular error:

3134293ms th_a       database_api.cpp:190          ~database_api_impl   ] freeing database api 117726992
3134296ms th_a       database_api.cpp:185          database_api_impl    ] creating database api 117730096
3134296ms th_a       websocket_api.cpp:88          on_message           ] message: {"jsonrpc":"2.0","method":"get_active_votes","params":["pharesim","ubuntu-14-04-miner-setup"],"id":0}
*** Error in `steem/programs/steemd/steemd': double free or corruption (fasttop): 0x00007fffe8214b20 ***
3134296ms th_a       database_api.cpp:190          ~database_api_impl   ] freeing database api 117730096

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff5c2e700 (LWP 5282)]
0x00007ffff69e8cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff69e8cc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff69ec0d8 in __GI_abort () at abort.c:89
#2  0x00007ffff6a25394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff6b33b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff6a3166e in malloc_printerr (ptr=<optimized out>, str=0x7ffff6b33cf0 "double free or corruption (fasttop)", action=1) at malloc.c:4996
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5  0x0000000000af4c1e in boost::asio::detail::reactive_socket_send_op<boost::asio::detail::consuming_buffers<boost::asio::const_buffer, std::vector<boost::asio::const_buffer, std::allocator<boost::asio::const_buffer> > >, boost::asio::detail::write_op<boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >, std::vector<boost::asio::const_buffer, std::allocator<boost::asio::const_buffer> >, boost::asio::detail::transfer_all_t, websocketpp::transport::asio::custom_alloc_handler<std::function<void (boost::system::error_code const&, unsigned long)> > > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#6  0x0000000000aba4a0 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#7  0x0000000000b5be1b in fc::asio::default_io_service_scope::default_io_service_scope()::{lambda()#1}::operator()() const ()
#8  0x0000000000c6567a in thread_proxy ()
#9  0x00007ffff7bc4182 in start_thread (arg=0x7ffff5c2e700) at pthread_create.c:312
#10 0x00007ffff6aac47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Ubuntu 14.04 64-bit

Strange behavior when switching witness signing key

I performed a witness server switch by swapping out the signing key.

The destination node had an unexpected hiccup, causing my missed blocks to go from 0.. to 1.
Without any intervention on my part, the issue resolved itself in time for the next block.

Is this a bug, and if not, how can I avoid it in the future?

Destination server:

641998ms th_a       witness.cpp:268               block_production_loo ] Not producing block for ${w} because I don't have the private key for STM6xg5F26etrTCmKVESbEoXJGy28VkUsxxjUBWjJtcSBmpS89bhW
645118ms th_a       application.cpp:437           handle_block         ] Got 1 transactions from network on block 921774
669060ms th_a       application.cpp:437           handle_block         ] Got 1 transactions from network on block 921782
683999ms th_a       database.cpp:1767             _apply_block         ] 10 assert_exception: Assert Exception
next_block.validate_signee( witness.signing_key ):
    {}
    th_a  database.cpp:1920 validate_block_header
683999ms th_a       database.cpp:557              _push_block          ] Failed to push new block:
10 assert_exception: Assert Exception
next_block.validate_signee( witness.signing_key ):
    {}
    th_a  database.cpp:1920 validate_block_header
rethrow
    {}
    th_a  database.cpp:1767 _apply_block
684000ms th_a       witness.cpp:373               maybe_produce_block  ] 10 assert_exception: Assert Exception
next_block.validate_signee( witness.signing_key ):
    {}
    th_a  database.cpp:1920 validate_block_header
rethrow
    {}
    th_a  database.cpp:1767 _apply_block

    {"new_block":{"previous":"000e10ba81d6228933b40b7f8bdd9df61ffd83e2","timestamp":"2016-04-26T07:11:24","witness":"roadscape","transaction_merkle_root":"ca857bbe721d731efc137d348eb91df840e92234","extensions":[],"witness_signature":"1f1d809fe5ab75fed1a9815f55d6cea3a73232183447fdbf035fff20f07fe9223c5bd05dbd504531f2d8db6e92f516f598c4169bc2a1e5634b276cd04b72a946f5","transactions":[{"ref_block_num":4282,"ref_block_prefix":2300761729,"expiration":"2016-04-26T07:11:51","operations":[["witness_update",{"owner":"roadscape","url":"https://steemd.com/@roadscape/witness-roadscape","block_signing_key":"STM5P5sgVcp8z3hYXVHsTZnZVLtyp8Hsrjsotan8XLsheVMicxMhS","props":{"account_creation_fee":"10.000 STEEM","maximum_block_size":131072,"sbd_interest_rate":1000},"fee":"0.000 STEEM"}]],"extensions":[],"signatures":["202c1e589141fa19dc99ef66a1b29c4e0c27bb667beea62be599f87a095ec1091b39375c290f6f365d52b76388849da03f55b62dff4c8ec1fb725d25564fa09c14"]}]}}
    th_a  database.cpp:563 _push_block

    {"witness_owner":"roadscape"}
    th_a  database.cpp:729 _generate_block
684000ms th_a       witness.cpp:374               maybe_produce_block  ] Clearing pending transactions and attempting again
684000ms th_a       witness.cpp:373               maybe_produce_block  ] 10 assert_exception: Assert Exception
witness_obj.signing_key == block_signing_private_key.get_public_key():
    {}
    th_a  database.cpp:642 _generate_block

    {"witness_owner":"roadscape"}
    th_a  database.cpp:729 _generate_block
684000ms th_a       witness.cpp:374               maybe_produce_block  ] Clearing pending transactions and attempting again
684000ms th_a       witness.cpp:280               block_production_loo ] Failure when producing block with no transactions
684998ms th_a       witness.cpp:268               block_production_loo ] Not producing block for ${w} because I don't have the private key for STM6xg5F26etrTCmKVESbEoXJGy28VkUsxxjUBWjJtcSBmpS89bhW
685998ms th_a       witness.cpp:268               block_production_loo ] Not producing block for ${w} because I don't have the private key for STM6xg5F26etrTCmKVESbEoXJGy28VkUsxxjUBWjJtcSBmpS89bhW
687180ms th_a       application.cpp:437           handle_block         ] Got 1 transactions from network on block 921787
690200ms th_a       application.cpp:437           handle_block         ] Got 1 transactions from network on block 921788
744000ms th_a       witness.cpp:256               block_production_loo ] Generated block #921806 with timestamp 2016-04-26T07:12:24 at time 2016-04-26T07:12:24 by roadscape
789001ms th_a       witness.cpp:256               block_production_loo ] Generated block #921821 with timestamp 2016-04-26T07:13:09 at time 2016-04-26T07:13:09 by roadscape
849000ms th_a       witness.cpp:256               block_production_loo ] Generated block #921840 with timestamp 2016-04-26T07:14:09 at time 2016-04-26T07:14:09 by roadscape

Source server:

498009ms th_a       witness.cpp:256               block_production_loo ] Generated block #921726 with timestamp 2016-04-26T07:08:18 at time 2016-04-26T07:08:18 by roadscape
561007ms th_a       witness.cpp:256               block_production_loo ] Generated block #921746 with timestamp 2016-04-26T07:09:21 at time 2016-04-26T07:09:21 by roadscape
570280ms th_a       application.cpp:431           handle_block         ] Got 1 transactions from network on block 921749
642007ms th_a       witness.cpp:256               block_production_loo ] Generated block #921773 with timestamp 2016-04-26T07:10:42 at time 2016-04-26T07:10:42 by roadscape
645211ms th_a       application.cpp:431           handle_block         ] Got 1 transactions from network on block 921774
669154ms th_a       application.cpp:431           handle_block         ] Got 1 transactions from network on block 921782
684005ms th_a       witness.cpp:268               block_production_loo ] Not producing block for ${w} because I don't have the private key for STM5P5sgVcp8z3hYXVHsTZnZVLtyp8Hsrjsotan8XLsheVMicxMhS

Bad HTTP response -- wrong status line: "\x00\x00\x00\x00\x00\x00\x00\x00 200 OK"

My steem node occasionally returns malformed data (over RPC) that the Ruby Net/HTTP lib chokes on.

Net::HTTPBadResponse -- wrong status line: "\x00\x00\x00\x00\x00\x00\x00\x00 200 OK"

I can't reproduce but it happens a few times per hour, on average.

I've not seen this error on any other graphene-based chains (including on the same server).

Any insight appreciated.

Error - corrupted double-linked list

Running Steem 0.2.0 (a212a04) on ubuntu 14.04:

5907ms th_a       database_api.cpp:194          ~database_api_impl   ] freeing database api 143979376
5909ms th_a       database_api.cpp:189          database_api_impl    ] creating database api 143527056
5909ms th_a       websocket_api.cpp:88          on_message           ] message: {"jsonrpc":"2.0","method":"get_accounts","params":[["xeroc"]],"id":0}
5909ms th_a       database_api.cpp:194          ~database_api_impl   ] freeing database api 143527056
*** Error in `steem/programs/steemd/steemd': corrupted double-linked list: 0x0000000001923640 ***

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7ffff3dd8700 (LWP 21646)]
0x00007ffff655bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff655bcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff655f0d8 in __GI_abort () at abort.c:89
#2  0x00007ffff6598394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff66a6b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff65a3ac2 in malloc_printerr (ptr=<optimized out>, str=0x7ffff66a2bfc "corrupted double-linked list", action=1) at malloc.c:4996
#4  malloc_consolidate (av=av@entry=0x7ffff68e3760 <main_arena>) at malloc.c:4165
#5  0x00007ffff65a456d in _int_free (av=0x7ffff68e3760 <main_arena>, p=<optimized out>, have_lock=0) at malloc.c:4057
#6  0x0000000000b1cd5a in websocketpp::http::parser::response::~response() ()
#7  0x0000000000b435e0 in websocketpp::connection<fc::http::detail::asio_with_stub_log>::~connection() ()
#8  0x00000000007b5639 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() ()
#9  0x0000000000aecc78 in std::_Function_base::_Base_manager<std::_Bind<std::_Mem_fn<void (websocketpp::connection<fc::http::detail::asio_with_stub_log>::*)(websocketpp::connection<fc::http::detail::asio_with_stub_log>::terminate_status, std::error_code const&)> (std::shared_ptr<websocketpp::connection<fc::http::detail::asio_with_stub_log> >, websocketpp::connection<fc::http::detail::asio_with_stub_log>::terminate_status, std::_Placeholder<1>)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) ()
#10 0x0000000000af30e3 in std::_Function_base::_Base_manager<std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation) ()
#11 0x0000000000b3b3f3 in boost::asio::detail::completion_handler<boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#12 0x0000000000b3b5df in void boost::asio::detail::strand_service::dispatch<boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> > >(boost::asio::detail::strand_service::strand_impl*&, boost::asio::detail::rewrapped_handler<boost::asio::detail::binder1<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)> >&) ()
#13 0x0000000000b3b97f in boost::asio::detail::wait_handler<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, std::_Bind<std::_Mem_fn<void (websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config>::*)(std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, boost::system::error_code const&)> (std::shared_ptr<websocketpp::transport::asio::connection<fc::http::detail::asio_with_stub_log::transport_config> >, std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock>, boost::asio::waitable_timer_service<std::chrono::_V2::steady_clock, boost::asio::wait_traits<std::chrono::_V2::steady_clock> > > >, std::function<void (std::error_code const&)>, std::_Placeholder<1>)>, boost::asio::detail::is_continuation_if_running> >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) ()
#14 0x0000000000ae3110 in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#15 0x0000000000b4ba5b in fc::asio::default_io_service_scope::default_io_service_scope()::{lambda()#1}::operator()() const ()
#16 0x0000000000c786ba in thread_proxy ()
#17 0x00007ffff7bc4182 in start_thread (arg=0x7ffff3dd8700) at pthread_create.c:312
#18 0x00007ffff661f47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Estimated time to produce becomes negative when target >= 31

The problem is with this line:

auto hashes = 1 << bits;

At least in my compiler (gcc), 1 << bits assumes a 32-bit signed integer, so when bits == 31, hashes becomes a negative number.

The easiest fix is to replace the line with:
auto hashes = 1ULL << bits;

I tried this and it worked on my computer. But this is only a temporary fix because if the mining queue becomes long enough (I think over 231) then this fix will also break. Perhaps the mining queue is unlikely to get that long and this is a good enough fix. Or maybe you guys want to come up with a more robust solution.

Separate hardfork constants per feature

The Steem hardfork numbering scheme used so far is different from Graphene. Each Steem hardfork time has a sequential number identifying the hardfork. However, the problem is that this confounds the code for several distinct features / bugfixes which take effect at the same time. For example STEEMIT_HARDFORK_1 is used to activate the following code:

  • Vesting share split
  • Asserting URL sizes in witness_update
  • Removing fees from witness account creation
  • Enforcing account creation fees
  • Forbidding updates of the temp account
  • Changing the permlink validation algorithm for comments
  • Removing the enforcement of once-per-minute posting time
  • Allowing zeroing vesting withdrawals
  • Enforcing minimum VESTS balance for withdrawal.

Each of these should have its own issue number which should be used to create a separate hardfork constant.

Witness node hang

The witness node sometimes just hang and stop receiving blocks.

I finally caught it in gdb.

Running steem v0.3.0 on Ubuntu 14.04 64bit

pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238
238 ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: No such file or directory.
(gdb) bt

0 pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:238

1 0x0000000000a13b68 in boost::cv_status boost::condition_variable::wait_until<boost::chrono::steady_clock, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > >(boost::unique_lockboost::mutex&, boost::chrono::time_point<boost::chrono::steady_clock, boost::chrono::duration<long, boost::ratio<1l, 1000000000l> > > const&) ()

2 0x0000000000a161a8 in fc::thread_d::process_tasks() ()

3 0x0000000000a16216 in fc::thread_d::start_process_tasks(long) ()

4 0x0000000000ca55f1 in make_fcontext ()

5 0x0000000000000000 in ?? ()

Block Timestamp Validation?

If a witness produces a block with a timestamp 100 years in the future, will the whole network get frozen / manipulated?
See cryptonomex/graphene#645 for reference.
Since miners are out of control, the issue in STEEM is much more serious than which in BitShares.

Prevent useless comment updates

Fail a comment_operation unless it contains data in the title, body, or json_metadata fields. This prevents a pointless and potentially unwanted update.

This is currently implemented. Creating issue for documentation.

Error - segmentation fault - __memcpy_sse2_unaligned

Forgot to post this, from a few days ago. Appears to be different from the others..

2525424ms th_a       database_api.cpp:194          ~database_api_impl   ] freeing database api 152340048
2525425ms th_a       database_api.cpp:189          database_api_impl    ] creating database api 152340048
2525425ms th_a       websocket_api.cpp:88          on_message           ] message: {"jsonrpc":"2.0","method":"get_accounts","params":[["danknugs"]],"id":0}

Program received signal SIGSEGV, Segmentation fault.

__memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
33      ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S: No such file or directory.
(gdb) bt
#0  __memcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/memcpy-sse2-unaligned.S:33
#1  0x00007ffff6ea3450 in std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007ffff6e9ac05 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x0000000000ae0d33 in websocketpp::http::parser::response::raw() const ()
#4  0x0000000000b11d8d in websocketpp::connection<fc::http::detail::asio_with_stub_log>::write_http_response(std::error_code const&) ()
#5  0x0000000000b11f76 in websocketpp::connection<fc::http::detail::asio_with_stub_log>::send_http_response() ()
#6  0x0000000000b19f1b in fc::detail::void_functor_run<fc::http::detail::websocket_server_impl::websocket_server_impl()::{lambda(std::weak_ptr<void>)#3}::operator()(std::weak_ptr<void>) const::{lambda()#1}::operator()() const::{lambda()#1}>::run(void*, {lambda()#1}) ()
#7  0x0000000000a2a1c3 in fc::task_base::run_impl() ()
#8  0x0000000000a2819e in fc::thread_d::process_tasks() ()
#9  0x0000000000a28426 in fc::thread_d::start_process_tasks(long) ()
#10 0x0000000000cba901 in make_fcontext ()
#11 0x0000000000000000 in ?? ()

Reserve Ratio is not Properly Capped

The bandwidth reserve ratio grows slowly over time without bound. This should be bounded to ensure the network can quickly recover from a spam attack.

Websocket Timer Expired

getting this error on 3 of my 4 servers (x86_64)

steem-cli_wallet -s ws://localhost:8040 -H 127.0.0.1:8042 --rpc-http-allowip=127.0.0.1
1349736ms th_a       main.cpp:101                  main                 ] allowed_ips: ["127.0.0.1"] 
Logging RPC to file: logs/rpc/rpc.log
Starting a new wallet
1349736ms th_a       main.cpp:154                  main                 ] wdata.ws_server: ws://localhost:8040 
0 exception: unspecified
Timer Expired
    {"message":"Timer Expired"}
    asio  websocket.cpp:439 operator()

    {"uri":"ws://localhost:8040"}
    th_a  websocket.cpp:624 connect

cmake

--   iostreams
--   coroutine
** websocketpp

=========== Used Build Configuration =============

-- ENABLE_CPP11        = ON
-- BUILD_EXAMPLES      = OFF
-- BUILD_TESTS         = OFF

-- WEBSOCKETPP_ROOT    = /home/jason/tmp/git/steem/libraries/fc/vendor/websocketpp
-- WEBSOCKETPP_BIN     = /home/jason/tmp/git/steem/libraries/fc/vendor/websocketpp/bin
-- WEBSOCKETPP_LIB     = /home/jason/tmp/git/steem/libraries/fc/vendor/websocketpp/lib
-- Install prefix      = /usr/local

-- WEBSOCKETPP_BOOST_LIBS        = 
-- WEBSOCKETPP_PLATFORM_LIBS     = 
-- WEBSOCKETPP_PLATFORM_TSL_LIBS = 

-- Finished fc module configuration...
-- 

             CONFIGURED FOR STEEM NETWORK             


-- 

             CONFIGURED FOR LOW MEMORY NODE          


-- Configuring done
-- Generating done

Built using boost 1.57 - 1.58 and 1.60 on 3 different x86_64 servers ubuntu 15.10 and Archlinux.
How do I connect with the cli-wallet?

CLI: format of static_variant type in result of help command

 >>> help
help
N2fc14static_variantIINS_14variant_objectEEEE about()
...
N2fc14static_variantIISt3setISsSt4lessISsESaISsEEEEE list_accounts(string, uint32_t)
...
N2fc14static_variantIISt3setISsSt4lessISsESaISsEEEEE list_witnesses(string, uint32_t)
...
steemit::chain::annotated_signed_transaction update_account_auth_account(string, N2fc14static_variantIIN7steemit6wallet14authority_typeEEEE, string, uint16_t, bool)
steemit::chain::annotated_signed_transaction update_account_auth_key(string, N2fc14static_variantIIN7steemit6wallet14authority_typeEEEE, steemit::chain::public_key_type, uint16_t, bool)
steemit::chain::annotated_signed_transaction update_account_auth_threshold(string, N2fc14static_variantIIN7steemit6wallet14authority_typeEEEE, uint32_t, bool)

Items for next hard fork

There are a number of soft fork changes we have made that need to be changed to hard forks.

  • Witness URL Size Check
if ( db.is_pruducing() )
   FC_ASSERT( url.size() <= 2048 );
  • Check Min Account Creation Fee
if( db().is_producing() )  {
   const witness_schedule_object& wso = db().get_witness_schedule_object();
   FC_ASSERT( o.fee >= wso.median_props.account_creation_fee, "Insufficient Fee: ${f} required, ${p} provided",
      ("f", wso.median_props.account_creation_fee)
      ("p", o.fee) );
}
  • ** Lower Min Account Creation Fee **
  • give witnesses more power / control
  • existing FEE is over $100 which is too high
  • new minimum 0.001 STEEM which is about as low as we can go
  • Check Witness Creation Fee
// TODO: Should be in next hardfork
   if ( db.is_producing() ) FC_ASSERT( o.fee >= std::max( asset( (STEEMIT_PRODUCER_APR * props.virtual_supply.amount.value) / (100*STEEMIT_BLOCKS_PER_YEAR), STEEM_SYMBOL), STEEMIT_MIN_PRODUCER_REWARD ) );

We have decided to remove witness creation fees altogether. This check needs to be removed in the hard fork

  • Permlink Validation
if( db().is_producing() )
{
   validate_permlink( o.parent_permlink );
   validate_permlink( o.permlink );
}
  • Reject TEMP Account
    • Reject any tx that ends with STEEMIT_TEMP_ACCOUNT not having correct authority
    • Reject any tx that ends with a balance in STEEMIT_TEMP_ACCOUNT

POSTPONED See #12

  • allow transfer of VESTS from one account to another
    • requires owner authority
    • requires the full balance to be transferred
    • verify votes update properly
    • receiving account has voting power as the min of 2 accounts
    • receiving account has bandwidth as sum of 2 accounts
    • account creation fee is destroyed

segfault when broadcasting a transaction

when broadcasting a transaction in OSX, the client invariably segfaults after having broadcasted it.

It happens because in here: https://github.com/steemit/steem/blob/master/libraries/app/api.cpp#L98 we have capture_this == nullptr.

After a quick analysis (I might be wrong but I think this is the issue), I believe this was introduced with this commit: 74e2412

The problem comes from the fact that shared_from_this() only works reliably when there already exists a shared_ptr from the class it is called, which was the case before, however after 74e2412 the explicit shared_ptr<network_broadcast_api>, etc. that were created upon login have been replaced with fc::api_ptr which is a generic pointer and breaks the promise of having a shared_ptr before (ie: the weak_ptr in std::enable_shared_from_this has not been initialized yet, see: http://en.cppreference.com/w/cpp/memory/enable_shared_from_this).

I have a hunch that the following issues might also be related to this: #10, #11, #26

Error - segmentation fault - _int_malloc

Running 0.4.1:

3183023ms th_a       database_api.cpp:195          database_api_impl    ] creating database api 169595440
3183023ms th_a       websocket_api.cpp:88          on_message           ] message: {"jsonrpc":"2.0","method":"get_active_votes","params":["thepresident","re-dantheman-re-thepresident-who-will-win-the-2016-u-20160503t192214102z-20160503t192447556z"],"id":0}
3183023ms th_a       database_api.cpp:200          ~database_api_impl   ] freeing database api 169595440

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff3dd8700 (LWP 30252)]
_int_malloc (av=0x7fffec000020, bytes=29) at malloc.c:3351
3351    malloc.c: No such file or directory.
(gdb) bt
#0  _int_malloc (av=0x7fffec000020, bytes=29) at malloc.c:3351
#1  0x00007ffff65a77b0 in __GI___libc_malloc (bytes=29) at malloc.c:2891
#2  0x00007ffff6e64dad in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff6ec0249 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x000000000087dd5e in char* std::string::_S_construct<char*>(char*, char*, std::allocator<char> const&, std::forward_iterator_tag) ()
#5  0x00007ffff6ec187c in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&, unsigned long, unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x0000000000b7dc15 in fc::console_appender::log(fc::log_message const&) ()
#7  0x0000000000adcfd0 in fc::logger::log(fc::log_message) ()
#8  0x0000000000b76168 in fc::asio::default_io_service_scope::default_io_service_scope()::{lambda()#1}::operator()() const ()
#9  0x0000000000ca539a in thread_proxy ()
#10 0x00007ffff7bc4182 in start_thread (arg=0x7ffff3dd8700) at pthread_create.c:312
#11 0x00007ffff661f47d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

adjust_witness_votes recursion issue

Test case:

Assume that STEEMIT_MAX_PROXY_RECURSION_DEPTH is 2.
Assume there are 5 accounts a1~a5, all have 1 VESTS.
Assume there is a witness w.

  • a1 vote for w, delta = 1
    • depth = 0: w.votes = 1
  • a2 set proxy a1, delta = 1
    • depth = 0: a1.proxied_vsf_votes = 0+1 = 1
    • depth = 1: w.votes = 1+1 = 2
  • a3 set proxy a2, delta = 1
    • depth = 0: a2.proxied_vsf_votes = 0+1 = 1
    • depth = 1: a1.proxied_vsf_votes = 1+1 = 2
    • depth = 2: w.votes = 2+1 = 3
  • a4 set proxy a3, delta = 1
    • depth = 0: a3.proxied_vsf_votes = 0+1 = 1
    • depth = 1: a2.proxied_vsf_votes = 1+1 = 2
    • depth = 2: a1.proxied_vsf_votes = 2+1 = 3
    • depth = 3: w.votes = 3+1 = 4
  • a5 set proxy a4, delta = 1
    • depth = 0: a4.proxied_vsf_votes = 0+1 = 1
    • depth = 1: a3.proxied_vsf_votes = 1+1 = 2
    • depth = 2: a2.proxied_vsf_votes = 2+1 = 3
    • depth = 3: a1.proxied_vsf_votes = 3+1 = 4
    • recursion end. w.votes remains 4
  • a1 vote for nobody, delta = -(4+1) = -5
    • depth = 0: w.votes = 4 + (-5) = -1

Huh?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.