Did it run Out of Gas? 오류

const CaverExtKAS = require(“caver-js-ext-kas”);
const caver = new CaverExtKAS();
caver.initKASAPI(appconfig.chainId, appconfig.accessKeyId, appconfig.secretAccessKey);

function run()
{
const senderTransaction = {
from: ownerAddress,
gas: 100000000
};
const contractInstance = new caver.klay.Contract(contractABI, contractAddress); ← 컨트랙트 객체 한번 생성하고 아래에서 계속 사용
contractInstance.setWallet(keyringContainer);

for (var i = 0; i < selectedAddresses.length; i++) <- 1657회 balanceOf 호출
{
	const amount = await contractInstance.methods.balanceOf(address).call(senderTransaction); <- 오류 발생 예상 위치
}

const paused = await contractInstance.methods.paused().call(senderTransaction);
if (!paused)
{
	await contractInstance.methods.pause().send(senderTransaction);
}

}

오류 메시지:
Error: Returned values aren’t valid, did it run Out of Gas? You might also see this error if you are not using the correct ABI for the contract you are retrieving data from, requesting data from a block number that does not exist, or querying a node which is not fully synced.
at ABI.decodeParametersWith (/…/api/node_modules/caver-js/packages/caver-abi/src/index.js:596:15)
at ABI.decodeParameters (/…/node_modules/caver-js/packages/caver-abi/src/index.js:578:17)
at Contract._decodeMethodReturn (/…/node_modules/caver-js/packages/caver-contract/src/index.js:924:24)
at Method.outputFormatter (/…/node_modules/caver-js/packages/caver-contract/src/index.js:1536:42)
at _formatOutput (/…/node_modules/caver-js/packages/caver-core-method/src/index.js:207:87)
at Method.formatOutput (/…/node_modules/caver-js/packages/caver-core-method/src/index.js:211:60)
at /…/node_modules/caver-js/packages/caver-core-method/src/index.js:240:25
at /…/node_modules/caver-js/packages/caver-core-requestmanager/src/index.js:162:17
at XMLHttpRequest.request.onreadystatechange (/…/node_modules/caver-js/packages/caver-core-requestmanager/caver-providers-http/src/index.js:119:13)
at XMLHttpRequestEventTarget.dispatchEvent (/…/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)

크론에 등록되어 하루에 한번씩 실행되는 함수 내의 코드 일부인데, 4일째만에 오류가 발생하였습니다.
오류가 발생하여 동일한 환경으로 구성된 개발 노트북에서 실행하니 한번에 정상으로 처리되었습니다.
당시 오너계정에는 16KLAY 정도의 충분한 수량이 있는 상태였습니다.

안녕하세요,
KAS 제품팀입니다.

문의하신 내용은 내부적으로 확인 후 답변을 드릴 수 있도록 하겠습니다.
연휴로 인해 답변이 다소 늦어질 수 있는 부분은 미리 양해를 부탁드리겠습니다.

감사합니다.

KAS 제품팀 드림,

@shun

안녕하세요.
우선 정확한 에러 파악을 위해 사용하신 소스코드 및 ContractABI 공유를 부탁드립니다. :slight_smile:

소스코드를 공유해주실 때 연결하는 Endpoint 의 URL 등 노출이 어려운 부분은 가려주셔도 좋습니다.

소스코드 다운로드: cron.zip - Google Drive

오류 메시지: 첫번째 올린 글 참조

  1. 오류의 요지는 out of gas 이며, 읽기 동작인 balanceOf를 1657회 호출하는 동안 충분한 KLAY가 있었음에도 발생하였고, 매번 나오는 오류가 아니라는 점입니다.

  2. cron.js 6번줄 const caver = new CaverExtKAS(); 이 코드가 서버시작하면서 한번 호출되고 전역으로 유지되는 상황인데 문제 없는지요?

  3. cron.js 20번줄 gas: 100000000 가스비를 너무 과도하게 입력한것은 아닌지요?

  4. balanceOf는 읽기 동작인데 가스비가 소모되는지요?

  5. 가스비가 어떻게 계산되는지 알고 싶습니다.

@shun

우선 주신 소스코드를 확인해보았습니다.
우선 appconfig.js 의 ChainId 필드 값을 1001로 수정 부탁드립니다.
저에게 주신 소스코드 원본의 컨트랙 주소는 Baobab에 배포가 되어 있더라구요. 따라서 테스트가 제대로 되려면 ChainId를 Baobab으로 지정하시는 것이 맞습니다.

참고로 ChainId를 잘못 지정해서 콜을 날리면 @shun 님께서 겪은 에러가 그대로 재현이 됩니다.

또한 해당 에러는 가스가 부족해서 발생했다기 보다는 노드로부터 데이터를 정상적으로 받아오지 못해 발생한 것으로 보입니다. 아래는 해당 에러를 발생시키는 소스 원본입니다.

caver-js > packages > caver-abi > src > index.js
// outpus: [ { internalType: 'uint256', name: 'balance', type: 'uint256' } ] 와 같은 ABI
// bytes: 실제 노드로부터 요청해서 리턴 받은 값
ABI.prototype.decodeParametersWith = function (outputs, bytes, loose) {
    if (outputs.length > 0 && (!bytes || bytes === '0x' || bytes === '0X')) {
        throw new Error(
            "Returned values aren't valid, did it run Out of Gas? " +
            'You might also see this error if you are not using the ' +
            'correct ABI for the contract you are retrieving data from, ' +
            'requesting data from a block number that does not exist, ' +
            'or querying a node which is not fully synced.'
        )
    }

질문들에 대한 답을 드려보면

  1. 우선 balanceOf 콜은 읽기 동작이므로 가스가 소요되지 않습니다. 여기서 발생하는 문제 같지는 않습니다.
  2. 전역으로 유지되도 크게 문제될 상황은 없습니다만, @shun 님이 운영하시는 코드에 따라 문제가 될 수 있는 소지가 있을 수 있습니다. Case by case 일 거 같습니다 :slight_smile:
  3. 소모할 수 있는 맥시멈 gas 수량을 기재하는 것이기 때문에 많이 기재하셔도 무방합니다. 가스비라는 용어보다는 이 경우 사용하는 가스량의 상한선이 좀 더 정확한 표현일 거 같습니다.
  4. 가스는 소모되지 않습니다.
  5. Klaytn의 GasPrice는 25 ston으로 고정되어 있습니다. 또한 Klaytn에는 gas 사용량의 상한선이 존재하지 않습니다. 가스에 대해서는 리밋이 없다고 보시면 되겠습니다. 대신 Computation cost 라는 개념이 존재하므로 첨부드린 링크에서 상세한 내용 확인을 부탁드립니다 :slight_smile:

답변 감사드립니다.

며칠동안 별도의 운영스트립트로 작업하면서 느끼는건데 아주 간헐적으로 서버 네트워크 상황에 따라 해당 오류가 발생함을 알게되었습니다. 곧바로 재실행하면 정상 처리됩니다.

그래서 크론탭 실행 소스에 재시도 기능을 넣어서 적용하였습니다.

감사합니다.

1 Like