Overview
Comment: | Many unrelated changes |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
5db79120e2e02c858d62af37fe0e054f |
User & Date: | rkeene on 2019-01-11 16:45:25 |
Other Links: | manifest | tags |
Context
2019-01-11
| ||
16:45 | Integrated monocypher changes check-in: eb79ca52ec user: rkeene tags: trunk | |
16:45 | Many unrelated changes check-in: 5db79120e2 user: rkeene tags: trunk | |
2018-12-09
| ||
22:11 | Removed extra auto_paths check-in: 542443e166 user: rkeene tags: trunk | |
Changes
Modified nano.tcl from [58efd19329] to [1cbf28674e].
︙ | ︙ | |||
343 344 345 346 347 348 349 | set pubKey [string toupper [binary encode hex $pubKey]] } return $pubKey } # Low-level block management | | > > > > > > > > | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | set pubKey [string toupper [binary encode hex $pubKey]] } return $pubKey } # Low-level block management proc ::nano::block::dict::toBlock {blockDict args} { array set block $blockDict set blockData "" # Include type if requested set field "-type" if {[lsearch -exact $args $field] != -1} { append blockData [binary format c [lsearch -exact $::nano::block::blockTypes $block(type)]] } switch -- $block(type) { "state" { append blockData [::nano::address::toPublicKey $block(account)] append blockData [binary decode hex $block(previous)] append blockData [::nano::address::toPublicKey $block(representative)] append blockData [binary decode hex [format %032llX $block(balance)]] |
︙ | ︙ | |||
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | append blockData [binary decode hex $block(previous)] append blockData [::nano::address::toPublicKey $block(representative)] } default { return -code error "Invalid block type $block(type)" } } return $blockData } proc ::nano::block::json::toBlock {blockJSON} { set blockDict [::nano::block::dict::fromJSON $blockJSON] tailcall ::nano::block::dict::toBlock $blockDict } proc ::nano::block::dict::fromJSON {blockJSON} { set retval [::json::json2dict $blockJSON] if {[dict get $retval "type"] eq "send"} { set balance [dict get $retval "balance"] set balance [format %lli "0x$balance"] dict set retval "balance" $balance } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < | < < < < < < < < < < < < < < < | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | append blockData [binary decode hex $block(previous)] append blockData [::nano::address::toPublicKey $block(representative)] } default { return -code error "Invalid block type $block(type)" } } foreach field {-work -signature} { if {[lsearch -exact $args $field] == -1} { # It makes no sense to miss an intermediate field, so if # one of them is excluded, stop processing further fields break } set field [string trim $field "-"] set value $block($field) switch -exact -- $field { "work" { if {[string length $value] != $::nano::work::workValueLength} { if {$block(type) eq "state"} { set value [binary format W $value] } else { set value [binary format w $value] } } } "signature" { if {[string length $value] != $::nano::block::signatureLength} { set value [binary decode hex $value] } } } append blockData $value } return $blockData } proc ::nano::block::json::toBlock {blockJSON} { set blockDict [::nano::block::dict::fromJSON $blockJSON] tailcall ::nano::block::dict::toBlock $blockDict } proc ::nano::block::dict::_addWorkData {blockDict} { # Do nothing if this is already set if {[dict exists $blockDict _workData]} { return $blockDict } # Parse out the work data if {[dict get $blockDict "type"] in {send receive change state}} { set workDataBasedOn "previous" } if {[dict get $blockDict "type"] eq "state" && [dict get $blockDict "previous"] eq $::nano::block::zero && [dict get $blockDict "link"] ne $::nano::block::zero} { set workDataBasedOn "account" } if {[dict get $blockDict "type"] eq "open"} { set workDataBasedOn "account" } if {[info exists workDataBasedOn]} { if {$workDataBasedOn eq "previous"} { dict set blockDict "_workData" [dict get $blockDict "previous"] } else { dict set blockDict "_workData" [::nano::address::toPublicKey [dict get $blockDict "account"]] } } return $blockDict } proc ::nano::block::dict::fromJSON {blockJSON} { set retval [::json::json2dict $blockJSON] if {[dict get $retval "type"] eq "send"} { set balance [dict get $retval "balance"] set balance [format %lli "0x$balance"] dict set retval "balance" $balance } set retval [::nano::block::dict::_addWorkData $retval] return $retval } proc ::nano::block::json::fromDict {blockDict} { array set block $blockDict |
︙ | ︙ | |||
690 691 692 693 694 695 696 | set addArgs_fromPublicKey [list] if {$addressPrefix eq "xrb_"} { lappend addArgs_fromPublicKey "-xrb" } switch -- $block(type) { "state" { | | | | | | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | set addArgs_fromPublicKey [list] if {$addressPrefix eq "xrb_"} { lappend addArgs_fromPublicKey "-xrb" } switch -- $block(type) { "state" { binary scan $blockData a32H64a32H32H64H128Wu \ block(account) \ block(previous) \ block(representative) \ block(balance) \ block(link) \ block(signature) \ block(work) } "open" { binary scan $blockData H64a32a32H128wu \ block(source) \ block(representative) \ block(account) \ block(signature) \ block(work) set block(_workData) $block(account) } "send" { binary scan $blockData H64a32H32H128wu \ block(previous) \ block(destination) \ block(balance) \ block(signature) \ block(work) set block(_workData) $block(previous) } "receive" { binary scan $blockData H64H64H128wu \ block(previous) \ block(source) \ block(signature) \ block(work) set block(_workData) $block(previous) } "change" { binary scan $blockData H64a32H128wu \ block(previous) \ block(representative) \ block(signature) \ block(work) set block(_workData) $block(previous) } |
︙ | ︙ | |||
754 755 756 757 758 759 760 761 762 763 764 765 766 767 | switch -exact -- $field { "account" - "representative" - "link_as_account" - "destination" { set block($field) [::nano::address::fromPublicKey $block($field) {*}$addArgs_fromPublicKey] } "balance" { set block($field) [format %lli "0x$block($field)"] } } } return [array get block] } | > > > | 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | switch -exact -- $field { "account" - "representative" - "link_as_account" - "destination" { set block($field) [::nano::address::fromPublicKey $block($field) {*}$addArgs_fromPublicKey] } "balance" { set block($field) [format %lli "0x$block($field)"] } "work" { set block($field) [format %016llx $block($field)] } } } return [array get block] } |
︙ | ︙ | |||
976 977 978 979 980 981 982 | } set retval [::nano::block::json::fromDict $retval] return $retval } | | > > > > | > > > | 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 | } set retval [::nano::block::json::fromDict $retval] return $retval } proc ::nano::block::dict::verifySignature {blockDict {publicKey ""}} { if {$publicKey eq ""} { if {![dict exists $blockDict "account"]} { error "Account or public key must be specified" } else { set publicKey [::nano::address::toPublicKey [dict get $blockDict account]] } } set signature [dict get $blockDict signature] set blockDict [_addBlockHash $blockDict] set blockHash [dict get $blockDict _blockHash] tailcall ::nano::block::verifyBlockHash $blockHash $signature $publicKey |
︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 | default { return -code error "Invalid option: $arg" } } } set blockDict [_addBlockHash $blockDict] set blockHash [dict get $blockDict _workData] set work [::nano::work::fromWorkData $blockHash -binary] if {$outputMode eq "work"} { if {$outputFormat eq "hex"} { | > | 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 | default { return -code error "Invalid option: $arg" } } } set blockDict [_addBlockHash $blockDict] set blockDict [_addWorkData $blockDict] set blockHash [dict get $blockDict _workData] set work [::nano::work::fromWorkData $blockHash -binary] if {$outputMode eq "work"} { if {$outputFormat eq "hex"} { |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 | set retval [::nano::block::json::fromDict $retval] return $retval } proc ::nano::block::dict::validateWork {blockDict} { set blockDict [_addBlockHash $blockDict] set blockHash [dict get $blockDict _workData] set work [dict get $blockDict work] tailcall ::nano::work::validate $blockHash $work } | > | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | set retval [::nano::block::json::fromDict $retval] return $retval } proc ::nano::block::dict::validateWork {blockDict} { set blockDict [_addBlockHash $blockDict] set blockDict [_addWorkData $blockDict] set blockHash [dict get $blockDict _workData] set work [dict get $blockDict work] tailcall ::nano::work::validate $blockHash $work } |
︙ | ︙ | |||
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 | proc ::nano::block::dict::genesis {network} { if {![info exists ::nano::block::dict::genesis($network)]} { set ::nano::block::dict::genesis($network) [::nano::block::dict::fromJSON [::nano::block::json::genesis $network]] } return $::nano::block::dict::genesis($network) } # send from <account> to <account> previousBalance <balance> # amount <amount> sourceBlock <sourceBlockHash> # previous <previousBlockHash> ?representative <representative>? proc ::nano::block::create::send {args} { array set block $args if {![info exists block(representative)]} { set block(representative) $block(from) } set block(balance) [expr {$block(previousBalance) - $block(amount)}] | > > > > > > > > > > > > > > > > > > | > > > > > > > > | | | | | | | | | > | 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 | proc ::nano::block::dict::genesis {network} { if {![info exists ::nano::block::dict::genesis($network)]} { set ::nano::block::dict::genesis($network) [::nano::block::dict::fromJSON [::nano::block::json::genesis $network]] } return $::nano::block::dict::genesis($network) } proc ::nano::block::dict::printable {blockDict} { dict for {key value} $blockDict { switch -exact -- $key { "_workData" { if {[string length $value] == $::nano::block::hashLength} { set value [binary encode hex $value] dict set blockDict $key $value } } } } dict unset blockDict _blockData return $blockDict } # send from <account> to <account> previousBalance <balance> # amount <amount> sourceBlock <sourceBlockHash> # previous <previousBlockHash> ?representative <representative>? proc ::nano::block::create::send {args} { array set block $args if {![info exists block(representative)]} { set block(representative) $block(from) } set block(balance) [expr {$block(previousBalance) - $block(amount)}] if {[info exists block(-legacy)] && $block(-legacy)} { set blockDict [dict create \ "type" send \ "previous" $block(previous) \ "balance" $block(balance) \ "_workData" $block(previous) \ "_comment" "Legacy send $block(amount) raw from $block(from) to $block(to)" \ ] } else { set blockDict [dict create \ "type" state \ "account" $block(from) \ "previous" $block(previous) \ "representative" $block(representative) \ "balance" $block(balance) \ "link_as_account" $block(to) \ "_workData" $block(previous) \ "_comment" "Send $block(amount) raw from $block(from) to $block(to)" \ ] } if {[info exists block(signKey)]} { set blockDict [::nano::block::dict::sign $blockDict $block(signKey) -update] } if {[info exists block(-json)] && $block(-json)} { return [::nano::block::json::fromDict $blockDict] |
︙ | ︙ | |||
1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 | array set block $args if {![info exists block(representative)]} { set block(representative) $block(to) } if {![info exists block(previous)]} { set block(previous) $::nano::block::zero set block(previousBalance) 0 set block(_workData) [::nano::address::toPublicKey $block(to) -hex] } else { set block(_workData) $block(previous) } set block(balance) [expr {$block(previousBalance) + $block(amount)}] | > > > > | > > > > > > > > > > > > > > > > > > | | | | | | | | | > | 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 | array set block $args if {![info exists block(representative)]} { set block(representative) $block(to) } if {![info exists block(previous)]} { set isOpen true set block(previous) $::nano::block::zero set block(previousBalance) 0 set block(_workData) [::nano::address::toPublicKey $block(to) -hex] } else { set isOpen false set block(_workData) $block(previous) } set block(balance) [expr {$block(previousBalance) + $block(amount)}] if {[info exists block(-legacy)] && $block(-legacy)} { if {$isOpen} { set blockDict [dict create \ "type" open \ "account" $block(to) \ "representative" $block(representative) \ "source" $block(sourceBlock) \ "_workData" $block(_workData) \ "_comment" "Legacy open + receive of $block(amount) raw on $block(to) from hash $block(sourceBlock)" \ ] } else { set blockDict [dict create \ "type" receive \ "source" $block(sourceBlock) \ "previous" $block(previous) \ "_workData" $block(_workData) \ "_comment" "Legacy receive $block(amount) raw on $block(to) from hash $block(sourceBlock)" \ ] } } else { set blockDict [dict create \ "type" state \ "account" $block(to) \ "previous" $block(previous) \ "representative" $block(representative) \ "balance" $block(balance) \ "link" $block(sourceBlock) \ "_workData" $block(_workData) \ "_comment" "Receive $block(amount) raw on $block(to) from hash $block(sourceBlock)" \ ] } if {[info exists block(signKey)]} { set blockDict [::nano::block::dict::sign $blockDict $block(signKey) -update] } if {[info exists block(-json)] && $block(-json)} { return [::nano::block::json::fromDict $blockDict] |
︙ | ︙ | |||
2422 2423 2424 2425 2426 2427 2428 | proc ::nano::protocol::parse::confirm_req {extensions blockData} { set blockTypeID [expr {($extensions >> 8) & 0x0f}] set blockType [::nano::block::typeFromTypeID $blockTypeID] set blockDict [::nano::block::dict::fromBlock $blockData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] | < < < < | | | 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 | proc ::nano::protocol::parse::confirm_req {extensions blockData} { set blockTypeID [expr {($extensions >> 8) & 0x0f}] set blockType [::nano::block::typeFromTypeID $blockTypeID] set blockDict [::nano::block::dict::fromBlock $blockData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] set retval(blockType) $blockType set retval(block) [::nano::block::dict::printable $blockDict] set retval(hash) $blockHash return [array get retval] } proc ::nano::protocol::parse::confirm_ack {extensions blockData} { set blockTypeID [expr {($extensions >> 8) & 0x0f}] set blockType [::nano::block::typeFromTypeID $blockTypeID] # Header binary scan $blockData H64H128wua* \ retval(voteAccount) \ retval(voteSignature) \ retval(voteSequence) \ newBlockData set blockData $newBlockData |
︙ | ︙ | |||
2474 2475 2476 2477 2478 2479 2480 | append signedData [binary decode hex $hash] } } else { set blockDict [::nano::block::dict::fromBlock $blockData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] append signedData [binary decode hex $blockHash] | < < < < | | 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 | append signedData [binary decode hex $hash] } } else { set blockDict [::nano::block::dict::fromBlock $blockData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] append signedData [binary decode hex $blockHash] set retval(blockType) $blockType set retval(hashes) [list $blockHash] set retval(block) [::nano::block::dict::printable $blockDict] } # Add the sequence number to the signed data append signedData [binary format w $retval(voteSequence)] # Verify signature of the hash set valid false |
︙ | ︙ | |||
2520 2521 2522 2523 2524 2525 2526 | set retval(valid) true } return [array get retval] } proc ::nano::protocol::create {network messageType args} { | | | | 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 | set retval(valid) true } return [array get retval] } proc ::nano::protocol::create {network messageType args} { set versionUsing 15 set versionMin 14 set versionMax $versionUsing set messageInfo(extensions) 0 set messageInfo(blockType) 0 set messageType [string tolower $messageType] set messageTypeID [lsearch -exact $::nano::network::messageTypes $messageType] if {$messageTypeID == -1} { |
︙ | ︙ | |||
3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 | set peerSock [::nano::node::createSocket realtime $address $port] #puts "Querying $peerSock with node_id_handshake (1)" ::nano::network::client $peerSock "node_id_handshake" query -query $node_id_nonce } } } return "" } proc ::nano::protocol::parse::node_id_handshake {extensions messageData} { array set result [list] set flags [nano::protocol::extensions::get "node_id_handshake" $extensions] | > > > > > > > > | 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 | set peerSock [::nano::node::createSocket realtime $address $port] #puts "Querying $peerSock with node_id_handshake (1)" ::nano::network::client $peerSock "node_id_handshake" query -query $node_id_nonce } } } # Stats incr ::nano::node::stats([list keepalive count]) incr ::nano::node::stats([list keepalive peers]) [llength $peers] foreach peer $peers { set ::nano::node::_stats_seen_hashes([list keepalive $peer]) 1 } set ::nano::node::stats([list keepalive peersUnique]) [llength [array names ::nano::node::_stats_seen_hashes [list keepalive *]]] return "" } proc ::nano::protocol::parse::node_id_handshake {extensions messageData} { array set result [list] set flags [nano::protocol::extensions::get "node_id_handshake" $extensions] |
︙ | ︙ | |||
3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 | proc ::nano::network::server::node_id_handshake {messageDict} { set retval "" if {"query" in [dict get $messageDict flags]} { set query [dict get $messageDict query] set clientID [dict get $::nano::node::configuration node client_id_private_key] set retval [dict create "invoke_client" [list node_id_handshake response -privateKey $clientID -query [binary decode hex $query]]] } if {"response" in [dict get $messageDict flags]} { set peerInfo [dict get $messageDict socket remote] set peerAddress [lindex $peerInfo 0] set peerPort [lindex $peerInfo 1] set peer [dict create address $peerAddress port $peerPort] # XXX:TODO: Verify the nonce if {![info exists ::nano::node::_node_id_nonces($peer)]} { return "" } set sentNonce $::nano::node::_node_id_nonces($peer) unset ::nano::node::_node_id_nonces($peer) # Add the peer to our list of peers #puts "Got node_id_handshake response from $peer" set ::nano::node::peers($peer) [dict create lastSeen [clock seconds]] } return $retval } proc ::nano::network::server::confirm_ack {messageDict} { # keep statistics dict with messageDict {} incr ::nano::node::stats([list confirm_ack valid $valid]) if {!$valid} { | > > > > > > > > > > > > > | 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 | proc ::nano::network::server::node_id_handshake {messageDict} { set retval "" if {"query" in [dict get $messageDict flags]} { set query [dict get $messageDict query] set clientID [dict get $::nano::node::configuration node client_id_private_key] set retval [dict create "invoke_client" [list node_id_handshake response -privateKey $clientID -query [binary decode hex $query]]] # Stats incr ::nano::node::stats([list node_id_handshake query count]) } if {"response" in [dict get $messageDict flags]} { set peerInfo [dict get $messageDict socket remote] set peerAddress [lindex $peerInfo 0] set peerPort [lindex $peerInfo 1] set peer [dict create address $peerAddress port $peerPort] # XXX:TODO: Verify the nonce if {![info exists ::nano::node::_node_id_nonces($peer)]} { return "" } set sentNonce $::nano::node::_node_id_nonces($peer) unset ::nano::node::_node_id_nonces($peer) # Add the peer to our list of peers #puts "Got node_id_handshake response from $peer" set ::nano::node::peers($peer) [dict create lastSeen [clock seconds]] # Stats incr ::nano::node::stats([list node_id_handshake response count]) set ::nano::node::_stats_seen_hashes([list node_id_handshake [dict get $messageDict key]]) 1 set ::nano::node::stats([list node_id_handshake response uniqueKeys]) [llength [array names ::nano::node::_stats_seen_hashes [list node_id_handshake *]]] } return $retval } proc ::nano::network::server::confirm_req {messageDict} { incr ::nano::node::stats([list confirm_req]) return "" } proc ::nano::network::server::confirm_ack {messageDict} { # keep statistics dict with messageDict {} incr ::nano::node::stats([list confirm_ack valid $valid]) if {!$valid} { |
︙ | ︙ | |||
3334 3335 3336 3337 3338 3339 3340 | proc ::nano::protocol::parse::publish {extensions messageData} { set blockTypeID [expr {($extensions >> 8) & 0x0f}] set blockType [::nano::block::typeFromTypeID $blockTypeID] set blockDict [::nano::block::dict::fromBlock $messageData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] | < < < < | > > > > > > > > > > > > > | > > | > > > > > > > > > > < > | 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 | proc ::nano::protocol::parse::publish {extensions messageData} { set blockTypeID [expr {($extensions >> 8) & 0x0f}] set blockType [::nano::block::typeFromTypeID $blockTypeID] set blockDict [::nano::block::dict::fromBlock $messageData -type=$blockType] set blockHash [::nano::block::dict::toHash $blockDict -hex] set retval(blockType) $blockType set retval(block) [::nano::block::dict::printable $blockDict] set retval(hash) $blockHash return [array get retval] } proc ::nano::internal::boolean {value} { if {$value} { return true } else { return false } } proc ::nano::network::server::publish {messageDict} { #puts "block: [binary encode hex $blockData]" #9e1272edade3c247c738a4bd303eb0cfc3da298444bb9d13b8ffbced34ff036f4e1ff833324efc81c237776242928ef76a2cdfaa53f4c4530ee39bfff1977e26e382dd09ec8cafc2427cf817e9afe1f372ce81085ab4feb1f3de1f25ee818e5d000000008fc492fd20e57d048e000000204e7a62f25df739eaa224d403cb107b3f9caa0280113b0328fad3b402c465169006f988549a8b1e20e0a09b4b4dcae5397f6fcc4d507675f58c2b29ae02341b0a4fe562201a61bf27481aa4567c287136b4fd26b4840c93c42c7d1f5c518503d68ec561af4b8cf8 #9e1272edade3c247c738a4bd303eb0cfc3da298444bb9d13b8ffbced34ff036fa5e3647d3d296ec72baea013ba7fa1bf5c3357c33c90196f078ba091295e6e03e382dd09ec8cafc2427cf817e9afe1f372ce81085ab4feb1f3de1f25ee818e5d000000008fb2604ebd1fe098b8000000204e7a62f25df739eaa224d403cb107b3f9caa0280113b0328fad3b402c465165287cd9c61752dc9d011f666534dbdc10461e927503f9599791d73b1cca7fdc032d76db3f91e5b5c3d6206fa48b01bd08da4a89f2e880242e9917cfc3db80d0b9bfe8e6d1dd183d5 if {[catch { set hash [dict get $messageDict hash] set block [dict get $messageDict block] switch -exact -- [dict get $block type] { "send" - "receive" - "change" { set valid maybe } "open" - "state" { set valid false } } catch { set valid [::nano::internal::boolean [::nano::block::dict::verifySignature $block]] } set validWork [::nano::internal::boolean [::nano::block::dict::validateWork $block]] incr ::nano::node::stats([list publish valid $valid]) incr ::nano::node::stats([list publish validWork $validWork]) incr ::nano::node::stats([list publish type [dict get $block type]]) set ::nano::node::_stats_seen_hashes([list publish $hash]) 1 set ::nano::node::stats([list publish unique]) [llength [array names ::nano::node::_stats_seen_hashes [list publish *]]] }]} { puts $::errorInfo } return "" } # Namespace ::nano::protocol::parse deals with the network level protocol (outside the node) # Namespace ::nano::network::server deals with the node's actual interaction with the network proc ::nano::protocol::parse {message} { |
︙ | ︙ | |||
3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 | return true } proc ::nano::rpc::client {action args} { ::nano::rpc::client::init set rpcURL [dict get $::nano::rpc::client::config "-url"] set jsonArgs [list] foreach {key value} $args { switch -exact -- $key { "-count" {} "-accounts" { set valueAsStrings [lmap valueItem $value { json::write string $valueItem }] set value [json::write array {*}$valueAsStrings] } default { set value [json::write string $value] } } set key [string range $key 1 end] lappend jsonArgs $key $value } set query [json::write object action [json::write string $action] {*}$jsonArgs] catch { | > > > > > > > > > > > > > > > > > > > > > > > | > | > | 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 | return true } proc ::nano::rpc::client {action args} { ::nano::rpc::client::init set rpcURL [dict get $::nano::rpc::client::config "-url"] switch -exact -- $action { "version" - "block" { set timeout 1000 } } set timeoutArgs [list] if {[info exists timeout]} { lappend timeoutArgs -timeout $timeout } set jsonArgs [list] set outputFormat "dict" foreach {key value} $args { switch -exact -- $key { "-outputformat" { switch -exact -- $value { "dict" - "json" { set outputFormat $value } default { error "Invalid output format: $value" } } continue } "-count" {} "-accounts" { set valueAsStrings [lmap valueItem $value { json::write string $valueItem }] set value [json::write array {*}$valueAsStrings] } default { set value [json::write string $value] } } set key [string range $key 1 end] lappend jsonArgs $key $value } set query [json::write object action [json::write string $action] {*}$jsonArgs] catch { set token [http::geturl $rpcURL -query $query {*}$timeoutArgs] set ncode [http::ncode $token] set data [http::data $token] } error if {![info exists data]} { set ncode -1 set data $error } if {[info exists token]} { http::cleanup $token } if {$ncode ne "200"} { return -code error "$ncode: $data" } if {$outputFormat eq "dict"} { set data [json::json2dict $data] } return $data } # Account balance manipulation proc ::nano::balance::toUnit {raw toUnit {decimals 0}} { if {![string is entier -strict $raw]} { |
︙ | ︙ | |||
3939 3940 3941 3942 3943 3944 3945 3946 | set nodeIDPublic [::nano::key::publicKeyFromPrivateKey $nodeIDPrivate -hex] return $nodeIDPublic } proc {::nano::node::cli::show logs} args { return [join [lrange $::nano::node::log end-19 end] "\n"] } | | < | | | | | > > > > > > > > > > > > > > > > > > > > > | 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 | set nodeIDPublic [::nano::key::publicKeyFromPrivateKey $nodeIDPrivate -hex] return $nodeIDPublic } proc {::nano::node::cli::show logs} args { return [join [lrange $::nano::node::log end-19 end] "\n"] } proc {::nano::node::cli::clear stats} args { set ::nano::node::statsStartTime [clock seconds] unset -nocomplain ::nano::node::stats unset -nocomplain ::nano::node::_stats_seen_hashes unset -nocomplain ::nano::node::_stats_seen_hashes_by_rep return } proc {::nano::node::cli::clear peers} args { set ::nano::node::statsStartTime [clock seconds] unset -nocomplain ::nano::node::peers array set ::nano::node::peers [list] return } proc {::nano::node::cli::show stats} args { set now [clock seconds] set statsStart $::nano::node::statsStartTime set uptimeStats [expr {$now - $statsStart}] set quiet false if {!$quiet} { set format {%-19s: %s} puts [format $format "Stats last cleared" "[::nano::_cli::interval $uptimeStats] ago"] puts "" } set globalOnly false if {[lindex $args 0] eq "-global"} { set globalOnly true } |
︙ | ︙ | |||
3986 3987 3988 3989 3990 3991 3992 | set maxKeyLen $keyLen } set localStats($key) $val } foreach {key val} [lsort -stride 2 -dictionary [array get localStats]] { | > > > > > > > > > | | 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 | set maxKeyLen $keyLen } set localStats($key) $val } foreach {key val} [lsort -stride 2 -dictionary [array get localStats]] { set extra "" if {![regexp { (min|max)[A-Z]} $key]} { if {[string is entier -strict $val]} { set valAvg [expr {($val * 1.0) / $uptimeStats}] set valAvg [format %.4f $valAvg] set extra " (avg: $valAvg per second)" } } puts [format "%-${maxKeyLen}s = %s%s" $key $val $extra] } return } proc {::nano::node::cli::show version} {} { return [package present nano] |
︙ | ︙ | |||
4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 | set endTime [clock seconds] set blocksPulled [::nano::node::bootstrap::TMP_LEDGER_BLOCKHASHCOUNT] set delta [expr {$endTime - $startTime}] puts "Pulled $blocksPulled blocks in [::nano::_cli::interval $delta]" } proc ::nano::node::cli::show {args} { tailcall ::nano::_cli::multiword node show {*}$args } proc ::nano::node::cli::config {args} { tailcall ::nano::_cli::multiword node config {*}$args | > > > > | 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 | set endTime [clock seconds] set blocksPulled [::nano::node::bootstrap::TMP_LEDGER_BLOCKHASHCOUNT] set delta [expr {$endTime - $startTime}] puts "Pulled $blocksPulled blocks in [::nano::_cli::interval $delta]" } proc ::nano::node::cli::clear {args} { tailcall ::nano::_cli::multiword node clear {*}$args } proc ::nano::node::cli::show {args} { tailcall ::nano::_cli::multiword node show {*}$args } proc ::nano::node::cli::config {args} { tailcall ::nano::_cli::multiword node config {*}$args |
︙ | ︙ | |||
4126 4127 4128 4129 4130 4131 4132 | return [join $response "\n"] } # RPC CLI proc ::nano::rpc::cli {args} { tailcall ::nano::_cli rpc -prompt { if {![info exists ::nano::rpc::cli::_cached_network]} { | > | > > | | | > > | > > > > > | > > > | 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 | return [join $response "\n"] } # RPC CLI proc ::nano::rpc::cli {args} { tailcall ::nano::_cli rpc -prompt { if {![info exists ::nano::rpc::cli::_cached_network]} { catch { set ::nano::rpc::cli::_cached_network [{::nano::rpc::cli::show network}] } } if {![info exists ::nano::rpc::cli::_cached_version]} { catch { set ::nano::rpc::cli::_cached_version [{::nano::rpc::cli::show version} -vendor] } } if {[info exists ::nano::rpc::cli::_cached_network]} { set network $::nano::rpc::cli::_cached_network } else { set network "<unknown>" } if {[info exists ::nano::rpc::cli::_cached_version]} { set version $::nano::rpc::cli::_cached_version } else { set version "<unknown>" } return "\[$network\] nano-rpc $version> " } {*}$args } proc ::nano::rpc::cli::help args { tailcall ::nano::_cli::help rpc "" {*}$args |
︙ | ︙ | |||
4213 4214 4215 4216 4217 4218 4219 4220 | } lappend response [join $bootstrapResponse "\n"] } } if {[lsearch -exact $args "-blocks"] != -1} { set blockCount [::nano::rpc::client block_count] lappend blocksResponse "Blocks:" | > > > | | > | | 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 | } lappend response [join $bootstrapResponse "\n"] } } if {[lsearch -exact $args "-blocks"] != -1} { set blockCount [::nano::rpc::client block_count] set blockCountInfoCount [dict get $blockCount count] set blockCountInfoUnchecked [dict get $blockCount unchecked] set blockCountInfoTotal [expr {$blockCountInfoCount + $blockCountInfoUnchecked}] lappend blocksResponse "Blocks:" lappend blocksResponse " Count = $blockCountInfoCount" lappend blocksResponse " Unchecked = $blockCountInfoUnchecked" lappend blocksResponse " Total = $blockCountInfoTotal" lappend response [join $blocksResponse "\n"] } return [join $response "\n\n"] } proc {::nano::rpc::cli::show network} args { foreach network {main beta} { set genesisBlock [::nano::block::dict::genesis $network] set genesisBlockHash [::nano::block::dict::toHash $genesisBlock -hex] catch { set check [dict create] set check [::nano::rpc::client block -hash $genesisBlockHash] } if {[dict exists $check contents]} { return $network } } error "Unable to locate genesis block" } proc {::nano::rpc::cli::show version} args { set versions [::nano::rpc::client version] set vendor [dict get $versions node_vendor] set vendorVersion [lindex [split $vendor] end] |
︙ | ︙ | |||
4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 | set peer [list address $peer port $peerPort] lappend result " $peer: version $peerVersion" } return [join $result "\n"] } # Export namespaces namespace eval ::nano::node::cli { namespace export -clear * } namespace eval ::nano::rpc::cli { | > > > > > > > > > > > > > > > > > > > > > > > > > > | 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 | set peer [list address $peer port $peerPort] lappend result " $peer: version $peerVersion" } return [join $result "\n"] } proc {::nano::rpc::cli::show node-id} args { set id [dict get [::nano::rpc::client node_id] "public"] return $id } proc ::nano::rpc::cli::rpc {action args} { set format "json" set endmarker [lsearch -exact $args "--"] if {$endmarker != -1} { set field [lrange $args $endmarker+1 end] set args [lrange $args 0 $endmarker-1] set format "dict" } set result [::nano::rpc::client $action -outputformat $format {*}$args] if {$format eq "json"} { set result [string trim $result "\n\r"] } if {[info exists field]} { set result [dict get $result {*}$field] } return $result } # Export namespaces namespace eval ::nano::node::cli { namespace export -clear * } namespace eval ::nano::rpc::cli { |
︙ | ︙ |