package clock
import (
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cybercongress/go-cyber/v7/app/helpers"
"time"
"github.com/cometbft/cometbft/libs/log"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cybercongress/go-cyber/v7/x/clock/keeper"
"github.com/cybercongress/go-cyber/v7/x/clock/types"
)
var endBlockSudoMessage = []byte(types.EndBlockSudoMessage)
var beginBlockSudoMessage = []byte(types.EndBlockSudoMessage)
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)
CallContracts(ctx, k, beginBlockSudoMessage)
}
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)
CallContracts(ctx, k, endBlockSudoMessage)
return nil
}
func CallContracts(ctx sdk.Context, k keeper.Keeper, msg []byte) {
logger := k.Logger(ctx)
p := k.GetParams(ctx)
contracts, err := k.GetAllContracts(ctx)
if err != nil {
logger.Error("Failed to get contracts", "error", err)
return
}
errorExecs := make([]string, len(contracts))
errorExists := false
for idx, contract := range contracts {
if contract.IsJailed {
continue
}
contractAddr := sdk.MustAccAddressFromBech32(contract.ContractAddress)
if handleError(ctx, k, logger, errorExecs, &errorExists, err, idx, contract.ContractAddress, msg) {
continue
}
childCtx := ctx.WithGasMeter(sdk.NewGasMeter(p.ContractGasLimit))
helpers.ExecuteContract(k.GetContractKeeper(), childCtx, contractAddr, msg, &err)
if handleError(ctx, k, logger, errorExecs, &errorExists, err, idx, contract.ContractAddress, msg) {
continue
}
logger.Info(
"abci callback to clock contract",
"type", string(msg),
"cause", err,
"contract-address", contract.ContractAddress,
)
}
if errorExists {
logger.Error("Failed to execute contracts", "contracts", errorExecs)
}
}
func handleError(
ctx sdk.Context,
k keeper.Keeper,
logger log.Logger,
errorExecs []string,
errorExists *bool,
err error,
idx int,
contractAddress string,
msg []byte,
) bool {
if err != nil {
*errorExists = true
errorExecs[idx] = contractAddress
logger.Error(
"abci callback to clock contract failed",
"type", string(msg),
"cause", err,
"contract-address", contractAddress,
)
err := k.SetJailStatus(ctx, contractAddress, true)
if err != nil {
logger.Error("Failed to jail contract", "contract", contractAddress, "error", err)
}
}
return err != nil
}