Check-in [34db25cf14]
Overview
Comment:Improved CLI
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 34db25cf142d4b1a66f299c166a74699d19a3970c761f6f70a03dde1f9f094ee
User & Date: rkeene on 2018-12-08 22:21:44
Other Links: manifest | tags
Context
2018-12-08
22:29
Updated documentation regarding dependencies check-in: fbea5985d4 user: rkeene tags: trunk
22:21
Improved CLI check-in: 34db25cf14 user: rkeene tags: trunk
03:36
Added start of documentation on Bulk_Pull_Account check-in: 15de2d5606 user: rkeene tags: trunk
Changes

Modified nano.tcl from [984f7c64c2] to [0b1342a368].

1906
1907
1908
1909
1910
1911
1912


1913
1914


1915






1916
1917
1918
1919
1920
1921
1922
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915

1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931







+
+

-
+
+

+
+
+
+
+
+







	proc ::nano::node::user_log {line} {
		puts stderr $line
	}
}

proc ::nano::node::log {message {level "debug"}} {
	set linePrefix ""
	set now [clock seconds]

	foreach line [split $message "\n"] {
		::nano::node::user_log [format {%-40s %10s [%5s] %s} [::info coroutine] [clock seconds] $level ${linePrefix}$line]
		set line [format {%-40s %10s [%5s] %s} [::info coroutine] $now $level ${linePrefix}$line]
		::nano::node::user_log $line
		set linePrefix "    "

		lappend ::nano::node::log $line
	}

	if {($now % 30) == 0} {
		set ::nano::node::log [lrange $::nano::node::log end-19 end]
	}
}

proc ::nano::protocol::extensions::get {messageType extensions} {
	::set flags [list]
	foreach {checkFlagName checkFlag} [dict get $::nano::protocol::extensions $messageType] {
		if {($extensions & $checkFlag) == $checkFlag} {
3231
3232
3233
3234
3235
3236
3237

3238

3239
3240
3241
3242
3243
3244
3245
3240
3241
3242
3243
3244
3245
3246
3247

3248
3249
3250
3251
3252
3253
3254
3255







+
-
+







}

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 -query [binary decode hex $query]]]
		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]
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
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







-
+














+
+
+
+
+
+
-
+
+
+
+
+







		}
		set interval [expr {$interval / $divisor}]
	}

	return "[lreverse $response]"
}

proc ::nano::node::cli::uptime {} {
proc {::nano::node::cli::show uptime} {} {
	set now [clock seconds]
	set start $::nano::node::startTime
	set statsStart $::nano::node::statsStartTime

	set uptime [expr {$now - $start}]
	set uptimeStats [expr {$now - $statsStart}]

	set format {%-19s: %s}
	lappend response [format $format Uptime [_interval $uptime]]
	lappend response [format $format "Stats last cleared" "[_interval $uptimeStats] ago"]

	return [join $response "\n"]
}

proc {::nano::node::cli::show node-id} args {
	set nodeIDPrivate [dict get $::nano::node::configuration node client_id_private_key]
	set nodeIDPublic [::nano::key::publicKeyFromPrivateKey $nodeIDPrivate -hex]
	return $nodeIDPublic
}

proc ::nano::node::cli::stats args {
proc {::nano::node::cli::show logs} args {
	return [join [lrange $::nano::node::log end-19 end] "\n"]
}

proc {::nano::node::cli::show stats} args {
	if {[lindex $args 0] eq "-clear"} {
		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

3833
3834
3835
3836
3837
3838
3839
3840

3841
3842
3843
3844

3845
3846
3847
3848


3849

3850
3851
3852
3853





3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864


3865
3866
3867
3868


3869
3870
3871
3872
3873
3874
3875

3876
3877
3878
3879
3880
3881
3882
3883
3884

3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901

3902
3903
3904
3905
3906
3907
3908
3853
3854
3855
3856
3857
3858
3859

3860
3861
3862
3863

3864
3865
3866
3867
3868
3869
3870

3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889


3890
3891
3892
3893


3894
3895







3896
3897








3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912


3913
3914
3915
3916
3917
3918
3919
3920
3921







-
+



-
+




+
+
-
+




+
+
+
+
+









-
-
+
+


-
-
+
+
-
-
-
-
-
-
-
+

-
-
-
-
-
-
-
-
+














-
-

+







	foreach {key val} [lsort -stride 2 -dictionary [array get localStats]] {
		puts [format "%-${maxKeyLen}s = $val" $key $val]
	}

	return
}

proc ::nano::node::cli::version {} {
proc {::nano::node::cli::show version} {} {
	return [package present nano]
}

proc ::nano::node::cli::help args {
proc ::nano::node::cli::_help {commandRoot args} {
	set response [list]
	if {[llength $args] == 0} {
		lappend response "Commands:"

		set pattern [string trimleft "${commandRoot} *"]

		foreach command [lsort -dictionary [info command ::nano::node::cli::*]] {
		foreach command [lsort -dictionary [info command ::nano::node::cli::${pattern}]] {
			set command [namespace tail $command]
			if {[string match "_*" $command]} {
				continue
			}

			set extra [string trim [string range $command [string length $commandRoot] end]]
			if {[string first " " $extra] != -1} {
				continue
			}

			set description ""
			lappend response [format "   %-12s - %s" $command $description]
		}
	}

	return [join $response "\n"]
}

proc ::nano::node::cli::network {} {
	return [dict get $::nano::node::configuration network]
proc ::nano::node::cli::help args {
	tailcall _help "" {*}$args
}

proc ::nano::node::cli::config args {
	set config $::nano::node::configuration
proc {::nano::node::cli::show network} {} {
	return [dict get $::nano::node::configuration network]
	dict set config node client_id_private_key [binary encode hex [dict get $config node client_id_private_key]]
	set subtreePrefix [lrange $args 0 end-1]
	set subtreeKey [lindex $args end]
	set subtreePrefixConfig [join $subtreePrefix /]
	if {$subtreePrefixConfig ne ""} {
		append subtreePrefixConfig "/"
	}
}

	set subtree [dict get $config {*}$subtreePrefix]

	set json [::nano::node::_configDictToJSON $subtree $subtreePrefixConfig $subtreeKey]

	return $json
}

proc ::nano::node::cli::peers args {
proc {::nano::node::cli::show peers} args {
	if {[lindex $args 0] eq "-count"} {
		return [llength [::nano::node::getPeers]]
	}

	if {[llength $args] == 1} {
		set glob [lindex $args 0]
		if {[string index $glob 0] eq "!"} {
			set globInvert true
			set glob [string range $glob 1 end]
		} else {
			set globInvert false
		}
	}

	lappend response "Peers:"

	set now [clock seconds]
	set response [list]
	foreach peer [::nano::node::getPeers] {
		if {[info exists glob]} {
			if {![string match $glob $peer] == !$globInvert} {
				continue
			}
		}

3955
3956
3957
3958
3959
3960
3961
3962



















































































3963
3964
3965
3966
3967
3968
3969
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







	set endTime [clock seconds]

	set blocksPulled [::nano::node::bootstrap::TMP_LEDGER_BLOCKHASHCOUNT]
	set delta [expr {$endTime - $startTime}]

	puts "Pulled $blocksPulled blocks in [::nano::node::cli::_interval $delta]"
}

proc ::nano::node::cli::_multiword {baseCommand args} {
	if {[llength $args] == 0} {
		set args [list "help"]
	}

	set matched false
	set includeBaseCommand false
	foreach base [list $baseCommand _multiword] {
		for {set included [expr {[llength $args] - 1}]} {$included >= 0} {incr included -1} {
			set proc "::nano::node::cli::${base} [join [lrange $args 0 $included] { }]"
			if {[info command $proc] ne ""} {
				set matched true

				break
			}
		}

		if {$matched} {
			if {$base eq "_multiword"} {
				set includeBaseCommand true
			}

			break
		}
	}

	if {!$matched} {
		return -code error "No matching commands in $baseCommand [join $args { }]"
	}

	set args [lrange $args $included+1 end]

	if {$includeBaseCommand} {
		set args [concat [list $baseCommand] $args]
	}

	tailcall $proc {*}$args
}

proc {::nano::node::cli::_multiword help} {base args} {
	tailcall _help ${base} {*}$args
}

proc ::nano::node::cli::show {args} {
	tailcall ::nano::node::cli::_multiword show {*}$args
}

proc ::nano::node::cli::config {args} {
	tailcall ::nano::node::cli::_multiword config {*}$args
}

proc {::nano::node::cli::config get} {args} {
	set config $::nano::node::configuration
	dict set config node client_id_private_key [binary encode hex [dict get $config node client_id_private_key]]
	set subtreePrefix [lrange $args 0 end-1]
	set subtreeKey [lindex $args end]
	set subtreePrefixConfig [join $subtreePrefix /]
	if {$subtreePrefixConfig ne ""} {
		append subtreePrefixConfig "/"
	}

	set subtree [dict get $config {*}$subtreePrefix]

	set json [::nano::node::_configDictToJSON $subtree $subtreePrefixConfig $subtreeKey]

	return $json
}

proc {::nano::node::cli::config set} {args} {
	set val [lindex $args end]
	set key [lrange $args 0 end-1]
	lappend response "Old:"
	lappend response [{::nano::node::cli::config get} {*}$key]

	dict set ::nano::node::configuration {*}$key $val

	lappend response ""
	lappend response "New:"
	lappend response [{::nano::node::cli::config get} {*}$key]

	return [join $response "\n"]
}

namespace eval ::nano::node::cli {
	namespace export -clear *
}

if {[info exists ::nano::node::cli::_using_repl]} {
	::nano::node::cli -import
}