New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gas used sanity check #2567
Gas used sanity check #2567
Conversation
@@ -1841,7 +1841,20 @@ func newMetaBlockProcessor( | |||
rater sharding.PeerAccountListAndRatingHandler, | |||
) (process.BlockProcessor, error) { | |||
|
|||
builtInFuncs := builtInFunctions.NewBuiltInFunctionContainer() | |||
argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will cause conflicts with soft-restart feature branch (not having a great idea how to overcome this)
@@ -1719,7 +1727,7 @@ func (tpn *TestProcessorNode) LoadTxSignSkBytes(skBytes []byte) { | |||
// ProposeBlock proposes a new block | |||
func (tpn *TestProcessorNode) ProposeBlock(round uint64, nonce uint64) (data.BodyHandler, data.HeaderHandler, [][]byte) { | |||
startTime := time.Now() | |||
maxTime := time.Second * 2 | |||
maxTime := time.Second * 20000 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might revert the values here and on L1953 and L1983
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
totalGasInVMOutput := vmOutput.GasRemaining | ||
for _, outAcc := range vmOutput.OutputAccounts { | ||
for _, outTransfer := range outAcc.OutputTransfers { | ||
transferGas, err := safeAddUint64(outTransfer.GasLocked, outTransfer.GasLimit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
safeSubUint64 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no. these are added.
process/smartContract/process.go
Outdated
@@ -481,10 +528,15 @@ func (sc *scProcessor) computeTotalConsumedFeeAndDevRwd( | |||
} | |||
|
|||
senderInSelfShard := sc.isSelfShard(tx.GetSndAddr()) | |||
consumedGas := safeSubUint64(tx.GetGasLimit(), vmOutput.GasRemaining) | |||
consumedGas, err := safeSubUint64(tx.GetGasLimit(), vmOutput.GasRemaining) | |||
log.LogIfError(err, "computeTotalConsumedFeeAndDevRwd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need a third parameter here, otherwise computeTotalConsumedFeeAndDevRwd won't be displayed. Add more info as to easily pin-point the errors in case they appear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
err = sc.gasConsumedChecks(tx, vmOutput) | ||
if err != nil { | ||
log.Error("gasConsumedChecks with problem ", "err", err.Error(), "txHash", txHash) | ||
return vmcommon.ExecutionFailed, sc.ProcessIfError(acntSnd, txHash, tx, err.Error(), []byte("gas consumed exceeded"), snapshot, vmInput.GasLocked) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this still backwards-compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. it is. only in asynccall we had these issues. plus this shouldn't ever happen
@@ -1144,6 +1213,8 @@ func (sc *scProcessor) processVMOutput( | |||
if !createdAsyncCallback && callType == vmcommon.AsynchronousCall { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if L1213-L1218 were to be extracted to another function, then we could have avoided the else-if situation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tried, but does not look good. thanks golang.
log.Error("gasConsumedChecks with problem ", "err", err.Error(), "txHash", txHash) | ||
return vmcommon.ExecutionFailed, sc.ProcessIfError(acntSnd, txHash, tx, err.Error(), []byte("gas consumed exceeded"), snapshot, vmInput.GasLocked) | ||
} | ||
|
||
createdAsyncCallback := false | ||
scrResults := make([]data.TransactionHandler, 0, len(vmOutput.OutputAccounts)+1) | ||
outputAccounts := process.SortVMOutputInsideData(vmOutput) | ||
for _, outAcc := range outputAccounts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like duplicated code L167x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it has subtle differences.
process/smartContract/vmInput.go
Outdated
@@ -100,6 +109,10 @@ func (sc *scProcessor) createVMCallInput( | |||
vmCallInput.VMInput.Arguments = finalArguments | |||
vmCallInput.GasProvided = vmCallInput.GasProvided - gasLocked | |||
|
|||
if vmCallInput.GasProvided+vmCallInput.GasLocked > tx.GetGasLimit() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't we use here the safe add? What happens if the sum overflows the uint64 max value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
process/errors.go
Outdated
var ErrAdditionOverflow = errors.New("uint64 addition overflow") | ||
|
||
// ErrSubtractionOverflow signals that uint64 subtraction overflowed | ||
var ErrSubtractionOverflow = errors.New("signals the uint64 subtraction overflowed") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fix error message "uint64 subtraction overflowed"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
process/smartContract/process.go
Outdated
vmOutput *vmcommon.VMOutput, | ||
) error { | ||
if tx.GetGasLimit() == 0 && sc.shardCoordinator.ComputeId(tx.GetSndAddr()) == core.MetachainShardId { | ||
// special case for issueing and minting ESDT tokens for normal users |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo issueing -> issuing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
|
||
result.CallType = vmcommon.AsynchronousCallBack | ||
result.GasLimit += vmOutput.GasRemaining |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
safeAdd?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error was treated before on gasConsumedChecks which is called before this function.
process/smartContract/vmInput.go
Outdated
@@ -100,6 +109,14 @@ func (sc *scProcessor) createVMCallInput( | |||
vmCallInput.VMInput.Arguments = finalArguments | |||
vmCallInput.GasProvided = vmCallInput.GasProvided - gasLocked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use here safeSub instead of adding a check with safeAdd afterwards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. left both of them.
process/smartContract/process.go
Outdated
@@ -587,7 +641,8 @@ func (sc *scProcessor) ExecuteBuiltInFunction( | |||
log.Debug("processed built in functions error", "error", err.Error()) | |||
return 0, err | |||
} | |||
builtInFuncGasUsed := safeSubUint64(vmInput.GasProvided, vmOutput.GasRemaining) | |||
builtInFuncGasUsed, err := safeSubUint64(vmInput.GasProvided, vmOutput.GasRemaining) | |||
log.LogIfError(err, "computeTotalConsumedFeeAndDevRwd", "executeBuildInFunction") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
log.LogIfError(err, "ExecuteBuildInFunction", "builtInFuncGasUsed")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1454,6 +1523,34 @@ func (sc *scProcessor) createSmartContractResults( | |||
return createdAsyncCallBack, scResults | |||
} | |||
|
|||
func (sc *scProcessor) useLastTransferAsAsyncCallBackWhenNeeded( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldUseLastTransferAsAsyncCallBack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would leave it as it is.
isLastOutTransfer := i == lenOutTransfers-1 | ||
if isLastOutTransfer && isAsyncTransferBackToSender && sc.isTransferWithNoDataOrBuiltInCall(outputTransfer.Data) { | ||
addVMOutputResultsToSCR(vmOutput, result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not need to call addVMOutputResultsToSCR? In line 1548 and 1549 it is done now only part of this whole method. Also
is done result.GasLimit += vmOutput.GasRemaining instead result.GasLimit = vmOutput.GasRemaining like it is done in addVMOutputResultsToSCR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to call. that method was wrongly called here and would have deleted the actual issueing of ESDT token from an smart contract. in case of outPutTransfer you need different operations here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
process/smartContract/process.go
Outdated
if !createdAsyncCallback { | ||
createdAsyncCallback = tmpCreatedAsyncCallback | ||
} | ||
createdAsyncCallback = createdAsyncCallback || tmpCreatedAsyncCallback | ||
|
||
scrResults = append(scrResults, newSCRTxs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if len(newSCRTxs) != 0 {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
process/smartContract/process.go
Outdated
if !createdAsyncCallback { | ||
createdAsyncCallback = tmpCreatedAsyncCallback | ||
} | ||
createdAsyncCallback = createdAsyncCallback || tmpCreatedAsyncCallback | ||
scrResults = append(scrResults, scTxs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if len(scTxs) != 0 {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
e47d180
9b1ced5
@@ -210,6 +210,12 @@ func (irp *intermediateResultsProcessor) AddIntermediateTransactions(txs []data. | |||
return process.ErrWrongTypeAssertion | |||
} | |||
|
|||
err := irp.checkSmartContractResultIntegrity(addScr) | |||
if err != nil { | |||
log.Error("AddIntermediateTransaction", "error", err, "dump", spew.Sdump(addScr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -235,6 +241,31 @@ func (irp *intermediateResultsProcessor) AddIntermediateTransactions(txs []data. | |||
return nil | |||
} | |||
|
|||
func (irp *intermediateResultsProcessor) checkSmartContractResultIntegrity(scr *smartContractResult.SmartContractResult) error { | |||
if len(scr.RcvAddr) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could have made InterceptedUnsignedTransaction.integrity() exported function without pointer receiver (with the SmartContractResult parameter) and used it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not think it will work - maybe we will have some cyclic imports.
@@ -257,6 +257,10 @@ func checkSmartContractResultIntegrity(scr *smartContractResult.SmartContractRes | |||
if len(scr.PrevTxHash) == 0 { | |||
return process.ErrNilTxHash | |||
} | |||
sndId := irp.shardCoordinator.ComputeId(scr.SndAddr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sndShardID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -258,7 +258,8 @@ func (irp *intermediateResultsProcessor) checkSmartContractResultIntegrity(scr * | |||
return process.ErrNilTxHash | |||
} | |||
sndId := irp.shardCoordinator.ComputeId(scr.SndAddr) | |||
if !core.IsEmptyAddress(scr.SndAddr) && sndId != irp.shardCoordinator.SelfId() { | |||
dstId := irp.shardCoordinator.ComputeId(scr.RcvAddr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dstShardID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -258,7 +258,8 @@ func (irp *intermediateResultsProcessor) checkSmartContractResultIntegrity(scr * | |||
return process.ErrNilTxHash | |||
} | |||
sndId := irp.shardCoordinator.ComputeId(scr.SndAddr) | |||
if !core.IsEmptyAddress(scr.SndAddr) && sndId != irp.shardCoordinator.SelfId() { | |||
dstId := irp.shardCoordinator.ComputeId(scr.RcvAddr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if scr.SndAddr or scr.RcvAddr are nil. Maybe you should move this inside
if !core.IsEmptyAddress(scr.SndAddr) && !core.IsEmptyAddress(scr.RcvAddr) {
sndShardID := irp.shardCoordinator.ComputeId(scr.SndAddr)
dstShardID := irp.shardCoordinator.ComputeId(scr.RcvAddr)
if sndShardID != irp.shardCoordinator.SelfId() && dstShardID != irp.shardCoordinator.SelfId() {
return process.ErrShardIdMissmatch
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nil checks are done above. for both sender, receiver and prevtxhash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
modified to your suggestion
@@ -1600,11 +1604,16 @@ func (sc *scProcessor) createSCRForSenderAndRelayer( | |||
relayedSCR, isRelayed := isRelayedTx(tx) | |||
shouldRefundGasToRelayerSCR := isRelayed && callType != vmcommon.AsynchronousCall && gasRefund.Cmp(zero) > 0 | |||
if shouldRefundGasToRelayerSCR { | |||
senderForRelayerRefund := tx.GetRcvAddr() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have instead some hardcoded (constant) sender addresses for relayed txs that are constructed for each shard?
added check on vmInput and vmOutput for gasProvided and gas used
smart contract results do not need to consume move balance gas - as that part was already taken out at the sneder shard.