Chainlink Keeper not running upkeep - chainlink

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.

Related

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 performUpkeep, yet checkUpkeep returns true

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.

What is balanceRecived in solidity? what it will be strore?

i am begginer can any one explain me what is balanceRecived in solidity? what it will be strore?
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.1;
contract SendMoneyExample {
uint public balanceReceived;
function receiveMoney() public payable {
balanceReceived += msg.value;
}
function getBalance() public view returns(uint) {
return address(this).balance;
}
function withdrawMoney() public {
address payable to = payable(msg.sender);
to.transfer(getBalance());
}
}
Each time when someone executes the receiveMoney() function, it happens as a result of a transaction.
A transaction can hold value in the form of the network native currency. Your question is tagged Ethereum, and the native currency for the Ethereum network is ETH. (If the contract was on the Binance Smart Chain network, the native currency would be BNB, the Tron network has TRX, and so on...)
So each time the receiveMoney() function is executed, in adds the current transaction value to the total number hold in balanceReceived.
Example:
First transaction executing receiveMoney(), sending along 1 wei (the smallest unit of ETH). The value of balanceReceived becomes 1.
Second transaction executing receiveMoney(), sending along 5 wei. The value of balanceReceived becomes 6.

interaction between the oracle smart contract and the oracle service

I want to use this code to recover the temperature and return the result to the smart contract
contract CMCOracle {
// Contract owner address public owner;
// BTC Marketcap Storage uint public btcMarketCap;
// Callback function event CallbackGetBTCCap();
function CMCOracle() public {
owner = msg.sender;
}
function updateWe() public {
// Calls the callback function
CallbackGetBTCCap();
}
function setBTCCap(uint cap) public {
// If it isn't sent by a trusted oracle
// a.k.a ourselves, ignore it
require(msg.sender == owner);
btcMarketCap = cap;
}
function getBTCCap() constant public returns (uint) {
return btcMarketCap;
}
}
var fetch = require('fetch')
var OracleContract = require('./build/contracts/CMCOracle.json')
var contract = require('truffle-contract')
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider('https://localhost:8545'));
// Truffle abstraction to interact with our
// deployed contract
var oracleContract = contract(OracleContract);
oracleContract.setProvider(web3.currentProvider);
// Dirty hack for web3#1.0.0 support for localhost testrpc
// see https://github.com/trufflesuite/truffle-contract/issues/56#issuecomment-331084530
if (typeof oracleContract.currentProvider.sendAsync !== "function") {
oracleContract.currentProvider.sendAsync = function() {
return oracleContract.currentProvider.send.apply(
oracleContract.currentProvider, arguments
);
};
}
// Get accounts from web3 web3.eth.getAccounts((err, accounts) => {
oracleContract.deployed().then((oracleInstance) => {
// Watch event and respond to event
// With a callback function
oracleInstance.CallbackGetBTCCap()
.watch((err, event) => {
// Fetch data
// and update it into the contract
fetch.fetchUrl('https://api.coinmarketcap.com/v1/global/',(err, m, b)=> {
const cmcJson = JSON.parse(b.toString());
const btcMarketCap = parseInt(cmcJson.total_market_cap_usd);
// Send data back contract on-chain
oracleInstance.setBTCCap(btcMarketCap, {from: accounts[0]});
})
})
}).catch((err) => { console.log(err) });
but I can't understand how to change the code.
How does the smart contract pass a city whose temperature I want to know to the oracle service?
What API does the oracle service use to fetch the temperature from the external source?
How should i change this code?
source: https://kndrck.co/posts/ethereum_oracles_a_simple_guide/
A smart contract does not interact with the API but the Oracle itself. Normally, it should have been two different contracts like one of the contracts should be separated from the external world. Oracle contract is the API for blockchain, which is basically residing in the blockchain. You can reach out to the contract by means of contract wrapper libraries (web3j, ethereumj)
The contract wrapper will fetch the data from API as JSON. And then the application will convert the data into primitive data that has been defined in the Solidity language. Once it is done, data will send via emit-event functions continuously to the blockchain as long as the application fetched data from the API. In the end, you will have a deterministic database source so that you can copy this source and transfer another place as it is.
For instance, you may change the API endpoint called "https://api.coinmarketcap.com/v1/global/" with "api.openweathermap.org/data/2.5/weather" and data structures (link: https://openweathermap.org/current).

How to use lambda capture with lock?

In the code below, the member variable (match_room_list_) is a shared resource. So I used a mutex.
But locking confuses me.
Should I use lock or not in an inner lambda function?
void room::join_room(int user_id)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
std::shared_ptr<match_room> find_room = nullptr;
for (auto iter : match_room_list_)
{
if (false == iter.second->is_public_room())
{
continue;
}
if (true == iter.second->is_full())
{
continue;
}
find_room = iter.second;
break;
}
// Something
// async ( other thread call this lambda function )
// call database
database_manager::get_instance().join_room(find_room->get_room_id(), user_id, [=](bool success, std::string room_id, std::vector<int> user_id_list)
{
// How do you think I should using lock?
// std::lock_guard<std::recursive_mutex> lock(mutex_);
// shared resource
match_room_list_[room_id].join_user(user_id);
response_join_room_ntf(room_id, user_id_list);
}
}
If your lambda function will ever run on a different thread (and that's likely) then yes, you do need to lock it.
The only possible problem with doing so could be if it was called on the same thread from a function that had already locked the mutex. But that won't be an issue here since your mutex is a recursive one and a given thread can lock that as many times as it wants.
You may also want to look into conditions such as:
if (false == iter.second->is_public_room())
if (true == iter.second->is_full())
They would be far better written as:
if (! iter.second->is_public_room())
if (iter.second->is_full())

Resources