Skip to content

Commit 7473e14

Browse files
authored
Merge pull request #99 from koinos/cache-nonce
Cache nonce, rclimit command, fixes
2 parents a8f847b + fce8c35 commit 7473e14

7 files changed

Lines changed: 279 additions & 38 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/ethereum/go-ethereum v1.10.9
1010
github.com/joho/godotenv v1.3.0
1111
github.com/koinos/koinos-proto-golang v0.2.1-0.20220224180227-6fbc5fe4a89a
12-
github.com/koinos/koinos-util-golang v0.0.0-20220224193402-85a6df362833
12+
github.com/koinos/koinos-util-golang v0.0.0-20220301215016-a6dd44e1b886
1313
github.com/minio/sio v0.3.0
1414
github.com/mr-tron/base58 v1.2.0
1515
github.com/multiformats/go-multihash v0.1.0

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,14 @@ github.com/koinos/koinos-util-golang v0.0.0-20220209191034-96c779bbca9a h1:VeYCG
272272
github.com/koinos/koinos-util-golang v0.0.0-20220209191034-96c779bbca9a/go.mod h1:G4qXv/aoybzmzoHzsd9aU7DaCQrn3ek/vc7PhbG4dZ8=
273273
github.com/koinos/koinos-util-golang v0.0.0-20220224193402-85a6df362833 h1:7H/Rwdt4VrbW6O3R0WIKbcrUE07vstzOb+xB60sS0PI=
274274
github.com/koinos/koinos-util-golang v0.0.0-20220224193402-85a6df362833/go.mod h1:0+oSa/Ml9+INjfAGubMtKNOq+e4a/OoEz7GfaQPN/P8=
275+
github.com/koinos/koinos-util-golang v0.0.0-20220301201441-4f2c3518ee81 h1:AqiEGcCH3O2baOT+YgGL+teK1hua7mnDPYYOGZ8Twdk=
276+
github.com/koinos/koinos-util-golang v0.0.0-20220301201441-4f2c3518ee81/go.mod h1:0+oSa/Ml9+INjfAGubMtKNOq+e4a/OoEz7GfaQPN/P8=
277+
github.com/koinos/koinos-util-golang v0.0.0-20220301212911-ed0a25655b57 h1:aiuAXLZqWpmFeAx8YKxxU0auH7rnJeNXWT2IlzKBI1c=
278+
github.com/koinos/koinos-util-golang v0.0.0-20220301212911-ed0a25655b57/go.mod h1:0+oSa/Ml9+INjfAGubMtKNOq+e4a/OoEz7GfaQPN/P8=
279+
github.com/koinos/koinos-util-golang v0.0.0-20220301213529-8bf7f9fb7703 h1:3RYpwppM0o9ahpHEPXIeyyZB4In2anH09Yn0lWrpHlg=
280+
github.com/koinos/koinos-util-golang v0.0.0-20220301213529-8bf7f9fb7703/go.mod h1:0+oSa/Ml9+INjfAGubMtKNOq+e4a/OoEz7GfaQPN/P8=
281+
github.com/koinos/koinos-util-golang v0.0.0-20220301215016-a6dd44e1b886 h1:aCqcoOZnpL0+xJ/T2c2hZIDH5JHKRR87ZczRqI0WDfs=
282+
github.com/koinos/koinos-util-golang v0.0.0-20220301215016-a6dd44e1b886/go.mod h1:0+oSa/Ml9+INjfAGubMtKNOq+e4a/OoEz7GfaQPN/P8=
275283
github.com/koinos/protobuf-go v1.27.2-0.20211016005428-adb3d63afc5e h1:e92AS0/Aklop09SUlZXIaKJKMAtFsp1bMCf8SKRdVVE=
276284
github.com/koinos/protobuf-go v1.27.2-0.20211016005428-adb3d63afc5e/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
277285
github.com/koinos/protobuf-go v1.27.2-0.20211026185306-2456c83214fe h1:PJ+2AnN4ibN2WxldiClplZZosQNPnXj7S5vOeFNtV+M=

internal/cli/cli_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ func makeTestParser() *CommandParser {
5858
*NewCommandArg("bool", BoolArg), *NewCommandArg("amount", AmountArg)))
5959
cs.AddCommand(NewCommandDeclaration("test_transfer", "Test command which looks like transfer", false, nil, *NewCommandArg("amount", AmountArg),
6060
*NewCommandArg("amount", AddressArg)))
61+
cs.AddCommand(NewCommandDeclaration("test_hex", "Test command which takes a hex argument", false, nil, *NewCommandArg("hex", HexArg)))
6162

6263
parser := NewCommandParser(cs)
6364

@@ -121,6 +122,12 @@ func TestBasicParser(t *testing.T) {
121122
if results.Len() != 0 {
122123
t.Error("Expected 0 results, got", results.Len())
123124
}
125+
126+
// Test hex parsing
127+
results, err = parser.Parse("test_hex 0x0123456789abcdef")
128+
if err != nil {
129+
t.Error(err)
130+
}
124131
}
125132

126133
func TestNonsensicalInput(t *testing.T) {

internal/cli/commands.go

Lines changed: 130 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"sort"
1212
"strconv"
13+
"time"
1314

1415
"google.golang.org/protobuf/proto"
1516

@@ -106,16 +107,18 @@ func NewKoinosCommandSet() *CommandSet {
106107
cs.AddCommand(NewCommandDeclaration("import", "Import a WIF private key to a new wallet file", false, NewImportCommand, *NewCommandArg("private-key", StringArg), *NewCommandArg("filename", FileArg), *NewOptionalCommandArg("password", StringArg)))
107108
cs.AddCommand(NewCommandDeclaration("list", "List available commands", false, NewListCommand))
108109
cs.AddCommand(NewCommandDeclaration("upload", "Upload a smart contract", false, NewUploadContractCommand, *NewCommandArg("filename", FileArg), *NewOptionalCommandArg("abi-filename", FileArg)))
109-
cs.AddCommand(NewCommandDeclaration("call", "Call a smart contract", false, NewCallCommand, *NewCommandArg("contract-id", StringArg), *NewCommandArg("entry-point", StringArg), *NewCommandArg("arguments", StringArg)))
110+
cs.AddCommand(NewCommandDeclaration("call", "Call a smart contract", false, NewCallCommand, *NewCommandArg("contract-id", StringArg), *NewCommandArg("entry-point", HexArg), *NewCommandArg("arguments", StringArg)))
110111
cs.AddCommand(NewCommandDeclaration("open", "Open a wallet file", false, NewOpenCommand, *NewCommandArg("filename", FileArg), *NewOptionalCommandArg("password", StringArg)))
111112
cs.AddCommand(NewCommandDeclaration("unlock", "Open a wallet file", true, NewOpenCommand, *NewCommandArg("filename", FileArg), *NewOptionalCommandArg("password", StringArg)))
112113
cs.AddCommand(NewCommandDeclaration("private", "Show the currently opened wallet's private key", false, NewPrivateCommand))
114+
cs.AddCommand(NewCommandDeclaration("rclimit", "Set or show the current rc limit. Give no limit to see current calue. Give limit as either mana for a percent (i.e. 80%).", false, NewRcLimitCommand, *NewOptionalCommandArg("limit", StringArg)))
113115
cs.AddCommand(NewCommandDeclaration("read", "Read from a smart contract", false, NewReadCommand, *NewCommandArg("contract-id", StringArg), *NewCommandArg("entry-point", StringArg), *NewCommandArg("arguments", StringArg)))
114116
cs.AddCommand(NewCommandDeclaration("register", "Register a smart contract's commands", false, NewRegisterCommand, *NewCommandArg("name", StringArg), *NewCommandArg("address", AddressArg), *NewOptionalCommandArg("abi-filename", FileArg)))
115117
cs.AddCommand(NewCommandDeclaration("transfer", "Transfer token from an open wallet to a given address", false, NewTransferCommand, *NewCommandArg("value", AmountArg), *NewCommandArg("to", AddressArg)))
116-
cs.AddCommand(NewCommandDeclaration("set_system_call", "Set a system call to a new contract and entry point", false, NewSetSystemCallCommand, *NewCommandArg("system-call", StringArg), *NewCommandArg("contract-id", StringArg), *NewCommandArg("entry-point", StringArg)))
117-
cs.AddCommand(NewCommandDeclaration("set_system_contract", "Change a contract's permission level between user and system", false, NewSetSystemContractCommand, *NewCommandArg("contract-id", StringArg), *NewCommandArg("system-contract", StringArg)))
118+
cs.AddCommand(NewCommandDeclaration("set_system_call", "Set a system call to a new contract and entry point", false, NewSetSystemCallCommand, *NewCommandArg("system-call", StringArg), *NewCommandArg("contract-id", AddressArg), *NewCommandArg("entry-point", HexArg)))
119+
cs.AddCommand(NewCommandDeclaration("set_system_contract", "Change a contract's permission level between user and system", false, NewSetSystemContractCommand, *NewCommandArg("contract-id", AddressArg), *NewCommandArg("system-contract", BoolArg)))
118120
cs.AddCommand(NewCommandDeclaration("session", "Create or manage a transaction session (begin, submit, cancel, or view)", false, NewSessionCommand, *NewCommandArg("command", StringArg)))
121+
cs.AddCommand(NewCommandDeclaration("sleep", "Sleep for the given number seconds", true, NewSleepCommand, *NewCommandArg("seconds", AmountArg)))
119122
cs.AddCommand(NewCommandDeclaration("exit", "Exit the wallet (quit also works)", false, NewExitCommand))
120123
cs.AddCommand(NewCommandDeclaration("quit", "", true, NewExitCommand))
121124

@@ -219,7 +222,7 @@ func (c *CloseCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*
219222
}
220223

221224
// Close the wallet
222-
ee.Key = nil
225+
ee.CloseWallet()
223226

224227
result := NewExecutionResult()
225228
result.AddMessage("Wallet closed")
@@ -398,22 +401,21 @@ func (c *UploadContractCommand) Execute(ctx context.Context, ee *ExecutionEnviro
398401
},
399402
}
400403

401-
er := NewExecutionResult()
402-
er.AddMessage(fmt.Sprintf("Contract uploaded with address %s", base58.Encode(ee.Key.AddressBytes())))
404+
result := NewExecutionResult()
405+
result.AddMessage(fmt.Sprintf("Contract uploaded with address %s", base58.Encode(ee.Key.AddressBytes())))
403406

404407
err = ee.Session.AddOperation(op, fmt.Sprintf("Upload contract with address %s", base58.Encode(ee.Key.AddressBytes())))
405408
if err == nil {
406-
er.AddMessage("Adding operation to transaction session")
409+
result.AddMessage("Adding operation to transaction session")
407410
}
408411
if err != nil {
409-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
412+
err := ee.SubmitTransaction(result, op)
410413
if err != nil {
411-
return nil, err
414+
return nil, fmt.Errorf("cannot upload contract, %w", err)
412415
}
413-
er.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
414416
}
415417

416-
return er, nil
418+
return result, nil
417419
}
418420

419421
// ----------------------------------------------------------------------------
@@ -652,7 +654,7 @@ func (c *CallCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
652654
}
653655

654656
// Get the argument bytes
655-
argumentBytes, err := base64.StdEncoding.DecodeString(c.Arguments[1:])
657+
argumentBytes, err := base64.StdEncoding.DecodeString(c.Arguments)
656658
if err != nil {
657659
return nil, err
658660
}
@@ -675,11 +677,10 @@ func (c *CallCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
675677
result.AddMessage("Adding operation to transaction session")
676678
}
677679
if err != nil {
678-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
680+
err := ee.SubmitTransaction(result, op)
679681
if err != nil {
680-
return nil, err
682+
return nil, fmt.Errorf("cannot call contract, %w", err)
681683
}
682-
result.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
683684
}
684685

685686
return result, nil
@@ -726,15 +727,92 @@ func (c *OpenCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
726727
return nil, err
727728
}
728729

729-
// Set the wallet keys
730-
ee.Key = key
730+
// Open the wallet
731+
ee.OpenWallet(key)
731732

732733
result := NewExecutionResult()
733734
result.AddMessage(fmt.Sprintf("Opened wallet: %s", c.Filename))
734735

735736
return result, nil
736737
}
737738

739+
// ----------------------------------------------------------------------------
740+
// RcLimit Command
741+
// ----------------------------------------------------------------------------
742+
743+
// RcLimitCommand is a command that sets or checks your cuttent rc limit
744+
type RcLimitCommand struct {
745+
limit *string
746+
}
747+
748+
// NewRcLimitCommand creates a new rc limit command object
749+
func NewRcLimitCommand(inv *CommandParseResult) Command {
750+
return &RcLimitCommand{limit: inv.Args["limit"]}
751+
}
752+
753+
// Execute handles the rc limit command
754+
func (c *RcLimitCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*ExecutionResult, error) {
755+
result := NewExecutionResult()
756+
// If no limit given, display current
757+
if c.limit == nil {
758+
if ee.rcLimit.absolute {
759+
result.AddMessage(fmt.Sprintf("Current rc limit: %f", ee.rcLimit.value))
760+
return result, nil
761+
}
762+
763+
// Otherwise its relative
764+
if !ee.IsOnline() || !ee.IsWalletOpen() {
765+
result.AddMessage(fmt.Sprintf("Current rc limit: %f%%", ee.rcLimit.value*100))
766+
return result, nil
767+
}
768+
769+
limit, err := ee.RPCClient.GetAccountRc(ee.Key.AddressBytes())
770+
if err != nil {
771+
return nil, err
772+
}
773+
774+
dAmount, err := util.SatoshiToDecimal(int64(limit), cliutil.KoinPrecision)
775+
if err != nil {
776+
return nil, err
777+
}
778+
779+
f, _ := dAmount.Mul(decimal.NewFromFloat(ee.rcLimit.value)).Float64()
780+
result.AddMessage(fmt.Sprintf("Current rc limit: %f%% (%f)", ee.rcLimit.value*100, f))
781+
return result, nil
782+
}
783+
784+
// Otherwise we are setting the limit
785+
s := *c.limit
786+
if s[len(s)-1] == '%' {
787+
res, err := strconv.ParseFloat(s[:len(s)-1], 64)
788+
if err != nil {
789+
return nil, err
790+
}
791+
792+
// Check bounds
793+
if res < 0 || res > 100 {
794+
return nil, fmt.Errorf("%w: percentage rc limit must be between 0%% and 100%%", cliutil.ErrInvalidParam)
795+
}
796+
797+
ee.rcLimit.value = res / 100.0
798+
ee.rcLimit.absolute = false
799+
result.AddMessage(fmt.Sprintf("Set rc limit to %f%%", res))
800+
return result, nil
801+
}
802+
803+
// Otherwise we are setting the absolute limit
804+
res, err := strconv.ParseFloat(s, 64)
805+
if err != nil {
806+
return nil, err
807+
}
808+
809+
ee.rcLimit.value = res
810+
ee.rcLimit.absolute = true
811+
result.AddMessage(fmt.Sprintf("Set rc limit to %f", res))
812+
813+
return result, nil
814+
}
815+
738816
// ----------------------------------------------------------------------------
739817
// Read
740818
// ----------------------------------------------------------------------------
@@ -781,6 +859,34 @@ func (c *ReadCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*E
781859
return result, nil
782860
}
783861

862+
// ----------------------------------------------------------------------------
863+
// Sleep Command
864+
// ----------------------------------------------------------------------------
865+
866+
// SleepCommand is a command that shows the currently opened wallet's address and private key
867+
type SleepCommand struct {
868+
Duration time.Duration
869+
}
870+
871+
// NewSleepCommand creates a new address command object
872+
func NewSleepCommand(inv *CommandParseResult) Command {
873+
f, err := strconv.ParseFloat(*inv.Args["seconds"], 32)
874+
if err != nil {
875+
return nil
876+
}
877+
878+
return &SleepCommand{Duration: time.Duration(f * float64(time.Second))}
879+
}
880+
881+
// Execute shows wallet address
882+
func (c *SleepCommand) Execute(ctx context.Context, ee *ExecutionEnvironment) (*ExecutionResult, error) {
883+
result := NewExecutionResult()
884+
result.AddMessage(fmt.Sprintf("Slept for %s", c.Duration))
885+
time.Sleep(c.Duration)
886+
887+
return result, nil
888+
}
889+
784890
// ----------------------------------------------------------------------------
785891
// Transfer
786892
// ----------------------------------------------------------------------------
@@ -881,11 +987,10 @@ func (c *TransferCommand) Execute(ctx context.Context, ee *ExecutionEnvironment)
881987
result.AddMessage("Adding operation to transaction session")
882988
}
883989
if err != nil {
884-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
990+
err := ee.SubmitTransaction(result, op)
885991
if err != nil {
886-
return nil, err
992+
return nil, fmt.Errorf("cannot transfer, %w", err)
887993
}
888-
result.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
889994
}
890995

891996
return result, nil
@@ -964,11 +1069,10 @@ func (c *SetSystemCallCommand) Execute(ctx context.Context, ee *ExecutionEnviron
9641069
result.AddMessage("Adding operation to transaction session")
9651070
}
9661071
if err != nil {
967-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
1072+
err := ee.SubmitTransaction(result, op)
9681073
if err != nil {
969-
return nil, err
1074+
return nil, fmt.Errorf("cannot set system call, %w", err)
9701075
}
971-
result.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
9721076
}
9731077

9741078
return result, nil
@@ -1034,11 +1138,10 @@ func (c *SetSystemContractCommand) Execute(ctx context.Context, ee *ExecutionEnv
10341138
result.AddMessage("Adding operation to transaction session")
10351139
}
10361140
if err != nil {
1037-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
1141+
err := ee.SubmitTransaction(result, op)
10381142
if err != nil {
1039-
return nil, err
1143+
return nil, fmt.Errorf("cannot set contract, %w", err)
10401144
}
1041-
result.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
10421145
}
10431146

10441147
return result, nil
@@ -1095,12 +1198,10 @@ func (c *SessionCommand) Execute(ctx context.Context, ee *ExecutionEnvironment)
10951198
ops[i] = reqs[i].Op
10961199
}
10971200

1098-
receipt, err := ee.RPCClient.SubmitTransaction(ops, ee.Key)
1201+
err := ee.SubmitTransaction(result, ops...)
10991202
if err != nil {
11001203
return nil, fmt.Errorf("error submitting transaction, %w", err)
11011204
}
1102-
1103-
result.AddMessage(cliutil.TransactionReceiptToString(receipt, len(ops)))
11041205
} else {
11051206
result.AddMessage("Cancelling transaction because session has 0 operations")
11061207
}

internal/cli/contract_commands.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -355,22 +355,21 @@ func (c *WriteContractCommand) Execute(ctx context.Context, ee *ExecutionEnviron
355355

356356
textMsg, _ := text.Marshal(msg)
357357

358-
er := NewExecutionResult()
359-
er.AddMessage(fmt.Sprintf("Calling %s with arguments '%s'", c.ParseResult.CommandName, textMsg))
358+
result := NewExecutionResult()
359+
result.AddMessage(fmt.Sprintf("Calling %s with arguments '%s'", c.ParseResult.CommandName, textMsg))
360360

361361
logMessage := fmt.Sprintf("Call %s with arguments '%s'", c.ParseResult.CommandName, textMsg)
362362

363363
err = ee.Session.AddOperation(op, logMessage)
364364
if err == nil {
365-
er.AddMessage("Adding operation to transaction session")
365+
result.AddMessage("Adding operation to transaction session")
366366
}
367367
if err != nil {
368-
receipt, err := ee.RPCClient.SubmitTransaction([]*protocol.Operation{op}, ee.Key)
368+
err := ee.SubmitTransaction(result, op)
369369
if err != nil {
370-
return nil, err
370+
return nil, fmt.Errorf("cannot make call, %w", err)
371371
}
372-
er.AddMessage(cliutil.TransactionReceiptToString(receipt, 1))
373372
}
374373

375-
return er, nil
374+
return result, nil
376375
}

0 commit comments

Comments
 (0)