Skip to content
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

Merged
merged 14 commits into from Dec 9, 2020
Merged

Gas used sanity check #2567

merged 14 commits into from Dec 9, 2020

Conversation

sasurobert
Copy link
Contributor

@sasurobert sasurobert commented Dec 8, 2020

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.

@@ -1841,7 +1841,20 @@ func newMetaBlockProcessor(
rater sharding.PeerAccountListAndRatingHandler,
) (process.BlockProcessor, error) {

builtInFuncs := builtInFunctions.NewBuiltInFunctionContainer()
argsBuiltIn := builtInFunctions.ArgsCreateBuiltInFunctionContainer{
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 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
Copy link
Contributor

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

Copy link
Contributor Author

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)
Copy link
Contributor

Choose a reason for hiding this comment

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

safeSubUint64 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no. these are added.

@@ -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")
Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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?

Copy link
Contributor Author

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

process/smartContract/process.go Show resolved Hide resolved
@@ -1144,6 +1213,8 @@ func (sc *scProcessor) processVMOutput(
if !createdAsyncCallback && callType == vmcommon.AsynchronousCall {
Copy link
Contributor

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

Copy link
Contributor Author

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 {
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it has subtle differences.

@@ -100,6 +109,10 @@ func (sc *scProcessor) createVMCallInput(
vmCallInput.VMInput.Arguments = finalArguments
vmCallInput.GasProvided = vmCallInput.GasProvided - gasLocked

if vmCallInput.GasProvided+vmCallInput.GasLocked > tx.GetGasLimit() {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

iulianpascalau
iulianpascalau previously approved these changes Dec 8, 2020
iulianpascalau
iulianpascalau previously approved these changes Dec 8, 2020
var ErrAdditionOverflow = errors.New("uint64 addition overflow")

// ErrSubtractionOverflow signals that uint64 subtraction overflowed
var ErrSubtractionOverflow = errors.New("signals the uint64 subtraction overflowed")
Copy link
Contributor

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"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

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
Copy link
Contributor

Choose a reason for hiding this comment

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

typo issueing -> issuing

Copy link
Contributor Author

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
Copy link
Contributor

Choose a reason for hiding this comment

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

safeAdd?

Copy link
Contributor Author

@sasurobert sasurobert Dec 8, 2020

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.

@@ -100,6 +109,14 @@ func (sc *scProcessor) createVMCallInput(
vmCallInput.VMInput.Arguments = finalArguments
vmCallInput.GasProvided = vmCallInput.GasProvided - gasLocked
Copy link
Contributor

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?

Copy link
Contributor Author

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.

iulianpascalau
iulianpascalau previously approved these changes Dec 8, 2020
AdoAdoAdo
AdoAdoAdo previously approved these changes Dec 8, 2020
@@ -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")
Copy link
Contributor

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")

Copy link
Contributor Author

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(
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldUseLastTransferAsAsyncCallBack

Copy link
Contributor Author

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)
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

if !createdAsyncCallback {
createdAsyncCallback = tmpCreatedAsyncCallback
}
createdAsyncCallback = createdAsyncCallback || tmpCreatedAsyncCallback

scrResults = append(scrResults, newSCRTxs...)
Copy link
Contributor

Choose a reason for hiding this comment

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

if len(newSCRTxs) != 0 {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

if !createdAsyncCallback {
createdAsyncCallback = tmpCreatedAsyncCallback
}
createdAsyncCallback = createdAsyncCallback || tmpCreatedAsyncCallback
scrResults = append(scrResults, scTxs...)
Copy link
Contributor

Choose a reason for hiding this comment

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

if len(scTxs) != 0 {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

iulianpascalau
iulianpascalau previously approved these changes Dec 8, 2020
SebastianMarian
SebastianMarian previously approved these changes Dec 8, 2020
mihaib79
mihaib79 previously approved these changes Dec 8, 2020
@@ -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))
Copy link
Contributor

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 {
Copy link
Contributor

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.

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 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)
Copy link
Contributor

Choose a reason for hiding this comment

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

sndShardID

Copy link
Contributor Author

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)
Copy link
Contributor

Choose a reason for hiding this comment

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

dstShardID

Copy link
Contributor Author

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)
Copy link
Contributor

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
   }
}

Copy link
Contributor Author

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

Copy link
Contributor Author

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()
Copy link
Contributor

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?

@sasurobert sasurobert merged commit c233ae1 into development Dec 9, 2020
@LucianMincu LucianMincu deleted the gasUsed-sanity-check branch December 29, 2020 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants