Check-in [5ed9a692b6]
Overview
Comment:Added start of balances and RPC client
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5ed9a692b663dbb400cdfe77f6eab21341e63fe0ded5b1119a5a11496825abb4
User & Date: rkeene on 2018-07-11 14:14:16
Other Links: manifest | tags
Context
2018-07-11
14:26
Fixed bugs with computing work check-in: 7ffe38e93e user: rkeene tags: trunk
14:14
Added start of balances and RPC client check-in: 5ed9a692b6 user: rkeene tags: trunk
2018-07-10
20:04
Describe the example in the man page check-in: f51a75c1aa user: rkeene tags: trunk
Changes

Modified nano.tcl from [1fa3e80c07] to [fc37a0ac35].

8
9
10
11
12
13
14



15
16
17
18
19
20
21
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24







+
+
+







namespace eval ::nano::key {}
namespace eval ::nano::block {}
namespace eval ::nano::block::json {}
namespace eval ::nano::block::dict {}
namespace eval ::nano::block::create {}
namespace eval ::nano::work {}
namespace eval ::nano::account {}
namespace eval ::nano::rpc {}
namespace eval ::nano::rpc::client {}
namespace eval ::nano::balance {}

# Constants
set ::nano::block::stateBlockPreamble [binary decode hex "0000000000000000000000000000000000000000000000000000000000000006"]
set ::nano::address::base32alphabet {13456789abcdefghijkmnopqrstuwxyz}

# Address management functions
proc ::nano::address::toPublicKey {address args} {
1100
1101
1102
1103
1104
1105
1106
















































































































































































1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
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
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
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







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

	set newFrontierHash [dict get [json::json2dict $block] "_blockHash"]

	setFrontier $account $newFrontierHash $balance $representative

	return $block
}

# RPC Client
proc ::nano::rpc::client::init args {
	dict with args {}

	if {![info exists url]} {
		set url {http://localhost:7076/}
	}

	set ::nano::rpc::client::url $url
}

proc ::nano::rpc::client {action args} {
	::nano::rpc::client::init

	set rpcURL $::nano::rpc::client::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 {
		set token [http::geturl $rpcURL -query $query]
		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"
	}

	set data [json::json2dict $data]

	return $data
}

# Account balance manipulation
set ::nano::balance::_conversion {
	GNano 1000000000000000000000000000000000000000
	MNano 1000000000000000000000000000000000000
	Gnano 1000000000000000000000000000000000
	Gxrb  1000000000000000000000000000000000
	KNano 1000000000000000000000000000000000
	Nano  1000000000000000000000000000000
	_USER 1000000000000000000000000000000
	NANO  1000000000000000000000000000000
	Mnano 1000000000000000000000000000000
	Mxrb  1000000000000000000000000000000
	Mrai  1000000000000000000000000000000
	knano 1000000000000000000000000000
	kxrb  1000000000000000000000000000
	mNano 1000000000000000000000000000
	nano  1000000000000000000000000
	xrb   1000000000000000000000000
	uNano 1000000000000000000000000
	mnano 1000000000000000000000
	mxrb  1000000000000000000000
	unano 1000000000000000000
	uxrb  1000000000000000000
	Traw  1000000000000
	Graw  1000000000
	Mraw  1000000
	Kraw  1000
	raw   1
}

proc ::nano::balance::toUnit {raw toUnit {decimals 0}} {
	set divisor [dict get $::nano::balance::_conversion $toUnit]

	if {$decimals == 0} {
		set balance [expr {entier(($raw / ($divisor * 1.0)) + 0.5)}]
	} else {
		set balance [expr {$raw / ($divisor * 1.0)}]
		set balance [format "%.${decimals}f" $balance]
	}

	return $balance
}

proc ::nano::balance::toRaw {balance fromUnit} {
	set multiplier [dict get $::nano::balance::_conversion $fromUnit]

	# Determine how long the multiplier is
	set zeros [expr {entier(log10($multiplier))}]

	# Find the location of the decimal point (or add it)
	set decimal [string first "." $balance]
	if {$decimal == -1} {
		append balance "."

		set decimal [string first "." $balance]
	}

	# Ensure that the balance has atleast the right number of trailing zeros
	append balance [string repeat "0" $zeros]

	# Remove the decimal point
	set balance [string replace $balance $decimal $decimal]

	# Get the subset of the string that corresponds to the balance
	set balance [string range $balance 0 [expr {$zeros + $decimal - 1}]]

	# Convert to a integer type
	set balance [expr {entier($balance)}]

	return $balance
}

proc ::nano::balance::normalizeUnitName {unit} {
	set multiplier [dict get $::nano::balance::_conversion $unit]
	foreach {unitName multiplierCheck} $::nano::balance::_conversion {
		if {$multiplierCheck == $multiplier} {
			return $unitName
		}
	}
}

proc ::nano::balance::toHuman {raw {decimals 3}} {
	set humanUnit [normalizeUnitName _USER]
	set humanUnitMultiplier [dict get $::nano::balance::_conversion $humanUnit]

	if {$raw > [expr {$humanUnitMultiplier / 10000000}]} {
		set balance [toUnit $raw $humanUnit 7]
		set baseUnit $humanUnit
		set balance [expr {entier($balance * 1000000)}]
		set labels {u m "" K M G T}
	} else {
		set balance $raw
		set baseUnit "raw"
		set labels {"" K M G T}
	}

	set labelIdx -1
	foreach label $labels {
		incr $labelIdx

		if {$balance < 1000} {
			break
		}

		set balance [expr {$balance / 1000}]
	}

	set unit "${label}${baseUnit}"
	set unit [normalizeUnitName $unit]

	set balance [toUnit $raw $unit $decimals]
	set balance [string trimright $balance "0."]

	set result [list $balance $unit]

	return $result
}

Modified test/test.tcl from [0ce1525912] to [b8561a2b70].

304
305
306
307
308
309
310
311










































































312
313
314
315
316
317
318
319

320
321
322
323
324
325
326
327
328

329
330
331
332
333
334

335
336
337
338
339
340
341
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
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
405
406
407
408

409
410
411
412
413
414
415
416








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








+








-
+





-
+







		puts "\[3.FAIL\] Exp: true"

		return false
	}

	return true
}

proc test_balances {} {
	set balance 1001500000000000000000000000000
	set balance [::nano::balance::toUnit $balance Nano 3]
	set balance_expected "1.001"
	if {$balance != $balance_expected} {
		puts "\[1.FAIL\] Got: $balance"
		puts "\[1.FAIL\] Exp: $balance_expected"

		return false
	}

	set balance 1001510000000000000000000000000
	set balance [::nano::balance::toUnit $balance Nano 3]
	set balance_expected "1.002"
	if {$balance != $balance_expected} {
		puts "\[2.FAIL\] Got: $balance"
		puts "\[2.FAIL\] Exp: $balance_expected"

		return false
	}

	set balance 100150000000000000000000000000000000000
	set balance [::nano::balance::toUnit $balance unano 3]
	set balance_expected "100150000000000000000.000"
	if {$balance != $balance_expected} {
		puts "\[3.FAIL\] Got: $balance"
		puts "\[3.FAIL\] Exp: $balance_expected"

		return false
	}
	set balance 10
	set balance [::nano::balance::toRaw $balance Nano]
	set balance_expected 10000000000000000000000000000000
	if {$balance != $balance_expected} {
		puts "\[4.FAIL\] Got: $balance"
		puts "\[4.FAIL\] Exp: $balance_expected"

		return false
	}

	set balance 1.000000000000000000001
	set balance [::nano::balance::toRaw $balance Nano]
	set balance_expected 1000000000000000000001000000000
	if {$balance != $balance_expected} {
		puts "\[5.FAIL\] Got: $balance"
		puts "\[5.FAIL\] Exp: $balance_expected"

		return false
	}

	set unitName [::nano::balance::normalizeUnitName Mnano]
	set unitName_expected "Nano"
	if {$unitName != $unitName_expected} {
		puts "\[6.FAIL\] Got: $unitName"
		puts "\[6.FAIL\] Exp: $unitName_expected"

		return false
	}

	set balance 3.3346
	set balance [::nano::balance::toRaw $balance unano]
	set balance_expected $balance
	set balance [::nano::balance::toHuman $balance]
	set balance [::nano::balance::toRaw {*}$balance]
	if {$balance != $balance_expected} {
		puts ""
		puts "\[7.FAIL\] Got: $balance"
		puts "\[7.FAIL\] Exp: $balance_expected"

		return false
	}
	return true
}

set tests {
	selftest
	signatures
	hashing
	keygeneration
	addressformat
	blocks
	work
	balances
}

foreach test $tests {
	puts -nonewline "\[    \] $test"
	flush stdout

	if {[catch {
		if {![test_$test]} {
			puts "\[FAIL\] $test"
			puts "\r\[FAIL\] $test"
			exit 1
		} else {
			puts "\r\[ OK \] $test"
		}
	} testErr]} {
		puts "\[ERR \] $test: $testErr"
		puts "\r\[ERR!\] $test: $testErr"
		exit 1
	}
}

puts "\[DONE\] All tests pass"

exit 0