Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Fix Block Walker For Transactions #5800

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/Cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ def bios_bootstrap(totalNodes, biosHost, biosPort, dontKill=False):
with open(Cluster.__bootlog) as bootFile:
for line in bootFile:
if p.search(line):
Utils.Print("ERROR: bios_boot.sh script resulted in errors. See %s" % (bootlog))
Utils.Print("ERROR: bios_boot.sh script resulted in errors. See %s" % (Cluster.__bootlog))
Utils.Print(line)
return None

Expand Down
87 changes: 39 additions & 48 deletions tests/Node.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def __init__(self, host, port, pid=None, cmd=None, enableMongo=False, mongoHost=
self.infoValid=None
self.lastRetrievedHeadBlockNum=None
self.lastRetrievedLIB=None
self.transCache={}
if self.enableMongo:
self.mongoEndpointArgs += "--host %s --port %d %s" % (mongoHost, mongoPort, mongoDb)

Expand Down Expand Up @@ -326,21 +327,19 @@ def isBlockFinalized(self, blockNum):
return self.isBlockPresent(blockNum, blockType=BlockType.lib)

class BlockWalker:
def __init__(self, node, transOrTransId, startBlockNum=None, endBlockNum=None):
assert(isinstance(transOrTransId, (str,dict)))
if isinstance(transOrTransId, str):
self.trans=None
self.transId=transOrTransId
else:
self.trans=transOrTransId
self.transId=Node.getTransId(trans)
def __init__(self, node, transId, startBlockNum=None, endBlockNum=None):
assert(isinstance(transId, str))
self.trans=None
self.transId=transId
self.node=node
self.startBlockNum=startBlockNum
self.endBlockNum=endBlockNum

def walkBlocks(self):
start=None
end=None
if self.trans is None and self.transId in self.transCache:
self.trans=self.transCache[self.transId]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw a KeyError exception if self.transId is not in self.transCache. It will not return None.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need self.transId in self.transCache.keys(), right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use self.transCache.get(self.transId). That returns None if the key is not present in the dictionary.

if self.trans is not None:
cntxt=Node.Context(self.trans, "trans")
cntxt.add("processed")
Expand Down Expand Up @@ -373,16 +372,11 @@ def walkBlocks(self):
block=self.node.getBlock(blockNum)
msg+=json.dumps(block, indent=2, sort_keys=True)+"\n"

return msg

# pylint: disable=too-many-branches
def getTransaction(self, transOrTransId, silentErrors=False, exitOnError=False, delayedRetry=True):
transId=None
trans=None
assert(isinstance(transOrTransId, (str,dict)))
if isinstance(transOrTransId, str):
transId=transOrTransId
else:
trans=transOrTransId
transId=Node.getTransId(trans)
def getTransaction(self, transId, silentErrors=False, exitOnError=False, delayedRetry=True):
assert(isinstance(transId, str))
exitOnErrorForDelayed=not delayedRetry and exitOnError
timeout=3
blockWalker=None
Expand All @@ -395,7 +389,7 @@ def getTransaction(self, transOrTransId, silentErrors=False, exitOnError=False,
if trans is not None or not delayedRetry:
return trans
if blockWalker is None:
blockWalker=Node.BlockWalker(self, transOrTransId)
blockWalker=Node.BlockWalker(self, transId)
if Utils.Debug: Utils.Print("Could not find transaction with id %s, delay and retry" % (transId))
time.sleep(timeout)

Expand Down Expand Up @@ -466,16 +460,11 @@ def isTransInBlock(self, transId, blockId):

return False

def getBlockIdByTransId(self, transOrTransId, delayedRetry=True):
"""Given a transaction (dictionary) or transaction Id (string), will return the actual block id (int) containing the transaction"""
assert(transOrTransId)
transId=None
assert(isinstance(transOrTransId, (str,dict)))
if isinstance(transOrTransId, str):
transId=transOrTransId
else:
transId=Node.getTransId(transOrTransId)
trans=self.getTransaction(transOrTransId, exitOnError=True, delayedRetry=delayedRetry)
def getBlockIdByTransId(self, transId, delayedRetry=True):
"""Given a transaction Id (string), will return the actual block id (int) containing the transaction"""
assert(transId)
assert(isinstance(transId, str))
trans=self.getTransaction(transId, exitOnError=True, delayedRetry=delayedRetry)

refBlockNum=None
key=""
Expand Down Expand Up @@ -565,7 +554,7 @@ def createInitializeAccount(self, account, creatorAccount, stakedDeposit=1000, w
account.activePublicKey, stakeNet, CORE_SYMBOL, stakeCPU, CORE_SYMBOL, buyRAM, CORE_SYMBOL)
msg="(creator account=%s, account=%s)" % (creatorAccount.name, account.name);
trans=self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError, exitMsg=msg)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)
transId=Node.getTransId(trans)

if stakedDeposit > 0:
Expand All @@ -583,13 +572,13 @@ def createAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTran
cmdDesc, 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)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)
transId=Node.getTransId(trans)

if stakedDeposit > 0:
self.waitForTransInBlock(transId) # seems like account creation needs to be finlized before transfer can happen
trans = self.transferFunds(creatorAccount, account, "%0.04f %s" % (stakedDeposit/10000, CORE_SYMBOL), "init")
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)
transId=Node.getTransId(trans)

return self.waitForTransBlockIfNeeded(trans, waitForTransBlock, exitOnError=exitOnError)
Expand Down Expand Up @@ -740,7 +729,7 @@ def transferFunds(self, source, destination, amountStr, memo="memo", force=False
trans=None
try:
trans=Utils.runCmdArrReturnJson(cmdArr)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)
except subprocess.CalledProcessError as ex:
msg=ex.output.decode("utf-8")
Utils.Print("ERROR: Exception during funds transfer. %s" % (msg))
Expand Down Expand Up @@ -922,7 +911,7 @@ def publishContract(self, account, contractDir, wasmFile, abiFile, waitForTransB
trans=None
try:
trans=Utils.runCmdReturnJson(cmd, trace=False)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)
except subprocess.CalledProcessError as ex:
if not shouldFail:
msg=ex.output.decode("utf-8")
Expand Down Expand Up @@ -980,7 +969,7 @@ def pushMessage(self, account, action, data, opts, silentErrors=False):
if Utils.Debug: Utils.Print("cmd: %s" % (cmdArr))
try:
trans=Utils.runCmdArrReturnJson(cmdArr)
Node.logCmdTransaction(trans, ignoreNonTrans=True)
self.trackCmdTransaction(trans, ignoreNonTrans=True)
return (True, trans)
except subprocess.CalledProcessError as ex:
msg=ex.output.decode("utf-8")
Expand All @@ -992,7 +981,7 @@ def setPermission(self, account, code, pType, requirement, waitForTransBlock=Fal
cmdDesc="set action permission"
cmd="%s -j %s %s %s %s" % (cmdDesc, account, code, pType, requirement)
trans=self.processCleosCmd(cmd, cmdDesc, silentErrors=False, exitOnError=exitOnError)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)

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

Expand All @@ -1006,7 +995,7 @@ def delegatebw(self, fromAccount, netQuantity, cpuQuantity, toAccount=None, tran
cmdDesc, 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)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)

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

Expand All @@ -1016,7 +1005,7 @@ def regproducer(self, producer, url, location, waitForTransBlock=False, exitOnEr
cmdDesc, producer.name, producer.activePublicKey, url, location)
msg="producer=%s" % (producer.name);
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)

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

Expand All @@ -1026,7 +1015,7 @@ def vote(self, account, producers, waitForTransBlock=False, exitOnError=False):
cmdDesc, account.name, " ".join(producers))
msg="account=%s, producers=[ %s ]" % (account.name, ", ".join(producers));
trans=self.processCleosCmd(cmd, cmdDesc, exitOnError=exitOnError, exitMsg=msg)
Node.logCmdTransaction(trans)
self.trackCmdTransaction(trans)

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

Expand Down Expand Up @@ -1336,23 +1325,25 @@ def isNodeAlive():
self.killed=False
return True

@staticmethod
def logCmdTransaction(trans, ignoreNonTrans=False):
if not Utils.Debug:
return

def trackCmdTransaction(self, trans, ignoreNonTrans=False):
if trans is None:
Utils.Print(" cmd returned transaction: %s" % (trans))
if Utils.Debug: Utils.Print(" cmd returned transaction: %s" % (trans))
return

if ignoreNonTrans and not Node.isTrans(trans):
Utils.Print(" cmd returned a non-transaction")
if Utils.Debug: Utils.Print(" cmd returned a non-transaction")
return

transId=Node.getTransId(trans)
status=Node.getTransStatus(trans)
blockNum=Node.getTransBlockNum(trans)
Utils.Print(" cmd returned transaction id: %s, status: %s, (possible) block num: %s" % (transId, status, blockNum))
if Utils.Debug:
status=Node.getTransStatus(trans)
blockNum=Node.getTransBlockNum(trans)
if transId in self.transCache.keys():
replaceMsg="replacing previous trans=\n%s" % json.dumps(self.transCache[transId], indent=2, sort_keys=True)
else:
replaceMsg=""
Utils.Print(" cmd returned transaction id: %s, status: %s, (possible) block num: %s %s" % (transId, status, blockNum, replaceMsg))
self.transCache[transId]=trans

def reportStatus(self):
Utils.Print("Node State:")
Expand Down
2 changes: 1 addition & 1 deletion tests/consensus-validation-malicious-producers.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ def myTest(transWillEnterBlock):
return False

Print("Get details for transaction %s" % (transId))
transaction=node2.getTransaction(trans[1], exitOnError=True)
transaction=node2.getTransaction(transId, exitOnError=True)
signature=transaction["transaction"]["signatures"][0]

blockNum=int(transaction["transaction"]["ref_block_num"])
Expand Down
2 changes: 1 addition & 1 deletion tests/launcher_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@

node.waitForTransInBlock(transId)

transaction=node.getTransaction(trans, exitOnError=True, delayedRetry=False)
transaction=node.getTransaction(transId, exitOnError=True, delayedRetry=False)

typeVal=None
amountVal=None
Expand Down
4 changes: 2 additions & 2 deletions tests/nodeos_run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@

node.waitForTransInBlock(transId)

transaction=node.getTransaction(trans, exitOnError=True, delayedRetry=False)
transaction=node.getTransaction(transId, exitOnError=True, delayedRetry=False)

typeVal=None
amountVal=None
Expand Down Expand Up @@ -467,7 +467,7 @@
raise

Print("Test for block decoded packed transaction (issue 2932)")
blockId=node.getBlockIdByTransId(trans[1])
blockId=node.getBlockIdByTransId(transId)
assert(blockId)
block=node.getBlock(blockId, exitOnError=True)

Expand Down