Logs of a pending ethereum transaction disappeared after confirmation - ethereum

When I used "eth_getLogs" to query logs of a pending transaction, the log info showed up as below, but after the tx was confirmed, the logs are not available on etherescan. This tx used the delegate call. Could anyone advise on why the logs disappeared?
log info by querying ""eth_getLogs"" when the tx is pending:
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x0000000000000000000000006463bd6026a2e7bfab5851b62969a92f7cca0eb6',
'0x000000000000000000000000860bd2dba9cd475a61e6d1b45e16c365f6d78f66'
],
data: '0x00000000000000000000000000000000000000000000058677bb9e53cb507ddd',
blockNumber: '0xb117d6',
transactionHash: '0x9b51d7093c4507fa96af3fd4418c508700cb9f69f3cea9d7f5a192afa30cd1bf',
transactionIndex: '0x41',
blockHash: '0x0000000000000000000000000000000000000000000000000000000000000000',
logIndex: '0x4f',
removed: false
}
transaction on etherscan after confirmation: https://etherscan.io/tx/0x9b51d7093c4507fa96af3fd4418c508700cb9f69f3cea9d7f5a192afa30cd1bf

Since the results of the transaction execution, including the generated events, depend on the state of the contract and the account at the time of execution, then, apparently, the shown log corresponds to the state if the transaction were included in block 0xb117d6, but at the time of real execution in the context of block 0xb117d8, the state block / account were already different, which led to a different result.
In addition, the prediction of the execution of pending transactions is based on the data of your specific node, which, in the presence of forks, may differ from the data of the main chain.

#Mad Jacal Thanks for your answer! Is my understanding bellow correct?
Let's say there's a contract like this:
contract test {
bool isTrue = true;
function foo() public {
if (isTrue) {
emit Event(..)
} else {
return;
}
}
function changeToFalse() public {
isTrue = false;
}
}
The first caller called "foo" function and second caller called "changeToFalse" function. The two txs are in the same block but the second caller's tx is in front of the first caller's tx due to higher gas price. The pending logs will show the event log if the node does not hear about the second caller's tx yet. Is this what you mean?

Related

Caffeine cache, perform eviction of expired element only when put succeds

I use Caffeine cache to cache data coming from the DB that need to served to a rest endpoint.
So the cache is updated ONLY on read operations on the DB.
In the nominal case, I want the cache to take the lead of responding until the data is not older than some point of time ( => this case is ok by defining the correct expiration options)
In case of DB access failure, I want to fallback to the cache even if the data in the cache is expired.
This use case supposes that expired data are not yet removed.
The solution I'm thinking of is to make Eviction of Items from the cache only after a successful PUT (a successful PUT means the DB is working correctly).
Is that possible to do?
This could be accomplished by using a victim cache to capture recently expired entries and resurrect from it on a load if the db is down. The victim cache would need its own bounding, e.g. a longer expiration threshold.
Cache<K, V> victimCache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTE)
.build();
LoadingCache<K, V> mainCache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTE)
.writer(new CacheWriter<K, V>() {
public void write(K key, V value) { /* ignored */ }
public void delete(K key, V value, RemovalCause cause) {
if (cause == RemovalCause.EXPIRED) {
victimCache.put(key, value);
}
})
.build(key -> {
try {
// load from db
} catch (DatabaseAccessException e) {
return victimCache.asMap().remove(key);
}
});
This would allow a load failure to resurrect the entry from the victim cache, if the entry is present.

How to sign a transaction send by contract

I am trying to understand the basics behind signing an ethereum transaction.
I come across Gnosis's MultiSigWallet :
https://github.com/gnosis/MultiSigWallet/blob/master/contracts/MultiSigWallet.sol
In which, a modifier onlyWallet requires a transaction must be sent from the contract itself, but the transaction is signed by one of the owners of the contracts:
modifier onlyWallet() {
require(msg.sender == address(this));
_;
}
for functions like:
function replaceOwner(address owner, address newOwner)
public
onlyWallet
ownerExists(owner)
ownerDoesNotExist(newOwner)
{...}
I have successfully deployed the contracts on my testnet, and tried its functionalities using their dapp https://wallet.gnosis.pm/#/transactions
However, I cannot understand how a transaction is signed and sent to meet the onlyWallet requirement, since signing a transaction using metamask for example will cause the msg.sender to be my own wallet address.
If possible, an example of this ethereumjs-tx's functions would be much appreciated.
like:
const privateKey = Buffer.from('<private key 1>','hex');
const txParams = {
nonce: web3.utils.toHex(11),
gasPrice: web3.utils.toHex(1000000000),
gasLimit: web3.utils.toHex(300000),
to: '<contract address>',
value: web3.utils.toHex(web3.utils.toWei("1",'ether')),
data: '0x00',
chainId: 1
};
let tx = new EthTx(txParams);
tx.sign(tx.serialize().toString('hex');
web3.eth.sendSignedTransaction(`0x${tx.serialize().toString('hex')}`,
(error, data) => {
if(!error) {
console.log(data);
}else console.log(error);
}
);
Thank you very much
Adding and removing an owner follows the same rules as confirming any transactions from the MultiSigWallet. Assume the wallet was deployed with 3 EOA addresses as owners and requiring 2 confirmations for execution. For any regular transaction, say donate funds from the wallet to a FundRaisingContract, one of the owners would need to first call submitTransaction() passing in the address of FundRaisingContract, the amount of ether, and the hash for the donate function. After submission, you still need 1 of the other owners to confirmTransaction (the submitter is automatically confirmed). Once completed, now executeTransaction can be successfully run which will execute the call to donate() from the MultiSigWallet address.
That last part is what you're looking for to answer your question. To add an owner, repeat the example but use the MultiSigWallet address and the hash of the addOwner method. When one of the other owners confirms the transaction, addOwner will be called and it will pass the onlyWallet modifier check.

How to detect a transaction that will fail in web3js

I've just recently finished working on a rather complex contract with the Remix IDE. I'm now attaching web3 to the frontend but when I call functions that should fail, they still go through on Metamask.
When testing my contract in Remix, I would often click on and call certain functions that had require statements that I knew would fail just to confirm that the contract state was recorded correctly. Remix didn't send the transaction to metamask and instead output an error message and I would like to handle the transaction error on my own as well.
How can I check my contract call to see whether it will fail. Must I use the method that predicts gas and detect it that way and if so how? My current code is below:
contract.callFunction(function(error, result) {
if (!error) alert(result);
else alert(error);
}
The above code catches rejecting the metamask confirmation as an error but transactions that should fail go through to metamask with an insanely high gas limit set. The function callFunction is in the contract and takes no parameters but does have an effect on the blockchain so it requires the transaction. The first line of the function is "require(state == 1);" and I have the contract set to state 2 currently so I'm expecting the transaction to fail, I just want to detect it failing.
In order to find out whether the transaction will fail we do have to call estimateGas() and attach a callback function. I assumed we'd have to check the gas estimate returned in order to predict whether it would fail but the process is made rather easy. Here's the full code I ended up with to successfully run a function while catching the two most common error cases.
contract.nextState.estimateGas(function(error, result) {
if (!error) {
contract.nextState(function(error, result) {
if (!error) {
alert("This is my value: " + result);
} else {
if (error.message.indexOf("User denied") != -1) {
alert("You rejected the transaction on Metamask!");
} else {
alert(error);
}
}
});
} else {
alert("This function cannot be run at this time.");
}
});
[EDIT] I'm coming back after the fact to help clear up information for those with a similar question. All of the information discussed below references the following link.
After creating a contract object, you can access any variable or function through using it's name. You can also access these members through array notation which is useful when the name of the variable or function isn't known at the time the code is written.
contract.foobar == contract["foobar"]
Once you have a function object (contract.foobar) you can use either call, send, or estimateGas. After first giving the function the parameters it needs (call it like any other function) you then use either call, send, or estimateGas on the returned object while providing options and a callback function.
This callback function takes 2 parameters. The first is the error which will be undefined if there was no error, and the second will be the result of the call, send, or estimateGas. Call and Send will both return the result of the function while estimateGas always returns a number showing how much gas is estimated to be necessary.

web3 calls Solidity contract function with extra parameter?

In the http://truffleframework.com/tutorials/pet-shop example, there is the following contract, and the function adopt(uint petId) has only one parameter.
contract Adoption {
address[16] public adopters;
function adopt(uint petId) public returns (uint) {
require(petId >= 0 && petId <= 15);
adopters[petId] = msg.sender;
return petId;
}
function getAdopters() public returns (address[16]) {
return adopters;
}
}
However, in the javascript code app.js, the handleAdopt function call the contract function using the following code.
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.adopt(petId, {from: account});
})
The function is called with the extra object {from: account}. Why? And is this parameter discarded in the solidity code?
BTW, there is an undefined global variable web3? Is the value be assigned by the MetaMask extension?
That is the transactionObject which describes general information about all transaction calls (gas limit, price, amount of ether to send, etc.). The JS code you posted is using the web3 library. That's not the direct call to the contract API. The web3 library converts it to an RPC. The transactionObject comes after all of the contract parameters. There is another parameter that comes after which is the callback with the results of the contract call (see here).
These are all of the options for the transactionobject described from the docs:
from: String - The address for the sending account. Uses the web3.eth.defaultAccount property, if not specified.
to: String - (optional) The destination address of the message, left undefined for a contract-creation transaction.
value: Number|String|BigNumber - (optional) The value transferred for the transaction in Wei, also the endowment if it's a contract-creation transaction.
gas: Number|String|BigNumber - (optional, default: To-Be-Determined) The amount of gas to use for the transaction (unused gas is refunded).
gasPrice: Number|String|BigNumber - (optional, default: To-Be-Determined) The price of gas for this transaction in wei, defaults to the mean network gas price.
data: String - (optional) Either a byte string containing the associated data of the message, or in the case of a contract-creation transaction, the initialisation code.
nonce: Number - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce.

How to force play framework to log exceptions which are thrown in another thread?

I have a function which is running in the separate thread. The code which calls this function not waits for result of it.
def sendEmail(email: String): Future[Unit] = {
...
}
def registration: Future[User] = {
...
// I do not want to wait for result of this function, just fire email sending
// in seprate thread and continue
sendEmail(email)
...
// Do another job
}
The problem is that if something went wrong in sendEmail function, I want to see this exception in log file.
Now log file and console output are empty if some exception is thrown there.
Is there a way to log exceptions from that separate thread?
P.S.: I do not want to log exception manually in sendEmail, but force play framework to log it.
In general, you wrap exceptions in the exceptionally block.
In java, it's like :
foobar.thenComposeAsync(arg -> {
sendEmail();
}).exceptionally(throwable -> {
// Do logging
});