Chainlink keeper not running performUpkeep, yet checkUpkeep returns true - chainlink

Like the title says, it seems all the conditions for a keeper to run performUpkeep have been met, yet it is not being called.
Here is the upkeep link: https://keepers.chain.link/kovan/upkeeps/413
Here is the contract: https://kovan.etherscan.io/address/0x969F42c92A6aeBD925982CCc1C943185B6D0E357#code
Here is the relevant code:
function checkUpkeep(bytes calldata checkData) external view override returns (bool upkeepNeeded, bytes memory performData) {
upkeepNeeded = shouldHarvest();
// We don't use the checkData
// checkData was defined when the Upkeep was registered
performData = checkData;
}
function performUpkeep(bytes calldata performData) external override {
harvest();
// We don't use the performData
// performData is generated by the Keeper's call to your `checkUpkeep` function
performData;
}
function shouldHarvest() internal view returns (bool) {
bool hasPendingOutput = IMasterChef(chef).pendingBall(poolId, address(this)) > harvestThreshold;
bool harvestCondition = hasPendingOutput && !paused();
return harvestCondition;
}
Things I have tried:
Increasing the gas limit, by making a new upkeep: https://keepers.chain.link/kovan/upkeeps/416
Using a contract without the "view" modifier on checkUpkeep (like the interface in #chainlink/contract npm package: https://keepers.chain.link/kovan/upkeeps/414
I used Remix to query checkUpkeep on the https://kovan.etherscan.io/address/0x969F42c92A6aeBD925982CCc1C943185B6D0E357#code to see that it is returning true.

It seems the issue is in the harvest function:
function harvest() public whenNotPaused onlyEOA
The onlyEOA modifier could be preventing the function from being called since Keepers likely calls it from a smart contract.

Related

Node Promise with Local Variable

async function A(){
const x = await B(); // reads a file or such thing
return x; // returns a promise
}
var foo;
function setFoo(){
foo = A(); // foo will be set to the promise returned by A()
// but I really want foo to be set to the data
// returned by the promise
}
function C(){
// here I need to use the value of the data returned
// by the promise. There are dozens of functions that
// will use foo. Those dozens of functions are called
// from outside of this module
}
Question - Is there some way to extract the data from the promise so I can use it in a local variable? Or do I need to use promise semantics i.e .then(function(...){...}) in every function like function C that needs to use the local variable foo? Or something else?
Don't use async in a function that does nothing other than return await. Just return the promise and you're done.
function A() {
return B(); // reads a file or such thing, returns a promise
}
Never try to set global/outer-scope variables to capture asynchronous values. Keep returning the promises, chain in worker functions with .then(). Keep returning the promise chain.
function foo(){
return A().then(C);
}
The worker functions (an event handler, really) receive the data:
function C(data) {
// here you get the data returned by B()
}
You could even wait for C() now:
foo().then(function (x) {
// `C()` ans finished and `x` will be whatever `C()` returned.
})

Chainlink Keeper not performing upkeep

I have a contract that is using Chainlink keepers for upkeep but the checkUpKeep/performUpkeep is not running. I have sufficiently funded the upkeep to ensure it has a high balance. The code from the contract was previously deployed, but now contains a minor change (outside the Chainlink functions), and the previous contract is receiving upkeeps. My code for checkUpKeep and performUpKeep are below:
function **checkUpkeep**(bytes calldata /* checkData */) external view override returns (bool upkeepNeeded, bytes memory /* performData */) {
if(lottery_state == LOTTERY_STATE.OPEN){
upkeepNeeded = (block.timestamp - lastTimeStamp) >= duration;
}
else{
upkeepNeeded = false;
}
}
function **performUpkeep**(bytes calldata /* performData */) external override {
require(msg.sender == 0x4Cb093f226983713164A62138C3F718A5b595F73);
lottery_state = LOTTERY_STATE.DRAWING;
Random(random).getRandomNumber();
}
As I mentioned earlier, this code is being used in another contract which is currently receiving upkeep so I am puzzled as to why it is not working in the new contract.
If your upkeeps are not being performed make sure to double-check the next items:
Are Chainlink Keepers currently available on the network you are deploying to?
Is your smart contract KeeperCompatible?
Call checkUpkeep. Did it return true or false?
Can you performUpkeep?
Did you register your contract for upkeeps?
Did you fund it?

Chainlink Keeper not running upkeep

I'm trying to use the Chainlink Keeper network and wrote a contract that implements KeeperCompatibleInterface. However, even if I explicitly set upkeepNeeded = true, the keeper network still does not run the upkeep. I have made sure the contract is adequately funded. What could be the problem?
Here is the relevant code snippet:
function checkUpkeep(bytes calldata checkData)
external
override
returns (bool upkeepNeeded, bytes memory performData)
{
return _checkUpkeep(checkData);
}
function _checkUpkeep(bytes memory checkData)
internal
view
returns (bool upkeepNeeded, bytes memory performData)
{
bool jobCanRun = (block.timestamp > _jobStartTime) &&
(block.timestamp < _expirationTime);
bool jobShouldRun = (block.timestamp.sub(_jobLastRun)) >=
_jobIntervalSeconds;
upkeepNeeded = jobCanRun && jobShouldRun;
performData = checkData;
// debug
upkeepNeeded = true;
}
function performUpkeep(bytes calldata performData) external override {
(bool upkeepNeeded, ) = _checkUpkeep("0");
require(upkeepNeeded, "Should not upkeep");
emit AtroposUpkeepPerformed();
_jobLastRun = block.timestamp;
}
Fund your upKeep contract with more LINK tokens.
The upKeep requires a minimum balance to even start running based on gas costs, the LINK token price, and how much gas your upkeep takes. I'd begin with at least 50 Link tokens.
Please keep in mind that Chainlink Keepers are in beta right now so all of this will be better documented after the beta ends and user feedback is aggregated.

Passing a lambda with return value into a callback without return value

This question involves boost::asio but is a pure C++ 11 question.
I am new to C++ 11 & lambda techniques which I am trying to use with boost::asio::async_connect for network communication.
Following is my function which attempts an asynchronous connect with the host.
bool MyAsyncConnectFunction() {
//some logic here to check validity of host
if (ip_is_not_resolved)
return false;
the_socket.reset(new tcp::socket(the_io_service));
auto my_connection_handler = [this]
(const boost::system::error_code& errc, const tcp::resolver::iterator& itr)
{
if (errc) {
//Set some variables to false as we are not connected
return false;
}
//Do some stuff as we are successfully connected at this point
return true;
};
//How is async_connect taking a lambda which
boost::asio::async_connect(the_socket, IP_destination, tcp::resolver::iterator(), my_connection_handler);
return true;
}
All works fine. There are no functional issues absolutely. However, I am wondering that boost::asio::async_connect takes a ConnectionHandler without a return type in its last parameter but I am passing a lambda i.e. my_connection_handler which returns a value.
How is it possible that I can pass a lambda with a return value whereas boost::asio::async_connect's 4th param takes a callback without a return value ?
boost::asio::async_connect is a function template that takes a callable as its fourth argument. It does not use the return value of said callable, nor does it care about it. Just as you could write :
auto f = []() { return true; };
f(); // Return value is discarded
The example of #m.s. is good too. Since it is a template, the function resolves the argument according to the template argument deduction rules.

Fallback callback when calling unavailable function

Is it possible to set a fallback callback which is called when the user wants to call a function which does not exists? E.g.
my_object.ThisFunctionDoesNotExists(2, 4);
Now I want that a function is getting called where the first parameter is the name and a stack (or something like that) with the arguments passed. To clarify, the fallback callback should be a C++ function.
Assuming your question is about embedded V8 engine which is inferred from tags, you can use harmony Proxies feature:
var A = Proxy.create({
get: function (proxy, name) {
return function (param) {
console.log(name, param);
}
}
});
A.hello('world'); // hello world
Use --harmony_proxies param to enable this feature. From C++ code:
static const char v8_flags[] = "--harmony_proxies";
v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1);
Other way:
There is a method on v8::ObjectTemplate called SetNamedPropertyHandler so you can intercept property access. For example:
void GetterCallback(v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info)
{
// This will be called on property read
// You can return function here to call it
}
...
object_template->SetNamedPropertyHandler(GetterCallback);

Resources