slashing

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2025 License: Apache-2.0 Imports: 18 Imported by: 11

README

Slashing Precompile

The Slashing precompile provides an EVM interface to the Cosmos SDK slashing module, enabling smart contracts to interact with validator slashing information and allowing jailed validators to unjail themselves.

Address

The precompile is available at the fixed address: 0x0000000000000000000000000000000000000806

Interface

Data Structures
// Validator signing information for liveness monitoring
struct SigningInfo {
    address validatorAddress;       // Validator operator address
    int64 startHeight;             // Height at which validator was first a candidate or was unjailed
    int64 indexOffset;             // Index offset into signed block bit array
    int64 jailedUntil;             // Timestamp until which validator is jailed
    bool tombstoned;               // Whether validator has been permanently removed
    int64 missedBlocksCounter;     // Count of missed blocks
}

// Slashing module parameters
struct Params {
    int64 signedBlocksWindow;      // Number of blocks to track for signing
    Dec minSignedPerWindow;        // Minimum percentage of blocks to sign
    int64 downtimeJailDuration;    // Duration of jail time for downtime
    Dec slashFractionDoubleSign;   // Slash percentage for double signing
    Dec slashFractionDowntime;     // Slash percentage for downtime
}

// Decimal type representation
struct Dec {
    string value;  // Decimal string representation
}
Transaction Methods
// Unjail a validator after downtime slashing
function unjail(address validatorAddress) external returns (bool success);
Query Methods
// Get signing info for a specific validator
function getSigningInfo(
    address consAddress
) external view returns (SigningInfo memory signingInfo);

// Get signing info for all validators with pagination
function getSigningInfos(
    PageRequest calldata pagination
) external view returns (
    SigningInfo[] memory signingInfos,
    PageResponse memory pageResponse
);

// Get slashing module parameters
function getParams() external view returns (Params memory params);

Gas Costs

Gas costs are calculated dynamically based on:

  • Base gas for the method
  • Storage operations for state changes
  • Query complexity for read operations

The precompile uses standard gas configuration for storage operations.

Implementation Details

Unjail Mechanism
  1. Eligibility Check: Validator must be jailed and jail period must have expired
  2. Sender Verification: Only the validator themselves can request unjailing
  3. State Update: Updates validator status from jailed to active
  4. Event Emission: Emits ValidatorUnjailed event
Signing Information
  • Consensus Address: Uses the validator's consensus address (from Tendermint ed25519 public key)
  • Liveness Tracking: Monitors block signing to detect downtime
  • Jail Status: Tracks jail duration and tombstone status
Parameter Management

The slashing parameters control:

  • Downtime Detection: Window size and minimum signing percentage
  • Penalties: Slash fractions for different infractions
  • Jail Duration: Time validators must wait before unjailing

Events

event ValidatorUnjailed(address indexed validator);

Security Considerations

  1. Authorization: Only validators can unjail themselves - no third-party unjailing
  2. Jail Period Enforcement: Cannot unjail before jail duration expires
  3. Tombstone Protection: Tombstoned validators cannot be unjailed
  4. Balance Handler: Proper integration with native token management

Usage Example

ISlashing slashing = ISlashing(SLASHING_PRECOMPILE_ADDRESS);

// Query validator signing info
address consAddress = 0x...; // Validator consensus address
SigningInfo memory info = slashing.getSigningInfo(consAddress);

// Check if validator is jailed
if (info.jailedUntil > int64(block.timestamp)) {
    // Validator is currently jailed

    // If jail period has expired and caller is the validator
    if (block.timestamp >= uint64(info.jailedUntil)) {
        // Unjail the validator
        bool success = slashing.unjail(msg.sender);
        require(success, "Failed to unjail");
    }
}

// Query slashing parameters
Params memory params = slashing.getParams();
// Access parameters like params.signedBlocksWindow

Integration with Validator Operations

contract ValidatorManager {
    ISlashing constant slashing = ISlashing(SLASHING_PRECOMPILE_ADDRESS);

    function checkValidatorStatus(address validatorAddr) public view returns (
        bool isJailed,
        int64 jailedUntil,
        bool canUnjail
    ) {
        // Convert to consensus address (implementation specific)
        address consAddr = getConsensusAddress(validatorAddr);

        SigningInfo memory info = slashing.getSigningInfo(consAddr);

        isJailed = info.jailedUntil > int64(block.timestamp);
        jailedUntil = info.jailedUntil;
        canUnjail = isJailed && block.timestamp >= uint64(info.jailedUntil) && !info.tombstoned;
    }

    function autoUnjail(address validatorAddr) external {
        (, , bool canUnjail) = checkValidatorStatus(validatorAddr);
        require(canUnjail, "Cannot unjail yet");
        require(msg.sender == validatorAddr, "Only validator can unjail");

        slashing.unjail(validatorAddr);
    }
}

Address Conversion

The precompile uses different address types:

  • Validator Address: Standard Ethereum address (operator address)
  • Consensus Address: Derived from validator's CometBFT public key

Consensus addresses are typically found in:

  • $HOME/.evmd/config/priv_validator_key.json
  • Validator info queries

Integration Notes

  • The precompile integrates directly with the Cosmos SDK slashing module
  • All slashing rules and parameters from the chain apply
  • Validators must monitor their signing performance to avoid jailing
  • Smart contracts can build automation around validator management

Documentation

Index

Constants

View Source
const (
	// GetSigningInfoMethod defines the ABI method name for the slashing SigningInfo query
	GetSigningInfoMethod = "getSigningInfo"
	// GetSigningInfosMethod defines the ABI method name for the slashing SigningInfos query
	GetSigningInfosMethod = "getSigningInfos"
	// GetParamsMethod defines the ABI method name for the slashing Params query
	GetParamsMethod = "getParams"
)
View Source
const (
	// EventTypeValidatorUnjailed defines the event type for validator unjailing
	EventTypeValidatorUnjailed = "ValidatorUnjailed"
)
View Source
const (
	// UnjailMethod defines the ABI method name for the slashing Unjail
	// transaction.
	UnjailMethod = "unjail"
)

Variables

This section is empty.

Functions

func LoadABI

func LoadABI() (abi.ABI, error)

LoadABI loads the slashing ABI from the embedded abi.json file for the slashing precompile.

func ParseSigningInfoArgs

func ParseSigningInfoArgs(args []interface{}, consCodec address.Codec) (*slashingtypes.QuerySigningInfoRequest, error)

ParseSigningInfoArgs parses the arguments for the signing info query

func ParseSigningInfosArgs

func ParseSigningInfosArgs(method *abi.Method, args []interface{}) (*slashingtypes.QuerySigningInfosRequest, error)

ParseSigningInfosArgs parses the arguments for the signing infos query

Types

type EventValidatorUnjailed

type EventValidatorUnjailed struct {
	Validator common.Address
}

Add this struct after the existing constants

type Params

type Params struct {
	SignedBlocksWindow      int64   `abi:"signedBlocksWindow"`
	MinSignedPerWindow      cmn.Dec `abi:"minSignedPerWindow"`
	DowntimeJailDuration    int64   `abi:"downtimeJailDuration"`
	SlashFractionDoubleSign cmn.Dec `abi:"slashFractionDoubleSign"`
	SlashFractionDowntime   cmn.Dec `abi:"slashFractionDowntime"`
}

Params defines the parameters for the slashing module

type ParamsOutput

type ParamsOutput struct {
	Params Params
}

ParamsOutput represents the output of the params query

func (*ParamsOutput) FromResponse

type Precompile

type Precompile struct {
	cmn.Precompile
	// contains filtered or unexported fields
}

Precompile defines the precompiled contract for slashing.

func NewPrecompile

func NewPrecompile(
	slashingKeeper slashingkeeper.Keeper,
	valCdc, consCdc address.Codec,
) (*Precompile, error)

NewPrecompile creates a new slashing Precompile instance as a PrecompiledContract interface.

func (Precompile) EmitValidatorUnjailedEvent

func (p Precompile) EmitValidatorUnjailedEvent(ctx sdk.Context, stateDB vm.StateDB, validator common.Address) error

EmitValidatorUnjailedEvent emits the ValidatorUnjailed event

func (*Precompile) GetParams

func (p *Precompile) GetParams(
	ctx sdk.Context,
	method *abi.Method,
	_ *vm.Contract,
	_ []interface{},
) ([]byte, error)

GetParams implements the query to get the slashing parameters.

func (*Precompile) GetSigningInfo

func (p *Precompile) GetSigningInfo(
	ctx sdk.Context,
	method *abi.Method,
	_ *vm.Contract,
	args []interface{},
) ([]byte, error)

GetSigningInfo handles the `getSigningInfo` precompile call. It expects a single argument: the validator’s consensus address in hex format. That address comes from the validator’s CometBFT ed25519 public key, typically found in `$HOME/.evmd/config/priv_validator_key.json`.

func (*Precompile) GetSigningInfos

func (p *Precompile) GetSigningInfos(
	ctx sdk.Context,
	method *abi.Method,
	_ *vm.Contract,
	args []interface{},
) ([]byte, error)

GetSigningInfos implements the query to get signing info for all validators.

func (Precompile) IsTransaction

func (Precompile) IsTransaction(method *abi.Method) bool

IsTransaction checks if the given method name corresponds to a transaction or query.

Available slashing transactions are: - Unjail

func (Precompile) Logger

func (p Precompile) Logger(ctx sdk.Context) log.Logger

Logger returns a precompile-specific logger.

func (Precompile) RequiredGas

func (p Precompile) RequiredGas(input []byte) uint64

RequiredGas calculates the precompiled contract's base gas rate.

func (Precompile) Run

func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz []byte, err error)

Run executes the precompiled contract slashing methods defined in the ABI.

func (Precompile) Unjail

func (p Precompile) Unjail(
	ctx sdk.Context,
	method *abi.Method,
	stateDB vm.StateDB,
	contract *vm.Contract,
	args []interface{},
) ([]byte, error)

Unjail implements the unjail precompile transaction, which allows validators to unjail themselves after being jailed for downtime.

type SigningInfo

type SigningInfo struct {
	ValidatorAddress    common.Address `abi:"validatorAddress"`
	StartHeight         int64          `abi:"startHeight"`
	IndexOffset         int64          `abi:"indexOffset"`
	JailedUntil         int64          `abi:"jailedUntil"`
	Tombstoned          bool           `abi:"tombstoned"`
	MissedBlocksCounter int64          `abi:"missedBlocksCounter"`
}

SigningInfo represents the signing info for a validator

type SigningInfoOutput

type SigningInfoOutput struct {
	SigningInfo SigningInfo
}

SigningInfoOutput represents the output of the signing info query

func (*SigningInfoOutput) FromResponse

type SigningInfosInput

type SigningInfosInput struct {
	Pagination query.PageRequest `abi:"pagination"`
}

SigningInfosInput represents the input for the signing infos query

type SigningInfosOutput

type SigningInfosOutput struct {
	SigningInfos []SigningInfo      `abi:"signingInfos"`
	PageResponse query.PageResponse `abi:"pageResponse"`
}

SigningInfosOutput represents the output of the signing infos query

func (*SigningInfosOutput) FromResponse

type ValidatorUnjailed

type ValidatorUnjailed struct {
	Validator common.Address
}

ValidatorUnjailed defines the data structure for the ValidatorUnjailed event.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL