Skip to content

Commit

Permalink
Merge pull request #8218 from EOSIO/8199-cleos-transaction-signatures
Browse files Browse the repository at this point in the history
Add option to provide transaction signature keys to cleos
  • Loading branch information
brianjohnson5972 authored and oschwaldp-oci committed Jun 27, 2022
1 parent 980fc79 commit 5e7edd3
Show file tree
Hide file tree
Showing 8 changed files with 635 additions and 178 deletions.
302 changes: 165 additions & 137 deletions programs/cleos/main.cpp

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions tests/Cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ def bootstrap(self, biosNode, totalNodes, prodCount, totalProducers, pfSetupPoli
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
trans=biosNode.publishContract(eosioAccount.name, contractDir, wasmFile, abiFile, waitForTransBlock=True)
trans=biosNode.publishContract(eosioAccount, contractDir, wasmFile, abiFile, waitForTransBlock=True)
if trans is None:
Utils.Print("ERROR: Failed to publish contract %s." % (contract))
return None
Expand Down Expand Up @@ -1238,7 +1238,7 @@ def bootstrap(self, biosNode, totalNodes, prodCount, totalProducers, pfSetupPoli
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
trans=biosNode.publishContract(eosioTokenAccount.name, contractDir, wasmFile, abiFile, waitForTransBlock=True)
trans=biosNode.publishContract(eosioTokenAccount, contractDir, wasmFile, abiFile, waitForTransBlock=True)
if trans is None:
Utils.Print("ERROR: Failed to publish contract %s." % (contract))
return None
Expand Down Expand Up @@ -1294,7 +1294,7 @@ def bootstrap(self, biosNode, totalNodes, prodCount, totalProducers, pfSetupPoli
wasmFile="%s.wasm" % (contract)
abiFile="%s.abi" % (contract)
Utils.Print("Publish %s contract" % (contract))
trans=biosNode.publishContract(eosioAccount.name, contractDir, wasmFile, abiFile, waitForTransBlock=True)
trans=biosNode.publishContract(eosioAccount, contractDir, wasmFile, abiFile, waitForTransBlock=True)
if trans is None:
Utils.Print("ERROR: Failed to publish contract %s." % (contract))
return None
Expand Down
87 changes: 59 additions & 28 deletions tests/Node.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,11 @@ def isTransFinalized(self, transId):


# Create & initialize account and return creation transactions. Return transaction json object
def createInitializeAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False, stakeNet=100, stakeCPU=100, buyRAM=10000, exitOnError=False, additionalArgs=''):
def createInitializeAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False, stakeNet=100, stakeCPU=100, buyRAM=10000, exitOnError=False, sign=False, additionalArgs=''):
signStr = Node.__sign_str(sign, [ creatorAccount.activePublicKey ])
cmdDesc="system newaccount"
cmd='%s -j %s %s %s %s --stake-net "%s %s" --stake-cpu "%s %s" --buy-ram "%s %s" %s' % (
cmdDesc, creatorAccount.name, account.name, account.ownerPublicKey,
cmd='%s -j %s %s %s %s %s --stake-net "%s %s" --stake-cpu "%s %s" --buy-ram "%s %s" %s' % (
cmdDesc, signStr, creatorAccount.name, account.name, account.ownerPublicKey,
account.activePublicKey, stakeNet, CORE_SYMBOL, stakeCPU, CORE_SYMBOL, buyRAM, CORE_SYMBOL, additionalArgs)
msg="(creator account=%s, account=%s)" % (creatorAccount.name, account.name);
trans=self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError, exitMsg=msg)
Expand All @@ -389,12 +390,13 @@ def createInitializeAccount(self, account, creatorAccount, stakedDeposit=1000, w

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

def createAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False, exitOnError=False):
def createAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False, exitOnError=False, sign=False):
"""Create account and return creation transactions. Return transaction json object.
waitForTransBlock: wait on creation transaction id to appear in a block."""
signStr = Node.__sign_str(sign, [ creatorAccount.activePublicKey ])
cmdDesc="create account"
cmd="%s -j %s %s %s %s" % (
cmdDesc, creatorAccount.name, account.name, account.ownerPublicKey, account.activePublicKey)
cmd="%s -j %s %s %s %s %s" % (
cmdDesc, signStr, creatorAccount.name, account.name, account.ownerPublicKey, account.activePublicKey)
msg="(creator account=%s, account=%s)" % (creatorAccount.name, account.name);
trans=self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError, exitMsg=msg)
self.trackCmdTransaction(trans)
Expand Down Expand Up @@ -524,7 +526,7 @@ def __call__(self):
def waitForIrreversibleBlock(self, blockNum, timeout=None, reportInterval=None):
return self.waitForBlock(blockNum, timeout=timeout, blockType=BlockType.lib, reportInterval=reportInterval)

def __transferFundsCmdArr(self, source, destination, amountStr, memo, force, retry):
def __transferFundsCmdArr(self, source, destination, amountStr, memo, force, retry, sign):
assert isinstance(amountStr, str)
assert(source)
assert(isinstance(source, Account))
Expand All @@ -534,6 +536,13 @@ def __transferFundsCmdArr(self, source, destination, amountStr, memo, force, ret
cmd="%s %s -v transfer --expiration 90 %s -j %s %s" % (
Utils.EosClientPath, self.eosClientArgs(), self.getRetryCmdArg(retry), source.name, destination.name)
cmdArr=cmd.split()
# not using __sign_str, since cmdArr messes up the string
if sign:
cmdArr.append("--sign-with")
cmdArr.append("[ \"%s\" ]" % (source.activePublicKey))

cmdArr.append(source.name)
cmdArr.append(destination.name)
cmdArr.append(amountStr)
cmdArr.append(memo)
if force:
Expand All @@ -543,8 +552,8 @@ def __transferFundsCmdArr(self, source, destination, amountStr, memo, force, ret
return cmdArr

# Trasfer funds. Returns "transfer" json return object
def transferFunds(self, source, destination, amountStr, memo="memo", force=False, waitForTransBlock=False, exitOnError=True, reportStatus=True, retry=None):
cmdArr = self.__transferFundsCmdArr(source, destination, amountStr, memo, force, retry)
def transferFunds(self, source, destination, amountStr, memo="memo", force=False, waitForTransBlock=False, exitOnError=True, reportStatus=True, retry=None, sign=False):
cmdArr = self.__transferFundsCmdArr(source, destination, amountStr, memo, force, retry, sign)
trans=None
start=time.perf_counter()
try:
Expand All @@ -569,8 +578,8 @@ def transferFunds(self, source, destination, amountStr, memo="memo", force=False
return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

# Trasfer funds. Returns (popen, cmdArr) for checkDelayedOutput
def transferFundsAsync(self, source, destination, amountStr, memo="memo", force=False, exitOnError=True, retry=None):
cmdArr = self.__transferFundsCmdArr(source, destination, amountStr, memo, force, retry)
def transferFundsAsync(self, source, destination, amountStr, memo="memo", force=False, exitOnError=True, retry=None, sign=False):
cmdArr = self.__transferFundsCmdArr(source, destination, amountStr, memo, force, retry, sign)
start=time.perf_counter()
try:
popen=Utils.delayedCheckOutput(cmdArr)
Expand Down Expand Up @@ -744,8 +753,9 @@ def getAccountCodeHash(self, account):
return None

# publish contract and return transaction as json object
def publishContract(self, account, contractDir, wasmFile, abiFile, waitForTransBlock=False, shouldFail=False):
cmd="%s %s -v set contract -j %s %s" % (Utils.EosClientPath, self.eosClientArgs(), account, contractDir)
def publishContract(self, account, contractDir, wasmFile, abiFile, waitForTransBlock=False, shouldFail=False, sign=False):
signStr = Node.__sign_str(sign, [ account.activePublicKey ])
cmd="%s %s -v set contract -j %s %s %s" % (Utils.EosClientPath, self.eosClientArgs(), signStr, account.name, contractDir)
cmd += "" if wasmFile is None else (" "+ wasmFile)
cmd += "" if abiFile is None else (" " + abiFile)
if Utils.Debug: Utils.Print("cmd: %s" % (cmd))
Expand Down Expand Up @@ -846,9 +856,13 @@ def pushTransaction(self, trans, opts="", silentErrors=False, permissions=None):
return (False, msg)

# returns tuple with transaction execution status and transaction
def pushMessage(self, account, action, data, opts, silentErrors=False):
def pushMessage(self, account, action, data, opts, silentErrors=False, signatures=None):
cmd="%s %s push action -j %s %s" % (Utils.EosClientPath, self.eosClientArgs(), account, action)
cmdArr=cmd.split()
# not using __sign_str, since cmdArr messes up the string
if signatures is not None:
cmdArr.append("--sign-with")
cmdArr.append("[ \"%s\" ]" % ("\", \"".join(signatures)))
if data is not None:
cmdArr.append(data)
if opts is not None:
Expand All @@ -870,55 +884,72 @@ def pushMessage(self, account, action, data, opts, silentErrors=False):
Utils.Print("ERROR: Exception during push message. cmd Duration=%.3f sec. %s" % (end - start, msg))
return (False, msg)

def setPermission(self, account, code, pType, requirement, waitForTransBlock=False, exitOnError=False):
@staticmethod
def __sign_str(sign, keys):
assert(isinstance(sign, bool))
assert(isinstance(keys, list))
if not sign:
return ""

return "--sign-with '[ \"" + "\", \"".join(keys) + "\" ]'"

def setPermission(self, account, code, pType, requirement, waitForTransBlock=False, exitOnError=False, sign=False):
assert(isinstance(account, Account))
assert(isinstance(code, Account))
signStr = Node.__sign_str(sign, [ account.activePublicKey ])
Utils.Print("REMOVE signStr: <%s>" % (signStr))
cmdDesc="set action permission"
cmd="%s -j %s %s %s %s" % (cmdDesc, account, code, pType, requirement)
cmd="%s -j %s %s %s %s %s" % (cmdDesc, signStr, account.name, code.name, pType, requirement)
trans=self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError)
self.trackCmdTransaction(trans)

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

def delegatebw(self, fromAccount, netQuantity, cpuQuantity, toAccount=None, transferTo=False, waitForTransBlock=False, exitOnError=False, reportStatus=True):
def delegatebw(self, fromAccount, netQuantity, cpuQuantity, toAccount=None, transferTo=False, waitForTransBlock=False, exitOnError=False, reportStatus=True, sign=False):
if toAccount is None:
toAccount=fromAccount

signStr = Node.__sign_str(sign, [ fromAccount.activePublicKey ])
cmdDesc="system delegatebw"
transferStr="--transfer" if transferTo else ""
cmd="%s -j %s %s \"%s %s\" \"%s %s\" %s" % (
cmdDesc, fromAccount.name, toAccount.name, netQuantity, CORE_SYMBOL, cpuQuantity, CORE_SYMBOL, transferStr)
cmd="%s -j %s %s %s \"%s %s\" \"%s %s\" %s" % (
cmdDesc, signStr, fromAccount.name, toAccount.name, netQuantity, CORE_SYMBOL, cpuQuantity, CORE_SYMBOL, transferStr)
msg="fromAccount=%s, toAccount=%s" % (fromAccount.name, toAccount.name);
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
self.trackCmdTransaction(trans, reportStatus=reportStatus)

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

def undelegatebw(self, fromAccount, netQuantity, cpuQuantity, toAccount=None, waitForTransBlock=False, exitOnError=False):
def undelegatebw(self, fromAccount, netQuantity, cpuQuantity, toAccount=None, waitForTransBlock=False, exitOnError=False, sign=False):
if toAccount is None:
toAccount=fromAccount

signStr = Node.__sign_str(sign, [ fromAccount.activePublicKey ])
cmdDesc="system undelegatebw"
cmd="%s -j %s %s \"%s %s\" \"%s %s\"" % (
cmdDesc, fromAccount.name, toAccount.name, netQuantity, CORE_SYMBOL, cpuQuantity, CORE_SYMBOL)
cmd="%s -j %s %s %s \"%s %s\" \"%s %s\"" % (
cmdDesc, signStr, fromAccount.name, toAccount.name, netQuantity, CORE_SYMBOL, cpuQuantity, CORE_SYMBOL)
msg="fromAccount=%s, toAccount=%s" % (fromAccount.name, toAccount.name);
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
self.trackCmdTransaction(trans)

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

def regproducer(self, producer, url, location, waitForTransBlock=False, exitOnError=False):
def regproducer(self, producer, url, location, waitForTransBlock=False, exitOnError=False, sign=False):
signStr = Node.__sign_str(sign, [ producer.activePublicKey ])
cmdDesc="system regproducer"
cmd="%s -j %s %s %s %s" % (
cmdDesc, producer.name, producer.activePublicKey, url, location)
cmd="%s -j %s %s %s %s %s" % (
cmdDesc, signStr, producer.name, producer.activePublicKey, url, location)
msg="producer=%s" % (producer.name);
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
self.trackCmdTransaction(trans)

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)

def vote(self, account, producers, waitForTransBlock=False, exitOnError=False):
def vote(self, account, producers, waitForTransBlock=False, exitOnError=False, sign=False):
signStr = Node.__sign_str(sign, [ account.activePublicKey ])
cmdDesc = "system voteproducer prods"
cmd="%s -j %s %s" % (
cmdDesc, account.name, " ".join(producers))
cmd="%s -j %s %s %s" % (
cmdDesc, signStr, account.name, " ".join(producers))
msg="account=%s, producers=[ %s ]" % (account.name, ", ".join(producers));
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
self.trackCmdTransaction(trans)
Expand Down
Loading

0 comments on commit 5e7edd3

Please sign in to comment.