Stacks Bootstrap Nodes - are there options?

According to documentation present here: Running a mainnet node | Stacks Docs, there are 3 bootstrap nodes.

02d[email protected]seed-0.mainnet.stacks.co:20444
02a[email protected]seed-1.mainnet.stacks.co:20444
036[email protected]seed-2.mainnet.stacks.co:20444

Is there anything special about these bootstrap nodes? Or can any Stacks Blockchain node act as a bootstrap node?

Also, what does “02da7a464ac770ae8337a343670778b93410f2f3fef6bea98dd1c3e9224459d36b” represent for the first bootstrap node? How do I get this value for my own node ?

Hello there!

There is nothing special about the 3 bootstrap nodes provided in the documentation, except perhaps that they are publicly available for free.

The hex value 02da… in [email protected]:20444 is the peer public key of the bootstrap node. The peer public key is derived from the local_peer_seed of the bootstrap node which is by default 0.

You can use your own node as a seed node to bootstrap other nodes. In your seed node config file, set the local_peer_seed to a private key. Then in the node you wish to initialize set the bootstrap node config file option to the seed node public key and host name.

You can use blockstack-cli to generate a key pair (source). Here secretKey is the private key and publicKey is the public key.

cargo run --bin blockstack-cli generate-sk

# Output
# {
#  secretKey: "b8d99fd45da58038d630d9855d3ca2466e8e0f89d3894c4724f0efc9ff4b51f001",
#  publicKey: "02781d2d3a545afdb7f6013a8241b9e400475397516a0d0f76863c6742210539b5",
#  stacksAddress: "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH"
# }

Keep in mind that:

  • your seed node must be up to date and synchronized.

  • the seed node need not be a mining node.

  • the local_peer_seed option, which is used for p2p network, is different from the seed option, which is used for mining. Perhaps the option seed should be renamed to mining_seed to avoid confusion.

1 Like

Thanks! Is there a recommended way or perhaps an example of how to create the public key / private key pair.

Would the following work for instance:
ssh-keygen -t ecdsa -b 521

This may work but the keys may be in a different format. I updated my reply above with instructions. Let me know if you have issues as I haven’t tested this.

Thanks. I was able to run that and generate the key pair. One more question is, if I have a running node that is fully synced, can I stop it and restart it with the local_peer_seed specified or would you recommend starting from scratch ?

You should be able to update the config and restart the node without issues. You can make a backup of the working directory in case you run into issues and need to revert.

You may consider making your new seed node publicly available to improve the bootstrapping decentralization.

2 Likes

I have restarted my node with the local_peer_seed option. But the /v2/info endpoint returns results that are a bit different from the seed nodes from the docs.

http://seed-0.mainnet.stacks.co:20443/v2/info returns:

{
"peer_version": 402653189,
"pox_consensus": "e9d035f270b39b9f1aefe6311bc9488dba7478ce",
"burn_block_height": 748345,
"stable_pox_consensus": "4926f8989ba9ed10f132431056168c1aaa339ebb",
"stable_burn_block_height": 748338,
"server_version": "stacks-node 2.05.0.2.2-rc1 (feat/unwrap-to-error:db3c7a2+, release build, linux [x86_64])",
"network_id": 1,
"parent_network_id": 3652501241,
"stacks_tip_height": 70670,
"stacks_tip": "42210d3d374763691e0e5b90fff1489cd7e9550325429c16e59588ab2c512ae8",
"stacks_tip_consensus_hash": "e9d035f270b39b9f1aefe6311bc9488dba7478ce",
"genesis_chainstate_hash": "74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b",
"unanchored_tip": "d405c0f5d1374dfc1d0558f078d6fb07fad6c697ff47a84cf9b16d12e89e2545",
"unanchored_seq": 0,
"exit_at_block_height": null,
"node_public_key": "0291949a58fe5f331f272fed3830f7b45e7e23157e933f1e109e96b6fb7489085d",
"node_public_key_hash": "e9af2766ab040b9eca56730876e12d280192f187"
}

But my node produces the following:

{
"peer_version": 402653189,
"pox_consensus": "e9d035f270b39b9f1aefe6311bc9488dba7478ce",
"burn_block_height": 748345,
"stable_pox_consensus": "4926f8989ba9ed10f132431056168c1aaa339ebb",
"stable_burn_block_height": 748338,
"server_version": "stacks-node 2.05.0.1.0 (master:de541f9, release build, linux [x86_64])",
"network_id": 1,
"parent_network_id": 3652501241,
"stacks_tip_height": 70670,
"stacks_tip": "42210d3d374763691e0e5b90fff1489cd7e9550325429c16e59588ab2c512ae8",
"stacks_tip_consensus_hash": "e9d035f270b39b9f1aefe6311bc9488dba7478ce",
"genesis_chainstate_hash": "74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b",
"unanchored_tip": "d405c0f5d1374dfc1d0558f078d6fb07fad6c697ff47a84cf9b16d12e89e2545",
"unanchored_seq": 0,
"exit_at_block_height": null
}

Any thoughts on the 2 missing attributes node_public_key & node_public_key_hash in my node and whether it is related to the local_peer_seed configuration.

Would you share your config file? Make sure to remove remove any keys.

I have now 2 seed nodes running and starting a 3rd node that is pointing to only my own 2 seed nodes and bitcoin full node and sync is working fine.

Crossing my fingers that the full sync can happen much faster than 5 days with this current set up.

Thanks for your help. Will make your initial response as the solution @igorsyl !!

This is great news! Keep in mind that if you control both the seed node and new node, you can duplicate the seed node’s working directory and use it to bootstrap the new node.

Yes. That indeed makes sense.

I am starting a new venture - https://burnchain.io to provide Stacks infrastructure as a service.

For individuals and teams to have their own nodes (especially API nodes) it seems to me they need to have their own blockchain node that syncs from the very beginning and forwards data block by block to their own API node. Is this not the case?

Also, generally the trust assumptions I reckon are quite different with me providing a copy of my working directory vs. providing a seed node in close network proximity (Same VPC or peered VPC or PrivateLink etc.,) to allow for faster sync times.

Coming here from twitter so i’m tagged on replies in this thread.
Really interesting idea, would love to help you out since I have a lot of experience here.

Thanks @jwiley ! The stacks-blockchain-docker project in github that y’all are working on has been a great help and resource to understand the intricacies.

I do have a ton of questions. But worry that I am being too intrusive and disrupting other work. Perhaps if you have time we can schedule a working session where I can bring all my questions at once instead of a million bites of your time.

1 Like

Not intrusive at all!

What you’re trying to do, namely run the blockchain/api/db is subjectively easy to do…but when you get into more complicated setups where you want things like failover, disaster recovery, blue-green deployments, read-only access to the API etc etc it gets a LOT more tricky.

Luckily, I’ve spent a lot of time looking into a lot of those things along with @Charlie at Hiro and I’m happy to give you some pointers and ideas on how you can accomplish what you’re trying to do.

It’s on my TODO list, but right now the docs on running an API are very much targeted for small devs (i.e. run all services on a single node). it works, but as you can imagine it makes scaling the deployment nearly impossible to do correctly or quickly.

In short - ask questions, if i have the answer i’m happy to help, or at the very least point you in the right direction.

@muthu.btc Additionally, if you’re planning on using Kubernetes to manage your container deployments, Hiro just authored a new series of Helm charts to help developers and entities run bitcoin, stacks-nodes, and APIs in a scalable and HA way!

Thanks @jwiley & @Charlie.

I do think a kubernetes based approach could work quite well for advanced development teams. I think though I need to crawl, walk, run for now.

Step 1 is for me to find a way to sync a new node (+api, +db, +explorer) from scratch within 2 days. Then make that available publicly at https://burnchain.io

Once that milestone is reached then that itself can be a service I can provide for others. Hope to have an initial sync budget of ~$30 (for 2 days of high compute/IO provisioned) and subsequently $30 a month to keep the node up and running. If I can hit this target then a lot more people can run their own nodes and reduce reliance on hiro’s infrastructure.

Next step is for me to scale up burnchain infrastructure (using serverless infrastructure as much as possible but also HA as much as possible) with a bit higher cost but not too high that other dev team cannot afford.

Final step might be to switch burnchain infrastructure to basically 99.99% availability likely leveraging kubernetes (and also provide that as an option for others).

Also, have information available for free for anyone that wants to just self-host and self-manage their infrastructure at all stages of my progress.

There is a parallel thread to all this which is running the whole thing on a raspberry pi 4. Waiting for PR 3199 to start executing on this.

Sorry for the rambling explanation :slight_smile:

Hi @muthu.btc, regarding:

Step 1 is for me to find a way to sync a new node (+api, +db, +explorer) from scratch within 2 days.

You may want to consider making a tarball of the working directory of a node you control and use it to bootstrap new nodes. You should have a fully synchronized node after the new nodes ingest any new blocks produced missing from the tarball. You can check the integrity of the new node by comparing the tip hash against your seed tip hash.

This method should allow you to bootstrap new nodes within minutes.

Yes @igorsyl I have indeed tested this and it does work quite well. Only problem is the only way to get a working API node and database is to sync a blockchain node from the beginning and have it forward data block by block to the API node.

Is there a way to create an API node + postgres database from a fully synced blockchain node ?

You should be able to archive the API node state (Postgres database) to bootstrap a new API node. @Charlie may know more about this.

@muthu.btc We (Hiro) recently started hosting synchronized archival datasets to download for the stacks-blockchain (2.05.0.2.2), API(v4.0.3), and postgres(v14).

You should be able to download and extract the contents (not needed for the pg archive, see below). The stacks-blockchain data can be dropped into the configured working directory on your node, and the API data, which should be just a TSV file, should be placed to where your API is configured to look for it (See example env variable config here).

The postgres data will need to be imported into an empty postgres database. You can do so without extracting the archive like so:

createdb stacks_node_api ENCODING=UTF8;
pg_restore -v -C -d stacks_node_api /var/validate_files/postgres/stacks_node_postgres.tar.gz
psql -c "alter user postgres with password '${PGPASSWORD}';"
psql -c "alter database stacks_node_api connection limit 100;"
psql -c "alter database stacks_node_api ALLOW_CONNECTIONS true;"

After setting this up, you should be able to bring all three up and it should hopefully just work. If you’re having issues, you may need to replay events from the API into the postgres database.

1 Like