Compare commits

..

60 Commits

Author SHA1 Message Date
Michael Vines
7566ac97b2 Add description tag 2019-10-02 23:11:48 -07:00
Michael Vines
c4b528f9f6 Add description tag 2019-10-02 23:01:28 -07:00
Michael Vines
fcda9d56e9 Enable patch branches 2019-10-02 22:23:31 -07:00
mergify[bot]
8f0cd4e456 Switch to solana-reed-solomon-erasure temporarily to fix windows build (#6220)
automerge
2019-10-02 19:39:45 -07:00
mergify[bot]
382663aef6 Bench-tps: flush tx queue when too old (#6201) (#6208)
automerge
2019-10-01 15:09:53 -07:00
mergify[bot]
ff79693568 Use built-in solana-gossip timeout for better error messages (#6189) (#6203)
automerge
2019-10-01 13:23:10 -07:00
mergify[bot]
517cebf7f0 Add native_token module to sdk (bp #6192) (#6196)
automerge
2019-10-01 13:02:43 -07:00
mergify[bot]
fcae91d7fa Rename bank height to block_height and expose method (#6199) (#6202)
automerge
2019-10-01 12:52:09 -07:00
Justin Starry
c44d3139fd Expose current stake accounts of a bank for use in cli tooling (#6184) (#6190)
automerge
2019-10-01 10:05:49 -07:00
mergify[bot]
effd2fd835 Cleanly error when trying to delegate-stake an existing stake account (#6158) (#6160)
(cherry picked from commit 284273a73f)
2019-10-01 09:02:28 -07:00
mergify[bot]
2cd832521a Clear download progress bar to avoid flicker during archive extraction (#6162) (#6176)
(cherry picked from commit 11fc684f3c)
2019-09-29 18:56:50 -07:00
mergify[bot]
77a4354b93 Don't try signging coding shred if fec rate is 0 (#6171) (#6172)
automerge

(cherry picked from commit 5637f88aff)
2019-09-28 19:38:00 -07:00
mergify[bot]
31f86158e8 Add get-epoch-info command (#6161) (#6173)
automerge
2019-09-27 22:53:47 -07:00
Jack May
29c892ee00 Validator-info doc update (#6152) (#6157) 2019-09-27 14:27:41 -07:00
mergify[bot]
06e34ef1cf Add ability to manually create a db (#6151) (#6154)
automerge
2019-09-27 12:42:17 -07:00
Ryan Shea
11bc11f0b7 Fix URLs for images (#6148) 2019-09-27 12:00:46 -07:00
mergify[bot]
8f27240211 get_new_blockhash() now retries longer (5s instead of 2s) (#6143) (#6150)
automerge
2019-09-27 11:27:43 -07:00
mergify[bot]
b8f680d1e7 doc: update validator-info publish arguments (bp #6146) (#6153)
* doc: update validator-info publish arguments (#6146)

(cherry picked from commit bf199a2ebc)

# Conflicts:
#	book/src/running-validator/validator-info.md

* Update validator-info.md
2019-09-27 11:25:57 -07:00
Michael Vines
2d4a081c3c Create vote account with 1 lamport instead of 1 SOL 2019-09-27 08:14:35 -07:00
mergify[bot]
be5f879e42 Avoid storing epoch 0 credits if no credits where earned in epoch 0 (#6132) (#6138)
automerge
2019-09-26 21:27:29 -07:00
mergify[bot]
8b353da83c Prevent subtract overflow panic when slot < MAX_LOCKOUT_HISTORY (#6135) (#6136)
automerge
2019-09-26 19:08:20 -07:00
Tyera Eulberg
61930c0dd3 Cherry-pick vote and stake authority changes (#6127)
* add authorized parameters to vote api (#6072)

* add authorized parameters to vote api

* code review

* add authorities to stake init (#6104)

* add authorities to stake init

* fixups

* code review
2019-09-26 17:18:31 -06:00
Michael Vines
232d2b3899 Remove CUDA feature (#6094) (#6126)
automerge
2019-09-26 14:38:30 -07:00
mergify[bot]
0f3a8314ae Enable SOL or lamports for create-vote-account, show-{stake,vote}-account commands (#6114) (#6116)
automerge
2019-09-26 11:35:14 -07:00
mergify[bot]
562034efe3 Remove serializing all ForkHashes (#6110) (#6111)
automerge
2019-09-26 02:43:15 -07:00
mergify[bot]
01c98c5e53 Remove some AccountStorage Serialization (#6047) (#6108)
automerge
2019-09-25 19:14:08 -07:00
mergify[bot]
a4128e886a Fix Bench-tps being too strict (#6105) (#6107)
automerge
2019-09-25 18:50:19 -07:00
mergify[bot]
2589816245 Change formula used in erasure statistics graph (#6102) (#6103)
automerge
2019-09-25 15:24:48 -07:00
mergify[bot]
0245e4cf94 Move status cache serialization to the Snapshot Packager service (#6081) (#6101)
automerge
2019-09-25 14:40:18 -07:00
Dan Albert
2293ad20d5 GitBook: [v0.19] 10 pages and 59 assets modified 2019-09-25 20:58:38 +00:00
mergify[bot]
c0195a2121 Prune fork_hashes with dead forks (#6085) (#6095)
automerge
2019-09-25 12:06:47 -07:00
mergify[bot]
d203adc3d9 Remove brace expansion in arg list (#6091) (#6092)
automerge
2019-09-25 10:28:19 -07:00
Dan Albert
0249d53a14 Update cargo files to 0.19.1 (#6093) 2019-09-25 13:12:00 -04:00
mergify[bot]
1db0fbc77e Add erasure recovery stats to dashboard (#6079) (#6087)
automerge
2019-09-24 22:34:12 -07:00
mergify[bot]
82153f934f Fix staker / voter credit redemption (#6074) (#6086)
automerge
2019-09-24 22:05:41 -07:00
mergify[bot]
4f3f662cfe Remove local_cluster tests from stable-perf job, removee other tests from local-cluster job (#6067) (#6084)
automerge
2019-09-24 21:00:10 -07:00
mergify[bot]
1942c47d73 Avoid accidential tx_count mismatches when using an accounts file (#6069) (#6082)
automerge
2019-09-24 20:37:22 -07:00
Tyera Eulberg
a90281ad5c Reduce poll sleep (#6068) (#6073)
* Reduce sleep in poll_for_signature_confirmations

* Unignore test_repairman_catchup
2019-09-24 20:01:04 -06:00
mergify[bot]
6360bac5e8 Fix using temp file for archive (#6058) (#6071)
* Fix using temp file for archive

* Rename the temp archive instead of hardlinking it

(cherry picked from commit 374b776a3e)
2019-09-24 18:29:11 -07:00
mergify[bot]
c54b23b9d5 Additional tests for should_retransmit_and_persist (#6062) (#6070)
automerge
2019-09-24 17:48:39 -07:00
mergify[bot]
04aaa714e6 Revert back to reqwest, using rustls feature (bp #6041) (#6064)
automerge
2019-09-24 15:35:07 -07:00
Michael Vines
2cc0ab2c5f Tweak Bank Slot Distance graph 2019-09-24 14:52:50 -07:00
mergify[bot]
aac0d7f2f5 Window service is filtering out coding shreds (#6052) (#6059)
automerge
2019-09-24 13:48:13 -07:00
mergify[bot]
9fd29b0575 Fix vote metrics (#6038) (#6040)
automerge
2019-09-24 13:20:27 -07:00
mergify[bot]
6abe3c2804 Fix race between observing tick height being set to last tick and blockhash being observed on a bank (#6013) (#6056)
automerge
2019-09-24 12:20:46 -07:00
mergify[bot]
01ce5beb19 Support primordial accounts with no data (#6053) (#6055)
automerge
2019-09-24 11:52:57 -07:00
mergify[bot]
2bd72318f6 Remove dead code from cluster_info (#6051) (#6054)
automerge
2019-09-24 11:29:52 -07:00
carllin
68a9224604 Fix race between observing tick height being set to last tick and blockhash being observed on a bank (#6013) 2019-09-24 11:16:24 -07:00
Rob Walker
181cad233c rename balance (#5984) 2019-09-24 11:15:15 -07:00
Justin Starry
0b66529f11 Fix BPF program static linking (#5992) (#6049)
automerge
2019-09-24 09:40:33 -07:00
Michael Vines
e20e4180a9 Flip order of arg to ensure -t sticks 2019-09-23 22:21:12 -07:00
mergify[bot]
de4309a905 Avoid hardlinking as that confuses tar (#6042) (#6045)
(cherry picked from commit 7fa809c16d)
2019-09-23 21:40:09 -07:00
mergify[bot]
d5248c936f Skip considering banks older than the latest vote slot (#6037) (#6043)
automerge
2019-09-23 20:44:47 -07:00
mergify[bot]
40bc37266d Don't recover coding shreds (#6034) (#6039)
automerge
2019-09-23 18:35:50 -07:00
mergify[bot]
1819f263f1 ' => " (#6035) (#6036)
automerge
2019-09-23 17:31:05 -07:00
Pankaj Garg
24a055e490 Upgrade to ReedSolomon 4.0 release (#6026) (#6030)
automerge
2019-09-23 15:29:52 -07:00
mergify[bot]
dfbd77f18d Fix really old banks triggering log spam (#6025) (#6029)
automerge
2019-09-23 15:27:38 -07:00
mergify[bot]
7c5557d69b Dump tar stdout/err on failure for better debug (#6024) (#6027)
automerge
2019-09-23 13:57:39 -07:00
mergify[bot]
d180eedd17 Remove the _/deps symlink, just copy instead (#6020) (#6021)
automerge
2019-09-23 09:50:07 -07:00
Michael Vines
3b274ca8db GitBook: [v0.19] 79 pages and 12 assets modified 2019-09-23 03:38:36 +00:00
992 changed files with 72550 additions and 103508 deletions

View File

@@ -1,15 +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_unknown_linux_gnu": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:Egc2dMrHDU0NcZ71LwGv/V66shUhwYUE:04VoIb8CKy7KYhQ5W4cEW9SDKZltxWBL5Hob106lMBbUOD/yUvKYcG3Ep8JfTMwO3K8zowW5HpU/IdGoilX0XWLiJJ6t+p05WWK0TA16nOEtwrEG+UK8wm3sN+xCO20i4jDhpNpgg3FYFHT5rKTHW8+zaBTNUX/SFxkN67Lm+92IM28CXYE43SU1WV6H99hGFFVpTK5JVM3JuYU1ex/dHRE+xCzTr4MYUB/F+nGoNFW8HUDV/y0e1jxT9to3x0SmnytEEuk+5RUzFuEt9cKNFeNml3fOCi4qL+sfj/Y5pjH9xDiUxsvH/8NL35jbLP244aFHgWcp]", "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_apple_darwin": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:NeOxSoWCvXB9AL4H6OK26l/7bmsKd/oz:Ijfoxtvk2CHlN1ZXHup3Gg/914kbbAkEGWJfvozA8UIe+aUzUObMyTrKkVOeNAH8Q8YH9tNzk7RRnrTcpnzeCCBLlWcVEeruMxHox3mPRzmSeDLxtbzCl9VePlRO3T7jg90K5hW+ZAkd5J/WJNzpAcmr93ts/of3MbvGHSujId/efCTzJEcP6JInnBb8Vrj7TlgKbzUlnqpq1+NjYPSXN3maKa9pKeo2JWxZlGBMoy6QWUUY5GbYEylw9smwh1LJcHZjlaZNMuOl4gNKtaSr38IXQkAXaRUJDPAmPras00YObKzXU8RkTrP4EoP/jx5LPR7f]", "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=]"
"SOLANA_INSTALL_UPDATE_MANIFEST_KEYPAIR_x86_64_pc_windows_msvc": "EJ[1:yGpTmjdbyjW2kjgIHkFoJv7Ue7EbUvUbqHyw6anGgWg=:7t+56twjW+jR7fpFNNeRFLPd7E4lbmyN:JuviDpkQrfVcNUGRGsa2e/UhvH6tTYyk1s4cHHE5xZH1NByL7Kpqx36VG/+o1AUGEeSQdsBnKgzYdMoFYbO8o50DoRPc86QIEVXCupD6J9avxLFtQgOWgJp+/mCdUVXlqXiFs/vQgS/L4psrcKdF6WHd77BeUr6ll8DjH+9m5FC9Rcai2pXno6VbPpunHQ0oUdYzhFR64+LiRacBaefQ9igZ+nSEWDLqbaZSyfm9viWkijoVFTq8gAgdXXEh7g0QdxVE5T6bPristJhT6jWBhWunPUCDNFFErWIsbRGctepl4pbCWqh2hNTw9btSgVfeY6uGCOsdy9E=]"
} }
} }

2
.github/stale.yml vendored
View File

@@ -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

2
.gitignore vendored
View File

@@ -1,6 +1,5 @@
/book/html/ /book/html/
/book/src/tests.ok /book/src/tests.ok
/book/src/.gitbook/assets/*.svg
/farf/ /farf/
/solana-release/ /solana-release/
/solana-release.tar.bz2 /solana-release.tar.bz2
@@ -16,7 +15,6 @@
# log files # log files
*.log *.log
log-*.txt log-*.txt
log-*/
# intellij files # intellij files
/.idea/ /.idea/

View File

@@ -19,6 +19,54 @@ pull_request_rules:
label: label:
add: add:
- automerge - automerge
- name: v0.16 backport
conditions:
- base=master
- label=v0.16
actions:
backport:
branches:
- v0.16
- name: v0.17 backport
conditions:
- base=master
- label=v0.17
actions:
backport:
branches:
- v0.17
- name: v0.18 backport
conditions:
- base=master
- label=v0.18
actions:
backport:
branches:
- 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 - name: v0.22 backport
conditions: conditions:
- base=master - base=master
@@ -27,19 +75,3 @@ pull_request_rules:
backport: backport:
branches: branches:
- v0.22 - v0.22
- name: v0.23 backport
conditions:
- base=master
- label=v0.23
actions:
backport:
branches:
- v0.23
- name: v0.24 backport
conditions:
- base=master
- label=v0.24
actions:
backport:
branches:
- v0.24

View File

@@ -3,10 +3,11 @@ os:
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
@@ -15,7 +16,7 @@ script:
branches: branches:
only: only:
- master - master
- /^v\d+\.\d+/ - /^v\d+\.\d+.\d+$/
notifications: notifications:
slack: slack:

View File

@@ -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,69 +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](book/src/terminology.md) [Terms currently in use](book/src/terminology.md)
## Design Proposals Design Proposals
---
Solana's architecture is described by a book generated from markdown files in Solana's architecture is described by a book generated from markdown files in
the `book/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 at least propose a change the content add a design proposal, you'll need to at least propose a change the content
under the [Accepted Design under the [Accepted Design
Proposals](https://docs.solana.com/book/v/master/proposals) chapter. Here's Proposals](https://docs.solana.com/book/v/master/proposals) chapter.
the full process: 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
directory `book/src/` and references it from the [table of directory `book/src/` and references it from the [table of
contents](book/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.

3728
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,62 +3,62 @@ members = [
"bench-exchange", "bench-exchange",
"bench-streamer", "bench-streamer",
"bench-tps", "bench-tps",
"banking-bench", "banking_bench",
"chacha",
"chacha-cuda",
"chacha-sys", "chacha-sys",
"cli-config",
"client", "client",
"core", "core",
"faucet", "drone",
"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",
"measure", "measure",
"metrics", "metrics",
"net-shaper", "programs/bpf_loader_api",
"programs/bpf_loader", "programs/bpf_loader_program",
"programs/budget", "programs/budget_api",
"programs/btc_spv", "programs/budget_program",
"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/storage", "programs/move_loader_api",
"programs/vest", "programs/move_loader_program",
"programs/vote", "programs/librapay_api",
"archiver", "programs/noop_program",
"archiver-lib", "programs/stake_api",
"archiver-utils", "programs/stake_program",
"remote-wallet", "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",
"sdk-c", "sdk-c",
"scripts",
"sys-tuner",
"upload-perf", "upload-perf",
"net-utils", "netutil",
"fixed-buf",
"vote-signer", "vote-signer",
"cli", "cli",
"rayon-threadlimit", "rayon-threadlimit",
"watchtower",
] ]
exclude = [ exclude = [
"programs/bpf", "programs/bpf",
"programs/move_loader",
"programs/librapay",
] ]

View File

@@ -78,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
@@ -126,7 +126,10 @@ Remote Testnets
--- ---
We maintain several testnets: We maintain several testnets:
* `testnet` - public stable testnet accessible via devnet.solana.com. Runs 24/7
* `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 ## Deploy process

View File

@@ -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 `book/src/running-archiver.md` and `book/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

View File

@@ -1,39 +0,0 @@
[package]
name = "solana-archiver-lib"
version = "0.23.9"
description = "Solana Archiver Library"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
edition = "2018"
[dependencies]
bincode = "1.2.1"
crossbeam-channel = "0.3"
ed25519-dalek = "=1.0.0-pre.1"
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-client = { path = "../client", version = "0.23.9" }
solana-storage-program = { path = "../programs/storage", version = "0.23.9" }
thiserror = "1.0"
serde = "1.0.104"
serde_json = "1.0.44"
serde_derive = "1.0.103"
solana-net-utils = { path = "../net-utils", version = "0.23.9" }
solana-chacha = { path = "../chacha", version = "0.23.9" }
solana-chacha-sys = { path = "../chacha-sys", version = "0.23.9" }
solana-ledger = { path = "../ledger", version = "0.23.9" }
solana-logger = { path = "../logger", version = "0.23.9" }
solana-perf = { path = "../perf", version = "0.23.9" }
solana-sdk = { path = "../sdk", version = "0.23.9" }
solana-core = { path = "../core", version = "0.23.9" }
solana-archiver-utils = { path = "../archiver-utils", version = "0.23.9" }
solana-metrics = { path = "../metrics", version = "0.23.9" }
[dev-dependencies]
hex = "0.4.0"
[lib]
name = "solana_archiver_lib"

View File

@@ -1,11 +0,0 @@
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate solana_metrics;
pub mod archiver;
mod result;

View File

@@ -1,48 +0,0 @@
use serde_json;
use solana_client::client_error;
use solana_ledger::blockstore;
use solana_sdk::transport;
use std::any::Any;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ArchiverError {
#[error("IO error")]
IO(#[from] std::io::Error),
#[error("blockstore error")]
BlockstoreError(#[from] blockstore::BlockstoreError),
#[error("crossbeam error")]
CrossbeamSendError(#[from] crossbeam_channel::SendError<u64>),
#[error("send error")]
SendError(#[from] std::sync::mpsc::SendError<u64>),
#[error("join error")]
JoinError(Box<dyn Any + Send + 'static>),
#[error("transport error")]
TransportError(#[from] transport::TransportError),
#[error("client error")]
ClientError(#[from] client_error::ClientError),
#[error("Json parsing error")]
JsonError(#[from] serde_json::error::Error),
#[error("Storage account has no balance")]
EmptyStorageAccountBalance,
#[error("No RPC peers..")]
NoRpcPeers,
#[error("Couldn't download full segment")]
SegmentDownloadError,
}
impl std::convert::From<Box<dyn Any + Send + 'static>> for ArchiverError {
fn from(e: Box<dyn Any + Send + 'static>) -> ArchiverError {
ArchiverError::JoinError(e)
}
}

View File

@@ -1,26 +0,0 @@
[package]
name = "solana-archiver-utils"
version = "0.23.9"
description = "Solana Archiver Utils"
authors = ["Solana Maintainers <maintainers@solana.com>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
edition = "2018"
[dependencies]
log = "0.4.8"
rand = "0.6.5"
rand_chacha = "0.1.1"
solana-chacha = { path = "../chacha", version = "0.23.9" }
solana-chacha-sys = { path = "../chacha-sys", version = "0.23.9" }
solana-ledger = { path = "../ledger", version = "0.23.9" }
solana-logger = { path = "../logger", version = "0.23.9" }
solana-perf = { path = "../perf", version = "0.23.9" }
solana-sdk = { path = "../sdk", version = "0.23.9" }
[dev-dependencies]
hex = "0.4.0"
[lib]
name = "solana_archiver_utils"

View File

@@ -1,120 +0,0 @@
#[macro_use]
extern crate log;
use solana_sdk::hash::{Hash, Hasher};
use std::fs::File;
use std::io::{self, BufReader, ErrorKind, Read, Seek, SeekFrom};
use std::mem::size_of;
use std::path::Path;
pub fn sample_file(in_path: &Path, sample_offsets: &[u64]) -> io::Result<Hash> {
let in_file = File::open(in_path)?;
let metadata = in_file.metadata()?;
let mut buffer_file = BufReader::new(in_file);
let mut hasher = Hasher::default();
let sample_size = size_of::<Hash>();
let sample_size64 = sample_size as u64;
let mut buf = vec![0; sample_size];
let file_len = metadata.len();
if file_len < sample_size64 {
return Err(io::Error::new(ErrorKind::Other, "file too short!"));
}
for offset in sample_offsets {
if *offset > (file_len - sample_size64) / sample_size64 {
return Err(io::Error::new(ErrorKind::Other, "offset too large"));
}
buffer_file.seek(SeekFrom::Start(*offset * sample_size64))?;
trace!("sampling @ {} ", *offset);
match buffer_file.read(&mut buf) {
Ok(size) => {
assert_eq!(size, buf.len());
hasher.hash(&buf);
}
Err(e) => {
warn!("Error sampling file");
return Err(e);
}
}
}
Ok(hasher.result())
}
#[cfg(test)]
mod tests {
use super::*;
use rand::{thread_rng, Rng};
use std::fs::{create_dir_all, remove_file};
use std::io::Write;
use std::path::PathBuf;
extern crate hex;
fn tmp_file_path(name: &str) -> PathBuf {
use std::env;
let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
let mut rand_bits = [0u8; 32];
thread_rng().fill(&mut rand_bits[..]);
let mut path = PathBuf::new();
path.push(out_dir);
path.push("tmp");
create_dir_all(&path).unwrap();
path.push(format!("{}-{:?}", name, hex::encode(rand_bits)));
println!("path: {:?}", path);
path
}
#[test]
fn test_sample_file() {
solana_logger::setup();
let in_path = tmp_file_path("test_sample_file_input.txt");
let num_strings = 4096;
let string = "12foobar";
{
let mut in_file = File::create(&in_path).unwrap();
for _ in 0..num_strings {
in_file.write(string.as_bytes()).unwrap();
}
}
let num_samples = (string.len() * num_strings / size_of::<Hash>()) as u64;
let samples: Vec<_> = (0..num_samples).collect();
let res = sample_file(&in_path, samples.as_slice());
let ref_hash: Hash = Hash::new(&[
173, 251, 182, 165, 10, 54, 33, 150, 133, 226, 106, 150, 99, 192, 179, 1, 230, 144,
151, 126, 18, 191, 54, 67, 249, 140, 230, 160, 56, 30, 170, 52,
]);
let res = res.unwrap();
assert_eq!(res, ref_hash);
// Sample just past the end
assert!(sample_file(&in_path, &[num_samples]).is_err());
remove_file(&in_path).unwrap();
}
#[test]
fn test_sample_file_invalid_offset() {
let in_path = tmp_file_path("test_sample_file_invalid_offset_input.txt");
{
let mut in_file = File::create(&in_path).unwrap();
for _ in 0..4096 {
in_file.write("123456foobar".as_bytes()).unwrap();
}
}
let samples = [0, 200000];
let res = sample_file(&in_path, &samples);
assert!(res.is_err());
remove_file(in_path).unwrap();
}
#[test]
fn test_sample_file_missing_file() {
let in_path = tmp_file_path("test_sample_file_that_doesnt_exist.txt");
let samples = [0, 5];
let res = sample_file(&in_path, &samples);
assert!(res.is_err());
}
}

View File

@@ -1,20 +0,0 @@
[package]
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-archiver"
version = "0.23.9"
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
[dependencies]
clap = "2.33.0"
console = "0.9.1"
solana-clap-utils = { path = "../clap-utils", version = "0.23.9" }
solana-core = { path = "../core", version = "0.23.9" }
solana-logger = { path = "../logger", version = "0.23.9" }
solana-metrics = { path = "../metrics", version = "0.23.9" }
solana-archiver-lib = { path = "../archiver-lib", version = "0.23.9" }
solana-net-utils = { path = "../net-utils", version = "0.23.9" }
solana-sdk = { path = "../sdk", version = "0.23.9" }

View File

@@ -1,147 +0,0 @@
use clap::{crate_description, crate_name, App, Arg};
use console::style;
use solana_archiver_lib::archiver::Archiver;
use solana_clap_utils::{
input_validators::is_keypair,
keypair::{
self, keypair_input, KeypairWithSource, ASK_SEED_PHRASE_ARG,
SKIP_SEED_PHRASE_VALIDATION_ARG,
},
};
use solana_core::{
cluster_info::{Node, VALIDATOR_PORT_RANGE},
contact_info::ContactInfo,
};
use solana_sdk::{commitment_config::CommitmentConfig, signature::Signer};
use std::{net::SocketAddr, path::PathBuf, process::exit, sync::Arc};
fn main() {
solana_logger::setup();
let matches = App::new(crate_name!())
.about(crate_description!())
.version(solana_clap_utils::version!())
.arg(
Arg::with_name("identity_keypair")
.short("i")
.long("identity-keypair")
.value_name("PATH")
.takes_value(true)
.validator(is_keypair)
.help("File containing an identity (keypair)"),
)
.arg(
Arg::with_name("entrypoint")
.short("n")
.long("entrypoint")
.value_name("HOST:PORT")
.takes_value(true)
.required(true)
.validator(solana_net_utils::is_host_port)
.help("Rendezvous with the cluster at this entry point"),
)
.arg(
Arg::with_name("ledger")
.short("l")
.long("ledger")
.value_name("DIR")
.takes_value(true)
.required(true)
.help("use DIR as persistent ledger location"),
)
.arg(
Arg::with_name("storage_keypair")
.short("s")
.long("storage-keypair")
.value_name("PATH")
.takes_value(true)
.validator(is_keypair)
.help("File containing the storage account keypair"),
)
.arg(
Arg::with_name(ASK_SEED_PHRASE_ARG.name)
.long(ASK_SEED_PHRASE_ARG.long)
.value_name("KEYPAIR NAME")
.multiple(true)
.takes_value(true)
.possible_values(&["identity-keypair", "storage-keypair"])
.help(ASK_SEED_PHRASE_ARG.help),
)
.arg(
Arg::with_name(SKIP_SEED_PHRASE_VALIDATION_ARG.name)
.long(SKIP_SEED_PHRASE_VALIDATION_ARG.long)
.requires(ASK_SEED_PHRASE_ARG.name)
.help(SKIP_SEED_PHRASE_VALIDATION_ARG.help),
)
.get_matches();
let ledger_path = PathBuf::from(matches.value_of("ledger").unwrap());
let identity_keypair = keypair_input(&matches, "identity_keypair")
.unwrap_or_else(|err| {
eprintln!("Identity keypair input failed: {}", err);
exit(1);
})
.keypair;
let KeypairWithSource {
keypair: storage_keypair,
source: storage_keypair_source,
} = keypair_input(&matches, "storage_keypair").unwrap_or_else(|err| {
eprintln!("Storage keypair input failed: {}", err);
exit(1);
});
if storage_keypair_source == keypair::Source::Generated {
clap::Error::with_description(
"The `storage-keypair` argument was not found",
clap::ErrorKind::ArgumentNotFound,
)
.exit();
}
let entrypoint_addr = matches
.value_of("entrypoint")
.map(|entrypoint| {
solana_net_utils::parse_host_port(entrypoint)
.expect("failed to parse entrypoint address")
})
.unwrap();
let gossip_addr = {
let ip = solana_net_utils::get_public_ip_addr(&entrypoint_addr).unwrap();
let mut addr = SocketAddr::new(ip, 0);
addr.set_ip(solana_net_utils::get_public_ip_addr(&entrypoint_addr).unwrap());
addr
};
let node = Node::new_archiver_with_external_ip(
&identity_keypair.pubkey(),
&gossip_addr,
VALIDATOR_PORT_RANGE,
);
println!(
"{} version {} (branch={}, commit={})",
style(crate_name!()).bold(),
solana_clap_utils::version!(),
option_env!("CI_BRANCH").unwrap_or("unknown"),
option_env!("CI_COMMIT").unwrap_or("unknown")
);
solana_metrics::set_host_id(identity_keypair.pubkey().to_string());
println!(
"replicating the data with identity_keypair={:?} gossip_addr={:?}",
identity_keypair.pubkey(),
gossip_addr
);
let entrypoint_info = ContactInfo::new_gossip_entry_point(&entrypoint_addr);
let archiver = Archiver::new(
&ledger_path,
node,
entrypoint_info,
Arc::new(identity_keypair),
Arc::new(storage_keypair),
CommitmentConfig::recent(),
)
.unwrap();
archiver.join();
}

View File

@@ -1,20 +0,0 @@
[package]
authors = ["Solana Maintainers <maintainers@solana.com>"]
edition = "2018"
name = "solana-banking-bench"
version = "0.23.9"
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.23.9" }
solana-ledger = { path = "../ledger", version = "0.23.9" }
solana-logger = { path = "../logger", version = "0.23.9" }
solana-runtime = { path = "../runtime", version = "0.23.9" }
solana-measure = { path = "../measure", version = "0.23.9" }
solana-sdk = { path = "../sdk", version = "0.23.9" }
rand = "0.6.5"
crossbeam-channel = "0.3"

19
banking_bench/Cargo.toml Normal file
View 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"

View File

@@ -1,16 +1,21 @@
#[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::bank_forks::BankForks;
use solana_core::banking_stage::{create_test_recorder, BankingStage}; use solana_core::banking_stage::{create_test_recorder, BankingStage};
use solana_core::blocktree::{get_tmp_ledger_path, Blocktree};
use solana_core::cluster_info::ClusterInfo; use solana_core::cluster_info::ClusterInfo;
use solana_core::cluster_info::Node; use solana_core::cluster_info::Node;
use solana_core::genesis_utils::{create_genesis_config, GenesisConfigInfo}; use solana_core::genesis_utils::{create_genesis_block, GenesisBlockInfo};
use solana_core::packet::to_packets_chunked; use solana_core::packet::to_packets_chunked;
use solana_core::poh_recorder::PohRecorder; use solana_core::poh_recorder::PohRecorder;
use solana_core::poh_recorder::WorkingBankEntry; use solana_core::poh_recorder::WorkingBankEntry;
use solana_ledger::bank_forks::BankForks; use solana_core::service::Service;
use solana_ledger::{blockstore::Blockstore, get_tmp_ledger_path};
use solana_measure::measure::Measure; use solana_measure::measure::Measure;
use solana_runtime::bank::Bank; use solana_runtime::bank::Bank;
use solana_sdk::hash::Hash; use solana_sdk::hash::Hash;
@@ -20,6 +25,7 @@ use solana_sdk::signature::Signature;
use solana_sdk::system_transaction; use solana_sdk::system_transaction;
use solana_sdk::timing::{duration_as_us, timestamp}; use solana_sdk::timing::{duration_as_us, timestamp};
use solana_sdk::transaction::Transaction; use solana_sdk::transaction::Transaction;
use std::iter;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::mpsc::Receiver; use std::sync::mpsc::Receiver;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
@@ -35,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();
} }
@@ -97,21 +103,21 @@ fn main() {
const PACKETS_PER_BATCH: usize = 192; const PACKETS_PER_BATCH: usize = 192;
let txes = PACKETS_PER_BATCH * num_threads * CHUNKS; let txes = PACKETS_PER_BATCH * num_threads * CHUNKS;
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, txes); info!("threads: {} txs: {}", num_threads, txes);
let mut transactions = make_accounts_txs(txes, &mint_keypair, genesis_config.hash()); let mut transactions = make_accounts_txs(txes, &mint_keypair, genesis_block.hash());
// fund all the accounts // fund all the accounts
transactions.iter().for_each(|tx| { transactions.iter().for_each(|tx| {
@@ -119,7 +125,7 @@ fn main() {
&mint_keypair, &mint_keypair,
&tx.message.account_keys[0], &tx.message.account_keys[0],
mint_total / txes as u64, mint_total / txes as u64,
genesis_config.hash(), genesis_block.hash(),
); );
let x = bank.process_transaction(&fund); let x = bank.process_transaction(&fund);
x.unwrap(); x.unwrap();
@@ -136,22 +142,27 @@ fn main() {
assert!(r.is_ok(), "sanity parallel execution"); assert!(r.is_ok(), "sanity parallel execution");
} }
bank.clear_signatures(); bank.clear_signatures();
let mut verified: Vec<_> = to_packets_chunked(&transactions.clone(), PACKETS_PER_BATCH); 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(RwLock::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);
@@ -162,8 +173,9 @@ fn main() {
// 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 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();
@@ -173,7 +185,6 @@ fn main() {
chunk_len, chunk_len,
num_threads, num_threads,
}; };
let mut total_sent = 0;
for _ in 0..ITERS { for _ in 0..ITERS {
let now = Instant::now(); let now = Instant::now();
let mut sent = 0; let mut sent = 0;
@@ -198,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();
} }
@@ -215,7 +226,7 @@ fn main() {
sleep(Duration::from_millis(5)); sleep(Duration::from_millis(5));
} }
} }
if check_txs(&signal_receiver, txes / CHUNKS, &poh_recorder) { if check_txs(&signal_receiver2, txes / CHUNKS, &poh_recorder) {
debug!( debug!(
"resetting bank {} tx count: {} txs_proc: {}", "resetting bank {} tx count: {} txs_proc: {}",
bank.slot(), bank.slot(),
@@ -224,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(
@@ -256,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()),
txes / 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() {
@@ -278,7 +288,13 @@ 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_BATCH); 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;
@@ -286,21 +302,18 @@ fn main() {
} }
eprintln!( eprintln!(
"{{'name': 'banking_bench_total', 'median': '{}'}}", "{{'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': '{}'}}", "{{'name': 'banking_bench_tx_total', 'median': '{}'}}",
(1000.0 * 1000.0 * total_sent as f64) / (tx_total_us as f64), tx_total / ITERS as u64,
); );
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);
} }

View File

@@ -2,40 +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 = "0.23.9" 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]
bincode = "1.2.1" bincode = "1.1.4"
bs58 = "0.3.0" bs58 = "0.3.0"
clap = "2.32.0" clap = "2.32.0"
env_logger = "0.7.1" env_logger = "0.6.2"
itertools = "0.8.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.6.5" rand = "0.6.5"
rayon = "1.2.0" rayon = "1.2.0"
serde = "1.0.104" serde = "1.0.101"
serde_derive = "1.0.103" serde_derive = "1.0.101"
serde_json = "1.0.44" serde_json = "1.0.40"
serde_yaml = "0.8.11" serde_yaml = "0.8.9"
solana-clap-utils = { path = "../clap-utils", version = "0.23.9" } # solana-runtime = { path = "../solana/runtime"}
solana-core = { path = "../core", version = "0.23.9" } solana-core = { path = "../core", version = "0.19.1" }
solana-genesis = { path = "../genesis", version = "0.23.9" } solana-genesis = { path = "../genesis", version = "0.19.1" }
solana-client = { path = "../client", version = "0.23.9" } solana-client = { path = "../client", version = "0.19.1" }
solana-faucet = { path = "../faucet", version = "0.23.9" } solana-drone = { path = "../drone", version = "0.19.1" }
solana-exchange-program = { path = "../programs/exchange", version = "0.23.9" } solana-exchange-api = { path = "../programs/exchange_api", version = "0.19.1" }
solana-logger = { path = "../logger", version = "0.23.9" } solana-exchange-program = { path = "../programs/exchange_program", version = "0.19.1" }
solana-metrics = { path = "../metrics", version = "0.23.9" } solana-logger = { path = "../logger", version = "0.19.1" }
solana-net-utils = { path = "../net-utils", version = "0.23.9" } solana-metrics = { path = "../metrics", version = "0.19.1" }
solana-runtime = { path = "../runtime", version = "0.23.9" } solana-netutil = { path = "../netutil", version = "0.19.1" }
solana-sdk = { path = "../sdk", version = "0.23.9" } solana-runtime = { path = "../runtime", version = "0.19.1" }
solana-sdk = { path = "../sdk", version = "0.19.1" }
untrusted = "0.7.0" untrusted = "0.7.0"
ws = "0.9.1" ws = "0.9.0"
[dev-dependencies]
solana-local-cluster = { path = "../local-cluster", version = "0.23.9" }

View File

@@ -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:

View File

@@ -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()
@@ -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![ 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 if client.get_balance(a).unwrap_or(0) >= amount {
.get_balance_with_commitment(a, CommitmentConfig::recent())
.unwrap_or(0)
>= amount
{
return true; 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();
@@ -775,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);
}); });
@@ -814,41 +779,27 @@ 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(vec![create_ix, request_ix]), Transaction::new_unsigned_instructions(vec![create_ix, request_ix]),
) )
}) })
@@ -867,12 +818,11 @@ 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");
@@ -881,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
@@ -898,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",
@@ -910,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 &notfunded { for f in &notfunded {
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)
} }
} }
@@ -972,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;
@@ -989,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
); );
} }
}; };

View File

@@ -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| { .unwrap_or_else(|e| {
eprintln!("failed to parse entrypoint address: {}", e); eprintln!("failed to parse entrypoint address: {}", e);
exit(1) exit(1)
}); });
args.faucet_addr = solana_net_utils::parse_host_port(matches.value_of("faucet").unwrap()) args.drone_addr = solana_netutil::parse_host_port(matches.value_of("drone").unwrap())
.unwrap_or_else(|e| { .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.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 = {

View File

@@ -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_clap_utils::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,7 +54,7 @@ fn main() {
); );
} else { } else {
info!("Connecting to the cluster"); info!("Connecting to the cluster");
let (nodes, _archivers) = let (nodes, _replicators) =
discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|_| { discover_cluster(&entrypoint_addr, num_nodes).unwrap_or_else(|_| {
panic!("Failed to discover nodes"); panic!("Failed to discover nodes");
}); });
@@ -73,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,
); );

View File

@@ -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;

View File

@@ -2,14 +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 = "0.23.9" 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.0" clap = "2.33.0"
solana-clap-utils = { path = "../clap-utils", version = "0.23.9" } solana-core = { path = "../core", version = "0.19.1" }
solana-core = { path = "../core", version = "0.23.9" } solana-logger = { path = "../logger", version = "0.19.1" }
solana-logger = { path = "../logger", version = "0.23.9" } solana-netutil = { path = "../netutil", version = "0.19.1" }
solana-net-utils = { path = "../net-utils", version = "0.23.9" }

View File

@@ -1,5 +1,7 @@
use clap::{crate_description, crate_name, App, Arg}; use clap::{crate_description, crate_name, crate_version, App, Arg};
use solana_core::packet::{Packet, Packets, PacketsRecycler, PACKET_DATA_SIZE}; use solana_core::packet::PacketsRecycler;
use solana_core::packet::{Packet, Packets, BLOB_SIZE, PACKET_DATA_SIZE};
use solana_core::result::Result;
use solana_core::streamer::{receiver, PacketReceiver}; 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};
@@ -7,7 +9,7 @@ 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_clap_utils::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")
@@ -75,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(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();

View File

@@ -2,38 +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 = "0.23.9" 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.0" clap = "2.33.0"
log = "0.4.8" log = "0.4.8"
rayon = "1.2.0" rayon = "1.2.0"
serde = "1.0.104" serde = "1.0.101"
serde_derive = "1.0.103" serde_derive = "1.0.101"
serde_json = "1.0.44" serde_json = "1.0.40"
serde_yaml = "0.8.11" serde_yaml = "0.8.9"
solana-clap-utils = { path = "../clap-utils", version = "0.23.9" } solana-core = { path = "../core", version = "0.19.1" }
solana-core = { path = "../core", version = "0.23.9" } solana-genesis = { path = "../genesis", version = "0.19.1" }
solana-genesis = { path = "../genesis", version = "0.23.9" } solana-client = { path = "../client", version = "0.19.1" }
solana-client = { path = "../client", version = "0.23.9" } solana-drone = { path = "../drone", version = "0.19.1" }
solana-faucet = { path = "../faucet", version = "0.23.9" } solana-librapay-api = { path = "../programs/librapay_api", version = "0.19.1" }
solana-librapay = { path = "../programs/librapay", version = "0.23.9", optional = true } solana-logger = { path = "../logger", version = "0.19.1" }
solana-logger = { path = "../logger", version = "0.23.9" } solana-metrics = { path = "../metrics", version = "0.19.1" }
solana-metrics = { path = "../metrics", version = "0.23.9" } solana-measure = { path = "../measure", version = "0.19.1" }
solana-measure = { path = "../measure", version = "0.23.9" } solana-netutil = { path = "../netutil", version = "0.19.1" }
solana-net-utils = { path = "../net-utils", version = "0.23.9" } solana-runtime = { path = "../runtime", version = "0.19.1" }
solana-runtime = { path = "../runtime", version = "0.23.9" } solana-sdk = { path = "../sdk", version = "0.19.1" }
solana-sdk = { path = "../sdk", version = "0.23.9" } solana-move-loader-program = { path = "../programs/move_loader_program", version = "0.19.1" }
solana-move-loader-program = { path = "../programs/move_loader", version = "0.23.9", optional = true } solana-move-loader-api = { path = "../programs/move_loader_api", version = "0.19.1" }
[dev-dependencies] [dev-dependencies]
serial_test = "0.3.2" serial_test = "0.2.0"
serial_test_derive = "0.3.1" serial_test_derive = "0.2.0"
solana-local-cluster = { path = "../local-cluster", version = "0.23.9" }
[features]
move = ["solana-librapay", "solana-move-loader-program"]

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +1,29 @@
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::FeeCalculator; 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,
} }
@@ -31,20 +32,18 @@ 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: FeeCalculator::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,
} }
@@ -52,9 +51,9 @@ impl Default for Config {
} }
/// 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")
@@ -64,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")
@@ -112,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")
@@ -124,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")
@@ -183,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");
} }
@@ -217,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") {
@@ -253,7 +232,6 @@ 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");

View File

@@ -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::FeeCalculator; 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_clap_utils::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;
FeeCalculator::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,15 +65,15 @@ fn main() {
return; return;
} }
info!("Connecting to the cluster"); println!("Connecting to the cluster");
let (nodes, _archivers) = let (nodes, _replicators) =
discover_cluster(&entrypoint_addr, *num_nodes).unwrap_or_else(|err| { discover_cluster(&entrypoint_addr, *num_nodes).unwrap_or_else(|err| {
eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err); eprintln!("Failed to discover {} nodes: {:?}", num_nodes, err);
exit(1); exit(1);
}); });
let client = if *multi_client {
let (client, num_clients) = get_multi_client(&nodes); let (client, num_clients) = get_multi_client(&nodes);
if nodes.len() < num_clients { if nodes.len() < num_clients {
eprintln!( eprintln!(
"Error: Insufficient nodes discovered. Expecting {} or more", "Error: Insufficient nodes discovered. Expecting {} or more",
@@ -82,17 +81,14 @@ fn main() {
); );
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 (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;
@@ -104,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(),
); );
@@ -117,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,
) )
@@ -133,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,
);
} }

15
book/art/consensus.msc Normal file
View 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" ] ;
}

View File

@@ -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()"] ;
} }

View File

@@ -1,19 +0,0 @@
+----------+
| Bank-Hash|
+----------+
^
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
: :
: +--------------+ +-------------+ :
: Hash( | Accounts-Hash| + | Block-Merkle| ) :
: +--------------+ +-------------+ :
: ^ :
+~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
|
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
: +---------------+ +---------------+ +---------------+ :
: Hash( | Hash(Account1)| + | Hash(Account2)| + ... + | Hash(AccountN)| ) :
: +---------------+ +---------------+ +---------------+ :
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+

View File

@@ -0,0 +1,18 @@
+------------+
| Bank-Merkle|
+------------+
^ ^
/ \
+-----------------+ +-------------+
| Bank-Diff-Merkle| | Block-Merkle|
+-----------------+ +-------------+
^ ^
/ \
+------+ +--------------------------+
| Hash | | Previous Bank-Diff-Merkle|
+------+ +--------------------------+
^ ^
/ \
+---------------+ +---------------+
| Hash(Account1)| | Hash(Account2)|
+---------------+ +---------------+

View File

@@ -7,7 +7,7 @@
| TVU | | | TVU | |
| | | | | |
| .-------. .------------. .----+---. .---------. | | .-------. .------------. .----+---. .---------. |
.------------. | | Shred | | Retransmit | | Replay | | Storage | | .------------. | | Blob | | Retransmit | | Replay | | Storage | |
| Upstream +----->| Fetch +-->| Stage +-->| Stage +-->| Stage | | | Upstream +----->| Fetch +-->| Stage +-->| Stage +-->| Stage | |
| Validators | | | Stage | | | | | | | | | Validators | | | Stage | | | | | | | |
`------------` | `-------` `----+-------` `----+---` `---------` | `------------` | `-------` `----+-------` `----+---` `---------` |

View File

@@ -1,4 +1,4 @@
.---------------------------------------. .--------------------------------------.
| Validator | | Validator |
| | | |
.--------. | .-------------------. | .--------. | .-------------------. |
@@ -8,23 +8,23 @@
`----+---` | `-------------------` | `----+---` | `-------------------` |
| | ^ | | | ^ |
| | | .----------------. | .------------------. | | | .----------------. | .------------------.
| | | | Gossip Service |<-----------| Validators | | | | | Gossip Service |<----------| Validators |
| | | `----------------` | | | | | | `----------------` | | |
| | | ^ | | | | | | ^ | | |
| | | | | | .------------. | | | | | | | .------------. |
| | .---+---. .----+---. .------------. | | | | | | | .---+---. .----+---. .-----------. | | | | |
| | | Bank |<-+ Replay | | ShredFetch |<------+ Upstream | | | | | Bank |<-+ Replay | | BlobFetch |<------+ Upstream | |
| | | Forks | | Stage | | Stage | | | | Validators | | | | | Forks | | Stage | | Stage | | | | Validators | |
| | `-------` `--------` `--+---------` | | | | | | | `-------` `--------` `--+--------` | | | | |
| | ^ ^ | | | `------------` | | | ^ ^ | | | `------------` |
| | | | v | | | | | | | v | | |
| | | .--+---------. | | | | | | .--+--------. | | |
| | | | Blockstore | | | | | | | | Blocktree | | | |
| | | `------------` | | .------------. | | | | `-----------` | | .------------. |
| | | ^ | | | | | | | | ^ | | | | |
| | | | | | | Downstream | | | | | | | | | Downstream | |
| | .--+--. .-------+---. | | | Validators | | | | .--+--. .-------+---. | | | Validators | |
`-------->| TPU +---->| Broadcast +---------------->| | | `-------->| TPU +---->| Broadcast +--------------->| | |
| `-----` | Stage | | | `------------` | | `-----` | Stage | | | `------------` |
| `-----------` | `------------------` | `-----------` | `------------------`
`---------------------------------------` `--------------------------------------`

View File

@@ -1,34 +0,0 @@
#!/usr/bin/env bash
set -e
cd "$(dirname "$0")"
usage=$(cargo -q run -p solana-cli -- -C ~/.foo --help | sed 's|'"$HOME"'|~|g')
out=${1:-src/cli/usage.md}
cat src/cli/.usage.md.header > "$out"
section() {
declare mark=${2:-"###"}
declare section=$1
read -r name rest <<<"$section"
printf '%s %s
' "$mark" "$name"
printf '```text
%s
```
' "$section"
}
section "$usage" >> "$out"
in_subcommands=0
while read -r subcommand rest; do
[[ $subcommand == "SUBCOMMANDS:" ]] && in_subcommands=1 && continue
if ((in_subcommands)); then
section "$(cargo -q run -p solana-cli -- help "$subcommand" | sed 's|'"$HOME"'|~|g')" "####" >> "$out"
fi
done <<<"$usage">>"$out"

11
book/build-svg.sh Executable file
View 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

View File

@@ -3,14 +3,4 @@ set -e
cd "$(dirname "$0")" cd "$(dirname "$0")"
# md check
find src -name '*.md' -a \! -name SUMMARY.md |
while read -r file; do
if ! grep -q '('"${file#src/}"')' src/SUMMARY.md; then
echo "Error: $file missing from SUMMARY.md"
exit 1
fi
done
make -j"$(nproc)" test make -j"$(nproc)" test

View File

@@ -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) 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)

View File

@@ -1,11 +0,0 @@
#!/usr/bin/env bash
CLI_USAGE_RELPATH="../cli/usage.md"
SED_OMIT_NONMATCHING=$'\nt\nd'
SED_CMD="s:^#### solana-(.*):* [\`\\1\`](${CLI_USAGE_RELPATH}#solana-\\1):${SED_OMIT_NONMATCHING}"
OFFLINE_CMDS=$(grep -E '#### solana-|--signer ' src/cli/usage.md | grep -B1 -- --signer | sed -Ee "$SED_CMD")
# Omit deprecated
grep -vE '\b(pay)\b' <<<"$OFFLINE_CMDS"

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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&#39;
</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

View 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&#39;
</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

View 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&#39;
</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

View 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&#39;
</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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 542 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

View File

@@ -0,0 +1,238 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
width="1320px" height="487px"
viewBox="0 0 1320 487"
xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges"
stroke-width="1" text-rendering="geometricPrecision">
<polygon fill="white" points="101,7 161,7 161,16 101,16"/>
<text x="132" y="16" textLength="59" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
VoteSigner
</text>
<polygon fill="white" points="371,7 419,7 419,16 371,16"/>
<text x="396" y="16" textLength="47" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Validator
</text>
<polygon fill="white" points="639,7 679,7 679,16 639,16"/>
<text x="660" y="16" textLength="38" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Cluster
</text>
<polygon fill="white" points="901,7 945,7 945,16 901,16"/>
<text x="924" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerX
</text>
<polygon fill="white" points="1165,7 1209,7 1209,16 1165,16"/>
<text x="1188" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerY
</text>
<line x1="132" y1="22" x2="132" y2="39" stroke="black"/>
<line x1="396" y1="22" x2="396" y2="39" stroke="black"/>
<line x1="660" y1="22" x2="660" y2="39" stroke="black"/>
<line x1="924" y1="22" x2="924" y2="39" stroke="black"/>
<line x1="1188" y1="22" x2="1188" y2="39" stroke="black"/>
<line x1="132" y1="39" x2="132" y2="67" stroke="black"/>
<line x1="396" y1="39" x2="396" y2="67" stroke="black"/>
<line x1="660" y1="39" x2="660" y2="67" stroke="black"/>
<line x1="924" y1="39" x2="924" y2="67" stroke="black"/>
<line x1="1188" y1="39" x2="1188" y2="67" stroke="black"/>
<polygon fill="white" points="272,39 520,39 520,61 272,61"/>
<line x1="272" y1="39" x2="520" y2="39" stroke="black"/>
<line x1="272" y1="61" x2="520" y2="61" stroke="black"/>
<line x1="272" y1="39" x2="272" y2="61" stroke="black"/>
<line x1="520" y1="39" x2="520" y2="61" stroke="black"/>
<polygon fill="white" points="379,46 411,46 411,55 379,55"/>
<text x="380" y="55" textLength="30" font-family="Helvetica" font-size="12" fill="black">
boot..
</text>
<line x1="132" y1="67" x2="132" y2="106" stroke="black"/>
<line x1="396" y1="67" x2="396" y2="106" stroke="black"/>
<line x1="660" y1="67" x2="660" y2="106" stroke="black"/>
<line x1="924" y1="67" x2="924" y2="106" stroke="black"/>
<line x1="1188" y1="67" x2="1188" y2="106" stroke="black"/>
<line x1="132" y1="82" x2="396" y2="82" stroke="black"/>
<line x1="132" y1="84" x2="396" y2="84" stroke="black"/>
<polygon fill="black" points="396,83 386,89 386,77"/>
<polygon fill="black" points="132,83 142,89 142,77"/>
<polygon fill="white" points="242,68 284,68 284,77 242,77"/>
<text x="243" y="77" textLength="40" font-family="Helvetica" font-size="12" fill="black">
register
</text>
<polygon fill="white" points="262,79 264,79 264,88 262,88"/>
<text x="263" y="88" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="237,90 289,90 289,99 237,99"/>
<text x="238" y="99" textLength="50" font-family="Helvetica" font-size="12" fill="black">
(optional)
</text>
<line x1="132" y1="106" x2="132" y2="134" stroke="black"/>
<line x1="396" y1="106" x2="396" y2="134" stroke="black"/>
<line x1="660" y1="106" x2="660" y2="134" stroke="black"/>
<line x1="924" y1="106" x2="924" y2="134" stroke="black"/>
<line x1="1188" y1="106" x2="1188" y2="134" stroke="black"/>
<line x1="396" y1="117" x2="660" y2="117" stroke="black"/>
<polygon fill="black" points="660,117 650,123 650,111"/>
<polygon fill="white" points="441,107 613,107 613,116 441,116"/>
<text x="442" y="116" textLength="170" font-family="Helvetica" font-size="12" fill="black">
VoteState::Initialize(VoteSigner)
</text>
<line x1="132" y1="134" x2="132" y2="162" stroke="black"/>
<line x1="396" y1="134" x2="396" y2="162" stroke="black"/>
<line x1="660" y1="134" x2="660" y2="162" stroke="black"/>
<line x1="924" y1="134" x2="924" y2="162" stroke="black"/>
<line x1="1188" y1="134" x2="1188" y2="162" stroke="black"/>
<line x1="924" y1="145" x2="660" y2="145" stroke="black"/>
<polygon fill="black" points="660,145 670,151 670,139"/>
<polygon fill="white" points="706,135 877,135 877,144 706,144"/>
<text x="707" y="144" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="162" x2="132" y2="190" stroke="black"/>
<line x1="396" y1="162" x2="396" y2="190" stroke="black"/>
<line x1="660" y1="162" x2="660" y2="190" stroke="black"/>
<line x1="924" y1="162" x2="924" y2="190" stroke="black"/>
<line x1="1188" y1="162" x2="1188" y2="190" stroke="black"/>
<line x1="1188" y1="173" x2="660" y2="173" stroke="black"/>
<polygon fill="black" points="660,173 670,179 670,167"/>
<polygon fill="white" points="838,163 1009,163 1009,172 838,172"/>
<text x="839" y="172" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="190" x2="132" y2="207" stroke="black"/>
<line x1="396" y1="190" x2="396" y2="207" stroke="black"/>
<line x1="660" y1="190" x2="660" y2="207" stroke="black"/>
<line x1="924" y1="190" x2="924" y2="207" stroke="black"/>
<line x1="1188" y1="190" x2="1188" y2="207" stroke="black"/>
<line x1="132" y1="207" x2="132" y2="246" stroke="black"/>
<line x1="396" y1="207" x2="396" y2="246" stroke="black"/>
<line x1="660" y1="207" x2="660" y2="246" stroke="black"/>
<line x1="924" y1="207" x2="924" y2="246" stroke="black"/>
<line x1="1188" y1="207" x2="1188" y2="246" stroke="black"/>
<polygon fill="white" points="272,207 784,207 784,240 272,240"/>
<line x1="272" y1="207" x2="784" y2="207" stroke="black"/>
<line x1="272" y1="240" x2="784" y2="240" stroke="black"/>
<line x1="272" y1="207" x2="272" y2="240" stroke="black"/>
<line x1="784" y1="207" x2="784" y2="240" stroke="black"/>
<polygon fill="white" points="526,208 528,208 528,217 526,217"/>
<text x="527" y="217" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="506,219 549,219 549,228 506,228"/>
<text x="507" y="228" textLength="41" font-family="Helvetica" font-size="12" fill="black">
validate
</text>
<polygon fill="white" points="526,230 528,230 528,239 526,239"/>
<text x="527" y="239" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="246" x2="132" y2="274" stroke="black"/>
<line x1="396" y1="246" x2="396" y2="274" stroke="black"/>
<line x1="660" y1="246" x2="660" y2="274" stroke="black"/>
<line x1="924" y1="246" x2="924" y2="274" stroke="black"/>
<line x1="1188" y1="246" x2="1188" y2="274" stroke="black"/>
<line x1="396" y1="257" x2="132" y2="257" stroke="black"/>
<polygon fill="black" points="132,257 142,263 142,251"/>
<polygon fill="white" points="236,247 291,247 291,256 236,256"/>
<text x="237" y="256" textLength="53" font-family="Helvetica" font-size="12" fill="black">
sign(vote)
</text>
<line x1="132" y1="274" x2="132" y2="302" stroke="black"/>
<line x1="396" y1="274" x2="396" y2="302" stroke="black"/>
<line x1="660" y1="274" x2="660" y2="302" stroke="black"/>
<line x1="924" y1="274" x2="924" y2="302" stroke="black"/>
<line x1="1188" y1="274" x2="1188" y2="302" stroke="black"/>
<line x1="132" y1="285" x2="396" y2="285" stroke="black" stroke-dasharray="2,2"/>
<polygon fill="black" points="396,285 386,291 386,279"/>
<polygon fill="white" points="232,275 295,275 295,284 232,284"/>
<text x="233" y="284" textLength="61" font-family="Helvetica" font-size="12" fill="black">
signed vote
</text>
<line x1="132" y1="302" x2="132" y2="330" stroke="black"/>
<line x1="396" y1="302" x2="396" y2="330" stroke="black"/>
<line x1="660" y1="302" x2="660" y2="330" stroke="black"/>
<line x1="924" y1="302" x2="924" y2="330" stroke="black"/>
<line x1="1188" y1="302" x2="1188" y2="330" stroke="black"/>
<line x1="396" y1="313" x2="660" y2="313" stroke="black"/>
<polygon fill="black" points="660,313 650,319 650,307"/>
<polygon fill="white" points="494,303 561,303 561,312 494,312"/>
<text x="495" y="312" textLength="65" font-family="Helvetica" font-size="12" fill="black">
gossip(vote)
</text>
<line x1="132" y1="330" x2="132" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="330" x2="396" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="330" x2="660" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="330" x2="924" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="330" x2="1188" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="347" x2="132" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="347" x2="396" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="347" x2="660" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="347" x2="924" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="347" x2="1188" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="364" x2="132" y2="414" stroke="black"/>
<line x1="396" y1="364" x2="396" y2="414" stroke="black"/>
<line x1="660" y1="364" x2="660" y2="414" stroke="black"/>
<line x1="924" y1="364" x2="924" y2="414" stroke="black"/>
<line x1="1188" y1="364" x2="1188" y2="414" stroke="black"/>
<polygon fill="white" points="278,364 514,364 514,408 278,408"/>
<polygon fill="white" points="278,364 278,408 272,386"/>
<polygon fill="white" points="514,364 514,408 520,386"/>
<line x1="278" y1="364" x2="514" y2="364" stroke="black"/>
<line x1="278" y1="408" x2="514" y2="408" stroke="black"/>
<line x1="278" y1="364" x2="272" y2="386" stroke="black"/>
<line x1="272" y1="386" x2="278" y2="408" stroke="black"/>
<line x1="514" y1="364" x2="520" y2="386" stroke="black"/>
<line x1="520" y1="386" x2="514" y2="408" stroke="black"/>
<polygon fill="white" points="394,365 396,365 396,374 394,374"/>
<text x="395" y="374" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="383,376 408,376 408,385 383,385"/>
<text x="384" y="385" textLength="23" font-family="Helvetica" font-size="12" fill="black">
max
</text>
<polygon fill="white" points="375,387 415,387 415,396 375,396"/>
<text x="376" y="396" textLength="38" font-family="Helvetica" font-size="12" fill="black">
lockout
</text>
<polygon fill="white" points="394,398 396,398 396,407 394,407"/>
<text x="395" y="407" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="414" x2="132" y2="431" stroke="black"/>
<line x1="396" y1="414" x2="396" y2="431" stroke="black"/>
<line x1="660" y1="414" x2="660" y2="431" stroke="black"/>
<line x1="924" y1="414" x2="924" y2="431" stroke="black"/>
<line x1="1188" y1="414" x2="1188" y2="431" stroke="black"/>
<line x1="132" y1="431" x2="132" y2="459" stroke="black"/>
<line x1="396" y1="431" x2="396" y2="459" stroke="black"/>
<line x1="660" y1="431" x2="660" y2="459" stroke="black"/>
<line x1="924" y1="431" x2="924" y2="459" stroke="black"/>
<line x1="1188" y1="431" x2="1188" y2="459" stroke="black"/>
<line x1="924" y1="442" x2="660" y2="442" stroke="black"/>
<polygon fill="black" points="660,442 670,448 670,436"/>
<polygon fill="white" points="712,432 871,432 871,441 712,441"/>
<text x="713" y="441" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="459" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="459" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="459" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="459" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="459" x2="1188" y2="487" stroke="black"/>
<line x1="1188" y1="470" x2="660" y2="470" stroke="black"/>
<polygon fill="black" points="660,470 670,476 670,464"/>
<polygon fill="white" points="844,460 1003,460 1003,469 844,469"/>
<text x="845" y="469" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="481" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="481" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="481" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="481" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="481" x2="1188" y2="487" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,238 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
width="1320px" height="487px"
viewBox="0 0 1320 487"
xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges"
stroke-width="1" text-rendering="geometricPrecision">
<polygon fill="white" points="101,7 161,7 161,16 101,16"/>
<text x="132" y="16" textLength="59" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
VoteSigner
</text>
<polygon fill="white" points="371,7 419,7 419,16 371,16"/>
<text x="396" y="16" textLength="47" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Validator
</text>
<polygon fill="white" points="639,7 679,7 679,16 639,16"/>
<text x="660" y="16" textLength="38" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Cluster
</text>
<polygon fill="white" points="901,7 945,7 945,16 901,16"/>
<text x="924" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerX
</text>
<polygon fill="white" points="1165,7 1209,7 1209,16 1165,16"/>
<text x="1188" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerY
</text>
<line x1="132" y1="22" x2="132" y2="39" stroke="black"/>
<line x1="396" y1="22" x2="396" y2="39" stroke="black"/>
<line x1="660" y1="22" x2="660" y2="39" stroke="black"/>
<line x1="924" y1="22" x2="924" y2="39" stroke="black"/>
<line x1="1188" y1="22" x2="1188" y2="39" stroke="black"/>
<line x1="132" y1="39" x2="132" y2="67" stroke="black"/>
<line x1="396" y1="39" x2="396" y2="67" stroke="black"/>
<line x1="660" y1="39" x2="660" y2="67" stroke="black"/>
<line x1="924" y1="39" x2="924" y2="67" stroke="black"/>
<line x1="1188" y1="39" x2="1188" y2="67" stroke="black"/>
<polygon fill="white" points="272,39 520,39 520,61 272,61"/>
<line x1="272" y1="39" x2="520" y2="39" stroke="black"/>
<line x1="272" y1="61" x2="520" y2="61" stroke="black"/>
<line x1="272" y1="39" x2="272" y2="61" stroke="black"/>
<line x1="520" y1="39" x2="520" y2="61" stroke="black"/>
<polygon fill="white" points="379,46 411,46 411,55 379,55"/>
<text x="380" y="55" textLength="30" font-family="Helvetica" font-size="12" fill="black">
boot..
</text>
<line x1="132" y1="67" x2="132" y2="106" stroke="black"/>
<line x1="396" y1="67" x2="396" y2="106" stroke="black"/>
<line x1="660" y1="67" x2="660" y2="106" stroke="black"/>
<line x1="924" y1="67" x2="924" y2="106" stroke="black"/>
<line x1="1188" y1="67" x2="1188" y2="106" stroke="black"/>
<line x1="132" y1="82" x2="396" y2="82" stroke="black"/>
<line x1="132" y1="84" x2="396" y2="84" stroke="black"/>
<polygon fill="black" points="396,83 386,89 386,77"/>
<polygon fill="black" points="132,83 142,89 142,77"/>
<polygon fill="white" points="242,68 284,68 284,77 242,77"/>
<text x="243" y="77" textLength="40" font-family="Helvetica" font-size="12" fill="black">
register
</text>
<polygon fill="white" points="262,79 264,79 264,88 262,88"/>
<text x="263" y="88" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="237,90 289,90 289,99 237,99"/>
<text x="238" y="99" textLength="50" font-family="Helvetica" font-size="12" fill="black">
(optional)
</text>
<line x1="132" y1="106" x2="132" y2="134" stroke="black"/>
<line x1="396" y1="106" x2="396" y2="134" stroke="black"/>
<line x1="660" y1="106" x2="660" y2="134" stroke="black"/>
<line x1="924" y1="106" x2="924" y2="134" stroke="black"/>
<line x1="1188" y1="106" x2="1188" y2="134" stroke="black"/>
<line x1="396" y1="117" x2="660" y2="117" stroke="black"/>
<polygon fill="black" points="660,117 650,123 650,111"/>
<polygon fill="white" points="441,107 613,107 613,116 441,116"/>
<text x="442" y="116" textLength="170" font-family="Helvetica" font-size="12" fill="black">
VoteState::Initialize(VoteSigner)
</text>
<line x1="132" y1="134" x2="132" y2="162" stroke="black"/>
<line x1="396" y1="134" x2="396" y2="162" stroke="black"/>
<line x1="660" y1="134" x2="660" y2="162" stroke="black"/>
<line x1="924" y1="134" x2="924" y2="162" stroke="black"/>
<line x1="1188" y1="134" x2="1188" y2="162" stroke="black"/>
<line x1="924" y1="145" x2="660" y2="145" stroke="black"/>
<polygon fill="black" points="660,145 670,151 670,139"/>
<polygon fill="white" points="706,135 877,135 877,144 706,144"/>
<text x="707" y="144" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="162" x2="132" y2="190" stroke="black"/>
<line x1="396" y1="162" x2="396" y2="190" stroke="black"/>
<line x1="660" y1="162" x2="660" y2="190" stroke="black"/>
<line x1="924" y1="162" x2="924" y2="190" stroke="black"/>
<line x1="1188" y1="162" x2="1188" y2="190" stroke="black"/>
<line x1="1188" y1="173" x2="660" y2="173" stroke="black"/>
<polygon fill="black" points="660,173 670,179 670,167"/>
<polygon fill="white" points="838,163 1009,163 1009,172 838,172"/>
<text x="839" y="172" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="190" x2="132" y2="207" stroke="black"/>
<line x1="396" y1="190" x2="396" y2="207" stroke="black"/>
<line x1="660" y1="190" x2="660" y2="207" stroke="black"/>
<line x1="924" y1="190" x2="924" y2="207" stroke="black"/>
<line x1="1188" y1="190" x2="1188" y2="207" stroke="black"/>
<line x1="132" y1="207" x2="132" y2="246" stroke="black"/>
<line x1="396" y1="207" x2="396" y2="246" stroke="black"/>
<line x1="660" y1="207" x2="660" y2="246" stroke="black"/>
<line x1="924" y1="207" x2="924" y2="246" stroke="black"/>
<line x1="1188" y1="207" x2="1188" y2="246" stroke="black"/>
<polygon fill="white" points="272,207 784,207 784,240 272,240"/>
<line x1="272" y1="207" x2="784" y2="207" stroke="black"/>
<line x1="272" y1="240" x2="784" y2="240" stroke="black"/>
<line x1="272" y1="207" x2="272" y2="240" stroke="black"/>
<line x1="784" y1="207" x2="784" y2="240" stroke="black"/>
<polygon fill="white" points="526,208 528,208 528,217 526,217"/>
<text x="527" y="217" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="506,219 549,219 549,228 506,228"/>
<text x="507" y="228" textLength="41" font-family="Helvetica" font-size="12" fill="black">
validate
</text>
<polygon fill="white" points="526,230 528,230 528,239 526,239"/>
<text x="527" y="239" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="246" x2="132" y2="274" stroke="black"/>
<line x1="396" y1="246" x2="396" y2="274" stroke="black"/>
<line x1="660" y1="246" x2="660" y2="274" stroke="black"/>
<line x1="924" y1="246" x2="924" y2="274" stroke="black"/>
<line x1="1188" y1="246" x2="1188" y2="274" stroke="black"/>
<line x1="396" y1="257" x2="132" y2="257" stroke="black"/>
<polygon fill="black" points="132,257 142,263 142,251"/>
<polygon fill="white" points="236,247 291,247 291,256 236,256"/>
<text x="237" y="256" textLength="53" font-family="Helvetica" font-size="12" fill="black">
sign(vote)
</text>
<line x1="132" y1="274" x2="132" y2="302" stroke="black"/>
<line x1="396" y1="274" x2="396" y2="302" stroke="black"/>
<line x1="660" y1="274" x2="660" y2="302" stroke="black"/>
<line x1="924" y1="274" x2="924" y2="302" stroke="black"/>
<line x1="1188" y1="274" x2="1188" y2="302" stroke="black"/>
<line x1="132" y1="285" x2="396" y2="285" stroke="black" stroke-dasharray="2,2"/>
<polygon fill="black" points="396,285 386,291 386,279"/>
<polygon fill="white" points="232,275 295,275 295,284 232,284"/>
<text x="233" y="284" textLength="61" font-family="Helvetica" font-size="12" fill="black">
signed vote
</text>
<line x1="132" y1="302" x2="132" y2="330" stroke="black"/>
<line x1="396" y1="302" x2="396" y2="330" stroke="black"/>
<line x1="660" y1="302" x2="660" y2="330" stroke="black"/>
<line x1="924" y1="302" x2="924" y2="330" stroke="black"/>
<line x1="1188" y1="302" x2="1188" y2="330" stroke="black"/>
<line x1="396" y1="313" x2="660" y2="313" stroke="black"/>
<polygon fill="black" points="660,313 650,319 650,307"/>
<polygon fill="white" points="494,303 561,303 561,312 494,312"/>
<text x="495" y="312" textLength="65" font-family="Helvetica" font-size="12" fill="black">
gossip(vote)
</text>
<line x1="132" y1="330" x2="132" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="330" x2="396" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="330" x2="660" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="330" x2="924" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="330" x2="1188" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="347" x2="132" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="347" x2="396" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="347" x2="660" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="347" x2="924" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="347" x2="1188" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="364" x2="132" y2="414" stroke="black"/>
<line x1="396" y1="364" x2="396" y2="414" stroke="black"/>
<line x1="660" y1="364" x2="660" y2="414" stroke="black"/>
<line x1="924" y1="364" x2="924" y2="414" stroke="black"/>
<line x1="1188" y1="364" x2="1188" y2="414" stroke="black"/>
<polygon fill="white" points="278,364 514,364 514,408 278,408"/>
<polygon fill="white" points="278,364 278,408 272,386"/>
<polygon fill="white" points="514,364 514,408 520,386"/>
<line x1="278" y1="364" x2="514" y2="364" stroke="black"/>
<line x1="278" y1="408" x2="514" y2="408" stroke="black"/>
<line x1="278" y1="364" x2="272" y2="386" stroke="black"/>
<line x1="272" y1="386" x2="278" y2="408" stroke="black"/>
<line x1="514" y1="364" x2="520" y2="386" stroke="black"/>
<line x1="520" y1="386" x2="514" y2="408" stroke="black"/>
<polygon fill="white" points="394,365 396,365 396,374 394,374"/>
<text x="395" y="374" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="383,376 408,376 408,385 383,385"/>
<text x="384" y="385" textLength="23" font-family="Helvetica" font-size="12" fill="black">
max
</text>
<polygon fill="white" points="375,387 415,387 415,396 375,396"/>
<text x="376" y="396" textLength="38" font-family="Helvetica" font-size="12" fill="black">
lockout
</text>
<polygon fill="white" points="394,398 396,398 396,407 394,407"/>
<text x="395" y="407" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="414" x2="132" y2="431" stroke="black"/>
<line x1="396" y1="414" x2="396" y2="431" stroke="black"/>
<line x1="660" y1="414" x2="660" y2="431" stroke="black"/>
<line x1="924" y1="414" x2="924" y2="431" stroke="black"/>
<line x1="1188" y1="414" x2="1188" y2="431" stroke="black"/>
<line x1="132" y1="431" x2="132" y2="459" stroke="black"/>
<line x1="396" y1="431" x2="396" y2="459" stroke="black"/>
<line x1="660" y1="431" x2="660" y2="459" stroke="black"/>
<line x1="924" y1="431" x2="924" y2="459" stroke="black"/>
<line x1="1188" y1="431" x2="1188" y2="459" stroke="black"/>
<line x1="924" y1="442" x2="660" y2="442" stroke="black"/>
<polygon fill="black" points="660,442 670,448 670,436"/>
<polygon fill="white" points="712,432 871,432 871,441 712,441"/>
<text x="713" y="441" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="459" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="459" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="459" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="459" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="459" x2="1188" y2="487" stroke="black"/>
<line x1="1188" y1="470" x2="660" y2="470" stroke="black"/>
<polygon fill="black" points="660,470 670,476 670,464"/>
<polygon fill="white" points="844,460 1003,460 1003,469 844,469"/>
<text x="845" y="469" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="481" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="481" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="481" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="481" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="481" x2="1188" y2="487" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,238 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
width="1320px" height="487px"
viewBox="0 0 1320 487"
xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges"
stroke-width="1" text-rendering="geometricPrecision">
<polygon fill="white" points="101,7 161,7 161,16 101,16"/>
<text x="132" y="16" textLength="59" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
VoteSigner
</text>
<polygon fill="white" points="371,7 419,7 419,16 371,16"/>
<text x="396" y="16" textLength="47" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Validator
</text>
<polygon fill="white" points="639,7 679,7 679,16 639,16"/>
<text x="660" y="16" textLength="38" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Cluster
</text>
<polygon fill="white" points="901,7 945,7 945,16 901,16"/>
<text x="924" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerX
</text>
<polygon fill="white" points="1165,7 1209,7 1209,16 1165,16"/>
<text x="1188" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerY
</text>
<line x1="132" y1="22" x2="132" y2="39" stroke="black"/>
<line x1="396" y1="22" x2="396" y2="39" stroke="black"/>
<line x1="660" y1="22" x2="660" y2="39" stroke="black"/>
<line x1="924" y1="22" x2="924" y2="39" stroke="black"/>
<line x1="1188" y1="22" x2="1188" y2="39" stroke="black"/>
<line x1="132" y1="39" x2="132" y2="67" stroke="black"/>
<line x1="396" y1="39" x2="396" y2="67" stroke="black"/>
<line x1="660" y1="39" x2="660" y2="67" stroke="black"/>
<line x1="924" y1="39" x2="924" y2="67" stroke="black"/>
<line x1="1188" y1="39" x2="1188" y2="67" stroke="black"/>
<polygon fill="white" points="272,39 520,39 520,61 272,61"/>
<line x1="272" y1="39" x2="520" y2="39" stroke="black"/>
<line x1="272" y1="61" x2="520" y2="61" stroke="black"/>
<line x1="272" y1="39" x2="272" y2="61" stroke="black"/>
<line x1="520" y1="39" x2="520" y2="61" stroke="black"/>
<polygon fill="white" points="379,46 411,46 411,55 379,55"/>
<text x="380" y="55" textLength="30" font-family="Helvetica" font-size="12" fill="black">
boot..
</text>
<line x1="132" y1="67" x2="132" y2="106" stroke="black"/>
<line x1="396" y1="67" x2="396" y2="106" stroke="black"/>
<line x1="660" y1="67" x2="660" y2="106" stroke="black"/>
<line x1="924" y1="67" x2="924" y2="106" stroke="black"/>
<line x1="1188" y1="67" x2="1188" y2="106" stroke="black"/>
<line x1="132" y1="82" x2="396" y2="82" stroke="black"/>
<line x1="132" y1="84" x2="396" y2="84" stroke="black"/>
<polygon fill="black" points="396,83 386,89 386,77"/>
<polygon fill="black" points="132,83 142,89 142,77"/>
<polygon fill="white" points="242,68 284,68 284,77 242,77"/>
<text x="243" y="77" textLength="40" font-family="Helvetica" font-size="12" fill="black">
register
</text>
<polygon fill="white" points="262,79 264,79 264,88 262,88"/>
<text x="263" y="88" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="237,90 289,90 289,99 237,99"/>
<text x="238" y="99" textLength="50" font-family="Helvetica" font-size="12" fill="black">
(optional)
</text>
<line x1="132" y1="106" x2="132" y2="134" stroke="black"/>
<line x1="396" y1="106" x2="396" y2="134" stroke="black"/>
<line x1="660" y1="106" x2="660" y2="134" stroke="black"/>
<line x1="924" y1="106" x2="924" y2="134" stroke="black"/>
<line x1="1188" y1="106" x2="1188" y2="134" stroke="black"/>
<line x1="396" y1="117" x2="660" y2="117" stroke="black"/>
<polygon fill="black" points="660,117 650,123 650,111"/>
<polygon fill="white" points="441,107 613,107 613,116 441,116"/>
<text x="442" y="116" textLength="170" font-family="Helvetica" font-size="12" fill="black">
VoteState::Initialize(VoteSigner)
</text>
<line x1="132" y1="134" x2="132" y2="162" stroke="black"/>
<line x1="396" y1="134" x2="396" y2="162" stroke="black"/>
<line x1="660" y1="134" x2="660" y2="162" stroke="black"/>
<line x1="924" y1="134" x2="924" y2="162" stroke="black"/>
<line x1="1188" y1="134" x2="1188" y2="162" stroke="black"/>
<line x1="924" y1="145" x2="660" y2="145" stroke="black"/>
<polygon fill="black" points="660,145 670,151 670,139"/>
<polygon fill="white" points="706,135 877,135 877,144 706,144"/>
<text x="707" y="144" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="162" x2="132" y2="190" stroke="black"/>
<line x1="396" y1="162" x2="396" y2="190" stroke="black"/>
<line x1="660" y1="162" x2="660" y2="190" stroke="black"/>
<line x1="924" y1="162" x2="924" y2="190" stroke="black"/>
<line x1="1188" y1="162" x2="1188" y2="190" stroke="black"/>
<line x1="1188" y1="173" x2="660" y2="173" stroke="black"/>
<polygon fill="black" points="660,173 670,179 670,167"/>
<polygon fill="white" points="838,163 1009,163 1009,172 838,172"/>
<text x="839" y="172" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="190" x2="132" y2="207" stroke="black"/>
<line x1="396" y1="190" x2="396" y2="207" stroke="black"/>
<line x1="660" y1="190" x2="660" y2="207" stroke="black"/>
<line x1="924" y1="190" x2="924" y2="207" stroke="black"/>
<line x1="1188" y1="190" x2="1188" y2="207" stroke="black"/>
<line x1="132" y1="207" x2="132" y2="246" stroke="black"/>
<line x1="396" y1="207" x2="396" y2="246" stroke="black"/>
<line x1="660" y1="207" x2="660" y2="246" stroke="black"/>
<line x1="924" y1="207" x2="924" y2="246" stroke="black"/>
<line x1="1188" y1="207" x2="1188" y2="246" stroke="black"/>
<polygon fill="white" points="272,207 784,207 784,240 272,240"/>
<line x1="272" y1="207" x2="784" y2="207" stroke="black"/>
<line x1="272" y1="240" x2="784" y2="240" stroke="black"/>
<line x1="272" y1="207" x2="272" y2="240" stroke="black"/>
<line x1="784" y1="207" x2="784" y2="240" stroke="black"/>
<polygon fill="white" points="526,208 528,208 528,217 526,217"/>
<text x="527" y="217" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="506,219 549,219 549,228 506,228"/>
<text x="507" y="228" textLength="41" font-family="Helvetica" font-size="12" fill="black">
validate
</text>
<polygon fill="white" points="526,230 528,230 528,239 526,239"/>
<text x="527" y="239" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="246" x2="132" y2="274" stroke="black"/>
<line x1="396" y1="246" x2="396" y2="274" stroke="black"/>
<line x1="660" y1="246" x2="660" y2="274" stroke="black"/>
<line x1="924" y1="246" x2="924" y2="274" stroke="black"/>
<line x1="1188" y1="246" x2="1188" y2="274" stroke="black"/>
<line x1="396" y1="257" x2="132" y2="257" stroke="black"/>
<polygon fill="black" points="132,257 142,263 142,251"/>
<polygon fill="white" points="236,247 291,247 291,256 236,256"/>
<text x="237" y="256" textLength="53" font-family="Helvetica" font-size="12" fill="black">
sign(vote)
</text>
<line x1="132" y1="274" x2="132" y2="302" stroke="black"/>
<line x1="396" y1="274" x2="396" y2="302" stroke="black"/>
<line x1="660" y1="274" x2="660" y2="302" stroke="black"/>
<line x1="924" y1="274" x2="924" y2="302" stroke="black"/>
<line x1="1188" y1="274" x2="1188" y2="302" stroke="black"/>
<line x1="132" y1="285" x2="396" y2="285" stroke="black" stroke-dasharray="2,2"/>
<polygon fill="black" points="396,285 386,291 386,279"/>
<polygon fill="white" points="232,275 295,275 295,284 232,284"/>
<text x="233" y="284" textLength="61" font-family="Helvetica" font-size="12" fill="black">
signed vote
</text>
<line x1="132" y1="302" x2="132" y2="330" stroke="black"/>
<line x1="396" y1="302" x2="396" y2="330" stroke="black"/>
<line x1="660" y1="302" x2="660" y2="330" stroke="black"/>
<line x1="924" y1="302" x2="924" y2="330" stroke="black"/>
<line x1="1188" y1="302" x2="1188" y2="330" stroke="black"/>
<line x1="396" y1="313" x2="660" y2="313" stroke="black"/>
<polygon fill="black" points="660,313 650,319 650,307"/>
<polygon fill="white" points="494,303 561,303 561,312 494,312"/>
<text x="495" y="312" textLength="65" font-family="Helvetica" font-size="12" fill="black">
gossip(vote)
</text>
<line x1="132" y1="330" x2="132" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="330" x2="396" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="330" x2="660" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="330" x2="924" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="330" x2="1188" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="347" x2="132" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="347" x2="396" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="347" x2="660" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="347" x2="924" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="347" x2="1188" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="364" x2="132" y2="414" stroke="black"/>
<line x1="396" y1="364" x2="396" y2="414" stroke="black"/>
<line x1="660" y1="364" x2="660" y2="414" stroke="black"/>
<line x1="924" y1="364" x2="924" y2="414" stroke="black"/>
<line x1="1188" y1="364" x2="1188" y2="414" stroke="black"/>
<polygon fill="white" points="278,364 514,364 514,408 278,408"/>
<polygon fill="white" points="278,364 278,408 272,386"/>
<polygon fill="white" points="514,364 514,408 520,386"/>
<line x1="278" y1="364" x2="514" y2="364" stroke="black"/>
<line x1="278" y1="408" x2="514" y2="408" stroke="black"/>
<line x1="278" y1="364" x2="272" y2="386" stroke="black"/>
<line x1="272" y1="386" x2="278" y2="408" stroke="black"/>
<line x1="514" y1="364" x2="520" y2="386" stroke="black"/>
<line x1="520" y1="386" x2="514" y2="408" stroke="black"/>
<polygon fill="white" points="394,365 396,365 396,374 394,374"/>
<text x="395" y="374" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="383,376 408,376 408,385 383,385"/>
<text x="384" y="385" textLength="23" font-family="Helvetica" font-size="12" fill="black">
max
</text>
<polygon fill="white" points="375,387 415,387 415,396 375,396"/>
<text x="376" y="396" textLength="38" font-family="Helvetica" font-size="12" fill="black">
lockout
</text>
<polygon fill="white" points="394,398 396,398 396,407 394,407"/>
<text x="395" y="407" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="414" x2="132" y2="431" stroke="black"/>
<line x1="396" y1="414" x2="396" y2="431" stroke="black"/>
<line x1="660" y1="414" x2="660" y2="431" stroke="black"/>
<line x1="924" y1="414" x2="924" y2="431" stroke="black"/>
<line x1="1188" y1="414" x2="1188" y2="431" stroke="black"/>
<line x1="132" y1="431" x2="132" y2="459" stroke="black"/>
<line x1="396" y1="431" x2="396" y2="459" stroke="black"/>
<line x1="660" y1="431" x2="660" y2="459" stroke="black"/>
<line x1="924" y1="431" x2="924" y2="459" stroke="black"/>
<line x1="1188" y1="431" x2="1188" y2="459" stroke="black"/>
<line x1="924" y1="442" x2="660" y2="442" stroke="black"/>
<polygon fill="black" points="660,442 670,448 670,436"/>
<polygon fill="white" points="712,432 871,432 871,441 712,441"/>
<text x="713" y="441" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="459" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="459" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="459" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="459" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="459" x2="1188" y2="487" stroke="black"/>
<line x1="1188" y1="470" x2="660" y2="470" stroke="black"/>
<polygon fill="black" points="660,470 670,476 670,464"/>
<polygon fill="white" points="844,460 1003,460 1003,469 844,469"/>
<text x="845" y="469" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="481" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="481" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="481" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="481" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="481" x2="1188" y2="487" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,238 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
width="1320px" height="487px"
viewBox="0 0 1320 487"
xmlns="http://www.w3.org/2000/svg" shape-rendering="crispEdges"
stroke-width="1" text-rendering="geometricPrecision">
<polygon fill="white" points="101,7 161,7 161,16 101,16"/>
<text x="132" y="16" textLength="59" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
VoteSigner
</text>
<polygon fill="white" points="371,7 419,7 419,16 371,16"/>
<text x="396" y="16" textLength="47" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Validator
</text>
<polygon fill="white" points="639,7 679,7 679,16 639,16"/>
<text x="660" y="16" textLength="38" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
Cluster
</text>
<polygon fill="white" points="901,7 945,7 945,16 901,16"/>
<text x="924" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerX
</text>
<polygon fill="white" points="1165,7 1209,7 1209,16 1165,16"/>
<text x="1188" y="16" textLength="43" font-family="Helvetica" font-size="12" fill="black" text-anchor="middle">
StakerY
</text>
<line x1="132" y1="22" x2="132" y2="39" stroke="black"/>
<line x1="396" y1="22" x2="396" y2="39" stroke="black"/>
<line x1="660" y1="22" x2="660" y2="39" stroke="black"/>
<line x1="924" y1="22" x2="924" y2="39" stroke="black"/>
<line x1="1188" y1="22" x2="1188" y2="39" stroke="black"/>
<line x1="132" y1="39" x2="132" y2="67" stroke="black"/>
<line x1="396" y1="39" x2="396" y2="67" stroke="black"/>
<line x1="660" y1="39" x2="660" y2="67" stroke="black"/>
<line x1="924" y1="39" x2="924" y2="67" stroke="black"/>
<line x1="1188" y1="39" x2="1188" y2="67" stroke="black"/>
<polygon fill="white" points="272,39 520,39 520,61 272,61"/>
<line x1="272" y1="39" x2="520" y2="39" stroke="black"/>
<line x1="272" y1="61" x2="520" y2="61" stroke="black"/>
<line x1="272" y1="39" x2="272" y2="61" stroke="black"/>
<line x1="520" y1="39" x2="520" y2="61" stroke="black"/>
<polygon fill="white" points="379,46 411,46 411,55 379,55"/>
<text x="380" y="55" textLength="30" font-family="Helvetica" font-size="12" fill="black">
boot..
</text>
<line x1="132" y1="67" x2="132" y2="106" stroke="black"/>
<line x1="396" y1="67" x2="396" y2="106" stroke="black"/>
<line x1="660" y1="67" x2="660" y2="106" stroke="black"/>
<line x1="924" y1="67" x2="924" y2="106" stroke="black"/>
<line x1="1188" y1="67" x2="1188" y2="106" stroke="black"/>
<line x1="132" y1="82" x2="396" y2="82" stroke="black"/>
<line x1="132" y1="84" x2="396" y2="84" stroke="black"/>
<polygon fill="black" points="396,83 386,89 386,77"/>
<polygon fill="black" points="132,83 142,89 142,77"/>
<polygon fill="white" points="242,68 284,68 284,77 242,77"/>
<text x="243" y="77" textLength="40" font-family="Helvetica" font-size="12" fill="black">
register
</text>
<polygon fill="white" points="262,79 264,79 264,88 262,88"/>
<text x="263" y="88" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="237,90 289,90 289,99 237,99"/>
<text x="238" y="99" textLength="50" font-family="Helvetica" font-size="12" fill="black">
(optional)
</text>
<line x1="132" y1="106" x2="132" y2="134" stroke="black"/>
<line x1="396" y1="106" x2="396" y2="134" stroke="black"/>
<line x1="660" y1="106" x2="660" y2="134" stroke="black"/>
<line x1="924" y1="106" x2="924" y2="134" stroke="black"/>
<line x1="1188" y1="106" x2="1188" y2="134" stroke="black"/>
<line x1="396" y1="117" x2="660" y2="117" stroke="black"/>
<polygon fill="black" points="660,117 650,123 650,111"/>
<polygon fill="white" points="441,107 613,107 613,116 441,116"/>
<text x="442" y="116" textLength="170" font-family="Helvetica" font-size="12" fill="black">
VoteState::Initialize(VoteSigner)
</text>
<line x1="132" y1="134" x2="132" y2="162" stroke="black"/>
<line x1="396" y1="134" x2="396" y2="162" stroke="black"/>
<line x1="660" y1="134" x2="660" y2="162" stroke="black"/>
<line x1="924" y1="134" x2="924" y2="162" stroke="black"/>
<line x1="1188" y1="134" x2="1188" y2="162" stroke="black"/>
<line x1="924" y1="145" x2="660" y2="145" stroke="black"/>
<polygon fill="black" points="660,145 670,151 670,139"/>
<polygon fill="white" points="706,135 877,135 877,144 706,144"/>
<text x="707" y="144" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="162" x2="132" y2="190" stroke="black"/>
<line x1="396" y1="162" x2="396" y2="190" stroke="black"/>
<line x1="660" y1="162" x2="660" y2="190" stroke="black"/>
<line x1="924" y1="162" x2="924" y2="190" stroke="black"/>
<line x1="1188" y1="162" x2="1188" y2="190" stroke="black"/>
<line x1="1188" y1="173" x2="660" y2="173" stroke="black"/>
<polygon fill="black" points="660,173 670,179 670,167"/>
<polygon fill="white" points="838,163 1009,163 1009,172 838,172"/>
<text x="839" y="172" textLength="169" font-family="Helvetica" font-size="12" fill="black">
StakeState::Delegate(Validator)
</text>
<line x1="132" y1="190" x2="132" y2="207" stroke="black"/>
<line x1="396" y1="190" x2="396" y2="207" stroke="black"/>
<line x1="660" y1="190" x2="660" y2="207" stroke="black"/>
<line x1="924" y1="190" x2="924" y2="207" stroke="black"/>
<line x1="1188" y1="190" x2="1188" y2="207" stroke="black"/>
<line x1="132" y1="207" x2="132" y2="246" stroke="black"/>
<line x1="396" y1="207" x2="396" y2="246" stroke="black"/>
<line x1="660" y1="207" x2="660" y2="246" stroke="black"/>
<line x1="924" y1="207" x2="924" y2="246" stroke="black"/>
<line x1="1188" y1="207" x2="1188" y2="246" stroke="black"/>
<polygon fill="white" points="272,207 784,207 784,240 272,240"/>
<line x1="272" y1="207" x2="784" y2="207" stroke="black"/>
<line x1="272" y1="240" x2="784" y2="240" stroke="black"/>
<line x1="272" y1="207" x2="272" y2="240" stroke="black"/>
<line x1="784" y1="207" x2="784" y2="240" stroke="black"/>
<polygon fill="white" points="526,208 528,208 528,217 526,217"/>
<text x="527" y="217" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="506,219 549,219 549,228 506,228"/>
<text x="507" y="228" textLength="41" font-family="Helvetica" font-size="12" fill="black">
validate
</text>
<polygon fill="white" points="526,230 528,230 528,239 526,239"/>
<text x="527" y="239" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="246" x2="132" y2="274" stroke="black"/>
<line x1="396" y1="246" x2="396" y2="274" stroke="black"/>
<line x1="660" y1="246" x2="660" y2="274" stroke="black"/>
<line x1="924" y1="246" x2="924" y2="274" stroke="black"/>
<line x1="1188" y1="246" x2="1188" y2="274" stroke="black"/>
<line x1="396" y1="257" x2="132" y2="257" stroke="black"/>
<polygon fill="black" points="132,257 142,263 142,251"/>
<polygon fill="white" points="236,247 291,247 291,256 236,256"/>
<text x="237" y="256" textLength="53" font-family="Helvetica" font-size="12" fill="black">
sign(vote)
</text>
<line x1="132" y1="274" x2="132" y2="302" stroke="black"/>
<line x1="396" y1="274" x2="396" y2="302" stroke="black"/>
<line x1="660" y1="274" x2="660" y2="302" stroke="black"/>
<line x1="924" y1="274" x2="924" y2="302" stroke="black"/>
<line x1="1188" y1="274" x2="1188" y2="302" stroke="black"/>
<line x1="132" y1="285" x2="396" y2="285" stroke="black" stroke-dasharray="2,2"/>
<polygon fill="black" points="396,285 386,291 386,279"/>
<polygon fill="white" points="232,275 295,275 295,284 232,284"/>
<text x="233" y="284" textLength="61" font-family="Helvetica" font-size="12" fill="black">
signed vote
</text>
<line x1="132" y1="302" x2="132" y2="330" stroke="black"/>
<line x1="396" y1="302" x2="396" y2="330" stroke="black"/>
<line x1="660" y1="302" x2="660" y2="330" stroke="black"/>
<line x1="924" y1="302" x2="924" y2="330" stroke="black"/>
<line x1="1188" y1="302" x2="1188" y2="330" stroke="black"/>
<line x1="396" y1="313" x2="660" y2="313" stroke="black"/>
<polygon fill="black" points="660,313 650,319 650,307"/>
<polygon fill="white" points="494,303 561,303 561,312 494,312"/>
<text x="495" y="312" textLength="65" font-family="Helvetica" font-size="12" fill="black">
gossip(vote)
</text>
<line x1="132" y1="330" x2="132" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="330" x2="396" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="330" x2="660" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="330" x2="924" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="330" x2="1188" y2="347" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="347" x2="132" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="396" y1="347" x2="396" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="660" y1="347" x2="660" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="924" y1="347" x2="924" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="1188" y1="347" x2="1188" y2="364" stroke="black" stroke-dasharray="2,2"/>
<line x1="132" y1="364" x2="132" y2="414" stroke="black"/>
<line x1="396" y1="364" x2="396" y2="414" stroke="black"/>
<line x1="660" y1="364" x2="660" y2="414" stroke="black"/>
<line x1="924" y1="364" x2="924" y2="414" stroke="black"/>
<line x1="1188" y1="364" x2="1188" y2="414" stroke="black"/>
<polygon fill="white" points="278,364 514,364 514,408 278,408"/>
<polygon fill="white" points="278,364 278,408 272,386"/>
<polygon fill="white" points="514,364 514,408 520,386"/>
<line x1="278" y1="364" x2="514" y2="364" stroke="black"/>
<line x1="278" y1="408" x2="514" y2="408" stroke="black"/>
<line x1="278" y1="364" x2="272" y2="386" stroke="black"/>
<line x1="272" y1="386" x2="278" y2="408" stroke="black"/>
<line x1="514" y1="364" x2="520" y2="386" stroke="black"/>
<line x1="520" y1="386" x2="514" y2="408" stroke="black"/>
<polygon fill="white" points="394,365 396,365 396,374 394,374"/>
<text x="395" y="374" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<polygon fill="white" points="383,376 408,376 408,385 383,385"/>
<text x="384" y="385" textLength="23" font-family="Helvetica" font-size="12" fill="black">
max
</text>
<polygon fill="white" points="375,387 415,387 415,396 375,396"/>
<text x="376" y="396" textLength="38" font-family="Helvetica" font-size="12" fill="black">
lockout
</text>
<polygon fill="white" points="394,398 396,398 396,407 394,407"/>
<text x="395" y="407" textLength="0" font-family="Helvetica" font-size="12" fill="black">
</text>
<line x1="132" y1="414" x2="132" y2="431" stroke="black"/>
<line x1="396" y1="414" x2="396" y2="431" stroke="black"/>
<line x1="660" y1="414" x2="660" y2="431" stroke="black"/>
<line x1="924" y1="414" x2="924" y2="431" stroke="black"/>
<line x1="1188" y1="414" x2="1188" y2="431" stroke="black"/>
<line x1="132" y1="431" x2="132" y2="459" stroke="black"/>
<line x1="396" y1="431" x2="396" y2="459" stroke="black"/>
<line x1="660" y1="431" x2="660" y2="459" stroke="black"/>
<line x1="924" y1="431" x2="924" y2="459" stroke="black"/>
<line x1="1188" y1="431" x2="1188" y2="459" stroke="black"/>
<line x1="924" y1="442" x2="660" y2="442" stroke="black"/>
<polygon fill="black" points="660,442 670,448 670,436"/>
<polygon fill="white" points="712,432 871,432 871,441 712,441"/>
<text x="713" y="441" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="459" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="459" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="459" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="459" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="459" x2="1188" y2="487" stroke="black"/>
<line x1="1188" y1="470" x2="660" y2="470" stroke="black"/>
<polygon fill="black" points="660,470 670,476 670,464"/>
<polygon fill="white" points="844,460 1003,460 1003,469 844,469"/>
<text x="845" y="469" textLength="157" font-family="Helvetica" font-size="12" fill="black">
StakeState::RedeemCredits()
</text>
<line x1="132" y1="481" x2="132" y2="487" stroke="black"/>
<line x1="396" y1="481" x2="396" y2="487" stroke="black"/>
<line x1="660" y1="481" x2="660" y2="487" stroke="black"/>
<line x1="924" y1="481" x2="924" y2="487" stroke="black"/>
<line x1="1188" y1="481" x2="1188" y2="487" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,346 @@
<svg class="bob" font-family="arial" font-size="14" height="160" width="848" 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="160" width="848" x="0" y="0"/>
<g>
<line marker-end="url(#triangle)" x1="0" x2="28" y1="104" y2="104"/>
</g>
<g>
<line x1="4" x2="4" y1="12" y2="52"/>
<path d="M 4 52 A 4 4 0 0 0 8 56" fill="none"/>
<path d="M 8 8 A 4 4 0 0 0 4 12" fill="none"/>
</g>
<g>
<line x1="8" x2="104" y1="8" y2="8"/>
<path d="M 108 12 A 4 4 0 0 0 104 8" fill="none"/>
</g>
<g>
<line x1="8" x2="104" y1="56" y2="56"/>
<path d="M 104 56 A 4 4 0 0 0 108 52" fill="none"/>
</g>
<g>
<line x1="36" x2="36" y1="92" y2="116"/>
<path d="M 36 116 A 4 4 0 0 0 40 120" fill="none"/>
<path d="M 40 88 A 4 4 0 0 0 36 92" fill="none"/>
</g>
<g>
<line x1="40" x2="160" y1="88" y2="88"/>
<path d="M 164 92 A 4 4 0 0 0 160 88" fill="none"/>
</g>
<g>
<line x1="40" x2="160" y1="120" y2="120"/>
<path d="M 160 120 A 4 4 0 0 0 164 116" fill="none"/>
</g>
<g>
<line x1="108" x2="108" y1="12" y2="24"/>
<line x1="108" x2="108" y1="24" y2="52"/>
<line marker-end="url(#triangle)" x1="108" x2="140" y1="24" y2="24"/>
</g>
<g>
<line x1="156" x2="156" y1="12" y2="36"/>
<path d="M 156 36 A 4 4 0 0 0 160 40" fill="none"/>
<path d="M 160 8 A 4 4 0 0 0 156 12" fill="none"/>
</g>
<g>
<line x1="160" x2="248" y1="8" y2="8"/>
<path d="M 252 12 A 4 4 0 0 0 248 8" fill="none"/>
</g>
<g>
<line x1="160" x2="248" y1="40" y2="40"/>
<path d="M 248 40 A 4 4 0 0 0 252 36" fill="none"/>
</g>
<g>
<line x1="164" x2="164" y1="92" y2="104"/>
<line x1="164" x2="164" y1="104" y2="116"/>
<line marker-end="url(#triangle)" x1="164" x2="196" y1="104" y2="104"/>
</g>
<g>
<line x1="204" x2="204" y1="92" y2="116"/>
<path d="M 204 116 A 4 4 0 0 0 208 120" fill="none"/>
<path d="M 208 88 A 4 4 0 0 0 204 92" fill="none"/>
</g>
<g>
<line x1="208" x2="280" y1="88" y2="88"/>
<path d="M 284 92 A 4 4 0 0 0 280 88" fill="none"/>
</g>
<g>
<line x1="208" x2="280" y1="120" y2="120"/>
<path d="M 280 120 A 4 4 0 0 0 284 116" fill="none"/>
</g>
<g>
<line x1="252" x2="252" y1="12" y2="24"/>
<line x1="252" x2="252" y1="24" y2="36"/>
<line marker-end="url(#triangle)" x1="252" x2="284" y1="24" y2="24"/>
</g>
<g>
<line x1="284" x2="284" y1="92" y2="104"/>
<line x1="284" x2="284" y1="104" y2="116"/>
<line marker-end="url(#triangle)" x1="284" x2="316" y1="104" y2="104"/>
</g>
<g>
<line x1="292" x2="292" y1="12" y2="36"/>
<path d="M 292 36 A 4 4 0 0 0 296 40" fill="none"/>
<path d="M 296 8 A 4 4 0 0 0 292 12" fill="none"/>
</g>
<g>
<line x1="296" x2="416" y1="8" y2="8"/>
<path d="M 420 12 A 4 4 0 0 0 416 8" fill="none"/>
</g>
<g>
<line x1="296" x2="416" y1="40" y2="40"/>
<path d="M 416 40 A 4 4 0 0 0 420 36" fill="none"/>
</g>
<g>
<line x1="324" x2="324" y1="92" y2="132"/>
<path d="M 324 132 A 4 4 0 0 0 328 136" fill="none"/>
<path d="M 328 88 A 4 4 0 0 0 324 92" fill="none"/>
</g>
<g>
<line x1="328" x2="424" y1="88" y2="88"/>
<path d="M 428 92 A 4 4 0 0 0 424 88" fill="none"/>
</g>
<g>
<line x1="328" x2="424" y1="136" y2="136"/>
<path d="M 424 136 A 4 4 0 0 0 428 132" fill="none"/>
</g>
<g>
<line x1="420" x2="420" y1="12" y2="24"/>
<line x1="420" x2="420" y1="24" y2="36"/>
<line marker-end="url(#triangle)" x1="420" x2="452" y1="24" y2="24"/>
</g>
<g>
<line x1="428" x2="428" y1="92" y2="104"/>
<line x1="428" x2="428" y1="104" y2="132"/>
<line marker-end="url(#triangle)" x1="428" x2="460" y1="104" y2="104"/>
</g>
<g>
<line x1="460" x2="460" y1="12" y2="36"/>
<path d="M 460 36 A 4 4 0 0 0 464 40" fill="none"/>
<path d="M 464 8 A 4 4 0 0 0 460 12" fill="none"/>
</g>
<g>
<line x1="464" x2="576" y1="8" y2="8"/>
<path d="M 580 12 A 4 4 0 0 0 576 8" fill="none"/>
</g>
<g>
<line x1="464" x2="576" y1="40" y2="40"/>
<path d="M 576 40 A 4 4 0 0 0 580 36" fill="none"/>
</g>
<g>
<line x1="468" x2="468" y1="92" y2="116"/>
<path d="M 468 116 A 4 4 0 0 0 472 120" fill="none"/>
<path d="M 472 88 A 4 4 0 0 0 468 92" fill="none"/>
</g>
<g>
<line x1="472" x2="608" y1="88" y2="88"/>
<path d="M 612 92 A 4 4 0 0 0 608 88" fill="none"/>
</g>
<g>
<line x1="472" x2="608" y1="120" y2="120"/>
<path d="M 608 120 A 4 4 0 0 0 612 116" fill="none"/>
</g>
<g>
<line x1="580" x2="580" y1="12" y2="24"/>
<line x1="580" x2="580" y1="24" y2="36"/>
<line marker-end="url(#triangle)" x1="580" x2="612" y1="24" y2="24"/>
</g>
<g>
<line x1="612" x2="612" y1="92" y2="104"/>
<line x1="612" x2="612" y1="104" y2="116"/>
<line marker-end="url(#triangle)" x1="612" x2="636" y1="104" y2="104"/>
</g>
<g>
<line x1="620" x2="620" y1="12" y2="36"/>
<path d="M 620 36 A 4 4 0 0 0 624 40" fill="none"/>
<path d="M 624 8 A 4 4 0 0 0 620 12" fill="none"/>
</g>
<g>
<line x1="624" x2="808" y1="8" y2="8"/>
<path d="M 812 12 A 4 4 0 0 0 808 8" fill="none"/>
</g>
<g>
<line x1="624" x2="808" y1="40" y2="40"/>
<path d="M 808 40 A 4 4 0 0 0 812 36" fill="none"/>
</g>
<g>
<line x1="644" x2="644" y1="92" y2="116"/>
<path d="M 644 116 A 4 4 0 0 0 648 120" fill="none"/>
<path d="M 648 88 A 4 4 0 0 0 644 92" fill="none"/>
</g>
<g>
<line x1="648" x2="784" y1="88" y2="88"/>
<path d="M 788 92 A 4 4 0 0 0 784 88" fill="none"/>
</g>
<g>
<line x1="648" x2="784" y1="120" y2="120"/>
<path d="M 784 120 A 4 4 0 0 0 788 116" fill="none"/>
</g>
<g>
<line x1="788" x2="788" y1="92" y2="116"/>
</g>
<g>
<line x1="812" x2="812" y1="12" y2="24"/>
<line x1="812" x2="812" y1="24" y2="36"/>
<line marker-end="url(#triangle)" x1="812" x2="844" y1="24" y2="24"/>
</g>
<g>
<text x="17" y="28">
PoH
</text>
</g>
<g>
<text x="49" y="28">
verify
</text>
</g>
<g>
<text x="49" y="44">
TVU
</text>
</g>
<g>
<text x="49" y="108">
load
</text>
</g>
<g>
<text x="89" y="108">
accounts
</text>
</g>
<g>
<text x="169" y="28">
sigverify
</text>
</g>
<g>
<text x="217" y="108">
execute
</text>
</g>
<g>
<text x="305" y="28">
lock
</text>
</g>
<g>
<text x="337" y="108">
PoH
</text>
</g>
<g>
<text x="345" y="28">
accounts
</text>
</g>
<g>
<text x="361" y="124">
TPU
</text>
</g>
<g>
<text x="369" y="108">
record
</text>
</g>
<g>
<text x="473" y="28">
validate
</text>
</g>
<g>
<text x="481" y="108">
commit
</text>
</g>
<g>
<text x="537" y="108">
accounts
</text>
</g>
<g>
<text x="545" y="28">
fee
</text>
</g>
<g>
<text x="633" y="28">
allocate
</text>
</g>
<g>
<text x="657" y="108">
unlock
</text>
</g>
<g>
<text x="705" y="28">
new
</text>
</g>
<g>
<text x="713" y="108">
accounts
</text>
</g>
<g>
<text x="737" y="28">
accounts
</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

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