-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Fix off-by-one error in decodeLog #3692
Conversation
topics[0] identifies the event; the first indexed param is topics[1].
Thanks again @wbt could you provide examples of the errors you were seeing. Would help greatly to approve this :) |
Here is a simplified example set of reproduction steps: In shell with truffle globally installed:
New file contracts/Aggregator.sol: //SPDX-License-Identifier: GPL
pragma solidity ^0.6.5;
contract Aggregator {
uint32 public currentTotal;
//The first parameter is SIGNED and negative in functions removed from
//this simplified example; it is larger to accommodate the sign bit.
event TotalChanged(int40 indexed howMuchAdded, uint32 indexed newTotal);
function addToTotal(uint32 howMuch) public returns (uint32 newTotal) {
emit TotalChanged(howMuch, (newTotal = currentTotal+howMuch));
currentTotal = newTotal;
}
} New file migrations/2_contract_deploy.js: var Aggregator = artifacts.require("Aggregator");
module.exports = function(deployer, network, accounts) {
deployer.deploy(Aggregator);
}; New file migrations/3_aggregate.js: var Aggregator = artifacts.require("Aggregator");
var Web3 = require('web3');
const wait = ms => new Promise((r, j)=>setTimeout(r, ms));
const blockTime = 5000; //ms; change this to your network's block time
module.exports = function(deployer, network, accounts) {
let aggregatorInstance, txHash;
let web3Local = new Web3(deployer.provider);
console.log("Using web3 version",web3Local.version);
deployer.then(function() {
return Aggregator.deployed();
}).then(function(instance) {
aggregatorInstance = instance;
return startTransaction(aggregatorInstance);
}).then(function(hash) {
txHash = hash;
return wait(blockTime*2); //needed only with geth, not with automining ganache
}).then(function() {
return web3Local.eth.getTransactionReceipt(txHash);
}).then(function(receipt) {
if(receipt == null || !receipt.status) {
console.log("Receipt does not reflect completed transaction:",receipt);
} else {
console.log("Receipt: ",receipt);
let log = receipt.logs[0];
let logABI = aggregatorInstance.constructor.events[log.topics[0]];
let parsedLogs = web3Local.eth.abi.decodeLog(logABI.inputs, log.data, log.topics);
console.log("Calling web3.eth.abi.decodeLog(",logABI.inputs,",",
log.data,",", log.topics,") produced ",parsedLogs);
console.log("Added "+parsedLogs['howMuchAdded']+
" to the aggregator; the new total is "+parsedLogs['newTotal']+".");
}
}).catch(function(err) {
console.log(err.message);
});
};
startTransaction = function(aggregatorInstance) {
return new Promise(function(resolve, reject) {
aggregatorInstance.contract.methods.addToTotal(16).send(
{from: Aggregator.defaults().from},
function(error, data) {
if(error) {
reject(error);
} else {
if(typeof data === 'object') {
reject("Object returned from method call instead of transaction hash.");
} else {
resolve(data);
}
}
}
)
});
} In truffle-config.js: compilers: {
solc: {
version: "^0.6.5"
}
}, Also have Ganache running and/or set up network connections in truffle-config, having the node running. Then run Actual results at the end of the final migration after doing once with reset and once with just the final migration:
With the patch applied, running the final migration again produces the expected results:
(Note: 16*3=48). The cause of the issue becomes clear if you inspect the values of parameters passed to ABICoder.prototype.decodeParameters. |
The simplest workaround is, just before calling decodeLog, to call Unfortunately, if anybody is already using that workaround and the patch is applied, the result is an error:
|
This PR has been automatically marked as stale beacause it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment. |
topics[0] identifies the event; the first indexed param is topics[1].
Description
When trying to use web3.eth.abi.decodeLog on an event with two indexed parameters (an int40 and uint32), both of which were fairly small integers with the first constant between tests and the second increasing by steps of the first, I was regularly getting a constant large negative number for the first and a constant small number (matching the value of the first) for the second. This is because topics[0] is used to identify which event a log is for, and the indexed parameters follow.
Collaboration for the unchecked items below is welcome.
Type of change
Checklist:
npm run dtslint
with success and extended the tests and types if necessary.npm run test:unit
with success.npm run test:cov
and my test cases cover all the lines and branches of the added code.npm run build
and testeddist/web3.min.js
in a browser.CHANGELOG.md
file in the root folder.