Overview
Comment: | Better peer tracking and block verification |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
995dbd8993b43b8b63eb8750b7e9a0db |
User & Date: | rkeene on 2019-01-22 17:51:51 |
Other Links: | manifest | tags |
Context
2019-01-22
| ||
17:55 | Check to see if -mmpx can actually be linked in check-in: ad21e0c8c7 user: rkeene tags: trunk | |
17:51 | Better peer tracking and block verification check-in: 995dbd8993 user: rkeene tags: trunk | |
17:47 | Updated kit building check-in: 572ef3e921 user: rkeene tags: trunk | |
Changes
Modified nano.tcl from [42c9c4c386] to [62c2803e15].
︙ | ︙ | |||
204 205 206 207 208 209 210 211 212 213 214 215 216 217 | return -code error "Invalid option: $arg" } } } if {[string length $publicKey] != $::nano::key::publicKeyLength} { set publicKey [binary decode hex $publicKey] } set checksum [string reverse [::nano::internal::hashData $publicKey 5]] append publicKey $checksum set publicKey [binary encode hex $publicKey] set publicKey [expr "0x$publicKey"] | > > > > | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | return -code error "Invalid option: $arg" } } } if {[string length $publicKey] != $::nano::key::publicKeyLength} { set publicKey [binary decode hex $publicKey] if {[string length $publicKey] != $::nano::key::publicKeyLength} { return -code error "Invalid public key (length: [string length $publicKey], expected $::nano::key::publicKeyLength)" } } set checksum [string reverse [::nano::internal::hashData $publicKey 5]] append publicKey $checksum set publicKey [binary encode hex $publicKey] set publicKey [expr "0x$publicKey"] |
︙ | ︙ | |||
455 456 457 458 459 460 461 462 463 464 465 466 467 468 | 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] | > > > > > > > | 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | 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"]] } } if {[dict exists $blockDict "work"]} { set valid [::nano::work::validate [dict get $blockDict "_workData"] [dict get $blockDict "work"]] if {!$valid} { return -code error "Invalid work when adding block" } } return $blockDict } proc ::nano::block::dict::fromJSON {blockJSON} { set retval [::json::json2dict $blockJSON] |
︙ | ︙ | |||
3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 | } } } set now [clock seconds] # Cleanup nonces while we are here foreach {peerKey peerInfo} [array get ::nano::node::_node_id_nonces] { set lastSeen [dict get $peerInfo "lastSeen"] if {($now - $lastSeen) > (5 * 60)} { unset ::nano::node::_node_id_nonces($peerKey) } } # Come up with a list of peers that we have seen recently foreach {peerKeyInfo peerInfo} [array get ::nano::node::peers] { set lastSeen [dict get $peerInfo "lastSeen"] set address [dict get $peerKeyInfo "address"] set peerPort [dict get $peerKeyInfo "port"] set peerKey [dict create address $address port $peerPort] if {($now - $lastSeen) > (5 * 60)} { #puts "Have not seen $peerKey in a while, dropping (now=$now, lastSeen=$lastSeen)" | > > > > > > > > | 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 3295 3296 | } } } set now [clock seconds] # Cleanup nonces while we are here foreach {peerKey peerInfo} [array get ::nano::node::_node_id_nonces] { if {![dict exists $peerInfo "lastSeen"]} { continue } set lastSeen [dict get $peerInfo "lastSeen"] if {($now - $lastSeen) > (5 * 60)} { unset ::nano::node::_node_id_nonces($peerKey) } } # Come up with a list of peers that we have seen recently foreach {peerKeyInfo peerInfo} [array get ::nano::node::peers] { if {![dict exists $peerInfo "lastSeen"]} { continue } set lastSeen [dict get $peerInfo "lastSeen"] set address [dict get $peerKeyInfo "address"] set peerPort [dict get $peerKeyInfo "port"] set peerKey [dict create address $address port $peerPort] if {($now - $lastSeen) > (5 * 60)} { #puts "Have not seen $peerKey in a while, dropping (now=$now, lastSeen=$lastSeen)" |
︙ | ︙ | |||
3337 3338 3339 3340 3341 3342 3343 | # If this peer is not already known, contact them requesting a handshake if {![info exists ::nano::node::peers($peer)]} { if {![info exists ::nano::node::_node_id_nonces($peer)]} { set node_id_nonce [::nano::internal::randomBytes 32] set ::nano::node::_node_id_nonces($peer) [dict create query $node_id_nonce lastSeen $now] set peerSock [::nano::node::createSocket realtime $address $port] | < | 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 | # If this peer is not already known, contact them requesting a handshake if {![info exists ::nano::node::peers($peer)]} { if {![info exists ::nano::node::_node_id_nonces($peer)]} { set node_id_nonce [::nano::internal::randomBytes 32] set ::nano::node::_node_id_nonces($peer) [dict create query $node_id_nonce lastSeen $now] set peerSock [::nano::node::createSocket realtime $address $port] ::nano::network::client $peerSock "node_id_handshake" query -query $node_id_nonce } } } # Stats ::nano::node::stats::incr [list keepalive] |
︙ | ︙ | |||
3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 | if {"response" in $flags} { binary scan $messageData H64H128 result(key) result(signature) } return [array get result] } proc ::nano::network::server::node_id_handshake {messageDict} { set retval "" ::nano::node::stats::incr [list node_id_handshake] 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 ::nano::node::stats::incr [list node_id_handshake query] } if {"response" in [dict get $messageDict flags]} { | > > > > > > > > | < < < | | | 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 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 | if {"response" in $flags} { binary scan $messageData H64H128 result(key) result(signature) } return [array get result] } proc ::nano::network::_socketToPeer {realtimeSocket} { set peerInfo [dict get $realtimeSocket remote] set peerAddress [lindex $peerInfo 0] set peerPort [lindex $peerInfo 1] set peer [dict create address $peerAddress port $peerPort] return $peer } proc ::nano::network::server::node_id_handshake {messageDict} { set retval "" ::nano::node::stats::incr [list node_id_handshake] 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 ::nano::node::stats::incr [list node_id_handshake query] } if {"response" in [dict get $messageDict flags]} { set peer [::nano::network::_socketToPeer [dict get $messageDict socket]] # 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 dict set ::nano::node::peers($peer) lastSeen [clock seconds] dict set ::nano::node::peers($peer) nodeIdKey [dict get $messageDict key] # Stats ::nano::node::stats::incr [list node_id_handshake response] ::nano::node::stats::lappend [list node_id_handshake response uniqueKeys] [dict get $messageDict key] } return $retval |
︙ | ︙ | |||
3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 | if {![info exists messageTypeID]} { ::nano::node::log "*** Incoming: INVALID [binary encode hex $message] ($messageData)" return "" } ::nano::node::log "*** Incoming: $messageType ($messageTypeID on $networkType; from $peerSock) [binary encode hex $message] ($messageData)" if {![info exists messageDict]} { return "" } set configuredNetwork [dict get $::nano::node::configuration network] if {$network ne $configuredNetwork} { | > > > > > > | 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 | if {![info exists messageTypeID]} { ::nano::node::log "*** Incoming: INVALID [binary encode hex $message] ($messageData)" return "" } ::nano::node::log "*** Incoming: $messageType ($messageTypeID on $networkType; from $peerSock) [binary encode hex $message] ($messageData)" catch { set peer [::nano::network::_socketToPeer $peerSock] dict set ::nano::node::peers($peer) lastPacket [clock seconds] dict set ::nano::node::peers($peer) lastVersion $versionUsing } if {![info exists messageDict]} { return "" } set configuredNetwork [dict get $::nano::node::configuration network] if {$network ne $configuredNetwork} { |
︙ | ︙ | |||
4377 4378 4379 4380 4381 4382 4383 4384 4385 | foreach peer [::nano::node::getPeers] { if {[info exists glob]} { if {![string match $glob $peer] == !$globInvert} { continue } } if {[info exists ::nano::node::peers($peer)]} { set peerInfo $::nano::node::peers($peer) | > > > > > | > > > > > > > | > > > > > > > > > > > > > > | | | 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 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 | foreach peer [::nano::node::getPeers] { if {[info exists glob]} { if {![string match $glob $peer] == !$globInvert} { continue } } unset -nocomplain peerInfo set fields [list] if {[info exists ::nano::node::peers($peer)]} { set peerInfo $::nano::node::peers($peer) } catch { set versionUsing [dict get $peerInfo lastVersion] lappend fields "protocol $versionUsing" } catch { set lastSeen [dict get $peerInfo lastSeen] set delta [expr {$now - $lastSeen}] set age "last seen $delta seconds ago" lappend fields $age } catch { set lastPacket [dict get $peerInfo lastPacket] set delta [expr {$now - $lastPacket}] lappend fields "last packet $delta seconds ago" } catch { set nodeID [dict get $peerInfo nodeIdKey] lappend fields "node identifier $nodeID" } if {[llength $fields] == 0} { lappend fields "statically configured peer" } lappend response " $peer: [join $fields {, }]" } return [join $response "\n"] } proc ::nano::node::cli::_pull_chain {startBlockHash {endBlockHash "genesis"}} { if {$endBlockHash eq "genesis"} { set network [dict get $::nano::node::configuration network] |
︙ | ︙ |