Compare commits
60 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7566ac97b2 | ||
|
c4b528f9f6 | ||
|
fcda9d56e9 | ||
|
8f0cd4e456 | ||
|
382663aef6 | ||
|
ff79693568 | ||
|
517cebf7f0 | ||
|
fcae91d7fa | ||
|
c44d3139fd | ||
|
effd2fd835 | ||
|
2cd832521a | ||
|
77a4354b93 | ||
|
31f86158e8 | ||
|
29c892ee00 | ||
|
06e34ef1cf | ||
|
11bc11f0b7 | ||
|
8f27240211 | ||
|
b8f680d1e7 | ||
|
2d4a081c3c | ||
|
be5f879e42 | ||
|
8b353da83c | ||
|
61930c0dd3 | ||
|
232d2b3899 | ||
|
0f3a8314ae | ||
|
562034efe3 | ||
|
01c98c5e53 | ||
|
a4128e886a | ||
|
2589816245 | ||
|
0245e4cf94 | ||
|
2293ad20d5 | ||
|
c0195a2121 | ||
|
d203adc3d9 | ||
|
0249d53a14 | ||
|
1db0fbc77e | ||
|
82153f934f | ||
|
4f3f662cfe | ||
|
1942c47d73 | ||
|
a90281ad5c | ||
|
6360bac5e8 | ||
|
c54b23b9d5 | ||
|
04aaa714e6 | ||
|
2cc0ab2c5f | ||
|
aac0d7f2f5 | ||
|
9fd29b0575 | ||
|
6abe3c2804 | ||
|
01ce5beb19 | ||
|
2bd72318f6 | ||
|
68a9224604 | ||
|
181cad233c | ||
|
0b66529f11 | ||
|
e20e4180a9 | ||
|
de4309a905 | ||
|
d5248c936f | ||
|
40bc37266d | ||
|
1819f263f1 | ||
|
24a055e490 | ||
|
dfbd77f18d | ||
|
7c5557d69b | ||
|
d180eedd17 | ||
|
3b274ca8db |
42
.appveyor.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
version: '{build}'
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- /^v[0-9.]+\.[0-9.]+/
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- '%USERPROFILE%\.cargo'
|
||||||
|
- '%APPVEYOR_BUILD_FOLDER%\target'
|
||||||
|
|
||||||
|
clone_folder: d:\projects\solana
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- bash ci/publish-tarball.sh
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
- provider: Slack
|
||||||
|
incoming_webhook:
|
||||||
|
secure: GJsBey+F5apAtUm86MHVJ68Uqa6WN1SImcuIc4TsTZrDhA8K1QWUNw9FFQPybUWDyOcS5dly3kubnUqlGt9ux6Ad2efsfRIQYWv0tOVXKeY=
|
||||||
|
channel: ci-status
|
||||||
|
on_build_success: false
|
||||||
|
on_build_failure: true
|
||||||
|
on_build_status_changed: true
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
- provider: S3
|
||||||
|
access_key_id:
|
||||||
|
secure: fTbJl6JpFebR40J7cOWZ2mXBa3kIvEiXgzxAj6L3N7A=
|
||||||
|
secret_access_key:
|
||||||
|
secure: vItsBXb2rEFLvkWtVn/Rcxu5a5+2EwC+b7GsA0waJy9hXh6XuBAD0lnHd9re3g/4
|
||||||
|
bucket: release.solana.com
|
||||||
|
region: us-west-1
|
||||||
|
set_public: true
|
||||||
|
|
||||||
|
- provider: GitHub
|
||||||
|
auth_token:
|
||||||
|
secure: 81fEmPZ0cV1wLtNuUrcmtgxKF6ROQF1+/ft5m+fHX21z6PoeCbaNo8cTyLioWBj7
|
||||||
|
draft: false
|
||||||
|
prerelease: false
|
||||||
|
on:
|
||||||
|
appveyor_repo_tag: true
|
16
.buildkite/env/secrets.ejson
vendored
@@ -1,12 +1,14 @@
|
|||||||
{
|
{
|
||||||
"_public_key": "ae29f4f7ad2fc92de70d470e411c8426d5d48db8817c9e3dae574b122192335f",
|
"_public_key": "ae29f4f7ad2fc92de70d470e411c8426d5d48db8817c9e3dae574b122192335f",
|
||||||
"environment": {
|
"environment": {
|
||||||
"CODECOV_TOKEN": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:JnxhrIxh09AvqdJgrVSYmb7PxSrh19aE:07WzVExCHEd1lJ1m8QizRRthGri+WBNeZRKjjEvsy5eo4gv3HD7zVEm42tVTGkqITKkBNQ==]",
|
"CODECOV_TOKEN": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:ks2/ElgxwgxqgmFcxTHANNLmj23YH74h:U4uzRONRfiQyqy6HrPQ/e7OnBUY4HkW37R0iekkF3KJ9UGnHqT1UvwgVbDqLahtDIJ4rWw==]",
|
||||||
"CRATES_IO_TOKEN": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:d0jJqC32/axwzq/N7kMRmpxKhnRrhtpt:zvcPHwkOzGnjhNkAQSejwdy1Jkr9wR1qXFFCnfIjyt/XQYubzB1tLkoly/qdmeb5]",
|
"CRATES_IO_TOKEN": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:lKMh3aLW+jyRrfS/c7yvkpB+TaPhXqLq:j0v27EbaPgwRdHZAbsM0FlAnt3r9ScQrFbWJYOAZtM3qestEiByTlKpZ0eyF/823]",
|
||||||
"GEOLOCATION_API_KEY": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:R4gfB6Ey4i50HyfLt4UZDLBqg3qHEUye:UfZCOgt8XI6Y2g+ivCRVoS1fjFycFs7/GSevvCqh1B50mG0+hzpEyzXQLuKG5OeI]",
|
"GITHUB_TOKEN": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:Ll78c3jGpYqnTwR7HJq3mNNUC7pOv9Lu:GrInO2r8MjmP5c54szkyygdsrW5KQYkDgJQUVyFEPyG8SWfchyM9Gur8RV0a+cdwuxNkHLi4U2M=]",
|
||||||
"GITHUB_TOKEN": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:Vq2dkGTOzfEpRht0BAGHFp/hDogMvXJe:tFXHg1epVt2mq9hkuc5sRHe+KAnVREi/p8S+IZu67XRyzdiA/nGak1k860FXYuuzuaE0QWekaEc=]",
|
"INFLUX_DATABASE": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:IlH/ZLTXv3SwlY3TVyAPCX2KzLRY6iG3:gGmUGSU/kCfR/mTwKONaUC/X]",
|
||||||
"INFLUX_DATABASE": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:5KI9WBkXx3R/W4m256mU5MJOE7N8aAT9:Cb8QFELZ9I60t5zhJ9h55Kcs]",
|
"INFLUX_PASSWORD": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:o2qm95GU4VrrcC4OU06jjPvCwKZy/CZF:OW2ga3kLOQJvaDEdGRJ+gn3L2ckFm8AJZtv9wj/GeUIKDH2A4uBPTHsAH9PMe6zujpuHGk3qbeg=]",
|
||||||
"INFLUX_PASSWORD": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:hQRMpLCrav+OYkNphkeM4hagdVoZv5Iw:AUO76rr6+gF1OLJA8ZLSG8wHKXgYCPNk6gRCV8rBhZBJ4KwDaxpvOhMl7bxxXG6jol7v4aRa/Lk=]",
|
"INFLUX_USERNAME": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:yDWW/uIHsJqOTDYskZoSx3pzoB1vztWY:2z31oTA3g0Xs9fCczGNJRcx8xf/hFCed]",
|
||||||
"INFLUX_USERNAME": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:R7BNmQjfeqoGDAFTJu9bYTGHol2NgnYN:Q2tOT/EBcFvhFk+DKLKmVU7tLCpVC3Ui]"
|
"SOLANA_INSTALL_UPDATE_MANIFEST_KEYPAIR_x86_64_unknown_linux_gnu": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:RqRaHlYUvGPNFJa6gmciaYM3tRJTURUH:q78/3GTHCN3Uqx9z4nOBjPZcO1lOazNoB/mdhGRDFsnAqVd2hU8zbKkqLrZfLlGqyD8WQOFuw5oTJR9qWg6L9LcOyj3pGL8jWF2yjgZxdtNMXnkbSrCWLooWBBLT61jYQnEwg73gT8ld3Q8EVv3T+MeSMu6FnPz+0+bqQCAGgfqksP4hsUAJGzgZu+i0tNOdlT7fxnh5KJK/yFM/CKgN2sRwEjukA9hXsffyB61g2zqzTDJxCUDLbCVrCkA/bfUk7Of/t0W5t0nK1H3oyGZEc/lRMauCknDBka3Gz11dVss2QT19WQNh0u7bHVaT/U4lepX1j9Zv]",
|
||||||
|
"SOLANA_INSTALL_UPDATE_MANIFEST_KEYPAIR_x86_64_apple_darwin": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:wFDl3INEnA3EQDHRX40avqGe1OMoJxyy:6ncCRVRTIRuYI5o/gayeuWCudWvmKNYr8KEHAWeTq34a5bdcKInBdKhjmjX+wLHqsEwQ5gcyhcxy4Ri2mbuN6AHazfZOZlubQkGlyUOAIYO5D5jkbyIh40DAtjVzo1MD/0HsW9zdGOzqUKp5xJJeDsbR4F153jbxa7fvwF90Q4UQjYFTKAtExEmHtDGSJG48ToVwTabTV/OnISMIggDZBviIv2QWHvXgK07b2mUj34rHJywEDGN1nj5rITTDdUeRcB1x4BAMOe94kTFPSTaj/OszvYlGECt8rkKFqbm092qL+XLfiBaImqe/WJHRCnAj6Don]",
|
||||||
|
"SOLANA_INSTALL_UPDATE_MANIFEST_KEYPAIR_x86_64_pc_windows_msvc": "EJ[1:8iZ6baJB4fbBV+XDsrUooyGAnGL/8Ol+4Qd0zKh5YjI=:wAh+dBuZopv6vruVOYegUcq/aBnbksT1:qIJfCfDvDWiqicMOkmbJs/0n7UJLKNmgMQaKzeQ8J7Q60YpXbtWzKVW3tS6lzlgf64m3MrPXyo1C+mWh6jkjsb18T/OfggZy1ZHM4AcsOC6/ldUkV5YtuxUQuAmd5jCuV/R7iuYY8Z66AcfAevlb+bnLpgIifdA8fh/IktOo58nZUQwZDdppAacmftsLc6Frn5Er6A6+EXpxK1nmnlmLJ4AJztqlh6X0r+JvE2O7qeoZUXrIegnkxo7Aay7I/dd8zdYpp7ICSiTEtfVN/xNIu/5QmTRU7gWoz7cPl9epq4aiEALzPOzb6KVOiRcsOg+TlFvLQ71Ik5o=]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,18 +1,5 @@
|
|||||||
root: ./docs/src
|
root: ./book/src
|
||||||
|
|
||||||
structure:
|
structure:
|
||||||
readme: introduction.md
|
readme: introduction.md
|
||||||
summary: SUMMARY.md
|
summary: SUMMARY.md
|
||||||
|
|
||||||
redirects:
|
|
||||||
wallet: ./wallet-guide/README.md
|
|
||||||
wallet/app-wallets: ./wallet-guide/apps.md
|
|
||||||
wallet/app-wallets/trust-wallet: ./wallet-guide/trust-wallet.md
|
|
||||||
wallet/app-wallets/ledger-live: ./wallet-guide/ledger-live.md
|
|
||||||
wallet/cli-wallets: ./wallet-guide/cli.md
|
|
||||||
wallet/cli-wallets/paper-wallet: ./paper-wallet/README.md
|
|
||||||
wallet/cli-wallets/paper-wallet/paper-wallet-usage: ./paper-wallet/paper-wallet-usage.md
|
|
||||||
wallet/cli-wallets/remote-wallet: ./hardware-wallets/README.md
|
|
||||||
wallet/cli-wallets/remote-wallet/ledger: ./hardware-wallets/ledger.md
|
|
||||||
wallet/cli-wallets/file-system-wallet: ./file-system-wallet/README.md
|
|
||||||
wallet/support: ./wallet-guide/support.md
|
|
||||||
|
2
.github/stale.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
only: pulls
|
only: pulls
|
||||||
|
|
||||||
# Number of days of inactivity before a pull request becomes stale
|
# Number of days of inactivity before a pull request becomes stale
|
||||||
daysUntilStale: 7
|
daysUntilStale: 30
|
||||||
|
|
||||||
# Number of days of inactivity before a stale pull request is closed
|
# Number of days of inactivity before a stale pull request is closed
|
||||||
daysUntilClose: 7
|
daysUntilClose: 7
|
||||||
|
7
.gitignore
vendored
@@ -1,7 +1,5 @@
|
|||||||
/docs/html/
|
/book/html/
|
||||||
/docs/src/tests.ok
|
/book/src/tests.ok
|
||||||
/docs/src/cli/usage.md
|
|
||||||
/docs/src/.gitbook/assets/*.svg
|
|
||||||
/farf/
|
/farf/
|
||||||
/solana-release/
|
/solana-release/
|
||||||
/solana-release.tar.bz2
|
/solana-release.tar.bz2
|
||||||
@@ -17,7 +15,6 @@
|
|||||||
# log files
|
# log files
|
||||||
*.log
|
*.log
|
||||||
log-*.txt
|
log-*.txt
|
||||||
log-*/
|
|
||||||
|
|
||||||
# intellij files
|
# intellij files
|
||||||
/.idea/
|
/.idea/
|
||||||
|
56
.mergify.yml
@@ -19,27 +19,59 @@ pull_request_rules:
|
|||||||
label:
|
label:
|
||||||
add:
|
add:
|
||||||
- automerge
|
- automerge
|
||||||
- name: v1.0 backport
|
- name: v0.16 backport
|
||||||
conditions:
|
conditions:
|
||||||
- label=v1.0
|
- base=master
|
||||||
|
- label=v0.16
|
||||||
actions:
|
actions:
|
||||||
backport:
|
backport:
|
||||||
ignore_conflicts: true
|
|
||||||
branches:
|
branches:
|
||||||
- v1.0
|
- v0.16
|
||||||
- name: v1.1 backport
|
- name: v0.17 backport
|
||||||
conditions:
|
conditions:
|
||||||
- label=v1.1
|
- base=master
|
||||||
|
- label=v0.17
|
||||||
actions:
|
actions:
|
||||||
backport:
|
backport:
|
||||||
ignore_conflicts: true
|
|
||||||
branches:
|
branches:
|
||||||
- v1.1
|
- v0.17
|
||||||
- name: v1.2 backport
|
- name: v0.18 backport
|
||||||
conditions:
|
conditions:
|
||||||
- label=v1.2
|
- base=master
|
||||||
|
- label=v0.18
|
||||||
actions:
|
actions:
|
||||||
backport:
|
backport:
|
||||||
ignore_conflicts: true
|
|
||||||
branches:
|
branches:
|
||||||
- v1.2
|
- v0.18
|
||||||
|
- name: v0.19 backport
|
||||||
|
conditions:
|
||||||
|
- base=master
|
||||||
|
- label=v0.19
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- v0.19
|
||||||
|
- name: v0.20 backport
|
||||||
|
conditions:
|
||||||
|
- base=master
|
||||||
|
- label=v0.20
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- v0.20
|
||||||
|
- name: v0.21 backport
|
||||||
|
conditions:
|
||||||
|
- base=master
|
||||||
|
- label=v0.21
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- v0.21
|
||||||
|
- name: v0.22 backport
|
||||||
|
conditions:
|
||||||
|
- base=master
|
||||||
|
- label=v0.22
|
||||||
|
actions:
|
||||||
|
backport:
|
||||||
|
branches:
|
||||||
|
- v0.22
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
os:
|
os:
|
||||||
- osx
|
- osx
|
||||||
- windows
|
|
||||||
|
|
||||||
language: rust
|
language: rust
|
||||||
rust:
|
rust:
|
||||||
- stable
|
- 1.37.0
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- source ci/rust-version.sh
|
- source ci/rust-version.sh
|
||||||
|
- test $rust_stable = $TRAVIS_RUST_VERSION # Update .travis.yml rust version above when this fails
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- source ci/env.sh
|
- source ci/env.sh
|
||||||
@@ -16,7 +16,7 @@ script:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- /^v\d+\.\d+/
|
- /^v\d+\.\d+.\d+$/
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
slack:
|
slack:
|
||||||
|
270
CONTRIBUTING.md
@@ -1,41 +1,23 @@
|
|||||||
# Solana Coding Guidelines
|
Solana Coding Guidelines
|
||||||
|
===
|
||||||
|
|
||||||
The goal of these guidelines is to improve developer productivity by allowing
|
The goal of these guidelines is to improve developer productivity by allowing developers to
|
||||||
developers to jump into any file in the codebase and not need to adapt to
|
jump any file in the codebase and not need to adapt to inconsistencies in how the code is
|
||||||
inconsistencies in how the code is written. The codebase should appear as if it
|
written. The codebase should appear as if it had been authored by a single developer. If you
|
||||||
had been authored by a single developer. If you don't agree with a convention,
|
don't agree with a convention, submit a PR patching this document and let's discuss! Once
|
||||||
submit a PR patching this document and let's discuss! Once the PR is accepted,
|
the PR is accepted, *all* code should be updated as soon as possible to reflect the new
|
||||||
*all* code should be updated as soon as possible to reflect the new
|
|
||||||
conventions.
|
conventions.
|
||||||
|
|
||||||
## Pull Requests
|
Pull Requests
|
||||||
|
---
|
||||||
|
|
||||||
Small, frequent PRs are much preferred to large, infrequent ones. A large PR is
|
Small, frequent PRs are much preferred to large, infrequent ones. A large PR is difficult
|
||||||
difficult to review, can block others from making progress, and can quickly get
|
to review, can block others from making progress, and can quickly get its author into
|
||||||
its author into "rebase hell". A large PR oftentimes arises when one change
|
"rebase hell". A large PR oftentimes arises when one change requires another, which requires
|
||||||
requires another, which requires another, and then another. When you notice
|
another, and then another. When you notice those dependencies, put the fix into a commit of
|
||||||
those dependencies, put the fix into a commit of its own, then checkout a new
|
its own, then checkout a new branch, and cherrypick it. Open a PR to start the review
|
||||||
branch, and cherry-pick it.
|
process and then jump back to your original branch to keep making progress. Once the commit
|
||||||
|
is merged, you can use git-rebase to purge it from your original branch.
|
||||||
```bash
|
|
||||||
$ git commit -am "Fix foo, needed by bar"
|
|
||||||
$ git checkout master
|
|
||||||
$ git checkout -b fix-foo
|
|
||||||
$ git cherry-pick fix-bar
|
|
||||||
$ git push --set-upstream origin fix-foo
|
|
||||||
```
|
|
||||||
|
|
||||||
Open a PR to start the review process and then jump back to your original
|
|
||||||
branch to keep making progress. Consider rebasing to make your fix the first
|
|
||||||
commit:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ git checkout fix-bar
|
|
||||||
$ git rebase -i master <Move fix-foo to top>
|
|
||||||
```
|
|
||||||
|
|
||||||
Once the commit is merged, rebase the original branch to purge the
|
|
||||||
cherry-picked commit:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git pull --rebase upstream master
|
$ git pull --rebase upstream master
|
||||||
@@ -43,137 +25,26 @@ $ git pull --rebase upstream master
|
|||||||
|
|
||||||
### How big is too big?
|
### How big is too big?
|
||||||
|
|
||||||
If there are no functional changes, PRs can be very large and that's no
|
If there are no functional changes, PRs can be very large and that's no problem. If,
|
||||||
problem. If, however, your changes are making meaningful changes or additions,
|
however, your changes are making meaningful changes or additions, then about 1,000 lines of
|
||||||
then about 1,000 lines of changes is about the most you should ask a Solana
|
changes is about the most you should ask a Solana maintainer to review.
|
||||||
maintainer to review.
|
|
||||||
|
|
||||||
### Should I send small PRs as I develop large, new components?
|
### Should I send small PRs as I develop large, new components?
|
||||||
|
|
||||||
Add only code to the codebase that is ready to be deployed. If you are building
|
Add only code to the codebase that is ready to be deployed. If you are building a large
|
||||||
a large library, consider developing it in a separate git repository. When it
|
library, consider developing it in a separate git repository. When it is ready to be
|
||||||
is ready to be integrated, the Solana maintainers will work with you to decide
|
integrated, the Solana maintainers will work with you to decide on a path forward. Smaller
|
||||||
on a path forward. Smaller libraries may be copied in whereas very large ones
|
libraries may be copied in whereas very large ones may be pulled in with a package manager.
|
||||||
may be pulled in with a package manager.
|
|
||||||
|
|
||||||
## Getting Pull Requests Merged
|
|
||||||
|
|
||||||
There is no single person assigned to watching GitHub PR queue and ushering you
|
|
||||||
through the process. Typically, you will ask the person that wrote a component
|
|
||||||
to review changes to it. You can find the author using `git blame` or asking on
|
|
||||||
Discord. When working to get your PR merged, it's most important to understand
|
|
||||||
that changing the code is your priority and not necessarily a priority of the
|
|
||||||
person you need an approval from. Also, while you may interact the most with
|
|
||||||
the component author, you should aim to be inclusive of others. Providing a
|
|
||||||
detailed problem description is the most effective means of engaging both the
|
|
||||||
component author and other potentially interested parties.
|
|
||||||
|
|
||||||
Consider opening all PRs as Draft Pull Requests first. Using a draft PR allows
|
|
||||||
you to kickstart the CI automation, which typically takes between 10 and 30
|
|
||||||
minutes to execute. Use that time to write a detailed problem description. Once
|
|
||||||
the description is written and CI succeeds, click the "Ready to Review" button
|
|
||||||
and add reviewers. Adding reviewers before CI succeeds is a fast path to losing
|
|
||||||
reviewer engagement. Not only will they be notified and see the PR is not yet
|
|
||||||
ready for them, they will also be bombarded them with additional notifications
|
|
||||||
each time you push a commit to get past CI or until they "mute" the PR. Once
|
|
||||||
muted, you'll need to reach out over some other medium, such as Discord, to
|
|
||||||
request they have another look. When you use draft PRs, no notifications are
|
|
||||||
sent when you push commits and edit the PR description. Use draft PRs
|
|
||||||
liberally. Don't bug the humans until you have gotten past the bots.
|
|
||||||
|
|
||||||
### What should be in my PR description?
|
|
||||||
|
|
||||||
Reviewing code is hard work and generally involves an attempt to guess the
|
|
||||||
author's intent at various levels. Please assume reviewer time is scarce and do
|
|
||||||
what you can to make your PR as consumable as possible. Inspired by techniques
|
|
||||||
for writing good whitepapers, the guidance here aims to maximize reviewer
|
|
||||||
engagement.
|
|
||||||
|
|
||||||
Assume the reviewer will spend no more than a few seconds reading the PR title.
|
|
||||||
If it doesn't describe a noteworthy change, don't expect the reviewer to click
|
|
||||||
to see more.
|
|
||||||
|
|
||||||
Next, like the abstract of a whitepaper, the reviewer will spend ~30 seconds
|
|
||||||
reading the PR problem description. If what is described there doesn't look
|
|
||||||
more important than competing issues, don't expect the reviewer to read on.
|
|
||||||
|
|
||||||
Next, the reviewer will read the proposed changes. At this point, the reviewer
|
|
||||||
needs to be convinced the proposed changes are a *good* solution to the problem
|
|
||||||
described above. If the proposed changes, not the code changes, generates
|
|
||||||
discussion, consider closing the PR and returning with a design proposal
|
|
||||||
instead.
|
|
||||||
|
|
||||||
Finally, once the reviewer understands the problem and agrees with the approach
|
|
||||||
to solving it, the reviewer will view the code changes. At this point, the
|
|
||||||
reviewer is simply looking to see if the implementation actually implements
|
|
||||||
what was proposed and if that implementation is maintainable. When a concise,
|
|
||||||
readable test for each new code path is present, the reviewer can safely ignore
|
|
||||||
the details of its implementation. When those tests are missing, expect to
|
|
||||||
either lose engagement or get a pile of review comments as the reviewer
|
|
||||||
attempts to consider every ambiguity in your implementation.
|
|
||||||
|
|
||||||
### The PR Title
|
|
||||||
|
|
||||||
The PR title should contain a brief summary of the change, from the perspective
|
|
||||||
of the user. Examples of good titles:
|
|
||||||
|
|
||||||
* Add rent to accounts
|
|
||||||
* Fix out-of-memory error in validator
|
|
||||||
* Clean up `process_message()` in runtime
|
|
||||||
|
|
||||||
The conventions here are all the same as a good git commit title:
|
|
||||||
|
|
||||||
* First word capitalized and in the imperative mood, not past tense ("add", not
|
|
||||||
"added")
|
|
||||||
* No trailing period
|
|
||||||
* What was done, whom it was done to, and in what context
|
|
||||||
|
|
||||||
### The PR Problem Statement
|
|
||||||
|
|
||||||
The git repo implements a product with various features. The problem statement
|
|
||||||
should describe how the product is missing a feature, how a feature is
|
|
||||||
incomplete, or how the implementation of a feature is somehow undesirable. If
|
|
||||||
an issue being fixed already describes the problem, go ahead and copy-paste it.
|
|
||||||
As mentioned above, reviewer time is scarce. Given a queue of PRs to review,
|
|
||||||
the reviewer may ignore PRs that expect them to click through links to see if
|
|
||||||
the PR warrants attention.
|
|
||||||
|
|
||||||
### The Proposed Changes
|
|
||||||
|
|
||||||
Typically the content under the "Proposed changes" section will be a bulleted
|
|
||||||
list of steps taken to solve the problem. Oftentimes, the list is identical to
|
|
||||||
the subject lines of the git commits contained in the PR. It's especially
|
|
||||||
generous (and not expected) to rebase or reword commits such that each change
|
|
||||||
matches the logical flow in your PR description.
|
|
||||||
|
|
||||||
### When will my PR be reviewed?
|
### When will my PR be reviewed?
|
||||||
|
|
||||||
PRs are typically reviewed and merged in under 7 days. If your PR has been open
|
PRs are typically reviewed and merged in under 7 days. If your PR has been open for longer,
|
||||||
for longer, it's a strong indicator that the reviewers aren't confident the
|
it's a strong indicator that the reviewers aren't confident the change meets the quality
|
||||||
change meets the quality standards of the codebase. You might consider closing
|
standards of the codebase. You might consider closing it and coming back with smaller PRs
|
||||||
it and coming back with smaller PRs and longer descriptions detailing what
|
and longer descriptions detailing what problem it solves and how it solves it.
|
||||||
problem it solves and how it solves it. Old PRs will be marked stale and then
|
|
||||||
closed automatically 7 days later.
|
|
||||||
|
|
||||||
### How to manage review feedback?
|
Draft Pull Requests
|
||||||
|
---
|
||||||
After a reviewer provides feedback, you can quickly say "acknowledged, will
|
|
||||||
fix" using a thumb's up emoji. If you're confident your fix is exactly as
|
|
||||||
prescribed, add a reply "Fixed in COMMIT\_HASH" and mark the comment as
|
|
||||||
resolved. If you're not sure, reply "Is this what you had in mind?
|
|
||||||
COMMIT\_HASH" and if so, the reviewer will reply and mark the conversation as
|
|
||||||
resolved. Marking conversations as resolved is an excellent way to engage more
|
|
||||||
reviewers. Leaving conversations open may imply the PR is not yet ready for
|
|
||||||
additional review.
|
|
||||||
|
|
||||||
### When will my PR be re-reviewed?
|
|
||||||
|
|
||||||
Recall that once your PR is opened, a notification is sent every time you push
|
|
||||||
a commit. After a reviewer adds feedback, they won't be checking on the status
|
|
||||||
of that feedback after every new commit. Instead, directly mention the reviewer
|
|
||||||
when you feel your PR is ready for another pass.
|
|
||||||
|
|
||||||
## Draft Pull Requests
|
|
||||||
|
|
||||||
If you want early feedback on your PR, use GitHub's "Draft Pull Request"
|
If you want early feedback on your PR, use GitHub's "Draft Pull Request"
|
||||||
mechanism. Draft PRs are a convenient way to collaborate with the Solana
|
mechanism. Draft PRs are a convenient way to collaborate with the Solana
|
||||||
@@ -181,68 +52,67 @@ maintainers without triggering notifications as you make changes. When you feel
|
|||||||
your PR is ready for a broader audience, you can transition your draft PR to a
|
your PR is ready for a broader audience, you can transition your draft PR to a
|
||||||
standard PR with the click of a button.
|
standard PR with the click of a button.
|
||||||
|
|
||||||
Do not add reviewers to draft PRs. GitHub doesn't automatically clear
|
Do not add reviewers to draft PRs. GitHub doesn't automatically clear approvals
|
||||||
approvals when you click "Ready for Review", so a review that meant "I approve
|
when you click "Ready for Review", so a review that meant "I approve of the
|
||||||
of the direction" suddenly has the appearance of "I approve of these changes."
|
direction" suddenly has the appearance of "I approve of these changes." Instead,
|
||||||
Instead, add a comment that mentions the usernames that you would like a review
|
add a comment that mentions the usernames that you would like a review from. Ask
|
||||||
from. Ask explicitly what you would like feedback on.
|
explicitly what you would like feedback on.
|
||||||
|
|
||||||
## Rust coding conventions
|
Rust coding conventions
|
||||||
|
---
|
||||||
|
|
||||||
* All Rust code is formatted using the latest version of `rustfmt`. Once
|
* All Rust code is formatted using the latest version of `rustfmt`. Once installed, it will be
|
||||||
installed, it will be updated automatically when you update the compiler with
|
updated automatically when you update the compiler with `rustup`.
|
||||||
`rustup`.
|
|
||||||
|
|
||||||
* All Rust code is linted with Clippy. If you'd prefer to ignore its advice, do
|
* All Rust code is linted with Clippy. If you'd prefer to ignore its advice, do so explicitly:
|
||||||
so explicitly:
|
|
||||||
|
|
||||||
```rust #[allow(clippy::too_many_arguments)] ```
|
```rust
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
```
|
||||||
|
|
||||||
Note: Clippy defaults can be overridden in the top-level file `.clippy.toml`.
|
Note: Clippy defaults can be overridden in the top-level file `.clippy.toml`.
|
||||||
|
|
||||||
* For variable names, when in doubt, spell it out. The mapping from type names
|
* For variable names, when in doubt, spell it out. The mapping from type names to variable names
|
||||||
to variable names is to lowercase the type name, putting an underscore before
|
is to lowercase the type name, putting an underscore before each capital letter. Variable names
|
||||||
each capital letter. Variable names should *not* be abbreviated unless being
|
should *not* be abbreviated unless being used as closure arguments and the brevity improves
|
||||||
used as closure arguments and the brevity improves readability. When a function
|
readability. When a function has multiple instances of the same type, qualify each with a
|
||||||
has multiple instances of the same type, qualify each with a prefix and
|
prefix and underscore (i.e. alice_keypair) or a numeric suffix (i.e. tx0).
|
||||||
underscore (i.e. alice\_keypair) or a numeric suffix (i.e. tx0).
|
|
||||||
|
|
||||||
* For function and method names, use `<verb>_<subject>`. For unit tests, that
|
* For function and method names, use `<verb>_<subject>`. For unit tests, that verb should
|
||||||
verb should always be `test` and for benchmarks the verb should always be
|
always be `test` and for benchmarks the verb should always be `bench`. Avoid namespacing
|
||||||
`bench`. Avoid namespacing function names with some arbitrary word. Avoid
|
function names with some arbitrary word. Avoid abbreviating words in function names.
|
||||||
abbreviating words in function names.
|
|
||||||
|
|
||||||
* As they say, "When in Rome, do as the Romans do." A good patch should
|
* As they say, "When in Rome, do as the Romans do." A good patch should acknowledge the coding
|
||||||
acknowledge the coding conventions of the code that surrounds it, even in the
|
conventions of the code that surrounds it, even in the case where that code has not yet been
|
||||||
case where that code has not yet been updated to meet the conventions described
|
updated to meet the conventions described here.
|
||||||
here.
|
|
||||||
|
|
||||||
|
|
||||||
## Terminology
|
Terminology
|
||||||
|
---
|
||||||
|
|
||||||
Inventing new terms is allowed, but should only be done when the term is widely
|
Inventing new terms is allowed, but should only be done when the term is widely used and
|
||||||
used and understood. Avoid introducing new 3-letter terms, which can be
|
understood. Avoid introducing new 3-letter terms, which can be confused with 3-letter acronyms.
|
||||||
confused with 3-letter acronyms.
|
|
||||||
|
|
||||||
[Terms currently in use](docs/src/terminology.md)
|
[Terms currently in use](book/src/terminology.md)
|
||||||
|
|
||||||
|
|
||||||
## Design Proposals
|
Design Proposals
|
||||||
|
---
|
||||||
|
|
||||||
Solana's architecture is described by docs generated from markdown files in
|
Solana's architecture is described by a book generated from markdown files in
|
||||||
the `docs/src/` directory, maintained by an *editor* (currently @garious). To
|
the `book/src/` directory, maintained by an *editor* (currently @garious). To
|
||||||
add a design proposal, you'll need to include it in the
|
add a design proposal, you'll need to at least propose a change the content
|
||||||
[Accepted Design Proposals](https://docs.solana.com/proposals)
|
under the [Accepted Design
|
||||||
section of the Solana docs. Here's the full process:
|
Proposals](https://docs.solana.com/book/v/master/proposals) chapter.
|
||||||
|
Here's the full process:
|
||||||
|
|
||||||
1. Propose a design by creating a PR that adds a markdown document to the
|
1. Propose a design by creating a PR that adds a markdown document to the
|
||||||
`docs/src/proposals` directory and references it from the [table of
|
directory `book/src/` and references it from the [table of
|
||||||
contents](docs/src/SUMMARY.md). Add any relevant *maintainers* to the PR
|
contents](book/src/SUMMARY.md). Add any relevant *maintainers* to the PR review.
|
||||||
review.
|
|
||||||
2. The PR being merged indicates your proposed change was accepted and that the
|
2. The PR being merged indicates your proposed change was accepted and that the
|
||||||
maintainers support your plan of attack.
|
maintainers support your plan of attack.
|
||||||
3. Submit PRs that implement the proposal. When the implementation reveals the
|
3. Submit PRs that implement the proposal. When the implementation reveals the
|
||||||
need for tweaks to the proposal, be sure to update the proposal and have that
|
need for tweaks to the proposal, be sure to update the proposal and have
|
||||||
change reviewed by the same people as in step 1.
|
that change reviewed by the same people as in step 1.
|
||||||
4. Once the implementation is complete, submit a PR that moves the link from
|
4. Once the implementation is complete, submit a PR that moves the link from
|
||||||
the Accepted Proposals to the Implemented Proposals section.
|
the Accepted Proposals to the Implemented Proposals section.
|
||||||
|
7113
Cargo.lock
generated
74
Cargo.toml
@@ -3,66 +3,62 @@ members = [
|
|||||||
"bench-exchange",
|
"bench-exchange",
|
||||||
"bench-streamer",
|
"bench-streamer",
|
||||||
"bench-tps",
|
"bench-tps",
|
||||||
"accounts-bench",
|
"banking_bench",
|
||||||
"banking-bench",
|
"chacha-sys",
|
||||||
"cli-config",
|
|
||||||
"client",
|
"client",
|
||||||
"core",
|
"core",
|
||||||
"dos",
|
"drone",
|
||||||
"download-utils",
|
|
||||||
"faucet",
|
|
||||||
"perf",
|
|
||||||
"validator",
|
"validator",
|
||||||
"genesis",
|
"genesis",
|
||||||
"genesis-programs",
|
"genesis_programs",
|
||||||
"gossip",
|
"gossip",
|
||||||
"install",
|
"install",
|
||||||
"keygen",
|
"keygen",
|
||||||
"ledger",
|
"kvstore",
|
||||||
"ledger-tool",
|
"ledger-tool",
|
||||||
"local-cluster",
|
"local_cluster",
|
||||||
"logger",
|
"logger",
|
||||||
"log-analyzer",
|
|
||||||
"merkle-tree",
|
"merkle-tree",
|
||||||
"stake-o-matic",
|
|
||||||
"streamer",
|
|
||||||
"measure",
|
"measure",
|
||||||
"metrics",
|
"metrics",
|
||||||
"net-shaper",
|
"programs/bpf_loader_api",
|
||||||
"notifier",
|
"programs/bpf_loader_program",
|
||||||
"programs/bpf_loader",
|
"programs/budget_api",
|
||||||
"programs/budget",
|
"programs/budget_program",
|
||||||
"programs/btc_spv",
|
"programs/btc_spv_program",
|
||||||
|
"programs/btc_spv_api",
|
||||||
"programs/btc_spv_bin",
|
"programs/btc_spv_bin",
|
||||||
"programs/config",
|
"programs/config_api",
|
||||||
"programs/exchange",
|
"programs/config_program",
|
||||||
"programs/failure",
|
"programs/config_tests",
|
||||||
"programs/noop",
|
"programs/exchange_api",
|
||||||
"programs/ownable",
|
"programs/exchange_program",
|
||||||
"programs/stake",
|
"programs/failure_program",
|
||||||
"programs/vest",
|
"programs/move_loader_api",
|
||||||
"programs/vote",
|
"programs/move_loader_program",
|
||||||
"remote-wallet",
|
"programs/librapay_api",
|
||||||
"ramp-tps",
|
"programs/noop_program",
|
||||||
|
"programs/stake_api",
|
||||||
|
"programs/stake_program",
|
||||||
|
"programs/stake_tests",
|
||||||
|
"programs/storage_api",
|
||||||
|
"programs/storage_program",
|
||||||
|
"programs/token_api",
|
||||||
|
"programs/token_program",
|
||||||
|
"programs/vote_api",
|
||||||
|
"programs/vote_program",
|
||||||
|
"replicator",
|
||||||
"runtime",
|
"runtime",
|
||||||
"sdk",
|
"sdk",
|
||||||
"scripts",
|
"sdk-c",
|
||||||
"stake-accounts",
|
|
||||||
"stake-monitor",
|
|
||||||
"sys-tuner",
|
|
||||||
"tokens",
|
|
||||||
"transaction-status",
|
|
||||||
"upload-perf",
|
"upload-perf",
|
||||||
"net-utils",
|
"netutil",
|
||||||
"version",
|
"fixed-buf",
|
||||||
"vote-signer",
|
"vote-signer",
|
||||||
"cli",
|
"cli",
|
||||||
"rayon-threadlimit",
|
"rayon-threadlimit",
|
||||||
"watchtower",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude = [
|
exclude = [
|
||||||
"programs/bpf",
|
"programs/bpf",
|
||||||
"programs/move_loader",
|
|
||||||
"programs/librapay",
|
|
||||||
]
|
]
|
||||||
|
189
README.md
@@ -1,17 +1,76 @@
|
|||||||
<p align="center">
|
|
||||||
<a href="https://solana.com">
|
|
||||||
<img alt="Solana" src="https://i.imgur.com/OMnvVEz.png" width="250" />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
[](https://crates.io/crates/solana-core)
|
[](https://crates.io/crates/solana-core)
|
||||||
[](https://docs.rs/solana-core)
|
[](https://docs.rs/solana-core)
|
||||||
[](https://buildkite.com/solana-labs/solana/builds?branch=master)
|
[](https://buildkite.com/solana-labs/solana/builds?branch=master)
|
||||||
[](https://codecov.io/gh/solana-labs/solana)
|
[](https://codecov.io/gh/solana-labs/solana)
|
||||||
|
|
||||||
# Building
|
Blockchain Rebuilt for Scale
|
||||||
|
===
|
||||||
|
|
||||||
## **1. Install rustc, cargo and rustfmt.**
|
Solana™ is a new blockchain architecture built from the ground up for scale. The architecture supports
|
||||||
|
up to 710 thousand transactions per second on a gigabit network.
|
||||||
|
|
||||||
|
Disclaimer
|
||||||
|
===
|
||||||
|
|
||||||
|
All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the author's best effort. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore nothing in this project constitutes a solicitation for investment.
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
===
|
||||||
|
|
||||||
|
It's possible for a centralized database to process 710,000 transactions per second on a standard gigabit network if the transactions are, on average, no more than 176 bytes. A centralized database can also replicate itself and maintain high availability without significantly compromising that transaction rate using the distributed system technique known as Optimistic Concurrency Control [\[H.T.Kung, J.T.Robinson (1981)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.65.4735). At Solana, we're demonstrating that these same theoretical limits apply just as well to blockchain on an adversarial network. The key ingredient? Finding a way to share time when nodes can't trust one-another. Once nodes can trust time, suddenly ~40 years of distributed systems research becomes applicable to blockchain!
|
||||||
|
|
||||||
|
> Perhaps the most striking difference between algorithms obtained by our method and ones based upon timeout is that using timeout produces a traditional distributed algorithm in which the processes operate asynchronously, while our method produces a globally synchronous one in which every process does the same thing at (approximately) the same time. Our method seems to contradict the whole purpose of distributed processing, which is to permit different processes to operate independently and perform different functions. However, if a distributed system is really a single system, then the processes must be synchronized in some way. Conceptually, the easiest way to synchronize processes is to get them all to do the same thing at the same time. Therefore, our method is used to implement a kernel that performs the necessary synchronization--for example, making sure that two different processes do not try to modify a file at the same time. Processes might spend only a small fraction of their time executing the synchronizing kernel; the rest of the time, they can operate independently--e.g., accessing different files. This is an approach we have advocated even when fault-tolerance is not required. The method's basic simplicity makes it easier to understand the precise properties of a system, which is crucial if one is to know just how fault-tolerant the system is. [\[L.Lamport (1984)\]](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.71.1078)
|
||||||
|
|
||||||
|
Furthermore, and much to our surprise, it can be implemented using a mechanism that has existed in Bitcoin since day one. The Bitcoin feature is called nLocktime and it can be used to postdate transactions using block height instead of a timestamp. As a Bitcoin client, you'd use block height instead of a timestamp if you don't trust the network. Block height turns out to be an instance of what's being called a Verifiable Delay Function in cryptography circles. It's a cryptographically secure way to say time has passed. In Solana, we use a far more granular verifiable delay function, a SHA 256 hash chain, to checkpoint the ledger and coordinate consensus. With it, we implement Optimistic Concurrency Control and are now well en route towards that theoretical limit of 710,000 transactions per second.
|
||||||
|
|
||||||
|
Architecture
|
||||||
|
===
|
||||||
|
|
||||||
|
Before you jump into the code, review the online book [Solana: Blockchain Rebuilt for Scale](https://docs.solana.com/book/).
|
||||||
|
|
||||||
|
(The _latest_ development version of the online book is also [available here](https://docs.solana.com/book/v/master/).)
|
||||||
|
|
||||||
|
Release Binaries
|
||||||
|
===
|
||||||
|
Official release binaries are available at [Github Releases](https://github.com/solana-labs/solana/releases).
|
||||||
|
|
||||||
|
Additionally we provide pre-release binaries for the latest code on the edge and
|
||||||
|
beta channels. Note that these pre-release binaries may be less stable than an
|
||||||
|
official release.
|
||||||
|
|
||||||
|
### Edge channel
|
||||||
|
#### Linux (x86_64-unknown-linux-gnu)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/edge/solana-release-x86_64-unknown-linux-gnu.tar.bz2)
|
||||||
|
* [solana-install-init](http://release.solana.com/edge/solana-install-init-x86_64-unknown-linux-gnu) as a stand-alone executable
|
||||||
|
#### mac OS (x86_64-apple-darwin)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/edge/solana-release-x86_64-apple-darwin.tar.bz2)
|
||||||
|
* [solana-install-init](http://release.solana.com/edge/solana-install-init-x86_64-apple-darwin) as a stand-alone executable
|
||||||
|
#### Windows (x86_64-pc-windows-msvc)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/edge/solana-release-x86_64-pc-windows-msvc.tar.bz2)
|
||||||
|
* [solana-install-init.exe](http://release.solana.com/edge/solana-install-init-x86_64-pc-windows-msvc.exe) as a stand-alone executable
|
||||||
|
#### All platforms
|
||||||
|
* [solana-metrics.tar.bz2](http://release.solana.com.s3.amazonaws.com/edge/solana-metrics.tar.bz2)
|
||||||
|
|
||||||
|
### Beta channel
|
||||||
|
#### Linux (x86_64-unknown-linux-gnu)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/beta/solana-release-x86_64-unknown-linux-gnu.tar.bz2)
|
||||||
|
* [solana-install-init](http://release.solana.com/beta/solana-install-init-x86_64-unknown-linux-gnu) as a stand-alone executable
|
||||||
|
#### mac OS (x86_64-apple-darwin)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/beta/solana-release-x86_64-apple-darwin.tar.bz2)
|
||||||
|
* [solana-install-init](http://release.solana.com/beta/solana-install-init-x86_64-apple-darwin) as a stand-alone executable
|
||||||
|
#### Windows (x86_64-pc-windows-msvc)
|
||||||
|
* [solana.tar.bz2](http://release.solana.com/beta/solana-release-x86_64-pc-windows-msvc.tar.bz2)
|
||||||
|
* [solana-install-init.exe](http://release.solana.com/beta/solana-install-init-x86_64-pc-windows-msvc.exe) as a stand-alone executable
|
||||||
|
#### All platforms
|
||||||
|
* [solana-metrics.tar.bz2](http://release.solana.com.s3.amazonaws.com/beta/solana-metrics.tar.bz2)
|
||||||
|
|
||||||
|
Developing
|
||||||
|
===
|
||||||
|
|
||||||
|
Building
|
||||||
|
---
|
||||||
|
|
||||||
|
Install rustc, cargo and rustfmt:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl https://sh.rustup.rs -sSf | sh
|
$ curl https://sh.rustup.rs -sSf | sh
|
||||||
@@ -19,7 +78,7 @@ $ source $HOME/.cargo/env
|
|||||||
$ rustup component add rustfmt
|
$ rustup component add rustfmt
|
||||||
```
|
```
|
||||||
|
|
||||||
If your rustc version is lower than 1.39.0, please update it:
|
If your rustc version is lower than 1.37.0, please update it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rustup update
|
$ rustup update
|
||||||
@@ -28,43 +87,118 @@ $ rustup update
|
|||||||
On Linux systems you may need to install libssl-dev, pkg-config, zlib1g-dev, etc. On Ubuntu:
|
On Linux systems you may need to install libssl-dev, pkg-config, zlib1g-dev, etc. On Ubuntu:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ sudo apt-get update
|
$ sudo apt-get install libssl-dev pkg-config zlib1g-dev llvm clang
|
||||||
$ sudo apt-get install libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## **2. Download the source code.**
|
Download the source code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/solana-labs/solana.git
|
$ git clone https://github.com/solana-labs/solana.git
|
||||||
$ cd solana
|
$ cd solana
|
||||||
```
|
```
|
||||||
|
|
||||||
## **3. Build.**
|
Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cargo build
|
$ cargo build
|
||||||
```
|
```
|
||||||
|
|
||||||
## **4. Run a minimal local cluster.**
|
Then to run a minimal local cluster
|
||||||
```bash
|
```bash
|
||||||
$ ./run.sh
|
$ ./run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
# Testing
|
Testing
|
||||||
|
---
|
||||||
|
|
||||||
**Run the test suite:**
|
Run the test suite:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cargo test
|
$ cargo test
|
||||||
```
|
```
|
||||||
|
|
||||||
### Starting a local testnet
|
Local Testnet
|
||||||
Start your own testnet locally, instructions are in the [online docs](https://docs.solana.com/bench-tps).
|
---
|
||||||
|
|
||||||
### Accessing the remote testnet
|
Start your own testnet locally, instructions are in the book [Solana: Blockchain Rebuild for Scale: Getting Started](https://docs.solana.com/book/getting-started).
|
||||||
* `testnet` - public stable testnet accessible via devnet.solana.com. Runs 24/7
|
|
||||||
|
|
||||||
# Benchmarking
|
Remote Testnets
|
||||||
|
---
|
||||||
|
|
||||||
|
We maintain several testnets:
|
||||||
|
|
||||||
|
* `testnet` - public stable testnet accessible via testnet.solana.com. Runs 24/7
|
||||||
|
* `testnet-beta` - public beta channel testnet accessible via beta.testnet.solana.com. Runs 24/7
|
||||||
|
* `testnet-edge` - public edge channel testnet accessible via edge.testnet.solana.com. Runs 24/7
|
||||||
|
|
||||||
|
## Deploy process
|
||||||
|
|
||||||
|
They are deployed with the `ci/testnet-manager.sh` script through a list of [scheduled
|
||||||
|
buildkite jobs](https://buildkite.com/solana-labs/testnet-management/settings/schedules).
|
||||||
|
Each testnet can be manually manipulated from buildkite as well.
|
||||||
|
|
||||||
|
## How do I reset the testnet?
|
||||||
|
Manually trigger the [testnet-management](https://buildkite.com/solana-labs/testnet-management) pipeline
|
||||||
|
and when prompted select the desired testnet
|
||||||
|
|
||||||
|
## How can I scale the tx generation rate?
|
||||||
|
|
||||||
|
Increase the TX rate by increasing the number of cores on the client machine which is running
|
||||||
|
`bench-tps` or run multiple clients. Decrease by lowering cores or using the rayon env
|
||||||
|
variable `RAYON_NUM_THREADS=<xx>`
|
||||||
|
|
||||||
|
## How can I test a change on the testnet?
|
||||||
|
|
||||||
|
Currently, a merged PR is the only way to test a change on the testnet. But you
|
||||||
|
can run your own testnet using the scripts in the `net/` directory.
|
||||||
|
|
||||||
|
## Adjusting the number of clients or validators on the testnet
|
||||||
|
Edit `ci/testnet-manager.sh`
|
||||||
|
|
||||||
|
|
||||||
|
## Metrics Server Maintenance
|
||||||
|
Sometimes the dashboard becomes unresponsive. This happens due to glitch in the metrics server.
|
||||||
|
The current solution is to reset the metrics server. Use the following steps.
|
||||||
|
|
||||||
|
1. The server is hosted in a GCP VM instance. Check if the VM instance is down by trying to SSH
|
||||||
|
into it from the GCP console. The name of the VM is ```metrics-solana-com```.
|
||||||
|
2. If the VM is inaccessible, reset it from the GCP console.
|
||||||
|
3. Once VM is up (or, was already up), the metrics services can be restarted from build automation.
|
||||||
|
1. Navigate to https://buildkite.com/solana-labs/metrics-dot-solana-dot-com in your web browser
|
||||||
|
2. Click on ```New Build```
|
||||||
|
3. This will show a pop up dialog. Click on ```options``` drop down.
|
||||||
|
4. Type in ```FORCE_START=true``` in ```Environment Variables``` text box.
|
||||||
|
5. Click ```Create Build```
|
||||||
|
6. This will restart the metrics services, and the dashboards should be accessible afterwards.
|
||||||
|
|
||||||
|
## Debugging Testnet
|
||||||
|
Testnet may exhibit different symptoms of failures. Primary statistics to check are
|
||||||
|
1. Rise in Confirmation Time
|
||||||
|
2. Nodes are not voting
|
||||||
|
3. Panics, and OOM notifications
|
||||||
|
|
||||||
|
Check the following if there are any signs of failure.
|
||||||
|
1. Did testnet deployment fail?
|
||||||
|
1. View buildkite logs for the last deployment: https://buildkite.com/solana-labs/testnet-management
|
||||||
|
2. Use the relevant branch
|
||||||
|
3. If the deployment failed, look at the build logs. The build artifacts for each remote node is uploaded.
|
||||||
|
It's a good first step to triage from these logs.
|
||||||
|
2. You may have to log into remote node if the deployment succeeded, but something failed during runtime.
|
||||||
|
1. Get the private key for the testnet deployment from ```metrics-solana-com``` GCP instance.
|
||||||
|
2. SSH into ```metrics-solana-com``` using GCP console and do the following.
|
||||||
|
```bash
|
||||||
|
sudo bash
|
||||||
|
cd ~buildkite-agent/.ssh
|
||||||
|
ls
|
||||||
|
```
|
||||||
|
3. Copy the relevant private key to your local machine
|
||||||
|
4. Find the public IP address of the AWS instance for the remote node using AWS console
|
||||||
|
5. ```ssh -i <private key file> ubuntu@<ip address of remote node>```
|
||||||
|
6. The logs are in ```~solana\solana``` folder
|
||||||
|
|
||||||
|
|
||||||
|
Benchmarking
|
||||||
|
---
|
||||||
|
|
||||||
First install the nightly build of rustc. `cargo bench` requires use of the
|
First install the nightly build of rustc. `cargo bench` requires use of the
|
||||||
unstable features only available in the nightly build.
|
unstable features only available in the nightly build.
|
||||||
@@ -79,11 +213,13 @@ Run the benchmarks:
|
|||||||
$ cargo +nightly bench
|
$ cargo +nightly bench
|
||||||
```
|
```
|
||||||
|
|
||||||
# Release Process
|
Release Process
|
||||||
|
---
|
||||||
The release process for this project is described [here](RELEASE.md).
|
The release process for this project is described [here](RELEASE.md).
|
||||||
|
|
||||||
# Code coverage
|
|
||||||
|
Code coverage
|
||||||
|
---
|
||||||
|
|
||||||
To generate code coverage statistics:
|
To generate code coverage statistics:
|
||||||
|
|
||||||
@@ -92,6 +228,7 @@ $ scripts/coverage.sh
|
|||||||
$ open target/cov/lcov-local/index.html
|
$ open target/cov/lcov-local/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Why coverage? While most see coverage as a code quality metric, we see it primarily as a developer
|
Why coverage? While most see coverage as a code quality metric, we see it primarily as a developer
|
||||||
productivity metric. When a developer makes a change to the codebase, presumably it's a *solution* to
|
productivity metric. When a developer makes a change to the codebase, presumably it's a *solution* to
|
||||||
some problem. Our unit-test suite is how we encode the set of *problems* the codebase solves. Running
|
some problem. Our unit-test suite is how we encode the set of *problems* the codebase solves. Running
|
||||||
@@ -103,7 +240,3 @@ problem is solved by this code?" On the other hand, if a test does fail and you
|
|||||||
better way to solve the same problem, a Pull Request with your solution would most certainly be
|
better way to solve the same problem, a Pull Request with your solution would most certainly be
|
||||||
welcome! Likewise, if rewriting a test can better communicate what code it's protecting, please
|
welcome! Likewise, if rewriting a test can better communicate what code it's protecting, please
|
||||||
send us that patch!
|
send us that patch!
|
||||||
|
|
||||||
# Disclaimer
|
|
||||||
|
|
||||||
All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the author's best effort. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore nothing in this project constitutes a solicitation for investment.
|
|
||||||
|
27
RELEASE.md
@@ -138,11 +138,30 @@ There are three release channels that map to branches as follows:
|
|||||||
### Update documentation
|
### Update documentation
|
||||||
TODO: Documentation update procedure is WIP as we move to gitbook
|
TODO: Documentation update procedure is WIP as we move to gitbook
|
||||||
|
|
||||||
Document the new recommended version by updating `docs/src/running-archiver.md` and `docs/src/validator-testnet.md` on the release (beta) branch to point at the `solana-install` for the upcoming release version.
|
Document the new recommended version by updating `book/src/running-replicator.md` and `book/src/validator-testnet.md` on the release (beta) branch to point at the `solana-install` for the upcoming release version.
|
||||||
|
|
||||||
### Update software on devnet.solana.com
|
#### Publish updated Book
|
||||||
|
We maintain three copies of the "book" as official documentation:
|
||||||
|
|
||||||
The testnet running on devnet.solana.com is set to use a fixed release tag
|
1) "Book" is the documentation for the latest official release. This should get manually updated whenever a new release is made. It is published here:
|
||||||
|
https://solana-labs.github.io/book/
|
||||||
|
|
||||||
|
2) "Book-edge" tracks the tip of the master branch and updates automatically.
|
||||||
|
https://solana-labs.github.io/book-edge/
|
||||||
|
|
||||||
|
3) "Book-beta" tracks the tip of the beta branch and updates automatically.
|
||||||
|
https://solana-labs.github.io/book-beta/
|
||||||
|
|
||||||
|
To manually trigger an update of the "Book", create a new job of the manual-update-book pipeline.
|
||||||
|
Set the tag of the latest release as the PUBLISH_BOOK_TAG environment variable.
|
||||||
|
```bash
|
||||||
|
PUBLISH_BOOK_TAG=v0.16.6
|
||||||
|
```
|
||||||
|
https://buildkite.com/solana-labs/manual-update-book
|
||||||
|
|
||||||
|
### Update software on testnet.solana.com
|
||||||
|
|
||||||
|
The testnet running on testnet.solana.com is set to use a fixed release tag
|
||||||
which is set in the Buildkite testnet-management pipeline.
|
which is set in the Buildkite testnet-management pipeline.
|
||||||
This tag needs to be updated and the testnet restarted after a new release
|
This tag needs to be updated and the testnet restarted after a new release
|
||||||
tag is created.
|
tag is created.
|
||||||
@@ -182,4 +201,4 @@ TESTNET_OP=create-and-start
|
|||||||
### Alert the community
|
### Alert the community
|
||||||
|
|
||||||
Notify Discord users on #validator-support that a new release for
|
Notify Discord users on #validator-support that a new release for
|
||||||
devnet.solana.com is available
|
testnet.solana.com is available
|
||||||
|
@@ -1,22 +0,0 @@
|
|||||||
[package]
|
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|
||||||
edition = "2018"
|
|
||||||
name = "solana-accounts-bench"
|
|
||||||
version = "1.2.0"
|
|
||||||
repository = "https://github.com/solana-labs/solana"
|
|
||||||
license = "Apache-2.0"
|
|
||||||
homepage = "https://solana.com/"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
log = "0.4.6"
|
|
||||||
rayon = "1.3.0"
|
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
|
||||||
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
|
||||||
solana-measure = { path = "../measure", version = "1.2.0" }
|
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
|
||||||
rand = "0.7.0"
|
|
||||||
clap = "2.33.1"
|
|
||||||
crossbeam-channel = "0.4"
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@@ -1,105 +0,0 @@
|
|||||||
use clap::{value_t, App, Arg};
|
|
||||||
use rayon::prelude::*;
|
|
||||||
use solana_measure::measure::Measure;
|
|
||||||
use solana_runtime::{
|
|
||||||
accounts::{create_test_accounts, update_accounts, Accounts},
|
|
||||||
accounts_index::Ancestors,
|
|
||||||
};
|
|
||||||
use solana_sdk::pubkey::Pubkey;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
solana_logger::setup();
|
|
||||||
|
|
||||||
let matches = App::new("crate")
|
|
||||||
.about("about")
|
|
||||||
.version("version")
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("num_slots")
|
|
||||||
.long("num_slots")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("SLOTS")
|
|
||||||
.help("Number of slots to store to."),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("num_accounts")
|
|
||||||
.long("num_accounts")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("NUM_ACCOUNTS")
|
|
||||||
.help("Total number of accounts"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("iterations")
|
|
||||||
.long("iterations")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("ITERATIONS")
|
|
||||||
.help("Number of bench iterations"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("clean")
|
|
||||||
.long("clean")
|
|
||||||
.takes_value(false)
|
|
||||||
.help("Run clean"),
|
|
||||||
)
|
|
||||||
.get_matches();
|
|
||||||
|
|
||||||
let num_slots = value_t!(matches, "num_slots", usize).unwrap_or(4);
|
|
||||||
let num_accounts = value_t!(matches, "num_accounts", usize).unwrap_or(10_000);
|
|
||||||
let iterations = value_t!(matches, "iterations", usize).unwrap_or(20);
|
|
||||||
let clean = matches.is_present("clean");
|
|
||||||
println!("clean: {:?}", clean);
|
|
||||||
|
|
||||||
let path = PathBuf::from("farf/accounts-bench");
|
|
||||||
if fs::remove_dir_all(path.clone()).is_err() {
|
|
||||||
println!("Warning: Couldn't remove {:?}", path);
|
|
||||||
}
|
|
||||||
let accounts = Accounts::new(vec![path]);
|
|
||||||
println!("Creating {} accounts", num_accounts);
|
|
||||||
let mut create_time = Measure::start("create accounts");
|
|
||||||
let pubkeys: Vec<_> = (0..num_slots)
|
|
||||||
.into_par_iter()
|
|
||||||
.map(|slot| {
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
|
||||||
create_test_accounts(
|
|
||||||
&accounts,
|
|
||||||
&mut pubkeys,
|
|
||||||
num_accounts / num_slots,
|
|
||||||
slot as u64,
|
|
||||||
);
|
|
||||||
pubkeys
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let pubkeys: Vec<_> = pubkeys.into_iter().flatten().collect();
|
|
||||||
create_time.stop();
|
|
||||||
println!(
|
|
||||||
"created {} accounts in {} slots {}",
|
|
||||||
(num_accounts / num_slots) * num_slots,
|
|
||||||
num_slots,
|
|
||||||
create_time
|
|
||||||
);
|
|
||||||
let mut ancestors: Ancestors = vec![(0, 0)].into_iter().collect();
|
|
||||||
for i in 1..num_slots {
|
|
||||||
ancestors.insert(i as u64, i - 1);
|
|
||||||
accounts.add_root(i as u64);
|
|
||||||
}
|
|
||||||
for x in 0..iterations {
|
|
||||||
if clean {
|
|
||||||
let mut time = Measure::start("clean");
|
|
||||||
accounts.accounts_db.clean_accounts();
|
|
||||||
time.stop();
|
|
||||||
println!("{}", time);
|
|
||||||
for slot in 0..num_slots {
|
|
||||||
update_accounts(&accounts, &pubkeys, ((x + 1) * num_slots + slot) as u64);
|
|
||||||
accounts.add_root((x * num_slots + slot) as u64);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let mut pubkeys: Vec<Pubkey> = vec![];
|
|
||||||
let mut time = Measure::start("hash");
|
|
||||||
let hash = accounts.accounts_db.update_accounts_hash(0, &ancestors);
|
|
||||||
time.stop();
|
|
||||||
println!("hash: {} {}", hash, time);
|
|
||||||
create_test_accounts(&accounts, &mut pubkeys, 1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,28 +0,0 @@
|
|||||||
[package]
|
|
||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
|
||||||
edition = "2018"
|
|
||||||
name = "solana-banking-bench"
|
|
||||||
version = "1.2.0"
|
|
||||||
repository = "https://github.com/solana-labs/solana"
|
|
||||||
license = "Apache-2.0"
|
|
||||||
homepage = "https://solana.com/"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = "2.33.1"
|
|
||||||
crossbeam-channel = "0.4"
|
|
||||||
log = "0.4.6"
|
|
||||||
rand = "0.7.0"
|
|
||||||
rayon = "1.3.0"
|
|
||||||
solana-core = { path = "../core", version = "1.2.0" }
|
|
||||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
|
||||||
solana-streamer = { path = "../streamer", version = "1.2.0" }
|
|
||||||
solana-perf = { path = "../perf", version = "1.2.0" }
|
|
||||||
solana-ledger = { path = "../ledger", version = "1.2.0" }
|
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
|
||||||
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
|
||||||
solana-measure = { path = "../measure", version = "1.2.0" }
|
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
|
||||||
solana-version = { path = "../version", version = "1.2.0" }
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
19
banking_bench/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
name = "solana-banking-bench"
|
||||||
|
version = "0.19.1"
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.4.6"
|
||||||
|
rayon = "1.2.0"
|
||||||
|
solana-core = { path = "../core", version = "0.19.1" }
|
||||||
|
solana-logger = { path = "../logger", version = "0.19.1" }
|
||||||
|
solana-runtime = { path = "../runtime", version = "0.19.1" }
|
||||||
|
solana-measure = { path = "../measure", version = "0.19.1" }
|
||||||
|
solana-sdk = { path = "../sdk", version = "0.19.1" }
|
||||||
|
rand = "0.6.5"
|
||||||
|
crossbeam-channel = "0.3"
|
@@ -1,38 +1,36 @@
|
|||||||
use clap::{crate_description, crate_name, value_t, App, Arg};
|
#[macro_use]
|
||||||
|
extern crate solana_core;
|
||||||
|
extern crate crossbeam_channel;
|
||||||
|
|
||||||
use crossbeam_channel::unbounded;
|
use crossbeam_channel::unbounded;
|
||||||
use log::*;
|
use log::*;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use solana_core::{
|
use solana_core::bank_forks::BankForks;
|
||||||
banking_stage::{create_test_recorder, BankingStage},
|
use solana_core::banking_stage::{create_test_recorder, BankingStage};
|
||||||
cluster_info::ClusterInfo,
|
use solana_core::blocktree::{get_tmp_ledger_path, Blocktree};
|
||||||
cluster_info::Node,
|
use solana_core::cluster_info::ClusterInfo;
|
||||||
poh_recorder::PohRecorder,
|
use solana_core::cluster_info::Node;
|
||||||
poh_recorder::WorkingBankEntry,
|
use solana_core::genesis_utils::{create_genesis_block, GenesisBlockInfo};
|
||||||
};
|
use solana_core::packet::to_packets_chunked;
|
||||||
use solana_ledger::{
|
use solana_core::poh_recorder::PohRecorder;
|
||||||
bank_forks::BankForks,
|
use solana_core::poh_recorder::WorkingBankEntry;
|
||||||
blockstore::Blockstore,
|
use solana_core::service::Service;
|
||||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
|
||||||
get_tmp_ledger_path,
|
|
||||||
};
|
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_perf::packet::to_packets_chunked;
|
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::bank::Bank;
|
||||||
use solana_sdk::{
|
use solana_sdk::hash::Hash;
|
||||||
hash::Hash,
|
use solana_sdk::pubkey::Pubkey;
|
||||||
pubkey::Pubkey,
|
use solana_sdk::signature::Keypair;
|
||||||
signature::Keypair,
|
use solana_sdk::signature::Signature;
|
||||||
signature::Signature,
|
use solana_sdk::system_transaction;
|
||||||
system_transaction,
|
use solana_sdk::timing::{duration_as_us, timestamp};
|
||||||
timing::{duration_as_us, timestamp},
|
use solana_sdk::transaction::Transaction;
|
||||||
transaction::Transaction,
|
use std::iter;
|
||||||
};
|
use std::sync::atomic::Ordering;
|
||||||
use std::{
|
use std::sync::mpsc::Receiver;
|
||||||
sync::{atomic::Ordering, mpsc::Receiver, Arc, Mutex},
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
thread::sleep,
|
use std::thread::sleep;
|
||||||
time::{Duration, Instant},
|
use std::time::{Duration, Instant};
|
||||||
};
|
|
||||||
|
|
||||||
fn check_txs(
|
fn check_txs(
|
||||||
receiver: &Arc<Receiver<WorkingBankEntry>>,
|
receiver: &Arc<Receiver<WorkingBankEntry>>,
|
||||||
@@ -43,7 +41,7 @@ fn check_txs(
|
|||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let mut no_bank = false;
|
let mut no_bank = false;
|
||||||
loop {
|
loop {
|
||||||
if let Ok((_bank, (entry, _tick_height))) = receiver.recv_timeout(Duration::from_millis(10))
|
if let Ok((_bank, (entry, _tick_count))) = receiver.recv_timeout(Duration::from_millis(10))
|
||||||
{
|
{
|
||||||
total += entry.transactions.len();
|
total += entry.transactions.len();
|
||||||
}
|
}
|
||||||
@@ -65,22 +63,15 @@ fn check_txs(
|
|||||||
no_bank
|
no_bank
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_accounts_txs(
|
fn make_accounts_txs(txes: usize, mint_keypair: &Keypair, hash: Hash) -> Vec<Transaction> {
|
||||||
total_num_transactions: usize,
|
|
||||||
hash: Hash,
|
|
||||||
same_payer: bool,
|
|
||||||
) -> Vec<Transaction> {
|
|
||||||
let to_pubkey = Pubkey::new_rand();
|
let to_pubkey = Pubkey::new_rand();
|
||||||
let payer_key = Keypair::new();
|
let dummy = system_transaction::transfer(mint_keypair, &to_pubkey, 1, hash);
|
||||||
let dummy = system_transaction::transfer(&payer_key, &to_pubkey, 1, hash);
|
(0..txes)
|
||||||
(0..total_num_transactions)
|
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|_| {
|
.map(|_| {
|
||||||
let mut new = dummy.clone();
|
let mut new = dummy.clone();
|
||||||
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen()).collect();
|
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen()).collect();
|
||||||
if !same_payer {
|
new.message.account_keys[0] = Pubkey::new_rand();
|
||||||
new.message.account_keys[0] = Pubkey::new_rand();
|
|
||||||
}
|
|
||||||
new.message.account_keys[1] = Pubkey::new_rand();
|
new.message.account_keys[1] = Pubkey::new_rand();
|
||||||
new.signatures = vec![Signature::new(&sig[0..64])];
|
new.signatures = vec![Signature::new(&sig[0..64])];
|
||||||
new
|
new
|
||||||
@@ -104,150 +95,97 @@ fn bytes_as_usize(bytes: &[u8]) -> usize {
|
|||||||
bytes[0] as usize | (bytes[1] as usize) << 8
|
bytes[0] as usize | (bytes[1] as usize) << 8
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
|
||||||
fn main() {
|
fn main() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
|
let num_threads = BankingStage::num_threads() as usize;
|
||||||
let matches = App::new(crate_name!())
|
|
||||||
.about(crate_description!())
|
|
||||||
.version(solana_version::version!())
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("num_chunks")
|
|
||||||
.long("num-chunks")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("SIZE")
|
|
||||||
.help("Number of transaction chunks."),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("packets_per_chunk")
|
|
||||||
.long("packets-per-chunk")
|
|
||||||
.takes_value(true)
|
|
||||||
.value_name("SIZE")
|
|
||||||
.help("Packets per chunk"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("skip_sanity")
|
|
||||||
.long("skip-sanity")
|
|
||||||
.takes_value(false)
|
|
||||||
.help("Skip transaction sanity execution"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("same_payer")
|
|
||||||
.long("same-payer")
|
|
||||||
.takes_value(false)
|
|
||||||
.help("Use the same payer for transfers"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("iterations")
|
|
||||||
.long("iterations")
|
|
||||||
.takes_value(true)
|
|
||||||
.help("Number of iterations"),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("num_threads")
|
|
||||||
.long("num-threads")
|
|
||||||
.takes_value(true)
|
|
||||||
.help("Number of iterations"),
|
|
||||||
)
|
|
||||||
.get_matches();
|
|
||||||
|
|
||||||
let num_threads =
|
|
||||||
value_t!(matches, "num_threads", usize).unwrap_or(BankingStage::num_threads() as usize);
|
|
||||||
// a multiple of packet chunk duplicates to avoid races
|
// a multiple of packet chunk duplicates to avoid races
|
||||||
let num_chunks = value_t!(matches, "num_chunks", usize).unwrap_or(16);
|
const CHUNKS: usize = 8 * 2;
|
||||||
let packets_per_chunk = value_t!(matches, "packets_per_chunk", usize).unwrap_or(192);
|
const PACKETS_PER_BATCH: usize = 192;
|
||||||
let iterations = value_t!(matches, "iterations", usize).unwrap_or(1000);
|
let txes = PACKETS_PER_BATCH * num_threads * CHUNKS;
|
||||||
|
|
||||||
let total_num_transactions = num_chunks * num_threads * packets_per_chunk;
|
|
||||||
let mint_total = 1_000_000_000_000;
|
let mint_total = 1_000_000_000_000;
|
||||||
let GenesisConfigInfo {
|
let GenesisBlockInfo {
|
||||||
genesis_config,
|
genesis_block,
|
||||||
mint_keypair,
|
mint_keypair,
|
||||||
..
|
..
|
||||||
} = create_genesis_config(mint_total);
|
} = create_genesis_block(mint_total);
|
||||||
|
|
||||||
let (verified_sender, verified_receiver) = unbounded();
|
let (verified_sender, verified_receiver) = unbounded();
|
||||||
let (vote_sender, vote_receiver) = unbounded();
|
let (vote_sender, vote_receiver) = unbounded();
|
||||||
let bank0 = Bank::new(&genesis_config);
|
let bank0 = Bank::new(&genesis_block);
|
||||||
let mut bank_forks = BankForks::new(0, bank0);
|
let mut bank_forks = BankForks::new(0, bank0);
|
||||||
let mut bank = bank_forks.working_bank();
|
let mut bank = bank_forks.working_bank();
|
||||||
|
|
||||||
info!("threads: {} txs: {}", num_threads, total_num_transactions);
|
info!("threads: {} txs: {}", num_threads, txes);
|
||||||
|
|
||||||
let same_payer = matches.is_present("same_payer");
|
let mut transactions = make_accounts_txs(txes, &mint_keypair, genesis_block.hash());
|
||||||
let mut transactions =
|
|
||||||
make_accounts_txs(total_num_transactions, genesis_config.hash(), same_payer);
|
|
||||||
|
|
||||||
// fund all the accounts
|
// fund all the accounts
|
||||||
transactions.iter().for_each(|tx| {
|
transactions.iter().for_each(|tx| {
|
||||||
let mut fund = system_transaction::transfer(
|
let fund = system_transaction::transfer(
|
||||||
&mint_keypair,
|
&mint_keypair,
|
||||||
&tx.message.account_keys[0],
|
&tx.message.account_keys[0],
|
||||||
mint_total / total_num_transactions as u64,
|
mint_total / txes as u64,
|
||||||
genesis_config.hash(),
|
genesis_block.hash(),
|
||||||
);
|
);
|
||||||
// Ignore any pesky duplicate signature errors in the case we are using single-payer
|
|
||||||
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen()).collect();
|
|
||||||
fund.signatures = vec![Signature::new(&sig[0..64])];
|
|
||||||
let x = bank.process_transaction(&fund);
|
let x = bank.process_transaction(&fund);
|
||||||
x.unwrap();
|
x.unwrap();
|
||||||
});
|
});
|
||||||
|
//sanity check, make sure all the transactions can execute sequentially
|
||||||
let skip_sanity = matches.is_present("skip_sanity");
|
transactions.iter().for_each(|tx| {
|
||||||
if !skip_sanity {
|
let res = bank.process_transaction(&tx);
|
||||||
//sanity check, make sure all the transactions can execute sequentially
|
assert!(res.is_ok(), "sanity test transactions");
|
||||||
transactions.iter().for_each(|tx| {
|
});
|
||||||
let res = bank.process_transaction(&tx);
|
bank.clear_signatures();
|
||||||
assert!(res.is_ok(), "sanity test transactions error: {:?}", res);
|
//sanity check, make sure all the transactions can execute in parallel
|
||||||
});
|
let res = bank.process_transactions(&transactions);
|
||||||
bank.clear_signatures();
|
for r in res {
|
||||||
//sanity check, make sure all the transactions can execute in parallel
|
assert!(r.is_ok(), "sanity parallel execution");
|
||||||
let res = bank.process_transactions(&transactions);
|
|
||||||
for r in res {
|
|
||||||
assert!(r.is_ok(), "sanity parallel execution error: {:?}", r);
|
|
||||||
}
|
|
||||||
bank.clear_signatures();
|
|
||||||
}
|
}
|
||||||
|
bank.clear_signatures();
|
||||||
let mut verified: Vec<_> = to_packets_chunked(&transactions.clone(), packets_per_chunk);
|
let mut verified: Vec<_> = to_packets_chunked(&transactions.clone(), PACKETS_PER_BATCH)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| {
|
||||||
|
let len = x.packets.len();
|
||||||
|
(x, iter::repeat(1).take(len).collect())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
let ledger_path = get_tmp_ledger_path!();
|
let ledger_path = get_tmp_ledger_path!();
|
||||||
{
|
{
|
||||||
let blockstore = Arc::new(
|
let blocktree = Arc::new(
|
||||||
Blockstore::open(&ledger_path).expect("Expected to be able to open database ledger"),
|
Blocktree::open(&ledger_path).expect("Expected to be able to open database ledger"),
|
||||||
);
|
);
|
||||||
let (exit, poh_recorder, poh_service, signal_receiver) =
|
let (exit, poh_recorder, poh_service, signal_receiver) =
|
||||||
create_test_recorder(&bank, &blockstore, None);
|
create_test_recorder(&bank, &blocktree);
|
||||||
let cluster_info = ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info);
|
let cluster_info = ClusterInfo::new_with_invalid_keypair(Node::new_localhost().info);
|
||||||
let cluster_info = Arc::new(cluster_info);
|
let cluster_info = Arc::new(RwLock::new(cluster_info));
|
||||||
let banking_stage = BankingStage::new(
|
let _banking_stage = BankingStage::new(
|
||||||
&cluster_info,
|
&cluster_info,
|
||||||
&poh_recorder,
|
&poh_recorder,
|
||||||
verified_receiver,
|
verified_receiver,
|
||||||
vote_receiver,
|
vote_receiver,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
poh_recorder.lock().unwrap().set_bank(&bank);
|
poh_recorder.lock().unwrap().set_bank(&bank);
|
||||||
|
|
||||||
let chunk_len = verified.len() / num_chunks;
|
let chunk_len = verified.len() / CHUNKS;
|
||||||
let mut start = 0;
|
let mut start = 0;
|
||||||
|
|
||||||
// This is so that the signal_receiver does not go out of scope after the closure.
|
// This is so that the signal_receiver does not go out of scope after the closure.
|
||||||
// If it is dropped before poh_service, then poh_service will error when
|
// If it is dropped before poh_service, then poh_service will error when
|
||||||
// calling send() on the channel.
|
// calling send() on the channel.
|
||||||
let signal_receiver = Arc::new(signal_receiver);
|
let signal_receiver = Arc::new(signal_receiver);
|
||||||
let mut total_us = 0;
|
let signal_receiver2 = signal_receiver.clone();
|
||||||
let mut tx_total_us = 0;
|
let mut total = 0;
|
||||||
let base_tx_count = bank.transaction_count();
|
let mut tx_total = 0;
|
||||||
let mut txs_processed = 0;
|
let mut txs_processed = 0;
|
||||||
let mut root = 1;
|
let mut root = 1;
|
||||||
let collector = Pubkey::new_rand();
|
let collector = Pubkey::new_rand();
|
||||||
|
const ITERS: usize = 1_000;
|
||||||
let config = Config {
|
let config = Config {
|
||||||
packets_per_batch: packets_per_chunk,
|
packets_per_batch: PACKETS_PER_BATCH,
|
||||||
chunk_len,
|
chunk_len,
|
||||||
num_threads,
|
num_threads,
|
||||||
};
|
};
|
||||||
let mut total_sent = 0;
|
for _ in 0..ITERS {
|
||||||
for _ in 0..iterations {
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
let mut sent = 0;
|
let mut sent = 0;
|
||||||
|
|
||||||
@@ -271,7 +209,7 @@ fn main() {
|
|||||||
index,
|
index,
|
||||||
);
|
);
|
||||||
for xv in v {
|
for xv in v {
|
||||||
sent += xv.packets.len();
|
sent += xv.0.packets.len();
|
||||||
}
|
}
|
||||||
verified_sender.send(v.to_vec()).unwrap();
|
verified_sender.send(v.to_vec()).unwrap();
|
||||||
}
|
}
|
||||||
@@ -288,11 +226,7 @@ fn main() {
|
|||||||
sleep(Duration::from_millis(5));
|
sleep(Duration::from_millis(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if check_txs(
|
if check_txs(&signal_receiver2, txes / CHUNKS, &poh_recorder) {
|
||||||
&signal_receiver,
|
|
||||||
total_num_transactions / num_chunks,
|
|
||||||
&poh_recorder,
|
|
||||||
) {
|
|
||||||
debug!(
|
debug!(
|
||||||
"resetting bank {} tx count: {} txs_proc: {}",
|
"resetting bank {} tx count: {} txs_proc: {}",
|
||||||
bank.slot(),
|
bank.slot(),
|
||||||
@@ -301,7 +235,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
assert!(txs_processed < bank.transaction_count());
|
assert!(txs_processed < bank.transaction_count());
|
||||||
txs_processed = bank.transaction_count();
|
txs_processed = bank.transaction_count();
|
||||||
tx_total_us += duration_as_us(&now.elapsed());
|
tx_total += duration_as_us(&now.elapsed());
|
||||||
|
|
||||||
let mut poh_time = Measure::start("poh_time");
|
let mut poh_time = Measure::start("poh_time");
|
||||||
poh_recorder.lock().unwrap().reset(
|
poh_recorder.lock().unwrap().reset(
|
||||||
@@ -323,7 +257,7 @@ fn main() {
|
|||||||
poh_recorder.lock().unwrap().set_bank(&bank);
|
poh_recorder.lock().unwrap().set_bank(&bank);
|
||||||
assert!(poh_recorder.lock().unwrap().bank().is_some());
|
assert!(poh_recorder.lock().unwrap().bank().is_some());
|
||||||
if bank.slot() > 32 {
|
if bank.slot() > 32 {
|
||||||
bank_forks.set_root(root, &None, None);
|
bank_forks.set_root(root, &None);
|
||||||
root += 1;
|
root += 1;
|
||||||
}
|
}
|
||||||
debug!(
|
debug!(
|
||||||
@@ -333,21 +267,20 @@ fn main() {
|
|||||||
poh_time.as_us(),
|
poh_time.as_us(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
tx_total_us += duration_as_us(&now.elapsed());
|
tx_total += duration_as_us(&now.elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This signature clear may not actually clear the signatures
|
// This signature clear may not actually clear the signatures
|
||||||
// in this chunk, but since we rotate between CHUNKS then
|
// in this chunk, but since we rotate between CHUNKS then
|
||||||
// we should clear them by the time we come around again to re-use that chunk.
|
// we should clear them by the time we come around again to re-use that chunk.
|
||||||
bank.clear_signatures();
|
bank.clear_signatures();
|
||||||
total_us += duration_as_us(&now.elapsed());
|
total += duration_as_us(&now.elapsed());
|
||||||
debug!(
|
debug!(
|
||||||
"time: {} us checked: {} sent: {}",
|
"time: {} us checked: {} sent: {}",
|
||||||
duration_as_us(&now.elapsed()),
|
duration_as_us(&now.elapsed()),
|
||||||
total_num_transactions / num_chunks,
|
txes / CHUNKS,
|
||||||
sent,
|
sent,
|
||||||
);
|
);
|
||||||
total_sent += sent;
|
|
||||||
|
|
||||||
if bank.slot() > 0 && bank.slot() % 16 == 0 {
|
if bank.slot() > 0 && bank.slot() % 16 == 0 {
|
||||||
for tx in transactions.iter_mut() {
|
for tx in transactions.iter_mut() {
|
||||||
@@ -355,35 +288,32 @@ fn main() {
|
|||||||
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen()).collect();
|
let sig: Vec<u8> = (0..64).map(|_| thread_rng().gen()).collect();
|
||||||
tx.signatures[0] = Signature::new(&sig[0..64]);
|
tx.signatures[0] = Signature::new(&sig[0..64]);
|
||||||
}
|
}
|
||||||
verified = to_packets_chunked(&transactions.clone(), packets_per_chunk);
|
verified = to_packets_chunked(&transactions.clone(), PACKETS_PER_BATCH)
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| {
|
||||||
|
let len = x.packets.len();
|
||||||
|
(x, iter::repeat(1).take(len).collect())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
start += chunk_len;
|
start += chunk_len;
|
||||||
start %= verified.len();
|
start %= verified.len();
|
||||||
}
|
}
|
||||||
let txs_processed = bank_forks.working_bank().transaction_count();
|
|
||||||
debug!("processed: {} base: {}", txs_processed, base_tx_count);
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{{'name': 'banking_bench_total', 'median': '{:.2}'}}",
|
"{{'name': 'banking_bench_total', 'median': '{}'}}",
|
||||||
(1000.0 * 1000.0 * total_sent as f64) / (total_us as f64),
|
total / ITERS as u64,
|
||||||
);
|
);
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{{'name': 'banking_bench_tx_total', 'median': '{:.2}'}}",
|
"{{'name': 'banking_bench_tx_total', 'median': '{}'}}",
|
||||||
(1000.0 * 1000.0 * total_sent as f64) / (tx_total_us as f64),
|
tx_total / ITERS as u64,
|
||||||
);
|
|
||||||
eprintln!(
|
|
||||||
"{{'name': 'banking_bench_success_tx_total', 'median': '{:.2}'}}",
|
|
||||||
(1000.0 * 1000.0 * (txs_processed - base_tx_count) as f64) / (total_us as f64),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
drop(verified_sender);
|
|
||||||
drop(vote_sender);
|
drop(vote_sender);
|
||||||
exit.store(true, Ordering::Relaxed);
|
exit.store(true, Ordering::Relaxed);
|
||||||
banking_stage.join().unwrap();
|
|
||||||
debug!("waited for banking_stage");
|
|
||||||
poh_service.join().unwrap();
|
poh_service.join().unwrap();
|
||||||
sleep(Duration::from_secs(1));
|
sleep(Duration::from_secs(1));
|
||||||
debug!("waited for poh_service");
|
debug!("waited for poh_service");
|
||||||
}
|
}
|
||||||
let _unused = Blockstore::destroy(&ledger_path);
|
let _unused = Blocktree::destroy(&ledger_path);
|
||||||
}
|
}
|
@@ -2,37 +2,38 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-exchange"
|
name = "solana-bench-exchange"
|
||||||
version = "1.2.0"
|
version = "0.19.1"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.1"
|
bincode = "1.1.4"
|
||||||
itertools = "0.9.0"
|
bs58 = "0.3.0"
|
||||||
|
clap = "2.32.0"
|
||||||
|
env_logger = "0.6.2"
|
||||||
|
itertools = "0.8.0"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
num-derive = "0.3"
|
num-derive = "0.2"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
rand = "0.7.0"
|
rand = "0.6.5"
|
||||||
rayon = "1.3.0"
|
rayon = "1.2.0"
|
||||||
serde_json = "1.0.53"
|
serde = "1.0.101"
|
||||||
serde_yaml = "0.8.12"
|
serde_derive = "1.0.101"
|
||||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
serde_json = "1.0.40"
|
||||||
solana-core = { path = "../core", version = "1.2.0" }
|
serde_yaml = "0.8.9"
|
||||||
solana-genesis = { path = "../genesis", version = "1.2.0" }
|
# solana-runtime = { path = "../solana/runtime"}
|
||||||
solana-client = { path = "../client", version = "1.2.0" }
|
solana-core = { path = "../core", version = "0.19.1" }
|
||||||
solana-faucet = { path = "../faucet", version = "1.2.0" }
|
solana-genesis = { path = "../genesis", version = "0.19.1" }
|
||||||
solana-exchange-program = { path = "../programs/exchange", version = "1.2.0" }
|
solana-client = { path = "../client", version = "0.19.1" }
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
solana-drone = { path = "../drone", version = "0.19.1" }
|
||||||
solana-metrics = { path = "../metrics", version = "1.2.0" }
|
solana-exchange-api = { path = "../programs/exchange_api", version = "0.19.1" }
|
||||||
solana-net-utils = { path = "../net-utils", version = "1.2.0" }
|
solana-exchange-program = { path = "../programs/exchange_program", version = "0.19.1" }
|
||||||
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
solana-logger = { path = "../logger", version = "0.19.1" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
solana-metrics = { path = "../metrics", version = "0.19.1" }
|
||||||
solana-version = { path = "../version", version = "1.2.0" }
|
solana-netutil = { path = "../netutil", version = "0.19.1" }
|
||||||
|
solana-runtime = { path = "../runtime", version = "0.19.1" }
|
||||||
[dev-dependencies]
|
solana-sdk = { path = "../sdk", version = "0.19.1" }
|
||||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.0" }
|
untrusted = "0.7.0"
|
||||||
|
ws = "0.9.0"
|
||||||
[package.metadata.docs.rs]
|
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
||||||
|
@@ -360,7 +360,7 @@ The Matcher would initiate the following last swap:
|
|||||||
|
|
||||||
- Row 1, To: Investor 1 trades 2 A token to 12 B tokens
|
- Row 1, To: Investor 1 trades 2 A token to 12 B tokens
|
||||||
- Row 1, From: Investor 2 trades 2 A token from 12 B tokens
|
- Row 1, From: Investor 2 trades 2 A token from 12 B tokens
|
||||||
- Matcher takes 2 B tokens as profit
|
- Matcher takes 4 B tokens as profit
|
||||||
|
|
||||||
Table becomes:
|
Table becomes:
|
||||||
|
|
||||||
|
@@ -7,36 +7,32 @@ use rand::{thread_rng, Rng};
|
|||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use solana_client::perf_utils::{sample_txs, SampleStats};
|
use solana_client::perf_utils::{sample_txs, SampleStats};
|
||||||
use solana_core::gen_keys::GenKeys;
|
use solana_core::gen_keys::GenKeys;
|
||||||
use solana_exchange_program::{exchange_instruction, exchange_state::*, id};
|
use solana_drone::drone::request_airdrop_transaction;
|
||||||
use solana_faucet::faucet::request_airdrop_transaction;
|
use solana_exchange_api::exchange_instruction;
|
||||||
use solana_genesis::Base64Account;
|
use solana_exchange_api::exchange_state::*;
|
||||||
|
use solana_exchange_api::id;
|
||||||
|
use solana_genesis::PrimordialAccountDetails;
|
||||||
use solana_metrics::datapoint_info;
|
use solana_metrics::datapoint_info;
|
||||||
use solana_sdk::{
|
use solana_sdk::client::Client;
|
||||||
client::{Client, SyncClient},
|
use solana_sdk::client::SyncClient;
|
||||||
commitment_config::CommitmentConfig,
|
use solana_sdk::pubkey::Pubkey;
|
||||||
pubkey::Pubkey,
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
signature::{Keypair, Signer},
|
use solana_sdk::timing::{duration_as_ms, duration_as_s};
|
||||||
timing::{duration_as_ms, duration_as_s},
|
use solana_sdk::transaction::Transaction;
|
||||||
transaction::Transaction,
|
use solana_sdk::{system_instruction, system_program};
|
||||||
{system_instruction, system_program},
|
use std::cmp;
|
||||||
};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::{
|
use std::fs::File;
|
||||||
cmp,
|
use std::io::prelude::*;
|
||||||
collections::{HashMap, VecDeque},
|
use std::mem;
|
||||||
fs::File,
|
use std::net::SocketAddr;
|
||||||
io::prelude::*,
|
use std::path::Path;
|
||||||
mem,
|
use std::process::exit;
|
||||||
net::SocketAddr,
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
path::Path,
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
process::exit,
|
use std::sync::{Arc, RwLock};
|
||||||
sync::{
|
use std::thread::{sleep, Builder};
|
||||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
use std::time::{Duration, Instant};
|
||||||
mpsc::{channel, Receiver, Sender},
|
|
||||||
Arc, RwLock,
|
|
||||||
},
|
|
||||||
thread::{sleep, Builder},
|
|
||||||
time::{Duration, Instant},
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO Chunk length as specified results in a bunch of failures, divide by 10 helps...
|
// TODO Chunk length as specified results in a bunch of failures, divide by 10 helps...
|
||||||
// Assume 4MB network buffers, and 512 byte packets
|
// Assume 4MB network buffers, and 512 byte packets
|
||||||
@@ -93,7 +89,7 @@ pub fn create_client_accounts_file(
|
|||||||
keypairs.iter().for_each(|keypair| {
|
keypairs.iter().for_each(|keypair| {
|
||||||
accounts.insert(
|
accounts.insert(
|
||||||
serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap(),
|
serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap(),
|
||||||
Base64Account {
|
PrimordialAccountDetails {
|
||||||
balance: fund_amount,
|
balance: fund_amount,
|
||||||
executable: false,
|
executable: false,
|
||||||
owner: system_program::id().to_string(),
|
owner: system_program::id().to_string(),
|
||||||
@@ -144,7 +140,8 @@ where
|
|||||||
let path = Path::new(&client_ids_and_stake_file);
|
let path = Path::new(&client_ids_and_stake_file);
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
|
|
||||||
let accounts: HashMap<String, Base64Account> = serde_yaml::from_reader(file).unwrap();
|
let accounts: HashMap<String, PrimordialAccountDetails> =
|
||||||
|
serde_yaml::from_reader(file).unwrap();
|
||||||
accounts
|
accounts
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(keypair, _)| {
|
.map(|(keypair, _)| {
|
||||||
@@ -178,28 +175,19 @@ where
|
|||||||
|
|
||||||
info!("Generating {:?} account keys", total_keys);
|
info!("Generating {:?} account keys", total_keys);
|
||||||
let mut account_keypairs = generate_keypairs(total_keys);
|
let mut account_keypairs = generate_keypairs(total_keys);
|
||||||
let src_keypairs: Vec<_> = account_keypairs
|
let src_pubkeys: Vec<_> = account_keypairs
|
||||||
.drain(0..accounts_in_groups)
|
.drain(0..accounts_in_groups)
|
||||||
.map(|keypair| keypair)
|
|
||||||
.collect();
|
|
||||||
let src_pubkeys: Vec<Pubkey> = src_keypairs
|
|
||||||
.iter()
|
|
||||||
.map(|keypair| keypair.pubkey())
|
.map(|keypair| keypair.pubkey())
|
||||||
.collect();
|
.collect();
|
||||||
|
let profit_pubkeys: Vec<_> = account_keypairs
|
||||||
let profit_keypairs: Vec<_> = account_keypairs
|
|
||||||
.drain(0..accounts_in_groups)
|
.drain(0..accounts_in_groups)
|
||||||
.map(|keypair| keypair)
|
|
||||||
.collect();
|
|
||||||
let profit_pubkeys: Vec<Pubkey> = profit_keypairs
|
|
||||||
.iter()
|
|
||||||
.map(|keypair| keypair.pubkey())
|
.map(|keypair| keypair.pubkey())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
info!("Create {:?} source token accounts", src_pubkeys.len());
|
info!("Create {:?} source token accounts", src_pubkeys.len());
|
||||||
create_token_accounts(client, &trader_signers, &src_keypairs);
|
create_token_accounts(client, &trader_signers, &src_pubkeys);
|
||||||
info!("Create {:?} profit token accounts", profit_pubkeys.len());
|
info!("Create {:?} profit token accounts", profit_pubkeys.len());
|
||||||
create_token_accounts(client, &swapper_signers, &profit_keypairs);
|
create_token_accounts(client, &swapper_signers, &profit_pubkeys);
|
||||||
|
|
||||||
// Collect the max transaction rate and total tx count seen (single node only)
|
// Collect the max transaction rate and total tx count seen (single node only)
|
||||||
let sample_stats = Arc::new(RwLock::new(Vec::new()));
|
let sample_stats = Arc::new(RwLock::new(Vec::new()));
|
||||||
@@ -256,7 +244,7 @@ where
|
|||||||
trace!("Start trader thread");
|
trace!("Start trader thread");
|
||||||
let trader_thread = {
|
let trader_thread = {
|
||||||
let exit_signal = exit_signal.clone();
|
let exit_signal = exit_signal.clone();
|
||||||
|
let shared_txs = shared_txs.clone();
|
||||||
let client = clients[0].clone();
|
let client = clients[0].clone();
|
||||||
Builder::new()
|
Builder::new()
|
||||||
.name("solana-exchange-trader".to_string())
|
.name("solana-exchange-trader".to_string())
|
||||||
@@ -393,10 +381,7 @@ fn swapper<T>(
|
|||||||
let mut tries = 0;
|
let mut tries = 0;
|
||||||
let mut trade_index = 0;
|
let mut trade_index = 0;
|
||||||
while client
|
while client
|
||||||
.get_balance_with_commitment(
|
.get_balance(&trade_infos[trade_index].trade_account)
|
||||||
&trade_infos[trade_index].trade_account,
|
|
||||||
CommitmentConfig::recent(),
|
|
||||||
)
|
|
||||||
.unwrap_or(0)
|
.unwrap_or(0)
|
||||||
== 0
|
== 0
|
||||||
{
|
{
|
||||||
@@ -450,7 +435,7 @@ fn swapper<T>(
|
|||||||
account_group = (account_group + 1) % account_groups as usize;
|
account_group = (account_group + 1) % account_groups as usize;
|
||||||
|
|
||||||
let (blockhash, _fee_calculator) = client
|
let (blockhash, _fee_calculator) = client
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::recent())
|
.get_recent_blockhash()
|
||||||
.expect("Failed to get blockhash");
|
.expect("Failed to get blockhash");
|
||||||
let to_swap_txs: Vec<_> = to_swap
|
let to_swap_txs: Vec<_> = to_swap
|
||||||
.par_iter()
|
.par_iter()
|
||||||
@@ -459,7 +444,7 @@ fn swapper<T>(
|
|||||||
let owner = &signer.pubkey();
|
let owner = &signer.pubkey();
|
||||||
Transaction::new_signed_instructions(
|
Transaction::new_signed_instructions(
|
||||||
&[s],
|
&[s],
|
||||||
&[exchange_instruction::swap_request(
|
vec![exchange_instruction::swap_request(
|
||||||
owner,
|
owner,
|
||||||
&swap.0.pubkey,
|
&swap.0.pubkey,
|
||||||
&swap.1.pubkey,
|
&swap.1.pubkey,
|
||||||
@@ -573,39 +558,27 @@ fn trader<T>(
|
|||||||
trade_account: trade.pubkey(),
|
trade_account: trade.pubkey(),
|
||||||
order_info,
|
order_info,
|
||||||
});
|
});
|
||||||
trades.push((signer, trade, side, src));
|
trades.push((signer, trade.pubkey(), side, src));
|
||||||
}
|
}
|
||||||
account_group = (account_group + 1) % account_groups as usize;
|
account_group = (account_group + 1) % account_groups as usize;
|
||||||
|
|
||||||
let (blockhash, _fee_calculator) = client
|
let (blockhash, _fee_calculator) = client
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::recent())
|
.get_recent_blockhash()
|
||||||
.expect("Failed to get blockhash");
|
.expect("Failed to get blockhash");
|
||||||
|
|
||||||
trades.chunks(chunk_size).for_each(|chunk| {
|
trades.chunks(chunk_size).for_each(|chunk| {
|
||||||
let trades_txs: Vec<_> = chunk
|
let trades_txs: Vec<_> = chunk
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(owner, trade, side, src)| {
|
.map(|(signer, trade, side, src)| {
|
||||||
let owner_pubkey = &owner.pubkey();
|
let s: &Keypair = &signer;
|
||||||
let trade_pubkey = &trade.pubkey();
|
let owner = &signer.pubkey();
|
||||||
let space = mem::size_of::<ExchangeState>() as u64;
|
let space = mem::size_of::<ExchangeState>() as u64;
|
||||||
Transaction::new_signed_instructions(
|
Transaction::new_signed_instructions(
|
||||||
&[owner.as_ref(), trade],
|
&[s],
|
||||||
&[
|
vec![
|
||||||
system_instruction::create_account(
|
system_instruction::create_account(owner, trade, 1, space, &id()),
|
||||||
owner_pubkey,
|
|
||||||
trade_pubkey,
|
|
||||||
1,
|
|
||||||
space,
|
|
||||||
&id(),
|
|
||||||
),
|
|
||||||
exchange_instruction::trade_request(
|
exchange_instruction::trade_request(
|
||||||
owner_pubkey,
|
owner, trade, *side, pair, tokens, price, src,
|
||||||
trade_pubkey,
|
|
||||||
*side,
|
|
||||||
pair,
|
|
||||||
tokens,
|
|
||||||
price,
|
|
||||||
src,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
blockhash,
|
blockhash,
|
||||||
@@ -661,14 +634,12 @@ fn trader<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_transaction<T>(sync_client: &T, tx: &Transaction) -> bool
|
fn verify_transfer<T>(sync_client: &T, tx: &Transaction) -> bool
|
||||||
where
|
where
|
||||||
T: SyncClient + ?Sized,
|
T: SyncClient + ?Sized,
|
||||||
{
|
{
|
||||||
for s in &tx.signatures {
|
for s in &tx.signatures {
|
||||||
if let Ok(Some(r)) =
|
if let Ok(Some(r)) = sync_client.get_signature_status(s) {
|
||||||
sync_client.get_signature_status_with_commitment(s, CommitmentConfig::recent())
|
|
||||||
{
|
|
||||||
match r {
|
match r {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
return true;
|
return true;
|
||||||
@@ -687,21 +658,16 @@ fn verify_funding_transfer<T: SyncClient + ?Sized>(
|
|||||||
tx: &Transaction,
|
tx: &Transaction,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if verify_transaction(client, tx) {
|
for a in &tx.message().account_keys[1..] {
|
||||||
for a in &tx.message().account_keys[1..] {
|
if client.get_balance(a).unwrap_or(0) >= amount {
|
||||||
if client
|
return true;
|
||||||
.get_balance_with_commitment(a, CommitmentConfig::recent())
|
|
||||||
.unwrap_or(0)
|
|
||||||
>= amount
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Arc<Keypair>], lamports: u64) {
|
pub fn fund_keys(client: &dyn Client, source: &Keypair, dests: &[Arc<Keypair>], lamports: u64) {
|
||||||
let total = lamports * (dests.len() as u64 + 1);
|
let total = lamports * (dests.len() as u64 + 1);
|
||||||
let mut funded: Vec<(&Keypair, u64)> = vec![(source, total)];
|
let mut funded: Vec<(&Keypair, u64)> = vec![(source, total)];
|
||||||
let mut notfunded: Vec<&Arc<Keypair>> = dests.iter().collect();
|
let mut notfunded: Vec<&Arc<Keypair>> = dests.iter().collect();
|
||||||
@@ -749,7 +715,7 @@ pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Arc<Keypair>]
|
|||||||
.map(|(k, m)| {
|
.map(|(k, m)| {
|
||||||
(
|
(
|
||||||
k.clone(),
|
k.clone(),
|
||||||
Transaction::new_unsigned_instructions(&system_instruction::transfer_many(
|
Transaction::new_unsigned_instructions(system_instruction::transfer_many(
|
||||||
&k.pubkey(),
|
&k.pubkey(),
|
||||||
&m,
|
&m,
|
||||||
)),
|
)),
|
||||||
@@ -760,10 +726,9 @@ pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Arc<Keypair>]
|
|||||||
let mut retries = 0;
|
let mut retries = 0;
|
||||||
let amount = chunk[0].1[0].1;
|
let amount = chunk[0].1[0].1;
|
||||||
while !to_fund_txs.is_empty() {
|
while !to_fund_txs.is_empty() {
|
||||||
let receivers: usize = to_fund_txs
|
let receivers = to_fund_txs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, tx)| tx.message().instructions.len())
|
.fold(0, |len, (_, tx)| len + tx.message().instructions.len());
|
||||||
.sum();
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
" {} to {} in {} txs",
|
" {} to {} in {} txs",
|
||||||
@@ -776,9 +741,8 @@ pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Arc<Keypair>]
|
|||||||
to_fund_txs.len(),
|
to_fund_txs.len(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (blockhash, _fee_calculator) = client
|
let (blockhash, _fee_calculator) =
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::recent())
|
client.get_recent_blockhash().expect("blockhash");
|
||||||
.expect("blockhash");
|
|
||||||
to_fund_txs.par_iter_mut().for_each(|(k, tx)| {
|
to_fund_txs.par_iter_mut().for_each(|(k, tx)| {
|
||||||
tx.sign(&[*k], blockhash);
|
tx.sign(&[*k], blockhash);
|
||||||
});
|
});
|
||||||
@@ -815,50 +779,35 @@ pub fn fund_keys<T: Client>(client: &T, source: &Keypair, dests: &[Arc<Keypair>]
|
|||||||
});
|
});
|
||||||
funded.append(&mut new_funded);
|
funded.append(&mut new_funded);
|
||||||
funded.retain(|(k, b)| {
|
funded.retain(|(k, b)| {
|
||||||
client
|
client.get_balance(&k.pubkey()).unwrap_or(0) > lamports && *b > lamports
|
||||||
.get_balance_with_commitment(&k.pubkey(), CommitmentConfig::recent())
|
|
||||||
.unwrap_or(0)
|
|
||||||
> lamports
|
|
||||||
&& *b > lamports
|
|
||||||
});
|
});
|
||||||
debug!(" Funded: {} left: {}", funded.len(), notfunded.len());
|
debug!(" Funded: {} left: {}", funded.len(), notfunded.len());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_token_accounts<T: Client>(
|
pub fn create_token_accounts(client: &dyn Client, signers: &[Arc<Keypair>], accounts: &[Pubkey]) {
|
||||||
client: &T,
|
let mut notfunded: Vec<(&Arc<Keypair>, &Pubkey)> = signers.iter().zip(accounts).collect();
|
||||||
signers: &[Arc<Keypair>],
|
|
||||||
accounts: &[Keypair],
|
|
||||||
) {
|
|
||||||
let mut notfunded: Vec<(&Arc<Keypair>, &Keypair)> = signers.iter().zip(accounts).collect();
|
|
||||||
|
|
||||||
while !notfunded.is_empty() {
|
while !notfunded.is_empty() {
|
||||||
notfunded.chunks(FUND_CHUNK_LEN).for_each(|chunk| {
|
notfunded.chunks(FUND_CHUNK_LEN).for_each(|chunk| {
|
||||||
let mut to_create_txs: Vec<_> = chunk
|
let mut to_create_txs: Vec<_> = chunk
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(from_keypair, new_keypair)| {
|
.map(|(signer, new)| {
|
||||||
let owner_pubkey = &from_keypair.pubkey();
|
let owner_pubkey = &signer.pubkey();
|
||||||
let space = mem::size_of::<ExchangeState>() as u64;
|
let space = mem::size_of::<ExchangeState>() as u64;
|
||||||
let create_ix = system_instruction::create_account(
|
let create_ix =
|
||||||
owner_pubkey,
|
system_instruction::create_account(owner_pubkey, new, 1, space, &id());
|
||||||
&new_keypair.pubkey(),
|
let request_ix = exchange_instruction::account_request(owner_pubkey, new);
|
||||||
1,
|
|
||||||
space,
|
|
||||||
&id(),
|
|
||||||
);
|
|
||||||
let request_ix =
|
|
||||||
exchange_instruction::account_request(owner_pubkey, &new_keypair.pubkey());
|
|
||||||
(
|
(
|
||||||
(from_keypair, new_keypair),
|
signer,
|
||||||
Transaction::new_unsigned_instructions(&[create_ix, request_ix]),
|
Transaction::new_unsigned_instructions(vec![create_ix, request_ix]),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let accounts: usize = to_create_txs
|
let accounts = to_create_txs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, tx)| tx.message().instructions.len() / 2)
|
.fold(0, |len, (_, tx)| len + tx.message().instructions.len() / 2);
|
||||||
.sum();
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
" Creating {} accounts in {} txs",
|
" Creating {} accounts in {} txs",
|
||||||
@@ -869,13 +818,12 @@ pub fn create_token_accounts<T: Client>(
|
|||||||
let mut retries = 0;
|
let mut retries = 0;
|
||||||
while !to_create_txs.is_empty() {
|
while !to_create_txs.is_empty() {
|
||||||
let (blockhash, _fee_calculator) = client
|
let (blockhash, _fee_calculator) = client
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::recent())
|
.get_recent_blockhash()
|
||||||
.expect("Failed to get blockhash");
|
.expect("Failed to get blockhash");
|
||||||
to_create_txs
|
to_create_txs.par_iter_mut().for_each(|(k, tx)| {
|
||||||
.par_iter_mut()
|
let kp: &Keypair = k;
|
||||||
.for_each(|((from_keypair, to_keypair), tx)| {
|
tx.sign(&[kp], blockhash);
|
||||||
tx.sign(&[from_keypair.as_ref(), to_keypair], blockhash);
|
});
|
||||||
});
|
|
||||||
to_create_txs.iter().for_each(|(_, tx)| {
|
to_create_txs.iter().for_each(|(_, tx)| {
|
||||||
client.async_send_transaction(tx.clone()).expect("transfer");
|
client.async_send_transaction(tx.clone()).expect("transfer");
|
||||||
});
|
});
|
||||||
@@ -883,11 +831,11 @@ pub fn create_token_accounts<T: Client>(
|
|||||||
let mut waits = 0;
|
let mut waits = 0;
|
||||||
while !to_create_txs.is_empty() {
|
while !to_create_txs.is_empty() {
|
||||||
sleep(Duration::from_millis(200));
|
sleep(Duration::from_millis(200));
|
||||||
to_create_txs.retain(|(_, tx)| !verify_transaction(client, &tx));
|
to_create_txs.retain(|(_, tx)| !verify_transfer(client, &tx));
|
||||||
if to_create_txs.is_empty() {
|
if to_create_txs.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info!(
|
debug!(
|
||||||
" {} transactions outstanding, waits {:?}",
|
" {} transactions outstanding, waits {:?}",
|
||||||
to_create_txs.len(),
|
to_create_txs.len(),
|
||||||
waits
|
waits
|
||||||
@@ -900,7 +848,7 @@ pub fn create_token_accounts<T: Client>(
|
|||||||
|
|
||||||
if !to_create_txs.is_empty() {
|
if !to_create_txs.is_empty() {
|
||||||
retries += 1;
|
retries += 1;
|
||||||
info!(" Retry {:?} {} txes left", retries, to_create_txs.len());
|
debug!(" Retry {:?}", retries);
|
||||||
if retries >= 20 {
|
if retries >= 20 {
|
||||||
error!(
|
error!(
|
||||||
"create_token_accounts: Too many retries ({}), give up",
|
"create_token_accounts: Too many retries ({}), give up",
|
||||||
@@ -912,13 +860,9 @@ pub fn create_token_accounts<T: Client>(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut new_notfunded: Vec<(&Arc<Keypair>, &Keypair)> = vec![];
|
let mut new_notfunded: Vec<(&Arc<Keypair>, &Pubkey)> = vec![];
|
||||||
for f in ¬funded {
|
for f in ¬funded {
|
||||||
if client
|
if client.get_balance(&f.1).unwrap_or(0) == 0 {
|
||||||
.get_balance_with_commitment(&f.1.pubkey(), CommitmentConfig::recent())
|
|
||||||
.unwrap_or(0)
|
|
||||||
== 0
|
|
||||||
{
|
|
||||||
new_notfunded.push(*f)
|
new_notfunded.push(*f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -974,13 +918,8 @@ fn generate_keypairs(num: u64) -> Vec<Keypair> {
|
|||||||
rnd.gen_n_keypairs(num)
|
rnd.gen_n_keypairs(num)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn airdrop_lamports<T: Client>(
|
pub fn airdrop_lamports(client: &dyn Client, drone_addr: &SocketAddr, id: &Keypair, amount: u64) {
|
||||||
client: &T,
|
let balance = client.get_balance(&id.pubkey());
|
||||||
faucet_addr: &SocketAddr,
|
|
||||||
id: &Keypair,
|
|
||||||
amount: u64,
|
|
||||||
) {
|
|
||||||
let balance = client.get_balance_with_commitment(&id.pubkey(), CommitmentConfig::recent());
|
|
||||||
let balance = balance.unwrap_or(0);
|
let balance = balance.unwrap_or(0);
|
||||||
if balance >= amount {
|
if balance >= amount {
|
||||||
return;
|
return;
|
||||||
@@ -991,40 +930,33 @@ pub fn airdrop_lamports<T: Client>(
|
|||||||
info!(
|
info!(
|
||||||
"Airdropping {:?} lamports from {} for {}",
|
"Airdropping {:?} lamports from {} for {}",
|
||||||
amount_to_drop,
|
amount_to_drop,
|
||||||
faucet_addr,
|
drone_addr,
|
||||||
id.pubkey(),
|
id.pubkey(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tries = 0;
|
let mut tries = 0;
|
||||||
loop {
|
loop {
|
||||||
let (blockhash, _fee_calculator) = client
|
let (blockhash, _fee_calculator) = client
|
||||||
.get_recent_blockhash_with_commitment(CommitmentConfig::recent())
|
.get_recent_blockhash()
|
||||||
.expect("Failed to get blockhash");
|
.expect("Failed to get blockhash");
|
||||||
match request_airdrop_transaction(&faucet_addr, &id.pubkey(), amount_to_drop, blockhash) {
|
match request_airdrop_transaction(&drone_addr, &id.pubkey(), amount_to_drop, blockhash) {
|
||||||
Ok(transaction) => {
|
Ok(transaction) => {
|
||||||
let signature = client.async_send_transaction(transaction).unwrap();
|
let signature = client.async_send_transaction(transaction).unwrap();
|
||||||
|
|
||||||
for _ in 0..30 {
|
for _ in 0..30 {
|
||||||
if let Ok(Some(_)) = client.get_signature_status_with_commitment(
|
if let Ok(Some(_)) = client.get_signature_status(&signature) {
|
||||||
&signature,
|
|
||||||
CommitmentConfig::recent(),
|
|
||||||
) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sleep(Duration::from_millis(100));
|
sleep(Duration::from_millis(100));
|
||||||
}
|
}
|
||||||
if client
|
if client.get_balance(&id.pubkey()).unwrap_or(0) >= amount {
|
||||||
.get_balance_with_commitment(&id.pubkey(), CommitmentConfig::recent())
|
|
||||||
.unwrap_or(0)
|
|
||||||
>= amount
|
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
panic!(
|
panic!(
|
||||||
"Error requesting airdrop: {:?} to addr: {:?} amount: {}",
|
"Error requesting airdrop: {:?} to addr: {:?} amount: {}",
|
||||||
err, faucet_addr, amount
|
err, drone_addr, amount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
use clap::{crate_description, crate_name, value_t, App, Arg, ArgMatches};
|
use clap::{crate_description, crate_name, crate_version, value_t, App, Arg, ArgMatches};
|
||||||
use solana_core::gen_keys::GenKeys;
|
use solana_core::gen_keys::GenKeys;
|
||||||
use solana_faucet::faucet::FAUCET_PORT;
|
use solana_drone::drone::DRONE_PORT;
|
||||||
use solana_sdk::signature::{read_keypair_file, Keypair};
|
use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub entrypoint_addr: SocketAddr,
|
pub entrypoint_addr: SocketAddr,
|
||||||
pub faucet_addr: SocketAddr,
|
pub drone_addr: SocketAddr,
|
||||||
pub identity: Keypair,
|
pub identity: Keypair,
|
||||||
pub threads: usize,
|
pub threads: usize,
|
||||||
pub num_nodes: usize,
|
pub num_nodes: usize,
|
||||||
@@ -27,7 +27,7 @@ impl Default for Config {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
|
entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
|
||||||
faucet_addr: SocketAddr::from(([127, 0, 0, 1], FAUCET_PORT)),
|
drone_addr: SocketAddr::from(([127, 0, 0, 1], DRONE_PORT)),
|
||||||
identity: Keypair::new(),
|
identity: Keypair::new(),
|
||||||
num_nodes: 1,
|
num_nodes: 1,
|
||||||
threads: 4,
|
threads: 4,
|
||||||
@@ -44,10 +44,10 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
pub fn build_args<'a, 'b>() -> App<'a, 'b> {
|
||||||
App::new(crate_name!())
|
App::new(crate_name!())
|
||||||
.about(crate_description!())
|
.about(crate_description!())
|
||||||
.version(version)
|
.version(crate_version!())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("entrypoint")
|
Arg::with_name("entrypoint")
|
||||||
.short("n")
|
.short("n")
|
||||||
@@ -59,14 +59,14 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
.help("Cluster entry point; defaults to 127.0.0.1:8001"),
|
.help("Cluster entry point; defaults to 127.0.0.1:8001"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("faucet")
|
Arg::with_name("drone")
|
||||||
.short("d")
|
.short("d")
|
||||||
.long("faucet")
|
.long("drone")
|
||||||
.value_name("HOST:PORT")
|
.value_name("HOST:PORT")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.required(false)
|
.required(false)
|
||||||
.default_value("127.0.0.1:9900")
|
.default_value("127.0.0.1:9900")
|
||||||
.help("Location of the faucet; defaults to 127.0.0.1:9900"),
|
.help("Location of the drone; defaults to 127.0.0.1:9900"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("identity")
|
Arg::with_name("identity")
|
||||||
@@ -166,22 +166,20 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
||||||
let mut args = Config::default();
|
let mut args = Config::default();
|
||||||
|
|
||||||
args.entrypoint_addr = solana_net_utils::parse_host_port(
|
args.entrypoint_addr = solana_netutil::parse_host_port(matches.value_of("entrypoint").unwrap())
|
||||||
matches.value_of("entrypoint").unwrap(),
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|e| {
|
|
||||||
eprintln!("failed to parse entrypoint address: {}", e);
|
|
||||||
exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
args.faucet_addr = solana_net_utils::parse_host_port(matches.value_of("faucet").unwrap())
|
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
eprintln!("failed to parse faucet address: {}", e);
|
eprintln!("failed to parse entrypoint address: {}", e);
|
||||||
|
exit(1)
|
||||||
|
});
|
||||||
|
|
||||||
|
args.drone_addr = solana_netutil::parse_host_port(matches.value_of("drone").unwrap())
|
||||||
|
.unwrap_or_else(|e| {
|
||||||
|
eprintln!("failed to parse drone address: {}", e);
|
||||||
exit(1)
|
exit(1)
|
||||||
});
|
});
|
||||||
|
|
||||||
if matches.is_present("identity") {
|
if matches.is_present("identity") {
|
||||||
args.identity = read_keypair_file(matches.value_of("identity").unwrap())
|
args.identity = read_keypair(matches.value_of("identity").unwrap())
|
||||||
.expect("can't read client identity");
|
.expect("can't read client identity");
|
||||||
} else {
|
} else {
|
||||||
args.identity = {
|
args.identity = {
|
||||||
|
@@ -5,18 +5,18 @@ pub mod order_book;
|
|||||||
use crate::bench::{airdrop_lamports, create_client_accounts_file, do_bench_exchange, Config};
|
use crate::bench::{airdrop_lamports, create_client_accounts_file, do_bench_exchange, Config};
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_core::gossip_service::{discover_cluster, get_multi_client};
|
use solana_core::gossip_service::{discover_cluster, get_multi_client};
|
||||||
use solana_sdk::signature::Signer;
|
use solana_sdk::signature::KeypairUtil;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
solana_logger::setup();
|
solana_logger::setup();
|
||||||
solana_metrics::set_panic_hook("bench-exchange");
|
solana_metrics::set_panic_hook("bench-exchange");
|
||||||
|
|
||||||
let matches = cli::build_args(solana_version::version!()).get_matches();
|
let matches = cli::build_args().get_matches();
|
||||||
let cli_config = cli::extract_args(&matches);
|
let cli_config = cli::extract_args(&matches);
|
||||||
|
|
||||||
let cli::Config {
|
let cli::Config {
|
||||||
entrypoint_addr,
|
entrypoint_addr,
|
||||||
faucet_addr,
|
drone_addr,
|
||||||
identity,
|
identity,
|
||||||
threads,
|
threads,
|
||||||
num_nodes,
|
num_nodes,
|
||||||
@@ -54,9 +54,10 @@ fn main() {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
info!("Connecting to the cluster");
|
info!("Connecting to the cluster");
|
||||||
let nodes = discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|_| {
|
let (nodes, _replicators) =
|
||||||
panic!("Failed to discover nodes");
|
discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|_| {
|
||||||
});
|
panic!("Failed to discover nodes");
|
||||||
|
});
|
||||||
|
|
||||||
let (client, num_clients) = get_multi_client(&nodes);
|
let (client, num_clients) = get_multi_client(&nodes);
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ fn main() {
|
|||||||
const NUM_SIGNERS: u64 = 2;
|
const NUM_SIGNERS: u64 = 2;
|
||||||
airdrop_lamports(
|
airdrop_lamports(
|
||||||
&client,
|
&client,
|
||||||
&faucet_addr,
|
&drone_addr,
|
||||||
&config.identity,
|
&config.identity,
|
||||||
fund_amount * (accounts_in_groups + 1) as u64 * NUM_SIGNERS,
|
fund_amount * (accounts_in_groups + 1) as u64 * NUM_SIGNERS,
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
use itertools::EitherOrBoth::{Both, Left, Right};
|
use itertools::EitherOrBoth::{Both, Left, Right};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::*;
|
use log::*;
|
||||||
use solana_exchange_program::exchange_state::*;
|
use solana_exchange_api::exchange_state::*;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
|
@@ -2,18 +2,13 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-streamer"
|
name = "solana-bench-streamer"
|
||||||
version = "1.2.0"
|
version = "0.19.1"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33.1"
|
clap = "2.33.0"
|
||||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
solana-core = { path = "../core", version = "0.19.1" }
|
||||||
solana-streamer = { path = "../streamer", version = "1.2.0" }
|
solana-logger = { path = "../logger", version = "0.19.1" }
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
solana-netutil = { path = "../netutil", version = "0.19.1" }
|
||||||
solana-net-utils = { path = "../net-utils", version = "1.2.0" }
|
|
||||||
solana-version = { path = "../version", version = "1.2.0" }
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
||||||
|
@@ -1,13 +1,15 @@
|
|||||||
use clap::{crate_description, crate_name, App, Arg};
|
use clap::{crate_description, crate_name, crate_version, App, Arg};
|
||||||
use solana_streamer::packet::{Packet, Packets, PacketsRecycler, PACKET_DATA_SIZE};
|
use solana_core::packet::PacketsRecycler;
|
||||||
use solana_streamer::streamer::{receiver, PacketReceiver};
|
use solana_core::packet::{Packet, Packets, BLOB_SIZE, PACKET_DATA_SIZE};
|
||||||
|
use solana_core::result::Result;
|
||||||
|
use solana_core::streamer::{receiver, PacketReceiver};
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::thread::{spawn, JoinHandle, Result};
|
use std::thread::{spawn, JoinHandle};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
@@ -27,7 +29,7 @@ fn producer(addr: &SocketAddr, exit: Arc<AtomicBool>) -> JoinHandle<()> {
|
|||||||
let mut num = 0;
|
let mut num = 0;
|
||||||
for p in &msgs.packets {
|
for p in &msgs.packets {
|
||||||
let a = p.meta.addr();
|
let a = p.meta.addr();
|
||||||
assert!(p.meta.size < PACKET_DATA_SIZE);
|
assert!(p.meta.size < BLOB_SIZE);
|
||||||
send.send_to(&p.data[..p.meta.size], &a).unwrap();
|
send.send_to(&p.data[..p.meta.size], &a).unwrap();
|
||||||
num += 1;
|
num += 1;
|
||||||
}
|
}
|
||||||
@@ -52,7 +54,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let matches = App::new(crate_name!())
|
let matches = App::new(crate_name!())
|
||||||
.about(crate_description!())
|
.about(crate_description!())
|
||||||
.version(solana_version::version!())
|
.version(crate_version!())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("num-recv-sockets")
|
Arg::with_name("num-recv-sockets")
|
||||||
.long("num-recv-sockets")
|
.long("num-recv-sockets")
|
||||||
@@ -67,8 +69,7 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut port = 0;
|
let mut port = 0;
|
||||||
let ip_addr = IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0));
|
let mut addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
|
||||||
let mut addr = SocketAddr::new(ip_addr, 0);
|
|
||||||
|
|
||||||
let exit = Arc::new(AtomicBool::new(false));
|
let exit = Arc::new(AtomicBool::new(false));
|
||||||
|
|
||||||
@@ -76,7 +77,7 @@ fn main() -> Result<()> {
|
|||||||
let mut read_threads = Vec::new();
|
let mut read_threads = Vec::new();
|
||||||
let recycler = PacketsRecycler::default();
|
let recycler = PacketsRecycler::default();
|
||||||
for _ in 0..num_sockets {
|
for _ in 0..num_sockets {
|
||||||
let read = solana_net_utils::bind_to(ip_addr, port, false).unwrap();
|
let read = solana_netutil::bind_to(port, false).unwrap();
|
||||||
read.set_read_timeout(Some(Duration::new(1, 0))).unwrap();
|
read.set_read_timeout(Some(Duration::new(1, 0))).unwrap();
|
||||||
|
|
||||||
addr = read.local_addr().unwrap();
|
addr = read.local_addr().unwrap();
|
||||||
|
@@ -2,40 +2,34 @@
|
|||||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
name = "solana-bench-tps"
|
name = "solana-bench-tps"
|
||||||
version = "1.2.0"
|
version = "0.19.1"
|
||||||
repository = "https://github.com/solana-labs/solana"
|
repository = "https://github.com/solana-labs/solana"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://solana.com/"
|
homepage = "https://solana.com/"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bincode = "1.2.1"
|
bincode = "1.1.4"
|
||||||
clap = "2.33.1"
|
clap = "2.33.0"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rayon = "1.3.0"
|
rayon = "1.2.0"
|
||||||
serde_json = "1.0.53"
|
serde = "1.0.101"
|
||||||
serde_yaml = "0.8.12"
|
serde_derive = "1.0.101"
|
||||||
solana-clap-utils = { path = "../clap-utils", version = "1.2.0" }
|
serde_json = "1.0.40"
|
||||||
solana-core = { path = "../core", version = "1.2.0" }
|
serde_yaml = "0.8.9"
|
||||||
solana-genesis = { path = "../genesis", version = "1.2.0" }
|
solana-core = { path = "../core", version = "0.19.1" }
|
||||||
solana-client = { path = "../client", version = "1.2.0" }
|
solana-genesis = { path = "../genesis", version = "0.19.1" }
|
||||||
solana-faucet = { path = "../faucet", version = "1.2.0" }
|
solana-client = { path = "../client", version = "0.19.1" }
|
||||||
solana-librapay = { path = "../programs/librapay", version = "1.2.0", optional = true }
|
solana-drone = { path = "../drone", version = "0.19.1" }
|
||||||
solana-logger = { path = "../logger", version = "1.2.0" }
|
solana-librapay-api = { path = "../programs/librapay_api", version = "0.19.1" }
|
||||||
solana-metrics = { path = "../metrics", version = "1.2.0" }
|
solana-logger = { path = "../logger", version = "0.19.1" }
|
||||||
solana-measure = { path = "../measure", version = "1.2.0" }
|
solana-metrics = { path = "../metrics", version = "0.19.1" }
|
||||||
solana-net-utils = { path = "../net-utils", version = "1.2.0" }
|
solana-measure = { path = "../measure", version = "0.19.1" }
|
||||||
solana-runtime = { path = "../runtime", version = "1.2.0" }
|
solana-netutil = { path = "../netutil", version = "0.19.1" }
|
||||||
solana-sdk = { path = "../sdk", version = "1.2.0" }
|
solana-runtime = { path = "../runtime", version = "0.19.1" }
|
||||||
solana-move-loader-program = { path = "../programs/move_loader", version = "1.2.0", optional = true }
|
solana-sdk = { path = "../sdk", version = "0.19.1" }
|
||||||
solana-version = { path = "../version", version = "1.2.0" }
|
solana-move-loader-program = { path = "../programs/move_loader_program", version = "0.19.1" }
|
||||||
|
solana-move-loader-api = { path = "../programs/move_loader_api", version = "0.19.1" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = "0.4.0"
|
serial_test = "0.2.0"
|
||||||
serial_test_derive = "0.4.0"
|
serial_test_derive = "0.2.0"
|
||||||
solana-local-cluster = { path = "../local-cluster", version = "1.2.0" }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
move = ["solana-librapay", "solana-move-loader-program"]
|
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
||||||
|
@@ -1,62 +1,59 @@
|
|||||||
use clap::{crate_description, crate_name, App, Arg, ArgMatches};
|
use std::net::SocketAddr;
|
||||||
use solana_faucet::faucet::FAUCET_PORT;
|
use std::process::exit;
|
||||||
use solana_sdk::fee_calculator::FeeRateGovernor;
|
use std::time::Duration;
|
||||||
use solana_sdk::signature::{read_keypair_file, Keypair};
|
|
||||||
use std::{net::SocketAddr, process::exit, time::Duration};
|
|
||||||
|
|
||||||
const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::LAMPORTS_PER_SOL;
|
use clap::{crate_description, crate_name, crate_version, App, Arg, ArgMatches};
|
||||||
|
use solana_drone::drone::DRONE_PORT;
|
||||||
|
use solana_sdk::fee_calculator::FeeCalculator;
|
||||||
|
use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil};
|
||||||
|
|
||||||
|
const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = 64 * 1024;
|
||||||
|
|
||||||
/// Holds the configuration for a single run of the benchmark
|
/// Holds the configuration for a single run of the benchmark
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub entrypoint_addr: SocketAddr,
|
pub entrypoint_addr: SocketAddr,
|
||||||
pub faucet_addr: SocketAddr,
|
pub drone_addr: SocketAddr,
|
||||||
pub id: Keypair,
|
pub id: Keypair,
|
||||||
pub threads: usize,
|
pub threads: usize,
|
||||||
pub num_nodes: usize,
|
pub num_nodes: usize,
|
||||||
pub duration: Duration,
|
pub duration: Duration,
|
||||||
pub tx_count: usize,
|
pub tx_count: usize,
|
||||||
pub keypair_multiplier: usize,
|
|
||||||
pub thread_batch_sleep_ms: usize,
|
pub thread_batch_sleep_ms: usize,
|
||||||
pub sustained: bool,
|
pub sustained: bool,
|
||||||
pub client_ids_and_stake_file: String,
|
pub client_ids_and_stake_file: String,
|
||||||
pub write_to_client_file: bool,
|
pub write_to_client_file: bool,
|
||||||
pub read_from_client_file: bool,
|
pub read_from_client_file: bool,
|
||||||
pub target_lamports_per_signature: u64,
|
pub target_lamports_per_signature: u64,
|
||||||
pub multi_client: bool,
|
|
||||||
pub use_move: bool,
|
pub use_move: bool,
|
||||||
pub num_lamports_per_account: u64,
|
pub num_lamports_per_account: u64,
|
||||||
pub target_slots_per_epoch: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Config {
|
fn default() -> Config {
|
||||||
Config {
|
Config {
|
||||||
entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
|
entrypoint_addr: SocketAddr::from(([127, 0, 0, 1], 8001)),
|
||||||
faucet_addr: SocketAddr::from(([127, 0, 0, 1], FAUCET_PORT)),
|
drone_addr: SocketAddr::from(([127, 0, 0, 1], DRONE_PORT)),
|
||||||
id: Keypair::new(),
|
id: Keypair::new(),
|
||||||
threads: 4,
|
threads: 4,
|
||||||
num_nodes: 1,
|
num_nodes: 1,
|
||||||
duration: Duration::new(std::u64::MAX, 0),
|
duration: Duration::new(std::u64::MAX, 0),
|
||||||
tx_count: 50_000,
|
tx_count: 500_000,
|
||||||
keypair_multiplier: 8,
|
thread_batch_sleep_ms: 0,
|
||||||
thread_batch_sleep_ms: 1000,
|
|
||||||
sustained: false,
|
sustained: false,
|
||||||
client_ids_and_stake_file: String::new(),
|
client_ids_and_stake_file: String::new(),
|
||||||
write_to_client_file: false,
|
write_to_client_file: false,
|
||||||
read_from_client_file: false,
|
read_from_client_file: false,
|
||||||
target_lamports_per_signature: FeeRateGovernor::default().target_lamports_per_signature,
|
target_lamports_per_signature: FeeCalculator::default().target_lamports_per_signature,
|
||||||
multi_client: true,
|
|
||||||
use_move: false,
|
use_move: false,
|
||||||
num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT,
|
num_lamports_per_account: NUM_LAMPORTS_PER_ACCOUNT_DEFAULT,
|
||||||
target_slots_per_epoch: 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines and builds the CLI args for a run of the benchmark
|
/// Defines and builds the CLI args for a run of the benchmark
|
||||||
pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
pub fn build_args<'a, 'b>() -> App<'a, 'b> {
|
||||||
App::new(crate_name!()).about(crate_description!())
|
App::new(crate_name!()).about(crate_description!())
|
||||||
.version(version)
|
.version(crate_version!())
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("entrypoint")
|
Arg::with_name("entrypoint")
|
||||||
.short("n")
|
.short("n")
|
||||||
@@ -66,12 +63,12 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
.help("Rendezvous with the cluster at this entry point; defaults to 127.0.0.1:8001"),
|
.help("Rendezvous with the cluster at this entry point; defaults to 127.0.0.1:8001"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("faucet")
|
Arg::with_name("drone")
|
||||||
.short("d")
|
.short("d")
|
||||||
.long("faucet")
|
.long("drone")
|
||||||
.value_name("HOST:PORT")
|
.value_name("HOST:PORT")
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Location of the faucet; defaults to entrypoint:FAUCET_PORT"),
|
.help("Location of the drone; defaults to entrypoint:DRONE_PORT"),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("identity")
|
Arg::with_name("identity")
|
||||||
@@ -114,11 +111,6 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
.long("use-move")
|
.long("use-move")
|
||||||
.help("Use Move language transactions to perform transfers."),
|
.help("Use Move language transactions to perform transfers."),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name("no-multi-client")
|
|
||||||
.long("no-multi-client")
|
|
||||||
.help("Disable multi-client support, only transact with the entrypoint."),
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("tx_count")
|
Arg::with_name("tx_count")
|
||||||
.long("tx_count")
|
.long("tx_count")
|
||||||
@@ -126,13 +118,6 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.help("Number of transactions to send per batch")
|
.help("Number of transactions to send per batch")
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name("keypair_multiplier")
|
|
||||||
.long("keypair-multiplier")
|
|
||||||
.value_name("NUM")
|
|
||||||
.takes_value(true)
|
|
||||||
.help("Multiply by transaction count to determine number of keypairs to create")
|
|
||||||
)
|
|
||||||
.arg(
|
.arg(
|
||||||
Arg::with_name("thread-batch-sleep-ms")
|
Arg::with_name("thread-batch-sleep-ms")
|
||||||
.short("z")
|
.short("z")
|
||||||
@@ -174,15 +159,6 @@ pub fn build_args<'a, 'b>(version: &'b str) -> App<'a, 'b> {
|
|||||||
"Number of lamports per account.",
|
"Number of lamports per account.",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.arg(
|
|
||||||
Arg::with_name("target_slots_per_epoch")
|
|
||||||
.long("target-slots-per-epoch")
|
|
||||||
.value_name("SLOTS")
|
|
||||||
.takes_value(true)
|
|
||||||
.help(
|
|
||||||
"Wait until epochs are this many slots long.",
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a clap `ArgMatches` structure into a `Config`
|
/// Parses a clap `ArgMatches` structure into a `Config`
|
||||||
@@ -194,21 +170,21 @@ pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
|||||||
let mut args = Config::default();
|
let mut args = Config::default();
|
||||||
|
|
||||||
if let Some(addr) = matches.value_of("entrypoint") {
|
if let Some(addr) = matches.value_of("entrypoint") {
|
||||||
args.entrypoint_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
|
args.entrypoint_addr = solana_netutil::parse_host_port(addr).unwrap_or_else(|e| {
|
||||||
eprintln!("failed to parse entrypoint address: {}", e);
|
eprintln!("failed to parse entrypoint address: {}", e);
|
||||||
exit(1)
|
exit(1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(addr) = matches.value_of("faucet") {
|
if let Some(addr) = matches.value_of("drone") {
|
||||||
args.faucet_addr = solana_net_utils::parse_host_port(addr).unwrap_or_else(|e| {
|
args.drone_addr = solana_netutil::parse_host_port(addr).unwrap_or_else(|e| {
|
||||||
eprintln!("failed to parse faucet address: {}", e);
|
eprintln!("failed to parse drone address: {}", e);
|
||||||
exit(1)
|
exit(1)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches.is_present("identity") {
|
if matches.is_present("identity") {
|
||||||
args.id = read_keypair_file(matches.value_of("identity").unwrap())
|
args.id = read_keypair(matches.value_of("identity").unwrap())
|
||||||
.expect("can't read client identity");
|
.expect("can't read client identity");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,15 +204,7 @@ pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = matches.value_of("tx_count") {
|
if let Some(s) = matches.value_of("tx_count") {
|
||||||
args.tx_count = s.to_string().parse().expect("can't parse tx_count");
|
args.tx_count = s.to_string().parse().expect("can't parse tx_account");
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(s) = matches.value_of("keypair_multiplier") {
|
|
||||||
args.keypair_multiplier = s
|
|
||||||
.to_string()
|
|
||||||
.parse()
|
|
||||||
.expect("can't parse keypair-multiplier");
|
|
||||||
assert!(args.keypair_multiplier >= 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = matches.value_of("thread-batch-sleep-ms") {
|
if let Some(t) = matches.value_of("thread-batch-sleep-ms") {
|
||||||
@@ -264,18 +232,10 @@ pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
args.use_move = matches.is_present("use-move");
|
args.use_move = matches.is_present("use-move");
|
||||||
args.multi_client = !matches.is_present("no-multi-client");
|
|
||||||
|
|
||||||
if let Some(v) = matches.value_of("num_lamports_per_account") {
|
if let Some(v) = matches.value_of("num_lamports_per_account") {
|
||||||
args.num_lamports_per_account = v.to_string().parse().expect("can't parse lamports");
|
args.num_lamports_per_account = v.to_string().parse().expect("can't parse lamports");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(t) = matches.value_of("target_slots_per_epoch") {
|
|
||||||
args.target_slots_per_epoch = t
|
|
||||||
.to_string()
|
|
||||||
.parse()
|
|
||||||
.expect("can't parse target slots per epoch");
|
|
||||||
}
|
|
||||||
|
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
|
@@ -1,47 +1,46 @@
|
|||||||
use log::*;
|
|
||||||
use solana_bench_tps::bench::{do_bench_tps, generate_and_fund_keypairs, generate_keypairs};
|
use solana_bench_tps::bench::{do_bench_tps, generate_and_fund_keypairs, generate_keypairs};
|
||||||
use solana_bench_tps::cli;
|
use solana_bench_tps::cli;
|
||||||
use solana_core::gossip_service::{discover_cluster, get_client, get_multi_client};
|
use solana_core::gossip_service::{discover_cluster, get_multi_client};
|
||||||
use solana_genesis::Base64Account;
|
use solana_genesis::PrimordialAccountDetails;
|
||||||
use solana_sdk::fee_calculator::FeeRateGovernor;
|
use solana_sdk::fee_calculator::FeeCalculator;
|
||||||
use solana_sdk::signature::{Keypair, Signer};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_program;
|
use solana_sdk::system_program;
|
||||||
use std::{collections::HashMap, fs::File, io::prelude::*, path::Path, process::exit, sync::Arc};
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::exit;
|
||||||
|
|
||||||
/// Number of signatures for all transactions in ~1 week at ~100K TPS
|
/// Number of signatures for all transactions in ~1 week at ~100K TPS
|
||||||
pub const NUM_SIGNATURES_FOR_TXS: u64 = 100_000 * 60 * 60 * 24 * 7;
|
pub const NUM_SIGNATURES_FOR_TXS: u64 = 100_000 * 60 * 60 * 24 * 7;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
solana_logger::setup_with_default("solana=info");
|
solana_logger::setup_with_filter("solana=info");
|
||||||
solana_metrics::set_panic_hook("bench-tps");
|
solana_metrics::set_panic_hook("bench-tps");
|
||||||
|
|
||||||
let matches = cli::build_args(solana_version::version!()).get_matches();
|
let matches = cli::build_args().get_matches();
|
||||||
let cli_config = cli::extract_args(&matches);
|
let cli_config = cli::extract_args(&matches);
|
||||||
|
|
||||||
let cli::Config {
|
let cli::Config {
|
||||||
entrypoint_addr,
|
entrypoint_addr,
|
||||||
faucet_addr,
|
drone_addr,
|
||||||
id,
|
id,
|
||||||
num_nodes,
|
num_nodes,
|
||||||
tx_count,
|
tx_count,
|
||||||
keypair_multiplier,
|
|
||||||
client_ids_and_stake_file,
|
client_ids_and_stake_file,
|
||||||
write_to_client_file,
|
write_to_client_file,
|
||||||
read_from_client_file,
|
read_from_client_file,
|
||||||
target_lamports_per_signature,
|
target_lamports_per_signature,
|
||||||
use_move,
|
use_move,
|
||||||
multi_client,
|
|
||||||
num_lamports_per_account,
|
num_lamports_per_account,
|
||||||
..
|
..
|
||||||
} = &cli_config;
|
} = &cli_config;
|
||||||
|
|
||||||
let keypair_count = *tx_count * keypair_multiplier;
|
|
||||||
if *write_to_client_file {
|
if *write_to_client_file {
|
||||||
info!("Generating {} keypairs", keypair_count);
|
println!("Generating {} keypairs", *tx_count * 2);
|
||||||
let (keypairs, _) = generate_keypairs(&id, keypair_count as u64);
|
let (keypairs, _) = generate_keypairs(&id, *tx_count as u64 * 2);
|
||||||
let num_accounts = keypairs.len() as u64;
|
let num_accounts = keypairs.len() as u64;
|
||||||
let max_fee =
|
let max_fee = FeeCalculator::new(*target_lamports_per_signature).max_lamports_per_signature;
|
||||||
FeeRateGovernor::new(*target_lamports_per_signature, 0).max_lamports_per_signature;
|
|
||||||
let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee)
|
let num_lamports_per_account = (num_accounts - 1 + NUM_SIGNATURES_FOR_TXS * max_fee)
|
||||||
/ num_accounts
|
/ num_accounts
|
||||||
+ num_lamports_per_account;
|
+ num_lamports_per_account;
|
||||||
@@ -49,7 +48,7 @@ fn main() {
|
|||||||
keypairs.iter().for_each(|keypair| {
|
keypairs.iter().for_each(|keypair| {
|
||||||
accounts.insert(
|
accounts.insert(
|
||||||
serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap(),
|
serde_json::to_string(&keypair.to_bytes().to_vec()).unwrap(),
|
||||||
Base64Account {
|
PrimordialAccountDetails {
|
||||||
balance: num_lamports_per_account,
|
balance: num_lamports_per_account,
|
||||||
executable: false,
|
executable: false,
|
||||||
owner: system_program::id().to_string(),
|
owner: system_program::id().to_string(),
|
||||||
@@ -58,7 +57,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
info!("Writing {}", client_ids_and_stake_file);
|
println!("Writing {}", client_ids_and_stake_file);
|
||||||
let serialized = serde_yaml::to_string(&accounts).unwrap();
|
let serialized = serde_yaml::to_string(&accounts).unwrap();
|
||||||
let path = Path::new(&client_ids_and_stake_file);
|
let path = Path::new(&client_ids_and_stake_file);
|
||||||
let mut file = File::create(path).unwrap();
|
let mut file = File::create(path).unwrap();
|
||||||
@@ -66,32 +65,30 @@ fn main() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Connecting to the cluster");
|
println!("Connecting to the cluster");
|
||||||
let nodes = discover_cluster(&entrypoint_addr, *num_nodes).unwrap_or_else(|err| {
|
let (nodes, _replicators) =
|
||||||
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
|
discover_cluster(&entrypoint_addr, *num_nodes).unwrap_or_else(|err| {
|
||||||
exit(1);
|
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
|
||||||
});
|
|
||||||
|
|
||||||
let client = if *multi_client {
|
|
||||||
let (client, num_clients) = get_multi_client(&nodes);
|
|
||||||
if nodes.len() < num_clients {
|
|
||||||
eprintln!(
|
|
||||||
"Error: Insufficient nodes discovered. Expecting {} or more",
|
|
||||||
num_nodes
|
|
||||||
);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
});
|
||||||
Arc::new(client)
|
|
||||||
} else {
|
|
||||||
Arc::new(get_client(&nodes))
|
|
||||||
};
|
|
||||||
|
|
||||||
let (keypairs, move_keypairs) = if *read_from_client_file && !use_move {
|
let (client, num_clients) = get_multi_client(&nodes);
|
||||||
|
|
||||||
|
if nodes.len() < num_clients {
|
||||||
|
eprintln!(
|
||||||
|
"Error: Insufficient nodes discovered. Expecting {} or more",
|
||||||
|
num_nodes
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let (keypairs, move_keypairs, keypair_balance) = if *read_from_client_file && !use_move {
|
||||||
let path = Path::new(&client_ids_and_stake_file);
|
let path = Path::new(&client_ids_and_stake_file);
|
||||||
let file = File::open(path).unwrap();
|
let file = File::open(path).unwrap();
|
||||||
|
|
||||||
info!("Reading {}", client_ids_and_stake_file);
|
println!("Reading {}", client_ids_and_stake_file);
|
||||||
let accounts: HashMap<String, Base64Account> = serde_yaml::from_reader(file).unwrap();
|
let accounts: HashMap<String, PrimordialAccountDetails> =
|
||||||
|
serde_yaml::from_reader(file).unwrap();
|
||||||
let mut keypairs = vec![];
|
let mut keypairs = vec![];
|
||||||
let mut last_balance = 0;
|
let mut last_balance = 0;
|
||||||
|
|
||||||
@@ -103,10 +100,10 @@ fn main() {
|
|||||||
last_balance = primordial_account.balance;
|
last_balance = primordial_account.balance;
|
||||||
});
|
});
|
||||||
|
|
||||||
if keypairs.len() < keypair_count {
|
if keypairs.len() < tx_count * 2 {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Expected {} accounts in {}, only received {} (--tx_count mismatch?)",
|
"Expected {} accounts in {}, only received {} (--tx_count mismatch?)",
|
||||||
keypair_count,
|
tx_count * 2,
|
||||||
client_ids_and_stake_file,
|
client_ids_and_stake_file,
|
||||||
keypairs.len(),
|
keypairs.len(),
|
||||||
);
|
);
|
||||||
@@ -116,13 +113,13 @@ fn main() {
|
|||||||
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
// This prevents the amount of storage needed for bench-tps accounts from creeping up
|
||||||
// across multiple runs.
|
// across multiple runs.
|
||||||
keypairs.sort_by(|x, y| x.pubkey().to_string().cmp(&y.pubkey().to_string()));
|
keypairs.sort_by(|x, y| x.pubkey().to_string().cmp(&y.pubkey().to_string()));
|
||||||
(keypairs, None)
|
(keypairs, None, last_balance)
|
||||||
} else {
|
} else {
|
||||||
generate_and_fund_keypairs(
|
generate_and_fund_keypairs(
|
||||||
client.clone(),
|
&client,
|
||||||
Some(*faucet_addr),
|
Some(*drone_addr),
|
||||||
&id,
|
&id,
|
||||||
keypair_count,
|
*tx_count,
|
||||||
*num_lamports_per_account,
|
*num_lamports_per_account,
|
||||||
*use_move,
|
*use_move,
|
||||||
)
|
)
|
||||||
@@ -132,5 +129,11 @@ fn main() {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
do_bench_tps(client, cli_config, keypairs, move_keypairs);
|
do_bench_tps(
|
||||||
|
vec![client],
|
||||||
|
cli_config,
|
||||||
|
keypairs,
|
||||||
|
keypair_balance,
|
||||||
|
move_keypairs,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
26
book/README.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
Building the Solana book
|
||||||
|
---
|
||||||
|
|
||||||
|
Install the book's dependnecies, build, and test the book:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Run any Rust tests in the markdown:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make test
|
||||||
|
```
|
||||||
|
|
||||||
|
Render markdown as HTML:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make build
|
||||||
|
```
|
||||||
|
|
||||||
|
Render and view the book:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make open
|
||||||
|
```
|
15
book/art/consensus.msc
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
msc {
|
||||||
|
client,leader,verifier_a,verifier_b,verifier_c;
|
||||||
|
|
||||||
|
client=>leader [ label = "SUBMIT" ] ;
|
||||||
|
leader=>client [ label = "CONFIRMED" ] ;
|
||||||
|
leader=>verifier_a [ label = "CONFIRMED" ] ;
|
||||||
|
leader=>verifier_b [ label = "CONFIRMED" ] ;
|
||||||
|
leader=>verifier_c [ label = "CONFIRMED" ] ;
|
||||||
|
verifier_a=>leader [ label = "VERIFIED" ] ;
|
||||||
|
verifier_b=>leader [ label = "VERIFIED" ] ;
|
||||||
|
leader=>client [ label = "FINALIZED" ] ;
|
||||||
|
leader=>verifier_a [ label = "FINALIZED" ] ;
|
||||||
|
leader=>verifier_b [ label = "FINALIZED" ] ;
|
||||||
|
leader=>verifier_c [ label = "FINALIZED" ] ;
|
||||||
|
}
|
@@ -24,7 +24,7 @@ msc {
|
|||||||
... ;
|
... ;
|
||||||
Validator abox Validator [label="\nmax\nlockout\n"];
|
Validator abox Validator [label="\nmax\nlockout\n"];
|
||||||
|||;
|
|||;
|
||||||
Cluster box Cluster [label="credits redeemed (at epoch)"];
|
StakerX => Cluster [label="StakeState::RedeemCredits()"];
|
||||||
|
StakerY => Cluster [label="StakeState::RedeemCredits()"] ;
|
||||||
|
|
||||||
}
|
}
|
18
book/art/spv-bank-merkle.bob
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
+------------+
|
||||||
|
| Bank-Merkle|
|
||||||
|
+------------+
|
||||||
|
^ ^
|
||||||
|
/ \
|
||||||
|
+-----------------+ +-------------+
|
||||||
|
| Bank-Diff-Merkle| | Block-Merkle|
|
||||||
|
+-----------------+ +-------------+
|
||||||
|
^ ^
|
||||||
|
/ \
|
||||||
|
+------+ +--------------------------+
|
||||||
|
| Hash | | Previous Bank-Diff-Merkle|
|
||||||
|
+------+ +--------------------------+
|
||||||
|
^ ^
|
||||||
|
/ \
|
||||||
|
+---------------+ +---------------+
|
||||||
|
| Hash(Account1)| | Hash(Account2)|
|
||||||
|
+---------------+ +---------------+
|
22
book/art/tvu.bob
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
.--------.
|
||||||
|
| Leader |
|
||||||
|
`--------`
|
||||||
|
^
|
||||||
|
|
|
||||||
|
.------------------------------------|--------------------.
|
||||||
|
| TVU | |
|
||||||
|
| | |
|
||||||
|
| .-------. .------------. .----+---. .---------. |
|
||||||
|
.------------. | | Blob | | Retransmit | | Replay | | Storage | |
|
||||||
|
| Upstream +----->| Fetch +-->| Stage +-->| Stage +-->| Stage | |
|
||||||
|
| Validators | | | Stage | | | | | | | |
|
||||||
|
`------------` | `-------` `----+-------` `----+---` `---------` |
|
||||||
|
| ^ | | |
|
||||||
|
| | | | |
|
||||||
|
`--------|----------|----------------|--------------------`
|
||||||
|
| | |
|
||||||
|
| V v
|
||||||
|
.+-----------. .------.
|
||||||
|
| Gossip | | Bank |
|
||||||
|
| Service | `------`
|
||||||
|
`------------`
|
30
book/art/validator.bob
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
.--------------------------------------.
|
||||||
|
| Validator |
|
||||||
|
| |
|
||||||
|
.--------. | .-------------------. |
|
||||||
|
| |---->| | |
|
||||||
|
| Client | | | JSON RPC Service | |
|
||||||
|
| |<----| | |
|
||||||
|
`----+---` | `-------------------` |
|
||||||
|
| | ^ |
|
||||||
|
| | | .----------------. | .------------------.
|
||||||
|
| | | | Gossip Service |<----------| Validators |
|
||||||
|
| | | `----------------` | | |
|
||||||
|
| | | ^ | | |
|
||||||
|
| | | | | | .------------. |
|
||||||
|
| | .---+---. .----+---. .-----------. | | | | |
|
||||||
|
| | | Bank |<-+ Replay | | BlobFetch |<------+ Upstream | |
|
||||||
|
| | | Forks | | Stage | | Stage | | | | Validators | |
|
||||||
|
| | `-------` `--------` `--+--------` | | | | |
|
||||||
|
| | ^ ^ | | | `------------` |
|
||||||
|
| | | | v | | |
|
||||||
|
| | | .--+--------. | | |
|
||||||
|
| | | | Blocktree | | | |
|
||||||
|
| | | `-----------` | | .------------. |
|
||||||
|
| | | ^ | | | | |
|
||||||
|
| | | | | | | Downstream | |
|
||||||
|
| | .--+--. .-------+---. | | | Validators | |
|
||||||
|
`-------->| TPU +---->| Broadcast +--------------->| | |
|
||||||
|
| `-----` | Stage | | | `------------` |
|
||||||
|
| `-----------` | `------------------`
|
||||||
|
`--------------------------------------`
|
@@ -8,5 +8,3 @@ create-missing = false
|
|||||||
|
|
||||||
[output.html]
|
[output.html]
|
||||||
theme = "theme"
|
theme = "theme"
|
||||||
|
|
||||||
[output.linkcheck]
|
|
11
book/build-svg.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
make -j"$(nproc)" -B svg
|
||||||
|
|
||||||
|
if [[ -n $CI ]]; then
|
||||||
|
# In CI confirm that no svgs need to be built
|
||||||
|
git diff --exit-code
|
||||||
|
fi
|
6
book/build.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
make -j"$(nproc)" test
|
@@ -1,6 +1,6 @@
|
|||||||
BOB_SRCS=$(wildcard art/*.bob)
|
BOB_SRCS=$(wildcard art/*.bob)
|
||||||
MSC_SRCS=$(wildcard art/*.msc)
|
MSC_SRCS=$(wildcard art/*.msc)
|
||||||
MD_SRCS=$(wildcard src/*.md src/*/*.md) src/cli/usage.md
|
MD_SRCS=$(wildcard src/*.md)
|
||||||
|
|
||||||
SVG_IMGS=$(BOB_SRCS:art/%.bob=src/.gitbook/assets/%.svg) $(MSC_SRCS:art/%.msc=src/.gitbook/assets/%.svg)
|
SVG_IMGS=$(BOB_SRCS:art/%.bob=src/.gitbook/assets/%.svg) $(MSC_SRCS:art/%.msc=src/.gitbook/assets/%.svg)
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ test: $(TEST_STAMP)
|
|||||||
|
|
||||||
open: $(TEST_STAMP)
|
open: $(TEST_STAMP)
|
||||||
mdbook build --open
|
mdbook build --open
|
||||||
./set-solana-release-tag.sh
|
|
||||||
|
|
||||||
watch: $(SVG_IMGS)
|
watch: $(SVG_IMGS)
|
||||||
mdbook watch
|
mdbook watch
|
||||||
@@ -28,12 +27,6 @@ src/.gitbook/assets/%.svg: art/%.msc
|
|||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
mscgen -T svg -i $< -o $@
|
mscgen -T svg -i $< -o $@
|
||||||
|
|
||||||
../target/debug/solana:
|
|
||||||
cd ../cli && cargo build
|
|
||||||
|
|
||||||
src/cli/usage.md: build-cli-usage.sh ../target/debug/solana
|
|
||||||
./$<
|
|
||||||
|
|
||||||
src/%.md: %.md
|
src/%.md: %.md
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
@cp $< $@
|
@cp $< $@
|
||||||
@@ -44,7 +37,6 @@ $(TEST_STAMP): $(TARGET)
|
|||||||
|
|
||||||
$(TARGET): $(SVG_IMGS) $(MD_SRCS)
|
$(TARGET): $(SVG_IMGS) $(MD_SRCS)
|
||||||
mdbook build
|
mdbook build
|
||||||
./set-solana-release-tag.sh
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(SVG_IMGS) src/tests.ok
|
rm -f $(SVG_IMGS) src/tests.ok
|
192
book/src/.gitbook/assets/data-plane (1).svg
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="288" width="736" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="288" width="736" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="216" y2="280"/>
|
||||||
|
<line x1="4" x2="156" y1="216" y2="216"/>
|
||||||
|
<line x1="4" x2="172" y1="280" y2="280"/>
|
||||||
|
<line x1="156" x2="172" y1="216" y2="216"/>
|
||||||
|
<line x1="172" x2="172" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="168"/>
|
||||||
|
<line x1="124" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="156" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="156" x2="156" y1="168" y2="204"/>
|
||||||
|
<line x1="156" x2="204" y1="168" y2="168"/>
|
||||||
|
<line x1="204" x2="292" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="168" y2="204"/>
|
||||||
|
<line x1="204" x2="292" y1="168" y2="168"/>
|
||||||
|
<line x1="292" x2="292" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="216" y2="280"/>
|
||||||
|
<line x1="188" x2="204" y1="216" y2="216"/>
|
||||||
|
<line x1="188" x2="356" y1="280" y2="280"/>
|
||||||
|
<line x1="204" x2="356" y1="216" y2="216"/>
|
||||||
|
<line x1="356" x2="356" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="40" y2="92"/>
|
||||||
|
<line x1="204" x2="276" y1="40" y2="40"/>
|
||||||
|
<line x1="276" x2="276" y1="8" y2="40"/>
|
||||||
|
<line x1="276" x2="444" y1="8" y2="8"/>
|
||||||
|
<line x1="276" x2="276" y1="40" y2="72"/>
|
||||||
|
<line x1="276" x2="444" y1="72" y2="72"/>
|
||||||
|
<line x1="444" x2="444" y1="8" y2="40"/>
|
||||||
|
<line x1="444" x2="444" y1="40" y2="72"/>
|
||||||
|
<line x1="444" x2="532" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="380" x2="380" y1="216" y2="280"/>
|
||||||
|
<line x1="380" x2="532" y1="216" y2="216"/>
|
||||||
|
<line x1="380" x2="548" y1="280" y2="280"/>
|
||||||
|
<line x1="532" x2="548" y1="216" y2="216"/>
|
||||||
|
<line x1="548" x2="548" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="444" x2="444" y1="104" y2="168"/>
|
||||||
|
<line x1="444" x2="532" y1="104" y2="104"/>
|
||||||
|
<line x1="444" x2="532" y1="168" y2="168"/>
|
||||||
|
<line x1="532" x2="612" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="168" y2="204"/>
|
||||||
|
<line x1="532" x2="580" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="580" x2="580" y1="168" y2="204"/>
|
||||||
|
<line x1="580" x2="612" y1="168" y2="168"/>
|
||||||
|
<line x1="612" x2="612" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="564" x2="564" y1="216" y2="280"/>
|
||||||
|
<line x1="564" x2="580" y1="216" y2="216"/>
|
||||||
|
<line x1="564" x2="732" y1="280" y2="280"/>
|
||||||
|
<line x1="580" x2="732" y1="216" y2="216"/>
|
||||||
|
<line x1="732" x2="732" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="252">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="153" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="252">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="252">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="140">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="697" y="252">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
192
book/src/.gitbook/assets/data-plane (2).svg
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="288" width="736" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="288" width="736" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="216" y2="280"/>
|
||||||
|
<line x1="4" x2="156" y1="216" y2="216"/>
|
||||||
|
<line x1="4" x2="172" y1="280" y2="280"/>
|
||||||
|
<line x1="156" x2="172" y1="216" y2="216"/>
|
||||||
|
<line x1="172" x2="172" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="168"/>
|
||||||
|
<line x1="124" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="156" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="156" x2="156" y1="168" y2="204"/>
|
||||||
|
<line x1="156" x2="204" y1="168" y2="168"/>
|
||||||
|
<line x1="204" x2="292" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="168" y2="204"/>
|
||||||
|
<line x1="204" x2="292" y1="168" y2="168"/>
|
||||||
|
<line x1="292" x2="292" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="216" y2="280"/>
|
||||||
|
<line x1="188" x2="204" y1="216" y2="216"/>
|
||||||
|
<line x1="188" x2="356" y1="280" y2="280"/>
|
||||||
|
<line x1="204" x2="356" y1="216" y2="216"/>
|
||||||
|
<line x1="356" x2="356" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="40" y2="92"/>
|
||||||
|
<line x1="204" x2="276" y1="40" y2="40"/>
|
||||||
|
<line x1="276" x2="276" y1="8" y2="40"/>
|
||||||
|
<line x1="276" x2="444" y1="8" y2="8"/>
|
||||||
|
<line x1="276" x2="276" y1="40" y2="72"/>
|
||||||
|
<line x1="276" x2="444" y1="72" y2="72"/>
|
||||||
|
<line x1="444" x2="444" y1="8" y2="40"/>
|
||||||
|
<line x1="444" x2="444" y1="40" y2="72"/>
|
||||||
|
<line x1="444" x2="532" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="380" x2="380" y1="216" y2="280"/>
|
||||||
|
<line x1="380" x2="532" y1="216" y2="216"/>
|
||||||
|
<line x1="380" x2="548" y1="280" y2="280"/>
|
||||||
|
<line x1="532" x2="548" y1="216" y2="216"/>
|
||||||
|
<line x1="548" x2="548" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="444" x2="444" y1="104" y2="168"/>
|
||||||
|
<line x1="444" x2="532" y1="104" y2="104"/>
|
||||||
|
<line x1="444" x2="532" y1="168" y2="168"/>
|
||||||
|
<line x1="532" x2="612" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="168" y2="204"/>
|
||||||
|
<line x1="532" x2="580" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="580" x2="580" y1="168" y2="204"/>
|
||||||
|
<line x1="580" x2="612" y1="168" y2="168"/>
|
||||||
|
<line x1="612" x2="612" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="564" x2="564" y1="216" y2="280"/>
|
||||||
|
<line x1="564" x2="580" y1="216" y2="216"/>
|
||||||
|
<line x1="564" x2="732" y1="280" y2="280"/>
|
||||||
|
<line x1="580" x2="732" y1="216" y2="216"/>
|
||||||
|
<line x1="732" x2="732" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="252">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="153" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="252">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="252">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="140">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="697" y="252">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
192
book/src/.gitbook/assets/data-plane (3).svg
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="288" width="736" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="288" width="736" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="216" y2="280"/>
|
||||||
|
<line x1="4" x2="156" y1="216" y2="216"/>
|
||||||
|
<line x1="4" x2="172" y1="280" y2="280"/>
|
||||||
|
<line x1="156" x2="172" y1="216" y2="216"/>
|
||||||
|
<line x1="172" x2="172" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="168"/>
|
||||||
|
<line x1="124" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="156" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="156" x2="156" y1="168" y2="204"/>
|
||||||
|
<line x1="156" x2="204" y1="168" y2="168"/>
|
||||||
|
<line x1="204" x2="292" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="168" y2="204"/>
|
||||||
|
<line x1="204" x2="292" y1="168" y2="168"/>
|
||||||
|
<line x1="292" x2="292" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="216" y2="280"/>
|
||||||
|
<line x1="188" x2="204" y1="216" y2="216"/>
|
||||||
|
<line x1="188" x2="356" y1="280" y2="280"/>
|
||||||
|
<line x1="204" x2="356" y1="216" y2="216"/>
|
||||||
|
<line x1="356" x2="356" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="40" y2="92"/>
|
||||||
|
<line x1="204" x2="276" y1="40" y2="40"/>
|
||||||
|
<line x1="276" x2="276" y1="8" y2="40"/>
|
||||||
|
<line x1="276" x2="444" y1="8" y2="8"/>
|
||||||
|
<line x1="276" x2="276" y1="40" y2="72"/>
|
||||||
|
<line x1="276" x2="444" y1="72" y2="72"/>
|
||||||
|
<line x1="444" x2="444" y1="8" y2="40"/>
|
||||||
|
<line x1="444" x2="444" y1="40" y2="72"/>
|
||||||
|
<line x1="444" x2="532" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="380" x2="380" y1="216" y2="280"/>
|
||||||
|
<line x1="380" x2="532" y1="216" y2="216"/>
|
||||||
|
<line x1="380" x2="548" y1="280" y2="280"/>
|
||||||
|
<line x1="532" x2="548" y1="216" y2="216"/>
|
||||||
|
<line x1="548" x2="548" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="444" x2="444" y1="104" y2="168"/>
|
||||||
|
<line x1="444" x2="532" y1="104" y2="104"/>
|
||||||
|
<line x1="444" x2="532" y1="168" y2="168"/>
|
||||||
|
<line x1="532" x2="612" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="168" y2="204"/>
|
||||||
|
<line x1="532" x2="580" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="580" x2="580" y1="168" y2="204"/>
|
||||||
|
<line x1="580" x2="612" y1="168" y2="168"/>
|
||||||
|
<line x1="612" x2="612" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="564" x2="564" y1="216" y2="280"/>
|
||||||
|
<line x1="564" x2="580" y1="216" y2="216"/>
|
||||||
|
<line x1="564" x2="732" y1="280" y2="280"/>
|
||||||
|
<line x1="580" x2="732" y1="216" y2="216"/>
|
||||||
|
<line x1="732" x2="732" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="252">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="153" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="252">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="252">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="140">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="697" y="252">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
183
book/src/.gitbook/assets/data-plane-fanout (1).svg
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="304" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="304" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="184"/>
|
||||||
|
<line x1="4" x2="540" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="540" y1="184" y2="184"/>
|
||||||
|
<line x1="540" x2="540" y1="8" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="28" x2="28" y1="232" y2="296"/>
|
||||||
|
<line x1="28" x2="108" y1="232" y2="232"/>
|
||||||
|
<line x1="28" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="108" x2="164" y1="232" y2="232"/>
|
||||||
|
<line x1="164" x2="196" y1="232" y2="232"/>
|
||||||
|
<line x1="196" x2="196" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="40" y2="104"/>
|
||||||
|
<line x1="36" x2="180" y1="40" y2="40"/>
|
||||||
|
<line x1="36" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="108" x2="108" y1="104" y2="176"/>
|
||||||
|
<line x1="108" x2="124" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="136"/>
|
||||||
|
<line x1="124" x2="180" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="364" y1="136" y2="136"/>
|
||||||
|
<line x1="180" x2="180" y1="40" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="56" y2="88"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="56" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="88" y2="104"/>
|
||||||
|
<line x1="180" x2="184" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="176"/>
|
||||||
|
<line x1="364" x2="420" y1="152" y2="152"/>
|
||||||
|
<line x1="420" x2="420" y1="104" y2="152"/>
|
||||||
|
<line x1="420" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="436" y1="104" y2="176"/>
|
||||||
|
<line x1="436" x2="508" y1="104" y2="104"/>
|
||||||
|
<line x1="508" x2="508" y1="40" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="176"/>
|
||||||
|
<line x1="164" x2="364" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="164" x2="164" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="88" y2="88"/>
|
||||||
|
<line x1="192" x2="364" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="56" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="88" y2="104"/>
|
||||||
|
<line x1="364" x2="420" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="232" y2="296"/>
|
||||||
|
<line x1="348" x2="364" y1="232" y2="232"/>
|
||||||
|
<line x1="348" x2="516" y1="296" y2="296"/>
|
||||||
|
<line x1="364" x2="436" y1="232" y2="232"/>
|
||||||
|
<line x1="436" x2="516" y1="232" y2="232"/>
|
||||||
|
<line x1="516" x2="516" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="40" y2="56"/>
|
||||||
|
<line x1="364" x2="508" y1="40" y2="40"/>
|
||||||
|
<line x1="364" x2="360" y1="56" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="364" x2="364" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="57" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="76">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="268">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="76">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="481" y="268">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
183
book/src/.gitbook/assets/data-plane-fanout (2).svg
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="304" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="304" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="184"/>
|
||||||
|
<line x1="4" x2="540" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="540" y1="184" y2="184"/>
|
||||||
|
<line x1="540" x2="540" y1="8" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="28" x2="28" y1="232" y2="296"/>
|
||||||
|
<line x1="28" x2="108" y1="232" y2="232"/>
|
||||||
|
<line x1="28" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="108" x2="164" y1="232" y2="232"/>
|
||||||
|
<line x1="164" x2="196" y1="232" y2="232"/>
|
||||||
|
<line x1="196" x2="196" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="40" y2="104"/>
|
||||||
|
<line x1="36" x2="180" y1="40" y2="40"/>
|
||||||
|
<line x1="36" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="108" x2="108" y1="104" y2="176"/>
|
||||||
|
<line x1="108" x2="124" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="136"/>
|
||||||
|
<line x1="124" x2="180" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="364" y1="136" y2="136"/>
|
||||||
|
<line x1="180" x2="180" y1="40" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="56" y2="88"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="56" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="88" y2="104"/>
|
||||||
|
<line x1="180" x2="184" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="176"/>
|
||||||
|
<line x1="364" x2="420" y1="152" y2="152"/>
|
||||||
|
<line x1="420" x2="420" y1="104" y2="152"/>
|
||||||
|
<line x1="420" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="436" y1="104" y2="176"/>
|
||||||
|
<line x1="436" x2="508" y1="104" y2="104"/>
|
||||||
|
<line x1="508" x2="508" y1="40" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="176"/>
|
||||||
|
<line x1="164" x2="364" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="164" x2="164" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="88" y2="88"/>
|
||||||
|
<line x1="192" x2="364" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="56" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="88" y2="104"/>
|
||||||
|
<line x1="364" x2="420" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="232" y2="296"/>
|
||||||
|
<line x1="348" x2="364" y1="232" y2="232"/>
|
||||||
|
<line x1="348" x2="516" y1="296" y2="296"/>
|
||||||
|
<line x1="364" x2="436" y1="232" y2="232"/>
|
||||||
|
<line x1="436" x2="516" y1="232" y2="232"/>
|
||||||
|
<line x1="516" x2="516" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="40" y2="56"/>
|
||||||
|
<line x1="364" x2="508" y1="40" y2="40"/>
|
||||||
|
<line x1="364" x2="360" y1="56" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="364" x2="364" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="57" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="76">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="268">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="76">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="481" y="268">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
183
book/src/.gitbook/assets/data-plane-fanout (3).svg
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="304" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="304" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="184"/>
|
||||||
|
<line x1="4" x2="540" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="540" y1="184" y2="184"/>
|
||||||
|
<line x1="540" x2="540" y1="8" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="28" x2="28" y1="232" y2="296"/>
|
||||||
|
<line x1="28" x2="108" y1="232" y2="232"/>
|
||||||
|
<line x1="28" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="108" x2="164" y1="232" y2="232"/>
|
||||||
|
<line x1="164" x2="196" y1="232" y2="232"/>
|
||||||
|
<line x1="196" x2="196" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="40" y2="104"/>
|
||||||
|
<line x1="36" x2="180" y1="40" y2="40"/>
|
||||||
|
<line x1="36" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="108" x2="108" y1="104" y2="176"/>
|
||||||
|
<line x1="108" x2="124" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="136"/>
|
||||||
|
<line x1="124" x2="180" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="364" y1="136" y2="136"/>
|
||||||
|
<line x1="180" x2="180" y1="40" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="56" y2="88"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="56" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="88" y2="104"/>
|
||||||
|
<line x1="180" x2="184" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="176"/>
|
||||||
|
<line x1="364" x2="420" y1="152" y2="152"/>
|
||||||
|
<line x1="420" x2="420" y1="104" y2="152"/>
|
||||||
|
<line x1="420" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="436" y1="104" y2="176"/>
|
||||||
|
<line x1="436" x2="508" y1="104" y2="104"/>
|
||||||
|
<line x1="508" x2="508" y1="40" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="176"/>
|
||||||
|
<line x1="164" x2="364" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="164" x2="164" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="88" y2="88"/>
|
||||||
|
<line x1="192" x2="364" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="56" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="88" y2="104"/>
|
||||||
|
<line x1="364" x2="420" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="232" y2="296"/>
|
||||||
|
<line x1="348" x2="364" y1="232" y2="232"/>
|
||||||
|
<line x1="348" x2="516" y1="296" y2="296"/>
|
||||||
|
<line x1="364" x2="436" y1="232" y2="232"/>
|
||||||
|
<line x1="436" x2="516" y1="232" y2="232"/>
|
||||||
|
<line x1="516" x2="516" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="40" y2="56"/>
|
||||||
|
<line x1="364" x2="508" y1="40" y2="40"/>
|
||||||
|
<line x1="364" x2="360" y1="56" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="364" x2="364" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="57" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="76">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="268">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="76">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="481" y="268">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
183
book/src/.gitbook/assets/data-plane-fanout.svg
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="304" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="304" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="184"/>
|
||||||
|
<line x1="4" x2="540" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="540" y1="184" y2="184"/>
|
||||||
|
<line x1="540" x2="540" y1="8" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="28" x2="28" y1="232" y2="296"/>
|
||||||
|
<line x1="28" x2="108" y1="232" y2="232"/>
|
||||||
|
<line x1="28" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="108" x2="164" y1="232" y2="232"/>
|
||||||
|
<line x1="164" x2="196" y1="232" y2="232"/>
|
||||||
|
<line x1="196" x2="196" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="40" y2="104"/>
|
||||||
|
<line x1="36" x2="180" y1="40" y2="40"/>
|
||||||
|
<line x1="36" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="108" x2="108" y1="104" y2="176"/>
|
||||||
|
<line x1="108" x2="124" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="136"/>
|
||||||
|
<line x1="124" x2="180" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="364" y1="136" y2="136"/>
|
||||||
|
<line x1="180" x2="180" y1="40" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="56" y2="88"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="56" y2="56"/>
|
||||||
|
<line x1="180" x2="180" y1="88" y2="104"/>
|
||||||
|
<line x1="180" x2="184" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="176"/>
|
||||||
|
<line x1="364" x2="420" y1="152" y2="152"/>
|
||||||
|
<line x1="420" x2="420" y1="104" y2="152"/>
|
||||||
|
<line x1="420" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="436" y1="104" y2="176"/>
|
||||||
|
<line x1="436" x2="508" y1="104" y2="104"/>
|
||||||
|
<line x1="508" x2="508" y1="40" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="176"/>
|
||||||
|
<line x1="164" x2="364" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="164" x2="164" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="88" y2="88"/>
|
||||||
|
<line x1="192" x2="364" y1="88" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="56" y2="88"/>
|
||||||
|
<line x1="364" x2="364" y1="88" y2="104"/>
|
||||||
|
<line x1="364" x2="420" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="232" y2="296"/>
|
||||||
|
<line x1="348" x2="364" y1="232" y2="232"/>
|
||||||
|
<line x1="348" x2="516" y1="296" y2="296"/>
|
||||||
|
<line x1="364" x2="436" y1="232" y2="232"/>
|
||||||
|
<line x1="436" x2="516" y1="232" y2="232"/>
|
||||||
|
<line x1="516" x2="516" y1="232" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="40" y2="56"/>
|
||||||
|
<line x1="364" x2="508" y1="40" y2="40"/>
|
||||||
|
<line x1="364" x2="360" y1="56" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="364" x2="364" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="192" y2="220"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="57" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="76">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="268">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="76">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="481" y="268">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
322
book/src/.gitbook/assets/data-plane-neighborhood (1).svg
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="400" width="856" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="400" width="856" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="152"/>
|
||||||
|
<line x1="4" x2="852" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="852" y1="152" y2="152"/>
|
||||||
|
<line x1="852" x2="852" y1="8" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="248" y2="392"/>
|
||||||
|
<line x1="4" x2="852" y1="248" y2="248"/>
|
||||||
|
<line x1="4" x2="852" y1="392" y2="392"/>
|
||||||
|
<line x1="852" x2="852" y1="248" y2="392"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="56" y2="120"/>
|
||||||
|
<line x1="60" x2="196" y1="56" y2="56"/>
|
||||||
|
<line x1="60" x2="84" y1="120" y2="120"/>
|
||||||
|
<line x1="84" x2="84" y1="120" y2="144"/>
|
||||||
|
<line x1="84" x2="196" y1="120" y2="120"/>
|
||||||
|
<line x1="196" x2="196" y1="56" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="72" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="104" y2="120"/>
|
||||||
|
<line x1="196" x2="200" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="296" y2="360"/>
|
||||||
|
<line x1="60" x2="84" y1="296" y2="296"/>
|
||||||
|
<line x1="60" x2="196" y1="360" y2="360"/>
|
||||||
|
<line x1="84" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="196" x2="196" y1="296" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="312" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="344" y2="360"/>
|
||||||
|
<line x1="196" x2="200" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="84" x2="84" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="84" x2="84" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="208" x2="260" y1="104" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="72" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="104" y2="120"/>
|
||||||
|
<line x1="260" x2="284" y1="120" y2="120"/>
|
||||||
|
<line x1="284" x2="284" y1="120" y2="144"/>
|
||||||
|
<line x1="284" x2="396" y1="120" y2="120"/>
|
||||||
|
<line x1="396" x2="396" y1="104" y2="120"/>
|
||||||
|
<line x1="396" x2="400" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="344" y2="344"/>
|
||||||
|
<line x1="208" x2="260" y1="344" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="312" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="344" y2="360"/>
|
||||||
|
<line x1="260" x2="396" y1="360" y2="360"/>
|
||||||
|
<line x1="396" x2="396" y1="344" y2="360"/>
|
||||||
|
<line x1="396" x2="400" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="56" y2="72"/>
|
||||||
|
<line x1="260" x2="396" y1="56" y2="56"/>
|
||||||
|
<line x1="260" x2="256" y1="72" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="56" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="296" y2="312"/>
|
||||||
|
<line x1="260" x2="284" y1="296" y2="296"/>
|
||||||
|
<line x1="260" x2="256" y1="312" y2="312"/>
|
||||||
|
<line x1="284" x2="396" y1="296" y2="296"/>
|
||||||
|
<line x1="396" x2="396" y1="296" y2="312"/>
|
||||||
|
<line x1="396" x2="396" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="284" x2="284" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="284" x2="284" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="104" y2="104"/>
|
||||||
|
<line x1="408" x2="460" y1="104" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="72" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="104" y2="120"/>
|
||||||
|
<line x1="460" x2="508" y1="120" y2="120"/>
|
||||||
|
<line x1="508" x2="508" y1="120" y2="144"/>
|
||||||
|
<line x1="508" x2="596" y1="120" y2="120"/>
|
||||||
|
<line x1="596" x2="596" y1="104" y2="120"/>
|
||||||
|
<line x1="596" x2="600" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="344" y2="344"/>
|
||||||
|
<line x1="408" x2="460" y1="344" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="312" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="344" y2="360"/>
|
||||||
|
<line x1="460" x2="596" y1="360" y2="360"/>
|
||||||
|
<line x1="596" x2="596" y1="344" y2="360"/>
|
||||||
|
<line x1="596" x2="600" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="56" y2="72"/>
|
||||||
|
<line x1="460" x2="596" y1="56" y2="56"/>
|
||||||
|
<line x1="460" x2="456" y1="72" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="56" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="296" y2="312"/>
|
||||||
|
<line x1="460" x2="508" y1="296" y2="296"/>
|
||||||
|
<line x1="460" x2="456" y1="312" y2="312"/>
|
||||||
|
<line x1="508" x2="596" y1="296" y2="296"/>
|
||||||
|
<line x1="596" x2="596" y1="296" y2="312"/>
|
||||||
|
<line x1="596" x2="596" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="508" x2="508" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="508" x2="508" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="104" y2="104"/>
|
||||||
|
<line x1="608" x2="660" y1="104" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="72" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="104" y2="120"/>
|
||||||
|
<line x1="660" x2="684" y1="120" y2="120"/>
|
||||||
|
<line x1="684" x2="684" y1="120" y2="144"/>
|
||||||
|
<line x1="684" x2="796" y1="120" y2="120"/>
|
||||||
|
<line x1="796" x2="796" y1="56" y2="120"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="344" y2="344"/>
|
||||||
|
<line x1="608" x2="660" y1="344" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="312" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="344" y2="360"/>
|
||||||
|
<line x1="660" x2="796" y1="360" y2="360"/>
|
||||||
|
<line x1="796" x2="796" y1="296" y2="360"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="56" y2="72"/>
|
||||||
|
<line x1="660" x2="796" y1="56" y2="56"/>
|
||||||
|
<line x1="660" x2="656" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="296" y2="312"/>
|
||||||
|
<line x1="660" x2="684" y1="296" y2="296"/>
|
||||||
|
<line x1="660" x2="656" y1="312" y2="312"/>
|
||||||
|
<line x1="684" x2="796" y1="296" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="684" x2="684" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="684" x2="684" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="92">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="332">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="28">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="92">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="332">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="28">
|
||||||
|
Above
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="268">
|
||||||
|
Below
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="92">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="332">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="92">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="332">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
322
book/src/.gitbook/assets/data-plane-neighborhood (2).svg
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="400" width="856" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="400" width="856" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="152"/>
|
||||||
|
<line x1="4" x2="852" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="852" y1="152" y2="152"/>
|
||||||
|
<line x1="852" x2="852" y1="8" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="248" y2="392"/>
|
||||||
|
<line x1="4" x2="852" y1="248" y2="248"/>
|
||||||
|
<line x1="4" x2="852" y1="392" y2="392"/>
|
||||||
|
<line x1="852" x2="852" y1="248" y2="392"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="56" y2="120"/>
|
||||||
|
<line x1="60" x2="196" y1="56" y2="56"/>
|
||||||
|
<line x1="60" x2="84" y1="120" y2="120"/>
|
||||||
|
<line x1="84" x2="84" y1="120" y2="144"/>
|
||||||
|
<line x1="84" x2="196" y1="120" y2="120"/>
|
||||||
|
<line x1="196" x2="196" y1="56" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="72" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="104" y2="120"/>
|
||||||
|
<line x1="196" x2="200" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="296" y2="360"/>
|
||||||
|
<line x1="60" x2="84" y1="296" y2="296"/>
|
||||||
|
<line x1="60" x2="196" y1="360" y2="360"/>
|
||||||
|
<line x1="84" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="196" x2="196" y1="296" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="312" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="344" y2="360"/>
|
||||||
|
<line x1="196" x2="200" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="84" x2="84" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="84" x2="84" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="208" x2="260" y1="104" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="72" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="104" y2="120"/>
|
||||||
|
<line x1="260" x2="284" y1="120" y2="120"/>
|
||||||
|
<line x1="284" x2="284" y1="120" y2="144"/>
|
||||||
|
<line x1="284" x2="396" y1="120" y2="120"/>
|
||||||
|
<line x1="396" x2="396" y1="104" y2="120"/>
|
||||||
|
<line x1="396" x2="400" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="344" y2="344"/>
|
||||||
|
<line x1="208" x2="260" y1="344" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="312" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="344" y2="360"/>
|
||||||
|
<line x1="260" x2="396" y1="360" y2="360"/>
|
||||||
|
<line x1="396" x2="396" y1="344" y2="360"/>
|
||||||
|
<line x1="396" x2="400" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="56" y2="72"/>
|
||||||
|
<line x1="260" x2="396" y1="56" y2="56"/>
|
||||||
|
<line x1="260" x2="256" y1="72" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="56" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="296" y2="312"/>
|
||||||
|
<line x1="260" x2="284" y1="296" y2="296"/>
|
||||||
|
<line x1="260" x2="256" y1="312" y2="312"/>
|
||||||
|
<line x1="284" x2="396" y1="296" y2="296"/>
|
||||||
|
<line x1="396" x2="396" y1="296" y2="312"/>
|
||||||
|
<line x1="396" x2="396" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="284" x2="284" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="284" x2="284" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="104" y2="104"/>
|
||||||
|
<line x1="408" x2="460" y1="104" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="72" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="104" y2="120"/>
|
||||||
|
<line x1="460" x2="508" y1="120" y2="120"/>
|
||||||
|
<line x1="508" x2="508" y1="120" y2="144"/>
|
||||||
|
<line x1="508" x2="596" y1="120" y2="120"/>
|
||||||
|
<line x1="596" x2="596" y1="104" y2="120"/>
|
||||||
|
<line x1="596" x2="600" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="344" y2="344"/>
|
||||||
|
<line x1="408" x2="460" y1="344" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="312" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="344" y2="360"/>
|
||||||
|
<line x1="460" x2="596" y1="360" y2="360"/>
|
||||||
|
<line x1="596" x2="596" y1="344" y2="360"/>
|
||||||
|
<line x1="596" x2="600" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="56" y2="72"/>
|
||||||
|
<line x1="460" x2="596" y1="56" y2="56"/>
|
||||||
|
<line x1="460" x2="456" y1="72" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="56" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="296" y2="312"/>
|
||||||
|
<line x1="460" x2="508" y1="296" y2="296"/>
|
||||||
|
<line x1="460" x2="456" y1="312" y2="312"/>
|
||||||
|
<line x1="508" x2="596" y1="296" y2="296"/>
|
||||||
|
<line x1="596" x2="596" y1="296" y2="312"/>
|
||||||
|
<line x1="596" x2="596" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="508" x2="508" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="508" x2="508" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="104" y2="104"/>
|
||||||
|
<line x1="608" x2="660" y1="104" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="72" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="104" y2="120"/>
|
||||||
|
<line x1="660" x2="684" y1="120" y2="120"/>
|
||||||
|
<line x1="684" x2="684" y1="120" y2="144"/>
|
||||||
|
<line x1="684" x2="796" y1="120" y2="120"/>
|
||||||
|
<line x1="796" x2="796" y1="56" y2="120"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="344" y2="344"/>
|
||||||
|
<line x1="608" x2="660" y1="344" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="312" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="344" y2="360"/>
|
||||||
|
<line x1="660" x2="796" y1="360" y2="360"/>
|
||||||
|
<line x1="796" x2="796" y1="296" y2="360"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="56" y2="72"/>
|
||||||
|
<line x1="660" x2="796" y1="56" y2="56"/>
|
||||||
|
<line x1="660" x2="656" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="296" y2="312"/>
|
||||||
|
<line x1="660" x2="684" y1="296" y2="296"/>
|
||||||
|
<line x1="660" x2="656" y1="312" y2="312"/>
|
||||||
|
<line x1="684" x2="796" y1="296" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="684" x2="684" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="684" x2="684" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="92">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="332">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="28">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="92">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="332">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="28">
|
||||||
|
Above
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="268">
|
||||||
|
Below
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="92">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="332">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="92">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="332">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
322
book/src/.gitbook/assets/data-plane-neighborhood (3).svg
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="400" width="856" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="400" width="856" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="152"/>
|
||||||
|
<line x1="4" x2="852" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="852" y1="152" y2="152"/>
|
||||||
|
<line x1="852" x2="852" y1="8" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="248" y2="392"/>
|
||||||
|
<line x1="4" x2="852" y1="248" y2="248"/>
|
||||||
|
<line x1="4" x2="852" y1="392" y2="392"/>
|
||||||
|
<line x1="852" x2="852" y1="248" y2="392"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="56" y2="120"/>
|
||||||
|
<line x1="60" x2="196" y1="56" y2="56"/>
|
||||||
|
<line x1="60" x2="84" y1="120" y2="120"/>
|
||||||
|
<line x1="84" x2="84" y1="120" y2="144"/>
|
||||||
|
<line x1="84" x2="196" y1="120" y2="120"/>
|
||||||
|
<line x1="196" x2="196" y1="56" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="72" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="104" y2="120"/>
|
||||||
|
<line x1="196" x2="200" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="296" y2="360"/>
|
||||||
|
<line x1="60" x2="84" y1="296" y2="296"/>
|
||||||
|
<line x1="60" x2="196" y1="360" y2="360"/>
|
||||||
|
<line x1="84" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="196" x2="196" y1="296" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="312" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="344" y2="360"/>
|
||||||
|
<line x1="196" x2="200" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="84" x2="84" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="84" x2="84" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="208" x2="260" y1="104" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="72" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="104" y2="120"/>
|
||||||
|
<line x1="260" x2="284" y1="120" y2="120"/>
|
||||||
|
<line x1="284" x2="284" y1="120" y2="144"/>
|
||||||
|
<line x1="284" x2="396" y1="120" y2="120"/>
|
||||||
|
<line x1="396" x2="396" y1="104" y2="120"/>
|
||||||
|
<line x1="396" x2="400" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="344" y2="344"/>
|
||||||
|
<line x1="208" x2="260" y1="344" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="312" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="344" y2="360"/>
|
||||||
|
<line x1="260" x2="396" y1="360" y2="360"/>
|
||||||
|
<line x1="396" x2="396" y1="344" y2="360"/>
|
||||||
|
<line x1="396" x2="400" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="56" y2="72"/>
|
||||||
|
<line x1="260" x2="396" y1="56" y2="56"/>
|
||||||
|
<line x1="260" x2="256" y1="72" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="56" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="296" y2="312"/>
|
||||||
|
<line x1="260" x2="284" y1="296" y2="296"/>
|
||||||
|
<line x1="260" x2="256" y1="312" y2="312"/>
|
||||||
|
<line x1="284" x2="396" y1="296" y2="296"/>
|
||||||
|
<line x1="396" x2="396" y1="296" y2="312"/>
|
||||||
|
<line x1="396" x2="396" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="284" x2="284" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="284" x2="284" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="104" y2="104"/>
|
||||||
|
<line x1="408" x2="460" y1="104" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="72" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="104" y2="120"/>
|
||||||
|
<line x1="460" x2="508" y1="120" y2="120"/>
|
||||||
|
<line x1="508" x2="508" y1="120" y2="144"/>
|
||||||
|
<line x1="508" x2="596" y1="120" y2="120"/>
|
||||||
|
<line x1="596" x2="596" y1="104" y2="120"/>
|
||||||
|
<line x1="596" x2="600" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="344" y2="344"/>
|
||||||
|
<line x1="408" x2="460" y1="344" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="312" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="344" y2="360"/>
|
||||||
|
<line x1="460" x2="596" y1="360" y2="360"/>
|
||||||
|
<line x1="596" x2="596" y1="344" y2="360"/>
|
||||||
|
<line x1="596" x2="600" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="56" y2="72"/>
|
||||||
|
<line x1="460" x2="596" y1="56" y2="56"/>
|
||||||
|
<line x1="460" x2="456" y1="72" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="56" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="296" y2="312"/>
|
||||||
|
<line x1="460" x2="508" y1="296" y2="296"/>
|
||||||
|
<line x1="460" x2="456" y1="312" y2="312"/>
|
||||||
|
<line x1="508" x2="596" y1="296" y2="296"/>
|
||||||
|
<line x1="596" x2="596" y1="296" y2="312"/>
|
||||||
|
<line x1="596" x2="596" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="508" x2="508" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="508" x2="508" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="104" y2="104"/>
|
||||||
|
<line x1="608" x2="660" y1="104" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="72" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="104" y2="120"/>
|
||||||
|
<line x1="660" x2="684" y1="120" y2="120"/>
|
||||||
|
<line x1="684" x2="684" y1="120" y2="144"/>
|
||||||
|
<line x1="684" x2="796" y1="120" y2="120"/>
|
||||||
|
<line x1="796" x2="796" y1="56" y2="120"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="344" y2="344"/>
|
||||||
|
<line x1="608" x2="660" y1="344" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="312" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="344" y2="360"/>
|
||||||
|
<line x1="660" x2="796" y1="360" y2="360"/>
|
||||||
|
<line x1="796" x2="796" y1="296" y2="360"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="56" y2="72"/>
|
||||||
|
<line x1="660" x2="796" y1="56" y2="56"/>
|
||||||
|
<line x1="660" x2="656" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="296" y2="312"/>
|
||||||
|
<line x1="660" x2="684" y1="296" y2="296"/>
|
||||||
|
<line x1="660" x2="656" y1="312" y2="312"/>
|
||||||
|
<line x1="684" x2="796" y1="296" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="684" x2="684" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="684" x2="684" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="92">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="332">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="28">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="92">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="332">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="28">
|
||||||
|
Above
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="268">
|
||||||
|
Below
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="92">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="332">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="92">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="332">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
322
book/src/.gitbook/assets/data-plane-neighborhood.svg
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="400" width="856" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="400" width="856" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="8" y2="152"/>
|
||||||
|
<line x1="4" x2="852" y1="8" y2="8"/>
|
||||||
|
<line x1="4" x2="852" y1="152" y2="152"/>
|
||||||
|
<line x1="852" x2="852" y1="8" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="248" y2="392"/>
|
||||||
|
<line x1="4" x2="852" y1="248" y2="248"/>
|
||||||
|
<line x1="4" x2="852" y1="392" y2="392"/>
|
||||||
|
<line x1="852" x2="852" y1="248" y2="392"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="56" y2="120"/>
|
||||||
|
<line x1="60" x2="196" y1="56" y2="56"/>
|
||||||
|
<line x1="60" x2="84" y1="120" y2="120"/>
|
||||||
|
<line x1="84" x2="84" y1="120" y2="144"/>
|
||||||
|
<line x1="84" x2="196" y1="120" y2="120"/>
|
||||||
|
<line x1="196" x2="196" y1="56" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="72" y2="72"/>
|
||||||
|
<line x1="196" x2="196" y1="104" y2="120"/>
|
||||||
|
<line x1="196" x2="200" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="60" x2="60" y1="296" y2="360"/>
|
||||||
|
<line x1="60" x2="84" y1="296" y2="296"/>
|
||||||
|
<line x1="60" x2="196" y1="360" y2="360"/>
|
||||||
|
<line x1="84" x2="196" y1="296" y2="296"/>
|
||||||
|
<line x1="196" x2="196" y1="296" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="196" x2="252" y1="312" y2="312"/>
|
||||||
|
<line x1="196" x2="196" y1="344" y2="360"/>
|
||||||
|
<line x1="196" x2="200" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="84" x2="84" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="84" x2="84" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="208" x2="260" y1="104" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="72" y2="104"/>
|
||||||
|
<line x1="260" x2="260" y1="104" y2="120"/>
|
||||||
|
<line x1="260" x2="284" y1="120" y2="120"/>
|
||||||
|
<line x1="284" x2="284" y1="120" y2="144"/>
|
||||||
|
<line x1="284" x2="396" y1="120" y2="120"/>
|
||||||
|
<line x1="396" x2="396" y1="104" y2="120"/>
|
||||||
|
<line x1="396" x2="400" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="208" x2="204" y1="344" y2="344"/>
|
||||||
|
<line x1="208" x2="260" y1="344" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="312" y2="344"/>
|
||||||
|
<line x1="260" x2="260" y1="344" y2="360"/>
|
||||||
|
<line x1="260" x2="396" y1="360" y2="360"/>
|
||||||
|
<line x1="396" x2="396" y1="344" y2="360"/>
|
||||||
|
<line x1="396" x2="400" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="56" y2="72"/>
|
||||||
|
<line x1="260" x2="396" y1="56" y2="56"/>
|
||||||
|
<line x1="260" x2="256" y1="72" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="56" y2="72"/>
|
||||||
|
<line x1="396" x2="396" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="296" y2="312"/>
|
||||||
|
<line x1="260" x2="284" y1="296" y2="296"/>
|
||||||
|
<line x1="260" x2="256" y1="312" y2="312"/>
|
||||||
|
<line x1="284" x2="396" y1="296" y2="296"/>
|
||||||
|
<line x1="396" x2="396" y1="296" y2="312"/>
|
||||||
|
<line x1="396" x2="396" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="396" x2="452" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="284" x2="284" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="284" x2="284" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="104" y2="104"/>
|
||||||
|
<line x1="408" x2="460" y1="104" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="72" y2="104"/>
|
||||||
|
<line x1="460" x2="460" y1="104" y2="120"/>
|
||||||
|
<line x1="460" x2="508" y1="120" y2="120"/>
|
||||||
|
<line x1="508" x2="508" y1="120" y2="144"/>
|
||||||
|
<line x1="508" x2="596" y1="120" y2="120"/>
|
||||||
|
<line x1="596" x2="596" y1="104" y2="120"/>
|
||||||
|
<line x1="596" x2="600" y1="104" y2="104"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="408" x2="404" y1="344" y2="344"/>
|
||||||
|
<line x1="408" x2="460" y1="344" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="312" y2="344"/>
|
||||||
|
<line x1="460" x2="460" y1="344" y2="360"/>
|
||||||
|
<line x1="460" x2="596" y1="360" y2="360"/>
|
||||||
|
<line x1="596" x2="596" y1="344" y2="360"/>
|
||||||
|
<line x1="596" x2="600" y1="344" y2="344"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="56" y2="72"/>
|
||||||
|
<line x1="460" x2="596" y1="56" y2="56"/>
|
||||||
|
<line x1="460" x2="456" y1="72" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="56" y2="72"/>
|
||||||
|
<line x1="596" x2="596" y1="72" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="296" y2="312"/>
|
||||||
|
<line x1="460" x2="508" y1="296" y2="296"/>
|
||||||
|
<line x1="460" x2="456" y1="312" y2="312"/>
|
||||||
|
<line x1="508" x2="596" y1="296" y2="296"/>
|
||||||
|
<line x1="596" x2="596" y1="296" y2="312"/>
|
||||||
|
<line x1="596" x2="596" y1="312" y2="344"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="596" x2="652" y1="312" y2="312"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="508" x2="508" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="508" x2="508" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="104" y2="104"/>
|
||||||
|
<line x1="608" x2="660" y1="104" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="72" y2="104"/>
|
||||||
|
<line x1="660" x2="660" y1="104" y2="120"/>
|
||||||
|
<line x1="660" x2="684" y1="120" y2="120"/>
|
||||||
|
<line x1="684" x2="684" y1="120" y2="144"/>
|
||||||
|
<line x1="684" x2="796" y1="120" y2="120"/>
|
||||||
|
<line x1="796" x2="796" y1="56" y2="120"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="608" x2="604" y1="344" y2="344"/>
|
||||||
|
<line x1="608" x2="660" y1="344" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="312" y2="344"/>
|
||||||
|
<line x1="660" x2="660" y1="344" y2="360"/>
|
||||||
|
<line x1="660" x2="796" y1="360" y2="360"/>
|
||||||
|
<line x1="796" x2="796" y1="296" y2="360"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="56" y2="72"/>
|
||||||
|
<line x1="660" x2="796" y1="56" y2="56"/>
|
||||||
|
<line x1="660" x2="656" y1="72" y2="72"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="660" x2="660" y1="296" y2="312"/>
|
||||||
|
<line x1="660" x2="684" y1="296" y2="296"/>
|
||||||
|
<line x1="660" x2="656" y1="312" y2="312"/>
|
||||||
|
<line x1="684" x2="796" y1="296" y2="296"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="684" x2="684" y1="160" y2="240"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="684" x2="684" y1="256" y2="284"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="92">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="161" y="332">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="28">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="353" y="268">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="92">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="332">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="28">
|
||||||
|
Above
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="457" y="268">
|
||||||
|
Below
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="489" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="92">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="561" y="332">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="92">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="689" y="332">
|
||||||
|
Neighbor
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="92">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="761" y="332">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
138
book/src/.gitbook/assets/data-plane-seeding (1).svg
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="240" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="240" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="104" y2="232"/>
|
||||||
|
<line x1="4" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="4" x2="540" y1="232" y2="232"/>
|
||||||
|
<line x1="108" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="540" y1="104" y2="104"/>
|
||||||
|
<line x1="540" x2="540" y1="104" y2="232"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="136" y2="200"/>
|
||||||
|
<line x1="36" x2="180" y1="136" y2="136"/>
|
||||||
|
<line x1="36" x2="180" y1="200" y2="200"/>
|
||||||
|
<line x1="180" x2="180" y1="136" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="152" y2="184"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="152" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="184" y2="200"/>
|
||||||
|
<line x1="180" x2="184" y1="184" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="40" y2="92"/>
|
||||||
|
<line x1="108" x2="212" y1="40" y2="40"/>
|
||||||
|
<line x1="212" x2="212" y1="8" y2="40"/>
|
||||||
|
<line x1="212" x2="332" y1="8" y2="8"/>
|
||||||
|
<line x1="212" x2="212" y1="40" y2="72"/>
|
||||||
|
<line x1="212" x2="332" y1="72" y2="72"/>
|
||||||
|
<line x1="332" x2="332" y1="8" y2="40"/>
|
||||||
|
<line x1="332" x2="332" y1="40" y2="72"/>
|
||||||
|
<line x1="332" x2="436" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="184" y2="184"/>
|
||||||
|
<line x1="192" x2="364" y1="184" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="184" y2="200"/>
|
||||||
|
<line x1="364" x2="508" y1="200" y2="200"/>
|
||||||
|
<line x1="508" x2="508" y1="136" y2="200"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="508" y1="136" y2="136"/>
|
||||||
|
<line x1="364" x2="360" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="172">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="44">
|
||||||
|
Leader
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="140">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="172">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
138
book/src/.gitbook/assets/data-plane-seeding (2).svg
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="240" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="240" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="104" y2="232"/>
|
||||||
|
<line x1="4" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="4" x2="540" y1="232" y2="232"/>
|
||||||
|
<line x1="108" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="540" y1="104" y2="104"/>
|
||||||
|
<line x1="540" x2="540" y1="104" y2="232"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="136" y2="200"/>
|
||||||
|
<line x1="36" x2="180" y1="136" y2="136"/>
|
||||||
|
<line x1="36" x2="180" y1="200" y2="200"/>
|
||||||
|
<line x1="180" x2="180" y1="136" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="152" y2="184"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="152" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="184" y2="200"/>
|
||||||
|
<line x1="180" x2="184" y1="184" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="40" y2="92"/>
|
||||||
|
<line x1="108" x2="212" y1="40" y2="40"/>
|
||||||
|
<line x1="212" x2="212" y1="8" y2="40"/>
|
||||||
|
<line x1="212" x2="332" y1="8" y2="8"/>
|
||||||
|
<line x1="212" x2="212" y1="40" y2="72"/>
|
||||||
|
<line x1="212" x2="332" y1="72" y2="72"/>
|
||||||
|
<line x1="332" x2="332" y1="8" y2="40"/>
|
||||||
|
<line x1="332" x2="332" y1="40" y2="72"/>
|
||||||
|
<line x1="332" x2="436" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="184" y2="184"/>
|
||||||
|
<line x1="192" x2="364" y1="184" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="184" y2="200"/>
|
||||||
|
<line x1="364" x2="508" y1="200" y2="200"/>
|
||||||
|
<line x1="508" x2="508" y1="136" y2="200"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="508" y1="136" y2="136"/>
|
||||||
|
<line x1="364" x2="360" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="172">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="44">
|
||||||
|
Leader
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="140">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="172">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
138
book/src/.gitbook/assets/data-plane-seeding (3).svg
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="240" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="240" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="104" y2="232"/>
|
||||||
|
<line x1="4" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="4" x2="540" y1="232" y2="232"/>
|
||||||
|
<line x1="108" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="540" y1="104" y2="104"/>
|
||||||
|
<line x1="540" x2="540" y1="104" y2="232"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="136" y2="200"/>
|
||||||
|
<line x1="36" x2="180" y1="136" y2="136"/>
|
||||||
|
<line x1="36" x2="180" y1="200" y2="200"/>
|
||||||
|
<line x1="180" x2="180" y1="136" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="152" y2="184"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="152" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="184" y2="200"/>
|
||||||
|
<line x1="180" x2="184" y1="184" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="40" y2="92"/>
|
||||||
|
<line x1="108" x2="212" y1="40" y2="40"/>
|
||||||
|
<line x1="212" x2="212" y1="8" y2="40"/>
|
||||||
|
<line x1="212" x2="332" y1="8" y2="8"/>
|
||||||
|
<line x1="212" x2="212" y1="40" y2="72"/>
|
||||||
|
<line x1="212" x2="332" y1="72" y2="72"/>
|
||||||
|
<line x1="332" x2="332" y1="8" y2="40"/>
|
||||||
|
<line x1="332" x2="332" y1="40" y2="72"/>
|
||||||
|
<line x1="332" x2="436" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="184" y2="184"/>
|
||||||
|
<line x1="192" x2="364" y1="184" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="184" y2="200"/>
|
||||||
|
<line x1="364" x2="508" y1="200" y2="200"/>
|
||||||
|
<line x1="508" x2="508" y1="136" y2="200"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="508" y1="136" y2="136"/>
|
||||||
|
<line x1="364" x2="360" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="172">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="44">
|
||||||
|
Leader
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="140">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="172">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
138
book/src/.gitbook/assets/data-plane-seeding.svg
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="240" width="544" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="240" width="544" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="104" y2="232"/>
|
||||||
|
<line x1="4" x2="108" y1="104" y2="104"/>
|
||||||
|
<line x1="4" x2="540" y1="232" y2="232"/>
|
||||||
|
<line x1="108" x2="436" y1="104" y2="104"/>
|
||||||
|
<line x1="436" x2="540" y1="104" y2="104"/>
|
||||||
|
<line x1="540" x2="540" y1="104" y2="232"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="36" x2="36" y1="136" y2="200"/>
|
||||||
|
<line x1="36" x2="180" y1="136" y2="136"/>
|
||||||
|
<line x1="36" x2="180" y1="200" y2="200"/>
|
||||||
|
<line x1="180" x2="180" y1="136" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="152" y2="184"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="180" x2="356" y1="152" y2="152"/>
|
||||||
|
<line x1="180" x2="180" y1="184" y2="200"/>
|
||||||
|
<line x1="180" x2="184" y1="184" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="108" x2="108" y1="40" y2="92"/>
|
||||||
|
<line x1="108" x2="212" y1="40" y2="40"/>
|
||||||
|
<line x1="212" x2="212" y1="8" y2="40"/>
|
||||||
|
<line x1="212" x2="332" y1="8" y2="8"/>
|
||||||
|
<line x1="212" x2="212" y1="40" y2="72"/>
|
||||||
|
<line x1="212" x2="332" y1="72" y2="72"/>
|
||||||
|
<line x1="332" x2="332" y1="8" y2="40"/>
|
||||||
|
<line x1="332" x2="332" y1="40" y2="72"/>
|
||||||
|
<line x1="332" x2="436" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="436" x2="436" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="192" x2="188" y1="184" y2="184"/>
|
||||||
|
<line x1="192" x2="364" y1="184" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="152" y2="184"/>
|
||||||
|
<line x1="364" x2="364" y1="184" y2="200"/>
|
||||||
|
<line x1="364" x2="508" y1="200" y2="200"/>
|
||||||
|
<line x1="508" x2="508" y1="136" y2="200"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="364" x2="364" y1="136" y2="152"/>
|
||||||
|
<line x1="364" x2="508" y1="136" y2="136"/>
|
||||||
|
<line x1="364" x2="360" y1="152" y2="152"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="145" y="172">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="44">
|
||||||
|
Leader
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="140">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="172">
|
||||||
|
Validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="172">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
192
book/src/.gitbook/assets/data-plane.svg
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="288" width="736" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="288" width="736" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="4" x2="4" y1="216" y2="280"/>
|
||||||
|
<line x1="4" x2="156" y1="216" y2="216"/>
|
||||||
|
<line x1="4" x2="172" y1="280" y2="280"/>
|
||||||
|
<line x1="156" x2="172" y1="216" y2="216"/>
|
||||||
|
<line x1="172" x2="172" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="104" y2="168"/>
|
||||||
|
<line x1="124" x2="204" y1="104" y2="104"/>
|
||||||
|
<line x1="124" x2="156" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="156" x2="156" y1="168" y2="204"/>
|
||||||
|
<line x1="156" x2="204" y1="168" y2="168"/>
|
||||||
|
<line x1="204" x2="292" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="168" y2="204"/>
|
||||||
|
<line x1="204" x2="292" y1="168" y2="168"/>
|
||||||
|
<line x1="292" x2="292" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="216" y2="280"/>
|
||||||
|
<line x1="188" x2="204" y1="216" y2="216"/>
|
||||||
|
<line x1="188" x2="356" y1="280" y2="280"/>
|
||||||
|
<line x1="204" x2="356" y1="216" y2="216"/>
|
||||||
|
<line x1="356" x2="356" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="204" x2="204" y1="40" y2="92"/>
|
||||||
|
<line x1="204" x2="276" y1="40" y2="40"/>
|
||||||
|
<line x1="276" x2="276" y1="8" y2="40"/>
|
||||||
|
<line x1="276" x2="444" y1="8" y2="8"/>
|
||||||
|
<line x1="276" x2="276" y1="40" y2="72"/>
|
||||||
|
<line x1="276" x2="444" y1="72" y2="72"/>
|
||||||
|
<line x1="444" x2="444" y1="8" y2="40"/>
|
||||||
|
<line x1="444" x2="444" y1="40" y2="72"/>
|
||||||
|
<line x1="444" x2="532" y1="40" y2="40"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="40" y2="92"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="380" x2="380" y1="216" y2="280"/>
|
||||||
|
<line x1="380" x2="532" y1="216" y2="216"/>
|
||||||
|
<line x1="380" x2="548" y1="280" y2="280"/>
|
||||||
|
<line x1="532" x2="548" y1="216" y2="216"/>
|
||||||
|
<line x1="548" x2="548" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="444" x2="444" y1="104" y2="168"/>
|
||||||
|
<line x1="444" x2="532" y1="104" y2="104"/>
|
||||||
|
<line x1="444" x2="532" y1="168" y2="168"/>
|
||||||
|
<line x1="532" x2="612" y1="104" y2="104"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="532" x2="532" y1="168" y2="204"/>
|
||||||
|
<line x1="532" x2="580" y1="168" y2="168"/>
|
||||||
|
<line marker-end="url(#triangle)" x1="580" x2="580" y1="168" y2="204"/>
|
||||||
|
<line x1="580" x2="612" y1="168" y2="168"/>
|
||||||
|
<line x1="612" x2="612" y1="104" y2="168"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="564" x2="564" y1="216" y2="280"/>
|
||||||
|
<line x1="564" x2="580" y1="216" y2="216"/>
|
||||||
|
<line x1="564" x2="732" y1="280" y2="280"/>
|
||||||
|
<line x1="580" x2="732" y1="216" y2="216"/>
|
||||||
|
<line x1="732" x2="732" y1="216" y2="280"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="252">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="153" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="217" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="44">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="321" y="252">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="44">
|
||||||
|
0
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="473" y="140">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="252">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="140">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="252">
|
||||||
|
Neighborhood
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="697" y="252">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
330
book/src/.gitbook/assets/fork-generation (1).svg
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="768" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="768" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="76" x2="76" y1="32" y2="172"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="24" y2="56"/>
|
||||||
|
<line x1="124" x2="164" y1="24" y2="24"/>
|
||||||
|
<line x1="124" x2="124" y1="56" y2="88"/>
|
||||||
|
<line x1="124" x2="164" y1="56" y2="56"/>
|
||||||
|
<line x1="124" x2="124" y1="88" y2="120"/>
|
||||||
|
<line x1="124" x2="164" y1="88" y2="88"/>
|
||||||
|
<line x1="124" x2="124" y1="120" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="120" y2="120"/>
|
||||||
|
<line x1="124" x2="124" y1="152" y2="184"/>
|
||||||
|
<line x1="124" x2="164" y1="152" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="184" y2="184"/>
|
||||||
|
<line x1="164" x2="164" y1="24" y2="56"/>
|
||||||
|
<line x1="164" x2="164" y1="56" y2="88"/>
|
||||||
|
<line x1="164" x2="164" y1="88" y2="120"/>
|
||||||
|
<line x1="164" x2="164" y1="120" y2="152"/>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="200" x2="208" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="224" x2="236" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="232" x2="240" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="236" x2="236" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="264" x2="272" y1="64" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="304" x2="316" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="316" x2="316" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="360" y1="136" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="368" x2="376" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="384" y1="48" y2="64"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="388" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="388" x2="388" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="416" x2="424" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="420" x2="420" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="436" x2="420" y1="104" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="448" x2="460" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="512" x2="640" y1="24" y2="24"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="108">
|
||||||
|
time
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="44">
|
||||||
|
L1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="76">
|
||||||
|
L2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="108">
|
||||||
|
L3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="140">
|
||||||
|
L4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="172">
|
||||||
|
L5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="140">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="209" y="108">
|
||||||
|
E3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="225" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="76">
|
||||||
|
E2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="108">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="172">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="313" y="44">
|
||||||
|
E1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="337" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="108">
|
||||||
|
E3'
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="449" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="12">
|
||||||
|
validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="60">
|
||||||
|
vote(E1)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="92">
|
||||||
|
vote(E2)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="124">
|
||||||
|
slash(E3)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="156">
|
||||||
|
vote(E4)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="188">
|
||||||
|
hang
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="553" y="188">
|
||||||
|
on
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="188">
|
||||||
|
to
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="12">
|
||||||
|
action
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="601" y="188">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="625" y="188">
|
||||||
|
and
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="657" y="188">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="681" y="188">
|
||||||
|
for
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="713" y="188">
|
||||||
|
more...
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
330
book/src/.gitbook/assets/fork-generation (2).svg
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="768" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="768" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="76" x2="76" y1="32" y2="172"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="24" y2="56"/>
|
||||||
|
<line x1="124" x2="164" y1="24" y2="24"/>
|
||||||
|
<line x1="124" x2="124" y1="56" y2="88"/>
|
||||||
|
<line x1="124" x2="164" y1="56" y2="56"/>
|
||||||
|
<line x1="124" x2="124" y1="88" y2="120"/>
|
||||||
|
<line x1="124" x2="164" y1="88" y2="88"/>
|
||||||
|
<line x1="124" x2="124" y1="120" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="120" y2="120"/>
|
||||||
|
<line x1="124" x2="124" y1="152" y2="184"/>
|
||||||
|
<line x1="124" x2="164" y1="152" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="184" y2="184"/>
|
||||||
|
<line x1="164" x2="164" y1="24" y2="56"/>
|
||||||
|
<line x1="164" x2="164" y1="56" y2="88"/>
|
||||||
|
<line x1="164" x2="164" y1="88" y2="120"/>
|
||||||
|
<line x1="164" x2="164" y1="120" y2="152"/>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="200" x2="208" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="224" x2="236" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="232" x2="240" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="236" x2="236" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="264" x2="272" y1="64" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="304" x2="316" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="316" x2="316" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="360" y1="136" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="368" x2="376" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="384" y1="48" y2="64"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="388" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="388" x2="388" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="416" x2="424" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="420" x2="420" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="436" x2="420" y1="104" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="448" x2="460" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="512" x2="640" y1="24" y2="24"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="108">
|
||||||
|
time
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="44">
|
||||||
|
L1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="76">
|
||||||
|
L2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="108">
|
||||||
|
L3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="140">
|
||||||
|
L4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="172">
|
||||||
|
L5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="140">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="209" y="108">
|
||||||
|
E3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="225" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="76">
|
||||||
|
E2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="108">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="172">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="313" y="44">
|
||||||
|
E1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="337" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="108">
|
||||||
|
E3'
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="449" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="12">
|
||||||
|
validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="60">
|
||||||
|
vote(E1)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="92">
|
||||||
|
vote(E2)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="124">
|
||||||
|
slash(E3)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="156">
|
||||||
|
vote(E4)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="188">
|
||||||
|
hang
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="553" y="188">
|
||||||
|
on
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="188">
|
||||||
|
to
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="12">
|
||||||
|
action
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="601" y="188">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="625" y="188">
|
||||||
|
and
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="657" y="188">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="681" y="188">
|
||||||
|
for
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="713" y="188">
|
||||||
|
more...
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
330
book/src/.gitbook/assets/fork-generation (3).svg
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="768" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="768" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="76" x2="76" y1="32" y2="172"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="24" y2="56"/>
|
||||||
|
<line x1="124" x2="164" y1="24" y2="24"/>
|
||||||
|
<line x1="124" x2="124" y1="56" y2="88"/>
|
||||||
|
<line x1="124" x2="164" y1="56" y2="56"/>
|
||||||
|
<line x1="124" x2="124" y1="88" y2="120"/>
|
||||||
|
<line x1="124" x2="164" y1="88" y2="88"/>
|
||||||
|
<line x1="124" x2="124" y1="120" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="120" y2="120"/>
|
||||||
|
<line x1="124" x2="124" y1="152" y2="184"/>
|
||||||
|
<line x1="124" x2="164" y1="152" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="184" y2="184"/>
|
||||||
|
<line x1="164" x2="164" y1="24" y2="56"/>
|
||||||
|
<line x1="164" x2="164" y1="56" y2="88"/>
|
||||||
|
<line x1="164" x2="164" y1="88" y2="120"/>
|
||||||
|
<line x1="164" x2="164" y1="120" y2="152"/>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="200" x2="208" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="224" x2="236" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="232" x2="240" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="236" x2="236" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="264" x2="272" y1="64" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="304" x2="316" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="316" x2="316" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="360" y1="136" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="368" x2="376" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="384" y1="48" y2="64"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="388" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="388" x2="388" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="416" x2="424" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="420" x2="420" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="436" x2="420" y1="104" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="448" x2="460" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="512" x2="640" y1="24" y2="24"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="108">
|
||||||
|
time
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="44">
|
||||||
|
L1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="76">
|
||||||
|
L2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="108">
|
||||||
|
L3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="140">
|
||||||
|
L4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="172">
|
||||||
|
L5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="140">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="209" y="108">
|
||||||
|
E3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="225" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="76">
|
||||||
|
E2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="108">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="172">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="313" y="44">
|
||||||
|
E1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="337" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="108">
|
||||||
|
E3'
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="449" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="12">
|
||||||
|
validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="60">
|
||||||
|
vote(E1)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="92">
|
||||||
|
vote(E2)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="124">
|
||||||
|
slash(E3)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="156">
|
||||||
|
vote(E4)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="188">
|
||||||
|
hang
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="553" y="188">
|
||||||
|
on
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="188">
|
||||||
|
to
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="12">
|
||||||
|
action
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="601" y="188">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="625" y="188">
|
||||||
|
and
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="657" y="188">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="681" y="188">
|
||||||
|
for
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="713" y="188">
|
||||||
|
more...
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
330
book/src/.gitbook/assets/fork-generation.svg
Normal file
@@ -0,0 +1,330 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="768" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="768" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line marker-end="url(#triangle)" x1="76" x2="76" y1="32" y2="172"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="124" x2="124" y1="24" y2="56"/>
|
||||||
|
<line x1="124" x2="164" y1="24" y2="24"/>
|
||||||
|
<line x1="124" x2="124" y1="56" y2="88"/>
|
||||||
|
<line x1="124" x2="164" y1="56" y2="56"/>
|
||||||
|
<line x1="124" x2="124" y1="88" y2="120"/>
|
||||||
|
<line x1="124" x2="164" y1="88" y2="88"/>
|
||||||
|
<line x1="124" x2="124" y1="120" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="120" y2="120"/>
|
||||||
|
<line x1="124" x2="124" y1="152" y2="184"/>
|
||||||
|
<line x1="124" x2="164" y1="152" y2="152"/>
|
||||||
|
<line x1="124" x2="164" y1="184" y2="184"/>
|
||||||
|
<line x1="164" x2="164" y1="24" y2="56"/>
|
||||||
|
<line x1="164" x2="164" y1="56" y2="88"/>
|
||||||
|
<line x1="164" x2="164" y1="88" y2="120"/>
|
||||||
|
<line x1="164" x2="164" y1="120" y2="152"/>
|
||||||
|
<line x1="164" x2="164" y1="152" y2="184"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="188" x2="188" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="200" x2="208" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="224" x2="236" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="232" x2="240" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="236" x2="236" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="260" x2="260" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="264" x2="272" y1="64" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="272" x2="280" y1="128" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="304" x2="316" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="316" x2="316" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="360" y1="136" y2="112"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="348" x2="348" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="368" x2="376" y1="96" y2="80"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="384" y1="48" y2="64"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="376" x2="388" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="388" x2="388" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="416" x2="424" y1="80" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="420" x2="420" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="436" x2="420" y1="104" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="448" x2="460" y1="112" y2="136"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="460" x2="460" y1="144" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="512" x2="640" y1="24" y2="24"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="108">
|
||||||
|
time
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="44">
|
||||||
|
L1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="76">
|
||||||
|
L2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="108">
|
||||||
|
L3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="140">
|
||||||
|
L4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="137" y="172">
|
||||||
|
L5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="140">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="185" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="209" y="108">
|
||||||
|
E3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="225" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="249" y="76">
|
||||||
|
E2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="140">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="257" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="289" y="108">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="305" y="172">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="313" y="44">
|
||||||
|
E1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="337" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="361" y="108">
|
||||||
|
E3'
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="377" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="393" y="76">
|
||||||
|
x
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="409" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="449" y="172">
|
||||||
|
xx
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="12">
|
||||||
|
validator
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="60">
|
||||||
|
vote(E1)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="92">
|
||||||
|
vote(E2)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="124">
|
||||||
|
slash(E3)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="156">
|
||||||
|
vote(E4)
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="513" y="188">
|
||||||
|
hang
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="553" y="188">
|
||||||
|
on
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="577" y="188">
|
||||||
|
to
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="593" y="12">
|
||||||
|
action
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="601" y="188">
|
||||||
|
E4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="625" y="188">
|
||||||
|
and
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="657" y="188">
|
||||||
|
E5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="681" y="188">
|
||||||
|
for
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="713" y="188">
|
||||||
|
more...
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
122
book/src/.gitbook/assets/forks (1).svg
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="96" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="96" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="48" x2="64" y1="16" y2="48"/>
|
||||||
|
<line x1="68" x2="64" y1="56" y2="48"/>
|
||||||
|
<line x1="68" x2="68" y1="64" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="68" x2="68" y1="80" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="72" x2="80" y1="80" y2="96"/>
|
||||||
|
<line x1="80" x2="88" y1="96" y2="112"/>
|
||||||
|
<line x1="92" x2="88" y1="120" y2="112"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="120"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="192"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="204">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
122
book/src/.gitbook/assets/forks (2).svg
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="96" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="96" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="48" x2="64" y1="16" y2="48"/>
|
||||||
|
<line x1="68" x2="64" y1="56" y2="48"/>
|
||||||
|
<line x1="68" x2="68" y1="64" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="68" x2="68" y1="80" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="72" x2="80" y1="80" y2="96"/>
|
||||||
|
<line x1="80" x2="88" y1="96" y2="112"/>
|
||||||
|
<line x1="92" x2="88" y1="120" y2="112"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="120"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="192"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="204">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
122
book/src/.gitbook/assets/forks (3).svg
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="96" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="96" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="48" x2="64" y1="16" y2="48"/>
|
||||||
|
<line x1="68" x2="64" y1="56" y2="48"/>
|
||||||
|
<line x1="68" x2="68" y1="64" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="68" x2="68" y1="80" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="72" x2="80" y1="80" y2="96"/>
|
||||||
|
<line x1="80" x2="88" y1="96" y2="112"/>
|
||||||
|
<line x1="92" x2="88" y1="120" y2="112"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="120"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="192"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="204">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
92
book/src/.gitbook/assets/forks-pruned (1).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="144" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="144" width="48" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned (2).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="144" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="144" width="48" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned (3).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="144" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="144" width="48" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned.svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="144" width="48" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="144" width="48" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned2 (1).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="176" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="176" width="40" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="48" y2="128"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="16" x2="32" y1="48" y2="80"/>
|
||||||
|
<line x1="36" x2="32" y1="88" y2="80"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="88"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="44">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="140">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="172">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned2 (2).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="176" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="176" width="40" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="48" y2="128"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="16" x2="32" y1="48" y2="80"/>
|
||||||
|
<line x1="36" x2="32" y1="88" y2="80"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="88"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="44">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="140">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="172">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned2 (3).svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="176" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="176" width="40" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="48" y2="128"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="16" x2="32" y1="48" y2="80"/>
|
||||||
|
<line x1="36" x2="32" y1="88" y2="80"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="88"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="44">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="140">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="172">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
92
book/src/.gitbook/assets/forks-pruned2.svg
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="176" width="40" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="176" width="40" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="12" x2="12" y1="48" y2="128"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="16" x2="32" y1="48" y2="80"/>
|
||||||
|
<line x1="36" x2="32" y1="88" y2="80"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="88"/>
|
||||||
|
<line x1="36" x2="36" y1="96" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="44">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="9" y="140">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="33" y="172">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
122
book/src/.gitbook/assets/forks.svg
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<svg class="bob" font-family="arial" font-size="14" height="208" width="96" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<marker id="triangle" markerHeight="8" markerWidth="8" orient="auto" refX="4" refY="2" viewBox="0 0 8 4">
|
||||||
|
<polygon fill="black" points="0,0 0,4 8,2 0,0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="clear_triangle" markerHeight="10" markerWidth="10" orient="auto" refX="1" refY="7" viewBox="0 0 20 14">
|
||||||
|
<polygon fill="none" points="2,2 2,12 18,7 2,2" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="circle" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="black" r="8"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="square" markerHeight="5" markerWidth="5" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<rect fill="black" height="20" width="20" x="0" y="0"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="open_circle" markerHeight="10" markerWidth="10" orient="auto" refX="10" refY="10" viewBox="0 0 20 20">
|
||||||
|
<circle cx="10" cy="10" fill="white" r="4" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
<marker id="big_open_circle" markerHeight="20" markerWidth="20" orient="auto" refX="20" refY="20" viewBox="0 0 40 40">
|
||||||
|
<circle cx="20" cy="20" fill="white" r="6" stroke="black" stroke-width="2"/>
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
line,path {
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
line.dashed {
|
||||||
|
stroke-dasharray: 5;
|
||||||
|
}
|
||||||
|
circle.solid {
|
||||||
|
fill:black;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
circle.open {
|
||||||
|
fill:none;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 2;
|
||||||
|
stroke-opacity: 1;
|
||||||
|
fill-opacity: 1;
|
||||||
|
stroke-linecap: round;
|
||||||
|
stroke-linejoin: miter;
|
||||||
|
}
|
||||||
|
tspan.head{
|
||||||
|
fill: none;
|
||||||
|
stroke: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<rect fill="white" height="208" width="96" x="0" y="0"/>
|
||||||
|
<g>
|
||||||
|
<line x1="20" x2="24" y1="88" y2="80"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="88"/>
|
||||||
|
<line x1="20" x2="20" y1="96" y2="128"/>
|
||||||
|
<line x1="24" x2="40" y1="80" y2="48"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="16" y2="32"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="44" x2="44" y1="48" y2="96"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="48" x2="64" y1="16" y2="48"/>
|
||||||
|
<line x1="68" x2="64" y1="56" y2="48"/>
|
||||||
|
<line x1="68" x2="68" y1="64" y2="56"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="68" x2="68" y1="80" y2="160"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<line x1="72" x2="80" y1="80" y2="96"/>
|
||||||
|
<line x1="80" x2="88" y1="96" y2="112"/>
|
||||||
|
<line x1="92" x2="88" y1="120" y2="112"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="120"/>
|
||||||
|
<line x1="92" x2="92" y1="128" y2="192"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="17" y="140">
|
||||||
|
5
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="12">
|
||||||
|
1
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="44">
|
||||||
|
2
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="41" y="108">
|
||||||
|
4
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="76">
|
||||||
|
3
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="65" y="172">
|
||||||
|
6
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<text x="89" y="204">
|
||||||
|
7
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (2).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (3).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (4).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (5).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (6).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule (7).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule-3 (1).png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule-3.png
Normal file
After Width: | Height: | Size: 256 KiB |
BIN
book/src/.gitbook/assets/p_ex_schedule.png
Normal file
After Width: | Height: | Size: 256 KiB |
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
BIN
book/src/.gitbook/assets/p_ex_supply (2).png
Normal file
After Width: | Height: | Size: 269 KiB |
BIN
book/src/.gitbook/assets/p_ex_supply (3).png
Normal file
After Width: | Height: | Size: 269 KiB |
BIN
book/src/.gitbook/assets/p_ex_supply (4).png
Normal file
After Width: | Height: | Size: 269 KiB |