i am writing a raffle game contract, I integrated Chainlink keepers to check how much time has passed and pick the winner to move on to next round.
function checkUpkeep(
bytes calldata
)
external
view
override
returns (bool upkeepNeeded, bytes memory)
{
upkeepNeeded = (!isPaused() && !awaitingRandomness && block.timestamp>=raffle[round.current()].endTime);
}
function performUpkeep(bytes calldata) external override {
if (!isPaused() && !awaitingRandomness && block.timestamp>=raffle[round.current()].endTime) {
pickWinner();
}
}
Then, to get a secure random value I integrated with VRF. When the pickWinner() function is called, It calls the requestRandomness function then just leaves the pickWinner() function.
function pickWinner() internal {
if(raffle[round.current()].playerCount == 0){
finishRound(address(0));
} else if(raffle[round.current()].playerCount == 1){
token.transfer(address(raffle[round.current()].players[0]), calculatePrize());
token.transfer(address(treasuryAddress), getBalance());
finishRound(address(raffle[round.current()].players[0]));
} else{
awaitingRandomness=true;
uint256 requestId = requestRandomness(callbackGasLimit,requestConfirmations,numWords);
randomnessIds[round.current()] = requestId;
raffle[round.current()].status = GameStatus.PICKING_WINNER;
}
}
After this point, everything stops until fulfillRandomWords() function of VRFV2WrapperConsumerBase is called back. Inside that function, I get the randomWord and use it as index for array of addresses that I keep for the current raffle round and chooses the winner. Then, starts the next round.
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
uint256 randomIndex = randomWords[0] % raffle[round.current()].players.length;
address winner = raffle[round.current()].players[randomIndex];
Game storage currentGameOfPlayer = players[winner][round.current()];
currentGameOfPlayer.status = PlayerStatus.WIN;
currentGameOfPlayer.earned = calculatePrize();
currentGameOfPlayer.updatedAt = block.timestamp;
raffle[round.current()].status = GameStatus.FINISHED;
raffle[round.current()].winner = winner;
token.transfer(winner, calculatePrize());
token.transfer(address(treasuryAddress), getBalance());
finishRound(winner);
}
My problem is that fulfillRandomWords() function gets stuck because of gas limit. Also, even if it wasn't stuck, since all this automated logic is dependent on fulfillRandomWords() function being called, I am not sure if it is usable.
My question is:
-Is VRF service reliable enough to make this logic dependent on fulfillRandomWords() being called?
-Do you have any suggestions or examples for implementing this game? Maybe using another service or a different logic?