staking

package
v2.5.0-rc1 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: Apache-2.0 Imports: 51 Imported by: 0

Documentation

Overview

Package staking is a generated GoMock package.

Package staking is a generated GoMock package.

Index

Constants

View Source
const (
	// StakingCandidatesNamespace is a namespace to store candidates with epoch start height
	StakingCandidatesNamespace = "stakingCandidates"
	// StakingBucketsNamespace is a namespace to store vote buckets with epoch start height
	StakingBucketsNamespace = "stakingBuckets"
	// StakingMetaNamespace is a namespace to store metadata
	StakingMetaNamespace = "stakingMeta"
)
View Source
const (
	// EndorseExpired means the endorsement is expired
	EndorseExpired = EndorsementStatus(iota)
	// UnEndorsing means the endorser has submitted unendorsement, but it is not expired yet
	UnEndorsing
	// Endorsed means the endorsement is valid
	Endorsed
)

EndorsementStatus

View Source
const (
	HandleCreateStake       = "createStake"
	HandleUnstake           = "unstake"
	HandleWithdrawStake     = "withdrawStake"
	HandleChangeCandidate   = "changeCandidate"
	HandleTransferStake     = "transferStake"
	HandleDepositToStake    = "depositToStake"
	HandleRestake           = "restake"
	HandleCandidateRegister = "candidateRegister"
	HandleCandidateUpdate   = "candidateUpdate"
)

constants

View Source
const (

	// CandsMapNS is the bucket name to store candidate map
	CandsMapNS = state.CandsMapNamespace

	// MaxDurationNumber is the maximum duration number
	MaxDurationNumber = math.MaxUint64
)
View Source
const NoSelfStakeBucketIndex = uint64(candidateNoSelfStakeBucketIndex)

NoSelfStakeBucketIndex is the sentinel a candidate carries when it has no self-stake bucket. Exported so the rewarding protocol, which freezes this index into its per-delegate work, uses the same sentinel.

View Source
const TestOnlyPerfBenchDelegateStakeDurationDays = _perfBenchStakeDuration

TestOnlyPerfBenchDelegateStakeDurationDays is the duration above, exported so a harness can reproduce a seeded delegate's self-stake weight from CalculateVoteWeight instead of reading it back out of the state the code under test also wrote.

Variables

View Source
var (
	// StakingContractJSONABI is the abi json of staking contract
	//go:embed contract_staking_abi_v2.json
	StakingContractJSONABI string
	// StakingContractABI is the abi of staking contract
	StakingContractABI abi.ABI
)
View Source
var (
	ErrWithdrawnBucket      = errors.New("the bucket is already withdrawn")
	ErrEndorsementNotExist  = errors.New("the endorsement does not exist")
	ErrNoSelfStakeBucket    = errors.New("no self-stake bucket")
	ErrCandidateNotExist    = errors.New("the candidate does not exist")
	ErrCandidateDeleted     = errors.New("candidate has been deleted")
	ErrExitNotRequested     = errors.New("exit not requested")
	ErrExitNotScheduled     = errors.New("exit not scheduled")
	ErrExitNotReady         = errors.New("exit not ready")
	ErrExitAlreadyRequested = errors.New("already request exit")
)

Errors

View Source
var (
	ErrInvalidOwner        = errors.New("invalid owner address")
	ErrInvalidOperator     = errors.New("invalid operator address")
	ErrInvalidReward       = errors.New("invalid reward address")
	ErrInvalidSelfStkIndex = errors.New("invalid self-staking bucket index")
	ErrMissingField        = errors.New("missing data field")
	ErrTypeAssertion       = errors.New("failed type assertion")
	ErrDurationTooHigh     = errors.New("stake duration cannot exceed 1050 days")
)

Errors

View Source
var ErrCompoundBucketOwnerMismatch = errors.New(
	"staking: compound bucket owner does not match voter")

ErrCompoundBucketOwnerMismatch is returned when the bucket's owner does not byte-equal the voter passed to AddDepositForCompound. Callers (currently only the rewarding protocol's distributeVoterReward) are expected to have already filtered via autodeposit.IsBucketEligibleForCompound; hitting this indicates a wiring bug, not on-chain data.

View Source
var ErrCompoundSelfStakeRoleChanged = errors.New(
	"staking: compound bucket self-stake role changed since the era freeze")

ErrCompoundSelfStakeRoleChanged is returned when the bucket's self-stake role is not the one the era froze: it became the candidate's self-stake bucket after the boundary, or stopped being it. The share was allocated against the frozen role, so compounding into the bucket now would grow a bucket whose weight the era never blessed and would move the candidate's votes by a different multiplier than the payout assumed.

It is a routing outcome, not a failure: the caller falls back to crediting the voter's reward destination, exactly as it does for an ineligible bucket.

View Source
var (
	ErrNilParameters = errors.New("parameter is nil")
)

Errors and vars

View Source
var (
	TotalBucketKey = append([]byte{_const}, []byte("totalBucket")...)
)

Functions

func AddrKeyWithPrefix

func AddrKeyWithPrefix(addr address.Address, prefix byte) []byte

AddrKeyWithPrefix returns address key with prefix

func BLSPopSigningRoot

func BLSPopSigningRoot(candidateID address.Address) []byte

BLSPopSigningRoot returns the bytes that a BLS proof-of-possession must be computed over for the given candidate.

The signed message is the domain tag plus the candidate's stable identity. The BLS public key is intentionally NOT in the message:

  • The pairing verifier Verify(PK, msg, sig) already commits PK into the signature equation. An attacker who does not know sk_PK cannot produce a sig that verifies under PK over any message, so the rogue-key registration attack ("register pk_rogue without owning its discrete log") is blocked by basic PoP correctness without needing pubkey-in-message.

  • Cross-candidate replay (PoP for candidate A re-submitted under candidate B) is blocked by the candidateID binding: distinct candidates have distinct signing roots, so the same signature never validates under two candidate identities.

  • Cross-domain replay (e.g. PoP reused as a consensus signature) is blocked by blsPopDomain.

  • The classical same-message aggregation attack on PoP requires two distinct honest signers to sign the *same* signing root. The candidateID binding rules that out: the protocol enforces unique candidate identifiers (see generateCandidateID + the ContainsName / ContainsOwner / ContainsOperator checks at register time), so no two honest delegates ever produce PoPs over the same root.

candidateID is the candidate's stable identity:

  • At register: act.OwnerAddress() (or actCtx.Caller if omitted), which becomes c.Identifier verbatim in the non-collision case via generateCandidateID's owner-first fast path.
  • At update: c.GetIdentifier(), which returns the immutable Identifier for post-Xingu candidates and falls back to c.Owner for pre-Xingu records. Stable across CandidateTransferOwnership.

func BeginEraCOWWindow

func BeginEraCOWWindow(ctx context.Context, sm protocol.StateManager, freezeHeight uint64) error

BeginEraCOWWindow opens the copy-on-write window for the era frozen at freezeHeight.

The poll protocol calls BeginEraCOWWindow immediately after FreezeCandidateRewardSnapshots at the end of the freeze block H. Everything written from there on is "after H" and is copied aside on first touch.

H is NOT the era boundary block. FreezeCandidateRewardSnapshots rides a PutPollResult action, which is created around the midpoint of the epoch *preceding* the target epoch, while voter reward distribution state is created at the last block of the boundary epoch -- roughly 1.5 epochs later (~2,160 blocks, ~90 minutes on mainnet). That gap is deliberate and is not a divergence risk, because H travels with the work as FreezeHeight and every recompute evaluates at it. See docs/iip-59-distribution-architecture.md §2.1.

Besides opening the window this freezes the two bucket high-water marks:

  • the native bucket index upper bound, read from totalBucketCount. It is the next index putBucket will hand out. Indices are strictly monotonic (delBucket never decrements the counter), so a native bucket with index >= this number cannot have existed at H.
  • each staking contract's NumOfBuckets, which is the highest contract bucket id seen so far, burnt ones included. Contract bucket ids come from a strictly monotonic counter inside the contract and are never reused, so a contract bucket with id > its contract's number cannot have existed at H either. Note the boundary differs: the native number is a next-index, the contract number is a max-seen-id.

Both are frozen as scalars rather than copied on write. That is strictly stronger: a scalar still rejects a post-H bucket even if that bucket's own copy were missed, whereas a copied counter would only be as good as the copy.

No-op pre-activation; eracow.Begin checks the fork gate before touching state, and the two reads below are behind the same check.

func BucketIndexFromReceiptLog

func BucketIndexFromReceiptLog(log *iotextypes.Log) (uint64, bool)

BucketIndexFromReceiptLog extracts bucket index from log

func CalculateVoteWeight

func CalculateVoteWeight(c genesis.VoteWeightCalConsts, v *VoteBucket, selfStake bool) *big.Int

CalculateVoteWeight calculates the vote weight

func CandidateRewardAddress

func CandidateRewardAddress(sr protocol.StateReader, candID address.Address) (address.Address, bool, error)

CandidateRewardAddress is retained for ReadState compatibility. It returns the persisted legacy reward address and whether it was updated post-fork.

func CollectEraCOWGarbage

func CollectEraCOWGarbage(ctx context.Context, sm protocol.StateManager, max int) (int, error)

CollectEraCOWGarbage deletes up to max copied entries older than the open window and returns how many it deleted.

Intended to be called once per block. It is bounded on purpose: an era can accumulate tens of thousands of copies and deleting them in one block would blow the very block budget the drain is chunked to respect.

No-op pre-activation and when there is no backlog.

func CreateBaseView

func CreateBaseView(ctx protocol.FeatureCtx, sr protocol.StateReader, enableSMStorage bool) (*viewData, uint64, error)

CreateBaseView creates the base view from state reader

func FreezeCandidateRewardSnapshots

func FreezeCandidateRewardSnapshots(
	ctx context.Context,
	sm protocol.StateManager,
	bridge *delegateprofile.Bridge,
	reader delegateprofile.ContractReader,
	freezeHeight uint64,
	era uint64,
) ([]*action.Log, error)

FreezeCandidateRewardSnapshots writes a CandidateRewardSnapshot for every candidate that is on the IIP-59 rails at freeze block H. This is the *only* writer of the snapshot; rewarding is a pure reader via CandidateRewardSnapshotFor.

THE SET IS THE OPTED-IN CANDIDATE SET. It is enumerated from the candidate center and filtered by the persisted VoterRewardOnchainOptIn bit. The activation migration sets that bit for pre-IIP-59 Hermes candidates.

It deliberately has nothing to do with the poll list this used to be handed. That list is filtered twice before a PutPollResult carries it -- ActiveCandidates drops anything failing isActiveCandidate, filterAndSortCandidatesByVoteScore drops anything below the vote-score threshold -- while this runs once per reward era (EpochsPerRewardEra epochs, ~24h on mainnet) and the set that actually receives epoch rewards is recomputed by rewarding at EVERY epoch inside that era. The two drift, and a candidate that is opted in but not frozen loses its voters a whole era: every reader treats "no snapshot" as "not on the rails", so the commission split falls back to 100% delegate / 0% voter, silently, for up to a full day. Freezing from the opt-in set closes that by construction rather than by union.

A candidate that has not opted in gets no record. Rewarding treats snapshot absence as the legacy route for this era, so no explicit disabled record is needed.

Sorted by identifier bytes, because the candidate center enumerates from a Go map and the order reaches both PutState and the DelegateProfile bridge call.

A per-delegate bridge read failure is absorbed by the bridge itself: the affected delegate lands with CommissionConfigured=false and rewarding uses the all-to-owner default. This prevents one bad on-chain profile from halting every era boundary.

Note what is deliberately absent: any materialized per-voter weight list. The retired VoterWeightView had one, and freezing it meant the boundary had to degrade whenever the list was incomplete. TotalWeight now comes from the candidate record's own Votes accumulator, which is complete at every height, and the drain enumerates voters from the bucket indexes.

func FrozenCandidatesForVoter

func FrozenCandidatesForVoter(
	sr protocol.StateReader,
	window eracow.Window,
	voter address.Address,
) ([]address.Address, error)

FrozenCandidatesForVoter returns the distinct candidates one voter's frozen buckets point at, ascending by address bytes.

The drain needs this to know which delegates a voter can be owed by. It exists so the per-candidate weight recompute is run only for candidates the voter actually has a bucket with, instead of once per delegate in the work list; the recompute itself stays the single implementation of the weight rule.

func FrozenVoterWeight

func FrozenVoterWeight(
	sr protocol.StateReader,
	window eracow.Window,
	p *Protocol,
	candidate address.Address,
	voter address.Address,
	selfStakeBucketIdx uint64,
	evalHeight uint64,
) (*big.Int, error)

FrozenVoterWeight recomputes what one voter's buckets are worth to one candidate as of an era freeze height.

evalHeight must be the era's freeze height. Contract buckets that are not timestamp-based measure their remaining duration against a block height, so using the current block would make their weight drift across drain chunks. selfStakeBucketIdx must likewise be the index frozen for this era, not the live candidate value.

func LoadEraCOWWindow

func LoadEraCOWWindow(sr protocol.StateReader) (eracow.Window, error)

LoadEraCOWWindow returns the open era window, or the zero value when none is open. The drain uses it for the bucket high-water marks.

func NewContractStakeViewBuilder added in v2.3.0

func NewContractStakeViewBuilder(
	indexer ContractStakingIndexer,
	blockdao BlockStore,
) *contractStakeViewBuilder

func ProtocolAddr

func ProtocolAddr() address.Address

ProtocolAddr returns the address generated from protocol id

func SealEraCOWWindow

func SealEraCOWWindow(ctx context.Context, sm protocol.StateManager) error

SealEraCOWWindow closes the era window and queues its copies for collection.

Call it when the era's drain completes. After it, the copy-on-write hooks on every bucket write become branch-only no-ops until the next boundary.

No-op pre-activation and when no window is open.

func SignBLSPop

func SignBLSPop(sk *crypto.BLS12381PrivateKey, candidateID address.Address) ([]byte, error)

SignBLSPop produces a proof-of-possession for the given BLS private key, binding it to the candidate's identity. Used by tooling (ioctl, SDK) to generate the bls_pop field on CandidateRegister / CandidateUpdate transactions.

At registration time pass the proposed owner address (which becomes the candidate identifier); at update time pass the candidate's existing identifier (c.GetIdentifier()).

func TestOnlyBeginEraCOWWindow

func TestOnlyBeginEraCOWWindow(ctx context.Context, sm protocol.StateManager, freezeHeight uint64) error

TestOnlyBeginEraCOWWindow opens an era copy-on-write window directly. Only tests may call it; production uses the poll protocol's explicit FreezeCandidateRewardSnapshots then BeginEraCOWWindow sequence.

func TestOnlyDeleteVoterBucketsThroughCOW

func TestOnlyDeleteVoterBucketsThroughCOW(
	ctx context.Context,
	sm protocol.StateManager,
	voter address.Address,
) (int, error)

TestOnlyDeleteVoterBucketsThroughCOW deletes every live native bucket a voter owns, through a candidate state manager so the copy-on-write hooks fire. It returns how many it deleted.

This models the case the copy-on-write layer exists for: a voter who withdraws their last bucket mid-drain. Afterwards the voter has no live _voterIndex key at all, so only the era's copies can still name them — and they are still owed the share the era froze.

Test-only, with the same caveats as TestOnlyPutVoterBucketThroughCOW: the candidate's Votes and the bucket pool are left untouched.

func TestOnlyPerfBenchDelegateAddress

func TestOnlyPerfBenchDelegateAddress(i int) address.Address

TestOnlyPerfBenchDelegateAddress returns the deterministic address the perf-bench seeder plants for delegate index i (0-based). The e2e harness uses this to build a matching genesis.Delegates list so the LifeLong poll protocol pays rewards to the seeded delegates rather than to identityset addresses.

func TestOnlyPerfBenchSpreadVoterAddress

func TestOnlyPerfBenchSpreadVoterAddress(j int) address.Address

TestOnlyPerfBenchSpreadVoterAddress returns a deterministic voter address whose first byte is j mod 256, spreading scale fixtures across the full ordered voter key space.

func TestOnlyPerfBenchVoterAddress

func TestOnlyPerfBenchVoterAddress(j int) address.Address

TestOnlyPerfBenchVoterAddress returns the deterministic address the perf-bench seeder plants for voter index j (0-based). Exported so tests asserting on planted voter state can round-trip the address.

func TestOnlyPutCandidateRewardAddress

func TestOnlyPutCandidateRewardAddress(
	ctx context.Context,
	sm protocol.StateManager,
	candID address.Address,
	owner address.Address,
	reward address.Address,
	updated bool,
	optedIn bool,
) error

TestOnlyPutCandidateRewardAddress seeds candidate state used by rewarding tests. When a staking view exists it updates state through CandidateStateManager.

func TestOnlyPutCandidateRewardSnapshotFor

func TestOnlyPutCandidateRewardSnapshotFor(
	sm protocol.StateManager,
	candID address.Address,
	snap *CandidateRewardSnapshot,
) error

TestOnlyPutCandidateRewardSnapshotFor seeds a CandidateRewardSnapshot directly under the same key layout FreezeCandidateRewardSnapshots uses. Intended solely for rewarding-package unit tests that exercise post-fork branches without standing up the full poll layer + DelegateProfile bridge. Production code MUST use FreezeCandidateRewardSnapshots at PutPollResult.

func TestOnlyPutVoterBucketThroughCOW

func TestOnlyPutVoterBucketThroughCOW(
	ctx context.Context,
	sm protocol.StateManager,
	candidate, voter address.Address,
	amount *big.Int,
	durationDays uint32,
	ctime time.Time,
	autoStake bool,
) (uint64, error)

TestOnlyPutVoterBucketThroughCOW plants one native vote bucket through a candidate state manager, so the IIP-59 copy-on-write hooks fire exactly as they do for a real staking action.

This is the deliberate opposite of TestOnlySeedNativeVoterBucket above, which bypasses csm so that state it plants looks pre-existing. Use this one to model a bucket created *after* an era froze: the voter's index key gets a tombstone, so the era's view of that voter stays empty and the drain owes them nothing.

Test-only. It maintains neither the candidate's vote accumulator nor the bucket pool, so nothing may assert on either afterwards.

func TestOnlySeedNativeVoterBucket

func TestOnlySeedNativeVoterBucket(
	sm protocol.StateManager,
	candidate, voter address.Address,
	amount *big.Int,
	durationDays uint32,
	ctime time.Time,
	autoStake bool,
) (uint64, error)

TestOnlySeedNativeVoterBucket plants one native vote bucket, bumps the total bucket count, and adds the index to the voter's and the candidate's bucket index lists. It returns the new bucket's index.

It exists so tests outside this package -- the rewarding protocol's drain tests in particular -- can build the voter key space the IIP-59 address walk enumerates. bucketKey, AddrKeyWithPrefix and the _voterIndex / _candIndex tags are package-private, and writing those keys by hand from another package would encode this package's key layout in a test, which is exactly the coupling that makes a layout change unreviewable.

It deliberately does not go through candSM. NewCandidateStateManager needs a live staking view, which the rewarding protocol's unit fixtures do not have, and going through candSM would also fire the era copy-on-write hooks -- the intended use is to plant state *before* a window is opened, so the drain sees it as pre-existing rather than as a post-freeze write.

Test-only. Production bucket creation goes through the staking handlers, which also maintain the bucket pool and the candidate's vote accumulator; this does neither.

func TestOnlySeedPerfBenchContractBuckets

func TestOnlySeedPerfBenchContractBuckets(
	ctx context.Context,
	sm protocol.StateManager,
	spec TestOnlyPerfBenchSpec,
) error

TestOnlySeedPerfBenchContractBuckets plants the contract-bucket portion of a perf fixture. Callers that defer it run this in a pre-activation block after Xingu, so the real state factory persists the bucket namespaces while the IIP-59 owner-index gate is still shut.

func TestOnlySeedPerfBenchState

func TestOnlySeedPerfBenchState(
	ctx context.Context,
	csm CandidateStateManager,
	spec TestOnlyPerfBenchSpec,
) ([]address.Address, error)

TestOnlySeedPerfBenchState plants NumDelegates candidates with self-stake buckets, then plants NumVoters voter buckets distributed round-robin. Returns the addresses of the planted delegates so the caller can look them up during the drain.

Uses csm.putBucketAndIndex / csm.Upsert directly so the caller need not route registrations through the action pool — this makes 27 020-voter mainnet-tier seeding practical in a single genesis-block transaction.

Intended solely for the e2e perf bench (task #68). Do not call from production paths.

func VerifyBLSPop

func VerifyBLSPop(blsPubKey, blsPop []byte, candidateID address.Address) error

VerifyBLSPop verifies the proof-of-possession against the provided pubkey and candidate identity. Returns nil on success.

Types

type BlockStore added in v2.3.0

type BlockStore interface {
	GetReceipts(uint64) ([]*action.Receipt, error)
	HeaderByHeight(height uint64) (*block.Header, error)
}

type BucketIndices

type BucketIndices []uint64

BucketIndices defines the array of bucket index for a

func (*BucketIndices) Decode added in v2.3.0

Decode decodes bucket indices from generic value

func (*BucketIndices) Deserialize

func (bis *BucketIndices) Deserialize(data []byte) error

Deserialize deserializes bytes into bucket indices

func (*BucketIndices) Encode added in v2.3.0

Encode encodes bucket indices into generic value

func (*BucketIndices) LoadProto

func (bis *BucketIndices) LoadProto(bucketIndicesPb *stakingpb.BucketIndices) error

LoadProto converts protobuf to bucket indices

func (*BucketIndices) Proto

func (bis *BucketIndices) Proto() *stakingpb.BucketIndices

Proto converts bucket indices to protobuf

func (*BucketIndices) Serialize

func (bis *BucketIndices) Serialize() ([]byte, error)

Serialize serializes bucket indices into bytes

type BucketPool

type BucketPool struct {
	// contains filtered or unexported fields
}

BucketPool implements the bucket pool

func (*BucketPool) Clone added in v2.2.0

func (bp *BucketPool) Clone() *BucketPool

Clone returns a copy of the bucket pool

func (*BucketPool) Commit

func (bp *BucketPool) Commit() error

Commit is called upon workingset commit

func (*BucketPool) Count

func (bp *BucketPool) Count() uint64

Count returns the total number of buckets in bucket pool

func (*BucketPool) CreditPool

func (bp *BucketPool) CreditPool(sm protocol.StateManager, amount *big.Int, deleteBucket bool) error

CreditPool subtracts staked amount out of the pool

func (*BucketPool) DebitPool

func (bp *BucketPool) DebitPool(sm protocol.StateManager, amount *big.Int, newBucket bool) error

DebitPool adds staked amount into the pool

func (*BucketPool) EnableSMStorage added in v2.2.0

func (bp *BucketPool) EnableSMStorage()

EnableSMStorage enables state manager storage

func (*BucketPool) IsDirty added in v2.2.0

func (bp *BucketPool) IsDirty() bool

IsDirty returns true if the bucket pool is dirty

func (*BucketPool) Total

func (bp *BucketPool) Total() *big.Int

Total returns the total amount staked in bucket pool

type BucketReader added in v2.3.0

type BucketReader interface {
	DeductBucket(address.Address, uint64) (*contractstaking.Bucket, error)
}

BucketReader defines the interface to read bucket info

type BucketSet

type BucketSet interface {
	// contains filtered or unexported methods
}

BucketSet related to setting bucket

type BuilderConfig

type BuilderConfig struct {
	Staking                       genesis.Staking
	PersistStakingPatchBlock      uint64
	FixAliasForNonStopHeight      uint64
	SkipContractStakingViewHeight uint64
	StakingPatchDir               string
	Revise                        ReviseConfig
}

BuilderConfig returns the configuration of the builder

type CalculateVoteWeightFunc added in v2.3.0

type CalculateVoteWeightFunc func(bkt *contractstaking.Bucket, height uint64) *big.Int

CalculateVoteWeightFunc is a function that calculates the vote weight of a bucket.

type Candidate

type Candidate struct {
	Owner              address.Address
	Operator           address.Address
	Reward             address.Address
	Identifier         address.Address
	BLSPubKey          []byte // BLS public key
	DeactivatedAt      uint64
	Name               string
	Votes              *big.Int
	SelfStakeBucketIdx uint64
	SelfStake          *big.Int
	// RewardAddressUpdated marks Reward as explicitly configured after
	// IIP-59 activation.
	RewardAddressUpdated bool
	// VoterRewardOnchainOptIn enables protocol-native reward distribution.
	// Existing Hermes candidates are migrated at activation; later opt-in is
	// owner-controlled. The transition is one-way.
	VoterRewardOnchainOptIn bool
}

Candidate represents the candidate

func (*Candidate) AddSelfStake

func (d *Candidate) AddSelfStake(amount *big.Int) error

AddSelfStake adds self stake

func (*Candidate) AddVote

func (d *Candidate) AddVote(amount *big.Int) error

AddVote adds vote

func (*Candidate) Clone

func (d *Candidate) Clone() *Candidate

Clone returns a copy

func (*Candidate) Collision

func (d *Candidate) Collision(c *Candidate) error

Collision checks collsion of 2 candidates

func (*Candidate) Decode added in v2.3.0

Decode decodes candidate from generic value

func (*Candidate) Deserialize

func (d *Candidate) Deserialize(buf []byte) error

Deserialize deserializes bytes to candidate

func (*Candidate) Encode added in v2.3.0

Encode encodes candidate into generic value

func (*Candidate) Equal

func (d *Candidate) Equal(c *Candidate) bool

Equal tests equality of 2 candidates

func (*Candidate) GetIdentifier

func (d *Candidate) GetIdentifier() address.Address

TODO: rename to ID GetIdentifier returns the identifier

func (*Candidate) Serialize

func (d *Candidate) Serialize() ([]byte, error)

Serialize serializes candidate to bytes

func (*Candidate) SubSelfStake

func (d *Candidate) SubSelfStake(amount *big.Int) error

SubSelfStake subtracts self stake

func (*Candidate) SubVote

func (d *Candidate) SubVote(amount *big.Int) error

SubVote subtracts vote

func (*Candidate) Validate

func (d *Candidate) Validate() error

Validate does the sanity check

type CandidateByAddressReader

type CandidateByAddressReader interface {
	CandidateByAddress(address.Address) (*Candidate, uint64, error)
}

CandidateByAddressReader reads candidates directly from staking state.

func NewCandidateByAddressReader

func NewCandidateByAddressReader(sr protocol.StateReader) CandidateByAddressReader

NewCandidateByAddressReader returns the state-backed candidate lookup for sr. Its narrow interface is safe for historical and archive readers, which do not carry the live staking view required by the full CandidateStateReader.

type CandidateCenter

type CandidateCenter struct {
	// contains filtered or unexported fields
}

CandidateCenter is a struct to manage the candidates

func NewCandidateCenter

func NewCandidateCenter(all CandidateList) (*CandidateCenter, error)

NewCandidateCenter creates an instance of CandidateCenter

func (*CandidateCenter) All

func (m *CandidateCenter) All() CandidateList

All returns all candidates in candidate center

func (CandidateCenter) Base

func (m CandidateCenter) Base() *CandidateCenter

Base returns the confirmed base state

func (*CandidateCenter) Clone added in v2.2.0

func (m *CandidateCenter) Clone() *CandidateCenter

func (*CandidateCenter) Commit

Commit writes the change into base

func (*CandidateCenter) ContainsName

func (m *CandidateCenter) ContainsName(name string) bool

ContainsName returns true if the map contains the candidate by name

func (*CandidateCenter) ContainsOperator

func (m *CandidateCenter) ContainsOperator(operator address.Address) bool

ContainsOperator returns true if the map contains the candidate by operator

func (*CandidateCenter) ContainsOwner

func (m *CandidateCenter) ContainsOwner(owner address.Address) bool

ContainsOwner returns true if the map contains the candidate by owner

func (*CandidateCenter) ContainsSelfStakingBucket

func (m *CandidateCenter) ContainsSelfStakingBucket(index uint64) bool

ContainsSelfStakingBucket returns true if the map contains the self staking bucket index

func (*CandidateCenter) GetByIdentifier

func (m *CandidateCenter) GetByIdentifier(identifier address.Address) *Candidate

GetByIdentifier returns the candidate by identifier

func (*CandidateCenter) GetByName

func (m *CandidateCenter) GetByName(name string) *Candidate

GetByName returns the candidate by name

func (*CandidateCenter) GetByOperator added in v2.3.0

func (m *CandidateCenter) GetByOperator(operator address.Address) *Candidate

GetByOperator returns the candidate by operator

func (*CandidateCenter) GetByOwner

func (m *CandidateCenter) GetByOwner(owner address.Address) *Candidate

GetByOwner returns the candidate by owner

func (*CandidateCenter) GetBySelfStakingIndex

func (m *CandidateCenter) GetBySelfStakingIndex(index uint64) *Candidate

GetBySelfStakingIndex returns the candidate by self-staking index

func (*CandidateCenter) HasBLSPubKeyOtherThan

func (m *CandidateCenter) HasBLSPubKeyOtherThan(blsPubKey []byte, self address.Address) bool

HasBLSPubKeyOtherThan reports whether any candidate other than self has registered the given BLS pubkey.

It answers a question about the whole set rather than naming one holder, and that is the point. A "return the first match" lookup reads All(), which walks candBase.identifierMap — a Go map, whose iteration order is randomised per process. Nothing forbids two candidates from sharing a BLS pubkey before the uniqueness rule activates, and for such a pair each node would name a different holder. Every caller then compares that holder against itself to pick between Success and ErrCandidateConflict, so the two nodes write different receipt statuses, different receipt roots, and fork.

Phrased as "does anyone else hold this", the answer no longer depends on which duplicate is seen first: for holders {A, B} it is true for A, for B, and for any third party alike. This also matches ContainsName and ContainsOperator, the two collision checks either side of it at the call sites, which are likewise existence predicates.

Linear scan over candidates — registration is rare and the candidate set is bounded, trading O(N) lookup for not having to maintain another index map across the change/base commit flow.

func (*CandidateCenter) IsDirty added in v2.2.0

func (m *CandidateCenter) IsDirty() bool

IsDirty returns true if the candidate center is dirty

func (*CandidateCenter) Size

func (m *CandidateCenter) Size() int

Size returns number of candidates

func (*CandidateCenter) Upsert

func (m *CandidateCenter) Upsert(d *Candidate) error

Upsert adds a candidate into map, overwrites if already exist

func (*CandidateCenter) WriteToStateDB added in v2.3.0

func (m *CandidateCenter) WriteToStateDB(sm protocol.StateManager) error

WriteToStateDB writes the candidate center to stateDB

type CandidateList

type CandidateList []*Candidate

CandidateList is a list of candidates which is sortable

func (*CandidateList) Decodes added in v2.3.3

func (l *CandidateList) Decodes(keys [][]byte, gvs []systemcontracts.GenericValue) error

Decode decodes candidate list from generic value

func (*CandidateList) Deserialize

func (l *CandidateList) Deserialize(buf []byte) error

Deserialize deserializes bytes to list of candidates

func (*CandidateList) Encodes added in v2.3.3

func (l *CandidateList) Encodes() ([][]byte, []systemcontracts.GenericValue, error)

Encode encodes candidate list into generic value

func (CandidateList) Len

func (l CandidateList) Len() int

func (CandidateList) Less

func (l CandidateList) Less(i, j int) bool

func (CandidateList) Serialize

func (l CandidateList) Serialize() ([]byte, error)

Serialize serializes candidate to bytes

func (CandidateList) Swap

func (l CandidateList) Swap(i, j int)

type CandidateRewardSnapshot

type CandidateRewardSnapshot struct {
	// BlockCommissionBasisPoints is the delegate's take of block rewards, in
	// basis points [0, 10000]. Defaults to 10000 when CommissionConfigured is false.
	BlockCommissionBasisPoints uint64
	// EpochCommissionBasisPoints is the delegate's take of epoch rewards, in
	// basis points [0, 10000]. Defaults to 10000 when CommissionConfigured is false.
	EpochCommissionBasisPoints uint64
	// CommissionConfigured is true when DelegateProfile returned both reward
	// portion fields as non-empty, valid values at snapshot time. It is not the
	// result of DelegateProfile.registered(address).
	CommissionConfigured bool
	// TotalWeight is the denominator the drain divides each recomputed voter
	// weight by: the frozen value of the candidate's Votes accumulator at H.
	//
	// candidate.Votes is the accepted denominator because it is the same
	// number the removed entry list summed to -- TestVoterWeightInvariant
	// asserts candidate.Votes == Σ_voters view[cand][voter] after every
	// staking handler -- read from the one place that still exists at H.
	// Zero means "this era has no payable voter set for this delegate"; the
	// delegate's pending pool is left intact and rolls into a later era.
	TotalWeight *big.Int
	// FreezeHeight is the era boundary height H this snapshot was taken at.
	//
	// The IIP-59 drain runs several blocks after H and recomputes voter weights
	// from bucket state. Contract-staking buckets that are not timestamp-based
	// have their remaining duration measured against a block height, so the
	// recompute has to be handed H rather than the height of whichever block
	// the chunk runs in. Copy-on-write cannot fix that on its own -- the input
	// is the evaluation height, not a stored value -- so H travels with the
	// snapshot.
	FreezeHeight uint64
	// SelfStakeBucketIdx is the candidate's self-stake bucket index at H.
	//
	// This is the only field of the candidate record the weight recompute
	// reads (`isSelfStake := b.ContractAddress == "" && b.Index ==
	// cand.SelfStakeBucketIdx`), so it is frozen as a scalar rather than
	// copy-on-writing the whole candidate record and the endorsement keys the
	// live lookup goes through. candidateNoSelfStakeBucketIndex
	// (math.MaxUint64) means "no self-stake bucket".
	SelfStakeBucketIdx uint64
}

CandidateRewardSnapshot is the frozen per-candidate view that IIP-59's rewarding path consumes at each epoch close. It is written once per reward era by FreezeCandidateRewardSnapshots (called from the poll layer's PutPollResult) for each opted-in candidate, and never mutated during the era. Mid-era DelegateProfile changes do not retroactively re-split rewards that have already begun accruing.

Every field is a scalar, deliberately. The snapshot used to also carry the delegate's full materialized (voter, weight) list, which made the era boundary cost proportional to the voter population and duplicated the voter set into consensus state. The drain is voter-major now: it walks the voter key space and recomputes each weight from the era's copy-on-write bucket window. Besides the commission policy, it only needs the denominator and the two inputs the recompute is sensitive to (FreezeHeight, SelfStakeBucketIdx).

func CandidateRewardSnapshotFor

func CandidateRewardSnapshotFor(sr protocol.StateReader, candID address.Address) (*CandidateRewardSnapshot, error)

CandidateRewardSnapshotFor returns the frozen snapshot written at the most recent PutPollResult for the given candidate identity. Returns (nil, state.ErrStateNotExist) when no snapshot has been written.

func (*CandidateRewardSnapshot) Decode

Decode implements systemcontracts.GenericValueContainer for Erigon dual-storage.

func (*CandidateRewardSnapshot) Deserialize

func (s *CandidateRewardSnapshot) Deserialize(buf []byte) error

Deserialize implements state.Deserializer.

func (*CandidateRewardSnapshot) Encode

Encode implements systemcontracts.GenericValueContainer for Erigon dual-storage.

func (*CandidateRewardSnapshot) Serialize

func (s *CandidateRewardSnapshot) Serialize() ([]byte, error)

Serialize implements state.Serializer.

type CandidateSet

type CandidateSet interface {
	// contains filtered or unexported methods
}

CandidateSet related to setting candidates

type CandidateStateManager

type CandidateStateManager interface {
	BucketSet
	NativeBucketGetByIndex
	CandidateSet
	// candidate and bucket pool related
	DirtyView() *viewData
	ContainsName(string) bool
	ContainsOwner(address.Address) bool
	ContainsOperator(address.Address) bool
	ContainsSelfStakingBucket(uint64) bool
	GetByName(string) *Candidate
	GetByOwner(address.Address) *Candidate
	GetByIdentifier(address.Address) *Candidate
	GetByOperator(address.Address) *Candidate
	// HasBLSPubKeyOtherThan reports whether any candidate except self
	// has registered the given BLS pubkey. Used to enforce one BLS
	// pubkey per delegate — a hard requirement for IIP-52's
	// FastAggregateVerify quorum-counting model.
	//
	// Deliberately a predicate and not a "who holds it" lookup: two
	// candidates may already share a pubkey from before the rule
	// existed, and naming one of them means naming whichever a Go map
	// happened to yield first, which differs per node.
	HasBLSPubKeyOtherThan(blsPubKey []byte, self address.Address) bool
	Upsert(*Candidate) error
	CreditBucketPool(*big.Int, bool) error
	DebitBucketPool(*big.Int, bool) error
	Commit(context.Context) error
	SM() protocol.StateManager
	SR() protocol.StateReader
}

CandidateStateManager is candidate state manager on top of StateManager

func NewCandidateStateManagerWithContext

func NewCandidateStateManagerWithContext(ctx context.Context, sm protocol.StateManager) (CandidateStateManager, error)

NewCandidateStateManagerWithContext returns a new CandidateStateManager whose native bucket writes participate in the IIP-59 era copy-on-write window.

ctx supplies the fork gate only. Pre-activation the session it builds is inert and performs no state access whatsoever, so adding the session does not change state access or writes until IIP-59 activates.

type CandidateStateReader

type CandidateStateReader interface {
	NativeBucketGetByIndex
	NumOfNativeBucket() (uint64, error)
	NativeBuckets() ([]*VoteBucket, uint64, error)
	NativeBucketsWithIndices(indices BucketIndices) ([]*VoteBucket, error)
	NativeBucketIndices(addr address.Address, prefix byte) (*BucketIndices, uint64, error)
	NativeBucketIndicesByVoter(addr address.Address) (*BucketIndices, uint64, error)
	NativeBucketIndicesByCandidate(addr address.Address) (*BucketIndices, uint64, error)
	FrozenNativeBucket(eracow.Window, uint64) (*VoteBucket, error)
	FrozenNativeBucketIndices(eracow.Window, address.Address) (BucketIndices, error)
	CandidateByAddress(name address.Address) (*Candidate, uint64, error)
	CreateCandidateCenter(ctx protocol.FeatureCtx) (*CandidateCenter, uint64, error)
	ReadState
	Height() uint64
	SR() protocol.StateReader
	BaseView() *viewData
	NewBucketPool(enableSMStorage bool) (*BucketPool, error)
	GetCandidateByName(string) *Candidate
	GetCandidateByOwner(address.Address) *Candidate
	AllCandidates() CandidateList
	TotalStakedAmount() *big.Int
	ActiveBucketsCount() uint64
	ContainsSelfStakingBucket(index uint64) bool
	GetByIdentifier(address.Address) *Candidate
}

CandidateStateReader contains candidate center and bucket pool

func ConstructBaseView

func ConstructBaseView(sr protocol.StateReader) (CandidateStateReader, error)

ConstructBaseView returns a candidate state reader that reflects the base view it will be used read-only

type CandidatesBucketsIndexer

type CandidatesBucketsIndexer struct {
	// contains filtered or unexported fields
}

CandidatesBucketsIndexer is an indexer to store candidates by given height

func NewStakingCandidatesBucketsIndexer

func NewStakingCandidatesBucketsIndexer(kv db.KVStoreForRangeIndex) (*CandidatesBucketsIndexer, error)

NewStakingCandidatesBucketsIndexer creates a new StakingCandidatesIndexer

func (*CandidatesBucketsIndexer) GetBuckets

func (cbi *CandidatesBucketsIndexer) GetBuckets(height uint64, offset, limit uint32) (*iotextypes.VoteBucketList, uint64, error)

GetBuckets gets vote buckets from indexer given epoch start height

func (*CandidatesBucketsIndexer) GetCandidates

func (cbi *CandidatesBucketsIndexer) GetCandidates(height uint64, offset, limit uint32) (*iotextypes.CandidateListV2, uint64, error)

GetCandidates gets candidates from indexer given epoch start height

func (*CandidatesBucketsIndexer) PutBuckets

func (cbi *CandidatesBucketsIndexer) PutBuckets(height uint64, buckets *iotextypes.VoteBucketList) error

PutBuckets puts vote buckets into indexer

func (*CandidatesBucketsIndexer) PutCandidates

func (cbi *CandidatesBucketsIndexer) PutCandidates(height uint64, candidates *iotextypes.CandidateListV2) error

PutCandidates puts candidates into indexer

func (*CandidatesBucketsIndexer) Start

Start starts the indexer

func (*CandidatesBucketsIndexer) Stop

Stop stops the indexer

type CandidiateStateCommon

type CandidiateStateCommon interface {
	ContainsSelfStakingBucket(uint64) bool
	GetByIdentifier(address.Address) *Candidate
	SR() protocol.StateReader
	NativeBucketGetByIndex
}

CandidiateStateCommon is the common interface for candidate state manager and reader

type Configuration

type Configuration struct {
	VoteWeightCalConsts               genesis.VoteWeightCalConsts
	RegistrationConsts                RegistrationConsts
	WithdrawWaitingPeriod             time.Duration
	MinStakeAmount                    *big.Int
	BootstrapCandidates               []genesis.BootstrapCandidate
	PersistStakingPatchBlock          uint64
	FixAliasForNonStopHeight          uint64
	SkipContractStakingViewHeight     uint64
	EndorsementWithdrawWaitingBlocks  uint64
	MigrateContractAddress            string
	TimestampedMigrateContractAddress string
	MinSelfStakeToBeActive            *big.Int
}

Configuration is the staking protocol configuration.

type ContractStakeView added in v2.2.0

type ContractStakeView interface {
	// Wrap wraps the contract stake view
	Wrap() ContractStakeView
	// Fork forks the contract stake view, commit will not affect the original view
	Fork() ContractStakeView
	// IsDirty checks if the contract stake view is dirty
	IsDirty() bool
	// Commit commits the contract stake view
	Commit(context.Context, protocol.StateManager) error
	// CreatePreStates creates pre states for the contract stake view
	CreatePreStates(ctx context.Context) error
	// Handle handles the receipt for the contract stake view
	Handle(ctx context.Context, receipt *action.Receipt) error
	// Migrate writes the bucket types and buckets to the state manager
	Migrate(context.Context, EventHandler) error
	// Revise updates the contract stake view with the latest bucket data
	Revise(context.Context)
	// BucketsByCandidate returns the buckets by candidate address
	CandidateStakeVotes(ctx context.Context, id address.Address) *big.Int
	AddBlockReceipts(ctx context.Context, receipts []*action.Receipt) error
}

ContractStakeView is the interface for contract stake view

type ContractStakeViewBuilder added in v2.3.0

type ContractStakeViewBuilder interface {
	Build(ctx context.Context, target uint64) (ContractStakeView, error)
}

type ContractStakingBucketType

type ContractStakingBucketType = contractstaking.BucketType

ContractStakingBucketType defines the type of contract staking bucket

type ContractStakingIndexer

type ContractStakingIndexer interface {
	lifecycle.StartStopper
	// PutBlock puts a block into the indexer
	PutBlock(context.Context, *block.Block) error
	// StartHeight returns the start height of the indexer
	StartHeight() uint64
	// Height returns the latest indexed height
	Height() (uint64, error)
	// Buckets returns active buckets
	Buckets(height uint64) ([]*VoteBucket, error)
	// BucketsByIndices returns active buckets by indices
	BucketsByIndices([]uint64, uint64) ([]*VoteBucket, error)
	// BucketsByCandidate returns active buckets by candidate
	BucketsByCandidate(ownerAddr address.Address, height uint64) ([]*VoteBucket, error)
	// TotalBucketCount returns the total number of buckets including burned buckets
	TotalBucketCount(height uint64) (uint64, error)
	// ContractAddress returns the contract address
	ContractAddress() address.Address
	// LoadStakeView loads the contract stake view from state reader
	LoadStakeView(context.Context, protocol.StateReader) (ContractStakeView, error)
	// CreateEventProcessor creates a new event processor
	CreateEventProcessor(context.Context, EventHandler) EventProcessor
	// ContractStakingBuckets returns all the contract staking buckets
	ContractStakingBuckets() (uint64, map[uint64]*contractstaking.Bucket, error)
	// IndexerAt returns the contract staking indexer at a specific height
	IndexerAt(protocol.StateReader) ContractStakingIndexer
	// BucketReader defines the interface to read buckets
	BucketReader
}

ContractStakingIndexer defines the interface of contract staking reader

func NewDelayTolerantIndexer added in v2.0.6

func NewDelayTolerantIndexer(indexer ContractStakingIndexer, duration time.Duration) ContractStakingIndexer

NewDelayTolerantIndexer creates a delay tolerant indexer

type ContractStakingIndexerWithBucketType

type ContractStakingIndexerWithBucketType interface {
	ContractStakingIndexer
	// BucketTypes returns the active bucket types
	BucketTypes(height uint64) ([]*ContractStakingBucketType, error)
}

ContractStakingIndexerWithBucketType defines the interface of contract staking reader with bucket type

func NewDelayTolerantIndexerWithBucketType added in v2.0.6

func NewDelayTolerantIndexerWithBucketType(indexer ContractStakingIndexerWithBucketType, duration time.Duration) ContractStakingIndexerWithBucketType

NewDelayTolerantIndexerWithBucketType creates a delay tolerant indexer with bucket type

type Endorsement

type Endorsement struct {
	// ExpireHeight is the height an endorsement is expired in legacy mode and it is the earliest height that can revoke the endorsement in new mode
	ExpireHeight uint64
}

Endorsement is a struct that contains the expire height of the Endorsement

func (*Endorsement) Decode added in v2.3.0

Decode decodes endorsement from generic value

func (*Endorsement) Deserialize

func (e *Endorsement) Deserialize(buf []byte) error

Deserialize deserializes bytes to endorsement

func (*Endorsement) Encode added in v2.3.0

Encode encodes endorsement into generic value

func (*Endorsement) LegacyStatus

func (e *Endorsement) LegacyStatus(height uint64) EndorsementStatus

func (*Endorsement) Serialize

func (e *Endorsement) Serialize() ([]byte, error)

Serialize serializes endorsement to bytes

func (*Endorsement) Status

func (e *Endorsement) Status(height uint64) EndorsementStatus

Status returns the status of the endorsement

type EndorsementStateManager

type EndorsementStateManager struct {
	protocol.StateManager
	*EndorsementStateReader
}

EndorsementStateManager defines the interface of endorsement state manager

func NewEndorsementStateManager

func NewEndorsementStateManager(sm protocol.StateManager) *EndorsementStateManager

NewEndorsementStateManager creates a new endorsement state manager

func (*EndorsementStateManager) Delete

func (esm *EndorsementStateManager) Delete(bucketIndex uint64) error

Delete deletes the endorsement of a bucket

func (*EndorsementStateManager) Put

func (esm *EndorsementStateManager) Put(bucketIndex uint64, endorse *Endorsement) error

Put puts the endorsement of a bucket

type EndorsementStateReader

type EndorsementStateReader struct {
	protocol.StateReader
}

EndorsementStateReader defines the interface of endorsement state reader

func NewEndorsementStateReader

func NewEndorsementStateReader(sr protocol.StateReader) *EndorsementStateReader

NewEndorsementStateReader creates a new endorsement state reader

func (*EndorsementStateReader) Get

func (esr *EndorsementStateReader) Get(bucketIndex uint64) (*Endorsement, error)

Get gets the endorsement of a bucket

func (*EndorsementStateReader) Status

func (esr *EndorsementStateReader) Status(ctx protocol.FeatureCtx, bucketIndex, height uint64) (EndorsementStatus, error)

Status returns the status of the endorsement of a bucket at a certain height If the endorsement does not exist, it returns EndorseExpired

type EndorsementStatus

type EndorsementStatus uint8

EndorsementStatus is a uint8 that represents the status of the endorsement

func (EndorsementStatus) String

func (s EndorsementStatus) String() string

String returns a human-readable string of the endorsement status

type EventHandler added in v2.3.0

EventHandler is the interface for handling staking events

type EventProcessor added in v2.3.0

type EventProcessor interface {
	// ProcessReceipts processes receipts
	ProcessReceipts(context.Context, ...*action.Receipt) error
}

EventProcessor is the interface for processing staking events

type FrozenSelfStake

type FrozenSelfStake struct {
	FreezeHeight uint64
	BucketIdx    uint64
}

FrozenSelfStake is an era's view of one candidate's self-stake bucket. FreezeHeight doubles as the presence flag: zero means the caller has no frozen era, while bucket index 0 remains a valid self-stake bucket.

func (FrozenSelfStake) Covers

func (f FrozenSelfStake) Covers(bucketIdx uint64) bool

Covers reports whether bucketIdx was the candidate's self-stake bucket at the freeze height. It is always false when the era is unknown.

func (FrozenSelfStake) Known

func (f FrozenSelfStake) Known() bool

Known reports whether this value came from a real era freeze.

type FrozenVoterPage

type FrozenVoterPage struct {
	Voters           []address.Address
	ResumeAfter      []byte
	Complete         bool
	IndexKeysScanned int
}

FrozenVoterPage is one bounded page of the voter address space at an era's freeze height. Voters are ascending and deduplicated. ResumeAfter is an exclusive cursor; it may name a scanned address at which no voter exists. Complete means the requested address range was covered completely.

func ScanFrozenVoters

func ScanFrozenVoters(
	sr protocol.StateReader,
	window eracow.Window,
	rangeStart []byte,
	rangeEnd []byte,
	resumeAfter []byte,
	voterLimit int,
	indexKeyLimit int,
) (FrozenVoterPage, error)

ScanFrozenVoters returns at most voterLimit voters in [rangeStart, rangeEnd), resuming strictly after resumeAfter. A nil rangeEnd means the top of the address space. A zero voterLimit or indexKeyLimit disables that bound.

The four streams are voter indexes, not bucket lists: native live, contract-staking live, and their two copy-on-write counterparts. The COW streams retain voters whose final bucket index was deleted after the freeze. This function owns their merge so rewarding can paginate voters without depending on the staking storage layout.

indexKeyLimit bounds index enumeration independently of voter processing. COW tombstones and duplicate addresses can consume keys without producing a voter, so a raw `Limit(voterLimit)` cannot be resumed safely. The merge only returns addresses at or below the minimum point covered by every truncated stream and uses that point as ResumeAfter when necessary.

type GenesisStateSeeder

type GenesisStateSeeder func(ctx context.Context, csm CandidateStateManager) error

GenesisStateSeeder plants additional genesis state inside the same candidate-state transaction that CreateGenesisStates uses for BootstrapCandidates. See WithGenesisStateSeeder.

type HelperCtx

type HelperCtx struct {
	BlockInterval func(uint64) time.Duration
	DepositGas    protocol.DepositGas
}

HelperCtx is the helper context for staking protocol

type MockBucketReader added in v2.3.0

type MockBucketReader struct {
	// contains filtered or unexported fields
}

MockBucketReader is a mock of BucketReader interface.

func NewMockBucketReader added in v2.3.0

func NewMockBucketReader(ctrl *gomock.Controller) *MockBucketReader

NewMockBucketReader creates a new mock instance.

func (*MockBucketReader) DeductBucket added in v2.3.0

func (m *MockBucketReader) DeductBucket(arg0 address.Address, arg1 uint64) (*contractstaking.Bucket, error)

DeductBucket mocks base method.

func (*MockBucketReader) EXPECT added in v2.3.0

EXPECT returns an object that allows the caller to indicate expected use.

type MockBucketReaderMockRecorder added in v2.3.0

type MockBucketReaderMockRecorder struct {
	// contains filtered or unexported fields
}

MockBucketReaderMockRecorder is the mock recorder for MockBucketReader.

func (*MockBucketReaderMockRecorder) DeductBucket added in v2.3.0

func (mr *MockBucketReaderMockRecorder) DeductBucket(arg0, arg1 any) *gomock.Call

DeductBucket indicates an expected call of DeductBucket.

type MockContractStakeView added in v2.3.0

type MockContractStakeView struct {
	// contains filtered or unexported fields
}

MockContractStakeView is a mock of ContractStakeView interface.

func NewMockContractStakeView added in v2.3.0

func NewMockContractStakeView(ctrl *gomock.Controller) *MockContractStakeView

NewMockContractStakeView creates a new mock instance.

func (*MockContractStakeView) AddBlockReceipts added in v2.3.0

func (m *MockContractStakeView) AddBlockReceipts(ctx context.Context, receipts []*action.Receipt) error

AddBlockReceipts mocks base method.

func (*MockContractStakeView) CandidateStakeVotes added in v2.3.0

func (m *MockContractStakeView) CandidateStakeVotes(ctx context.Context, id address.Address) *big.Int

CandidateStakeVotes mocks base method.

func (*MockContractStakeView) Commit added in v2.3.0

Commit mocks base method.

func (*MockContractStakeView) CreatePreStates added in v2.3.0

func (m *MockContractStakeView) CreatePreStates(ctx context.Context) error

CreatePreStates mocks base method.

func (*MockContractStakeView) EXPECT added in v2.3.0

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockContractStakeView) Fork added in v2.3.0

Fork mocks base method.

func (*MockContractStakeView) Handle added in v2.3.0

func (m *MockContractStakeView) Handle(ctx context.Context, receipt *action.Receipt) error

Handle mocks base method.

func (*MockContractStakeView) IsDirty added in v2.3.0

func (m *MockContractStakeView) IsDirty() bool

IsDirty mocks base method.

func (*MockContractStakeView) Migrate added in v2.3.0

func (m *MockContractStakeView) Migrate(arg0 context.Context, arg1 EventHandler) error

Migrate mocks base method.

func (*MockContractStakeView) Revise added in v2.3.0

func (m *MockContractStakeView) Revise(arg0 context.Context)

Revise mocks base method.

func (*MockContractStakeView) Wrap added in v2.3.0

Wrap mocks base method.

type MockContractStakeViewMockRecorder added in v2.3.0

type MockContractStakeViewMockRecorder struct {
	// contains filtered or unexported fields
}

MockContractStakeViewMockRecorder is the mock recorder for MockContractStakeView.

func (*MockContractStakeViewMockRecorder) AddBlockReceipts added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) AddBlockReceipts(ctx, receipts any) *gomock.Call

AddBlockReceipts indicates an expected call of AddBlockReceipts.

func (*MockContractStakeViewMockRecorder) CandidateStakeVotes added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) CandidateStakeVotes(ctx, id any) *gomock.Call

CandidateStakeVotes indicates an expected call of CandidateStakeVotes.

func (*MockContractStakeViewMockRecorder) Commit added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) Commit(arg0, arg1 any) *gomock.Call

Commit indicates an expected call of Commit.

func (*MockContractStakeViewMockRecorder) CreatePreStates added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) CreatePreStates(ctx any) *gomock.Call

CreatePreStates indicates an expected call of CreatePreStates.

func (*MockContractStakeViewMockRecorder) Fork added in v2.3.0

Fork indicates an expected call of Fork.

func (*MockContractStakeViewMockRecorder) Handle added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) Handle(ctx, receipt any) *gomock.Call

Handle indicates an expected call of Handle.

func (*MockContractStakeViewMockRecorder) IsDirty added in v2.3.0

IsDirty indicates an expected call of IsDirty.

func (*MockContractStakeViewMockRecorder) Migrate added in v2.3.0

func (mr *MockContractStakeViewMockRecorder) Migrate(arg0, arg1 any) *gomock.Call

Migrate indicates an expected call of Migrate.

func (*MockContractStakeViewMockRecorder) Revise added in v2.3.0

Revise indicates an expected call of Revise.

func (*MockContractStakeViewMockRecorder) Wrap added in v2.3.0

Wrap indicates an expected call of Wrap.

type MockContractStakingIndexer

type MockContractStakingIndexer struct {
	// contains filtered or unexported fields
}

MockContractStakingIndexer is a mock of ContractStakingIndexer interface.

func NewMockContractStakingIndexer

func NewMockContractStakingIndexer(ctrl *gomock.Controller) *MockContractStakingIndexer

NewMockContractStakingIndexer creates a new mock instance.

func (*MockContractStakingIndexer) Buckets

func (m *MockContractStakingIndexer) Buckets(height uint64) ([]*VoteBucket, error)

Buckets mocks base method.

func (*MockContractStakingIndexer) BucketsByCandidate

func (m *MockContractStakingIndexer) BucketsByCandidate(ownerAddr address.Address, height uint64) ([]*VoteBucket, error)

BucketsByCandidate mocks base method.

func (*MockContractStakingIndexer) BucketsByIndices

func (m *MockContractStakingIndexer) BucketsByIndices(arg0 []uint64, arg1 uint64) ([]*VoteBucket, error)

BucketsByIndices mocks base method.

func (*MockContractStakingIndexer) ContractAddress

func (m *MockContractStakingIndexer) ContractAddress() address.Address

ContractAddress mocks base method.

func (*MockContractStakingIndexer) ContractStakingBuckets added in v2.3.0

func (m *MockContractStakingIndexer) ContractStakingBuckets() (uint64, map[uint64]*contractstaking.Bucket, error)

ContractStakingBuckets mocks base method.

func (*MockContractStakingIndexer) CreateEventProcessor added in v2.3.0

func (m *MockContractStakingIndexer) CreateEventProcessor(arg0 context.Context, arg1 EventHandler) EventProcessor

CreateEventProcessor mocks base method.

func (*MockContractStakingIndexer) DeductBucket added in v2.3.0

DeductBucket mocks base method.

func (*MockContractStakingIndexer) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockContractStakingIndexer) Height added in v2.0.6

func (m *MockContractStakingIndexer) Height() (uint64, error)

Height mocks base method.

func (*MockContractStakingIndexer) IndexerAt added in v2.3.3

IndexerAt mocks base method.

func (*MockContractStakingIndexer) LoadStakeView added in v2.3.0

LoadStakeView mocks base method.

func (*MockContractStakingIndexer) PutBlock added in v2.3.0

func (m *MockContractStakingIndexer) PutBlock(arg0 context.Context, arg1 *block.Block) error

PutBlock mocks base method.

func (*MockContractStakingIndexer) Start added in v2.3.0

Start mocks base method.

func (*MockContractStakingIndexer) StartHeight added in v2.3.0

func (m *MockContractStakingIndexer) StartHeight() uint64

StartHeight mocks base method.

func (*MockContractStakingIndexer) Stop added in v2.3.0

Stop mocks base method.

func (*MockContractStakingIndexer) TotalBucketCount

func (m *MockContractStakingIndexer) TotalBucketCount(height uint64) (uint64, error)

TotalBucketCount mocks base method.

type MockContractStakingIndexerMockRecorder

type MockContractStakingIndexerMockRecorder struct {
	// contains filtered or unexported fields
}

MockContractStakingIndexerMockRecorder is the mock recorder for MockContractStakingIndexer.

func (*MockContractStakingIndexerMockRecorder) Buckets

Buckets indicates an expected call of Buckets.

func (*MockContractStakingIndexerMockRecorder) BucketsByCandidate

func (mr *MockContractStakingIndexerMockRecorder) BucketsByCandidate(ownerAddr, height any) *gomock.Call

BucketsByCandidate indicates an expected call of BucketsByCandidate.

func (*MockContractStakingIndexerMockRecorder) BucketsByIndices

func (mr *MockContractStakingIndexerMockRecorder) BucketsByIndices(arg0, arg1 any) *gomock.Call

BucketsByIndices indicates an expected call of BucketsByIndices.

func (*MockContractStakingIndexerMockRecorder) ContractAddress

func (mr *MockContractStakingIndexerMockRecorder) ContractAddress() *gomock.Call

ContractAddress indicates an expected call of ContractAddress.

func (*MockContractStakingIndexerMockRecorder) ContractStakingBuckets added in v2.3.0

func (mr *MockContractStakingIndexerMockRecorder) ContractStakingBuckets() *gomock.Call

ContractStakingBuckets indicates an expected call of ContractStakingBuckets.

func (*MockContractStakingIndexerMockRecorder) CreateEventProcessor added in v2.3.0

func (mr *MockContractStakingIndexerMockRecorder) CreateEventProcessor(arg0, arg1 any) *gomock.Call

CreateEventProcessor indicates an expected call of CreateEventProcessor.

func (*MockContractStakingIndexerMockRecorder) DeductBucket added in v2.3.0

func (mr *MockContractStakingIndexerMockRecorder) DeductBucket(arg0, arg1 any) *gomock.Call

DeductBucket indicates an expected call of DeductBucket.

func (*MockContractStakingIndexerMockRecorder) Height added in v2.0.6

Height indicates an expected call of Height.

func (*MockContractStakingIndexerMockRecorder) IndexerAt added in v2.3.3

IndexerAt indicates an expected call of IndexerAt.

func (*MockContractStakingIndexerMockRecorder) LoadStakeView added in v2.3.0

func (mr *MockContractStakingIndexerMockRecorder) LoadStakeView(arg0, arg1 any) *gomock.Call

LoadStakeView indicates an expected call of LoadStakeView.

func (*MockContractStakingIndexerMockRecorder) PutBlock added in v2.3.0

func (mr *MockContractStakingIndexerMockRecorder) PutBlock(arg0, arg1 any) *gomock.Call

PutBlock indicates an expected call of PutBlock.

func (*MockContractStakingIndexerMockRecorder) Start added in v2.3.0

Start indicates an expected call of Start.

func (*MockContractStakingIndexerMockRecorder) StartHeight added in v2.3.0

StartHeight indicates an expected call of StartHeight.

func (*MockContractStakingIndexerMockRecorder) Stop added in v2.3.0

Stop indicates an expected call of Stop.

func (*MockContractStakingIndexerMockRecorder) TotalBucketCount

func (mr *MockContractStakingIndexerMockRecorder) TotalBucketCount(height any) *gomock.Call

TotalBucketCount indicates an expected call of TotalBucketCount.

type MockContractStakingIndexerWithBucketType

type MockContractStakingIndexerWithBucketType struct {
	// contains filtered or unexported fields
}

MockContractStakingIndexerWithBucketType is a mock of ContractStakingIndexerWithBucketType interface.

func NewMockContractStakingIndexerWithBucketType

func NewMockContractStakingIndexerWithBucketType(ctrl *gomock.Controller) *MockContractStakingIndexerWithBucketType

NewMockContractStakingIndexerWithBucketType creates a new mock instance.

func (*MockContractStakingIndexerWithBucketType) BucketTypes

BucketTypes mocks base method.

func (*MockContractStakingIndexerWithBucketType) Buckets

Buckets mocks base method.

func (*MockContractStakingIndexerWithBucketType) BucketsByCandidate

func (m *MockContractStakingIndexerWithBucketType) BucketsByCandidate(ownerAddr address.Address, height uint64) ([]*VoteBucket, error)

BucketsByCandidate mocks base method.

func (*MockContractStakingIndexerWithBucketType) BucketsByIndices

func (m *MockContractStakingIndexerWithBucketType) BucketsByIndices(arg0 []uint64, arg1 uint64) ([]*VoteBucket, error)

BucketsByIndices mocks base method.

func (*MockContractStakingIndexerWithBucketType) ContractAddress

ContractAddress mocks base method.

func (*MockContractStakingIndexerWithBucketType) ContractStakingBuckets added in v2.3.0

ContractStakingBuckets mocks base method.

func (*MockContractStakingIndexerWithBucketType) CreateEventProcessor added in v2.3.0

CreateEventProcessor mocks base method.

func (*MockContractStakingIndexerWithBucketType) DeductBucket added in v2.3.0

DeductBucket mocks base method.

func (*MockContractStakingIndexerWithBucketType) EXPECT

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockContractStakingIndexerWithBucketType) Height added in v2.0.6

Height mocks base method.

func (*MockContractStakingIndexerWithBucketType) IndexerAt added in v2.3.3

IndexerAt mocks base method.

func (*MockContractStakingIndexerWithBucketType) LoadStakeView added in v2.3.0

LoadStakeView mocks base method.

func (*MockContractStakingIndexerWithBucketType) PutBlock added in v2.3.0

PutBlock mocks base method.

func (*MockContractStakingIndexerWithBucketType) Start added in v2.3.0

Start mocks base method.

func (*MockContractStakingIndexerWithBucketType) StartHeight added in v2.3.0

StartHeight mocks base method.

func (*MockContractStakingIndexerWithBucketType) Stop added in v2.3.0

Stop mocks base method.

func (*MockContractStakingIndexerWithBucketType) TotalBucketCount

func (m *MockContractStakingIndexerWithBucketType) TotalBucketCount(height uint64) (uint64, error)

TotalBucketCount mocks base method.

type MockContractStakingIndexerWithBucketTypeMockRecorder

type MockContractStakingIndexerWithBucketTypeMockRecorder struct {
	// contains filtered or unexported fields
}

MockContractStakingIndexerWithBucketTypeMockRecorder is the mock recorder for MockContractStakingIndexerWithBucketType.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) BucketTypes

BucketTypes indicates an expected call of BucketTypes.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) Buckets

Buckets indicates an expected call of Buckets.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) BucketsByCandidate

func (mr *MockContractStakingIndexerWithBucketTypeMockRecorder) BucketsByCandidate(ownerAddr, height any) *gomock.Call

BucketsByCandidate indicates an expected call of BucketsByCandidate.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) BucketsByIndices

func (mr *MockContractStakingIndexerWithBucketTypeMockRecorder) BucketsByIndices(arg0, arg1 any) *gomock.Call

BucketsByIndices indicates an expected call of BucketsByIndices.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) ContractAddress

ContractAddress indicates an expected call of ContractAddress.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) ContractStakingBuckets added in v2.3.0

ContractStakingBuckets indicates an expected call of ContractStakingBuckets.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) CreateEventProcessor added in v2.3.0

func (mr *MockContractStakingIndexerWithBucketTypeMockRecorder) CreateEventProcessor(arg0, arg1 any) *gomock.Call

CreateEventProcessor indicates an expected call of CreateEventProcessor.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) DeductBucket added in v2.3.0

DeductBucket indicates an expected call of DeductBucket.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) Height added in v2.0.6

Height indicates an expected call of Height.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) IndexerAt added in v2.3.3

IndexerAt indicates an expected call of IndexerAt.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) LoadStakeView added in v2.3.0

LoadStakeView indicates an expected call of LoadStakeView.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) PutBlock added in v2.3.0

PutBlock indicates an expected call of PutBlock.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) Start added in v2.3.0

Start indicates an expected call of Start.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) StartHeight added in v2.3.0

StartHeight indicates an expected call of StartHeight.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) Stop added in v2.3.0

Stop indicates an expected call of Stop.

func (*MockContractStakingIndexerWithBucketTypeMockRecorder) TotalBucketCount

TotalBucketCount indicates an expected call of TotalBucketCount.

type MockEventHandler added in v2.3.0

type MockEventHandler struct {
	// contains filtered or unexported fields
}

MockEventHandler is a mock of EventHandler interface.

func NewMockEventHandler added in v2.3.0

func NewMockEventHandler(ctrl *gomock.Controller) *MockEventHandler

NewMockEventHandler creates a new mock instance.

func (*MockEventHandler) DeductBucket added in v2.3.0

func (m *MockEventHandler) DeductBucket(arg0 address.Address, arg1 uint64) (*contractstaking.Bucket, error)

DeductBucket mocks base method.

func (*MockEventHandler) DeleteBucket added in v2.3.0

func (m *MockEventHandler) DeleteBucket(arg0 context.Context, arg1 address.Address, arg2 uint64) error

DeleteBucket mocks base method.

func (*MockEventHandler) EXPECT added in v2.3.0

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockEventHandler) PutBucket added in v2.3.0

func (m *MockEventHandler) PutBucket(arg0 context.Context, arg1 address.Address, arg2 uint64, arg3 *contractstaking.Bucket) error

PutBucket mocks base method.

func (*MockEventHandler) PutBucketType added in v2.3.0

func (m *MockEventHandler) PutBucketType(arg0 address.Address, arg1 *ContractStakingBucketType) error

PutBucketType mocks base method.

type MockEventHandlerMockRecorder added in v2.3.0

type MockEventHandlerMockRecorder struct {
	// contains filtered or unexported fields
}

MockEventHandlerMockRecorder is the mock recorder for MockEventHandler.

func (*MockEventHandlerMockRecorder) DeductBucket added in v2.3.0

func (mr *MockEventHandlerMockRecorder) DeductBucket(arg0, arg1 any) *gomock.Call

DeductBucket indicates an expected call of DeductBucket.

func (*MockEventHandlerMockRecorder) DeleteBucket added in v2.3.0

func (mr *MockEventHandlerMockRecorder) DeleteBucket(arg0, arg1, arg2 any) *gomock.Call

DeleteBucket indicates an expected call of DeleteBucket.

func (*MockEventHandlerMockRecorder) PutBucket added in v2.3.0

func (mr *MockEventHandlerMockRecorder) PutBucket(arg0, arg1, arg2, arg3 any) *gomock.Call

PutBucket indicates an expected call of PutBucket.

func (*MockEventHandlerMockRecorder) PutBucketType added in v2.3.0

func (mr *MockEventHandlerMockRecorder) PutBucketType(arg0, arg1 any) *gomock.Call

PutBucketType indicates an expected call of PutBucketType.

type MockEventProcessor added in v2.3.0

type MockEventProcessor struct {
	// contains filtered or unexported fields
}

MockEventProcessor is a mock of EventProcessor interface.

func NewMockEventProcessor added in v2.3.0

func NewMockEventProcessor(ctrl *gomock.Controller) *MockEventProcessor

NewMockEventProcessor creates a new mock instance.

func (*MockEventProcessor) EXPECT added in v2.3.0

EXPECT returns an object that allows the caller to indicate expected use.

func (*MockEventProcessor) ProcessReceipts added in v2.3.0

func (m *MockEventProcessor) ProcessReceipts(arg0 context.Context, arg1 ...*action.Receipt) error

ProcessReceipts mocks base method.

type MockEventProcessorMockRecorder added in v2.3.0

type MockEventProcessorMockRecorder struct {
	// contains filtered or unexported fields
}

MockEventProcessorMockRecorder is the mock recorder for MockEventProcessor.

func (*MockEventProcessorMockRecorder) ProcessReceipts added in v2.3.0

func (mr *MockEventProcessorMockRecorder) ProcessReceipts(arg0 any, arg1 ...any) *gomock.Call

ProcessReceipts indicates an expected call of ProcessReceipts.

type NativeBucketGetByIndex added in v2.3.0

type NativeBucketGetByIndex interface {
	NativeBucket(index uint64) (*VoteBucket, error)
}

NativeBucketGetByIndex related to obtaining bucket by index

type Option added in v2.2.0

type Option func(*Protocol)

Option is the option to create a protocol

func WithBlockStore added in v2.3.0

func WithBlockStore(bs BlockStore) Option

WithBlockStore sets the block store

func WithContractStakingIndexerV3 added in v2.2.0

func WithContractStakingIndexerV3(indexer ContractStakingIndexer) Option

WithContractStakingIndexerV3 sets the contract staking indexer v3

func WithDelegateProfileReader

func WithDelegateProfileReader(fn func(protocol.StateManager) delegateprofile.ContractReader) Option

WithDelegateProfileReader injects the reader used to consult the DelegateProfile contract during the Hermes opt-in migration.

It is injected rather than constructed here because the reader runs a simulated view call, which lives in the evm package. staking cannot reach the existing one in poll (poll imports staking), and importing evm directly would add a dependency edge to a package that otherwise only touches state. chainservice imports both and wires the two together.

Left unset, the migration falls back to its pre-ZanzibarBeta behaviour of migrating on reward address alone.

func WithGenesisStateSeeder

func WithGenesisStateSeeder(seeder GenesisStateSeeder) Option

WithGenesisStateSeeder sets a seeder invoked from CreateGenesisStates AFTER the BootstrapCandidates loop and BEFORE the final Commit. It lets a test harness plant candidates + voter buckets directly in the same genesis transaction, avoiding the action-pool bottleneck at mainnet-scale voter counts. Nothing in production wires this — a node built from config alone never reaches it, which is the point of it being an option rather than a package-level hook.

type PatchStore

type PatchStore struct {
	// contains filtered or unexported fields
}

PatchStore is the patch store of staking protocol

func NewPatchStore

func NewPatchStore(dir string) *PatchStore

NewPatchStore creates a new staking patch store

func (*PatchStore) Read

Read reads CandidateList by name and CandidateList by operator of given height

type Protocol

type Protocol struct {
	// contains filtered or unexported fields
}

Protocol defines the protocol of handling staking

func FindProtocol

func FindProtocol(registry *protocol.Registry) *Protocol

FindProtocol return a registered protocol from registry

func NewProtocol

func NewProtocol(
	helperCtx HelperCtx,
	cfg *BuilderConfig,
	blocksToDurationFn func(startHeight, endHeight, currentHeight uint64) time.Duration,
	candBucketsIndexer *CandidatesBucketsIndexer,
	contractStakingIndexer ContractStakingIndexerWithBucketType,
	contractStakingIndexerV2 ContractStakingIndexer,
	opts ...Option,
) (*Protocol, error)

NewProtocol instantiates the protocol of staking

func (*Protocol) ActiveCandidates

func (p *Protocol) ActiveCandidates(ctx context.Context, sr protocol.StateReader, height uint64) (state.CandidateList, error)

ActiveCandidates returns all active candidates in candidate center

func (*Protocol) AddDepositForCompound

func (p *Protocol) AddDepositForCompound(
	ctx context.Context,
	sm protocol.StateManager,
	voter address.Address,
	bucketID uint64,
	amount *big.Int,
	era FrozenSelfStake,
) error

AddDepositForCompound applies an IIP-59 §3.6 compound deposit into voter's registered AutoDeposit bucket. It is the rewarding-side counterpart to handleDepositToStake: same in-place bucket + candidate + bucket-pool updates, but without the user-action plumbing (no signature check, no gas, no caller balance debit, no receipt log — the caller emits a batched DelegateVoterRewardsDistributed log instead).

Preconditions the caller MUST have already established:

  1. bucketID came from AutoDeposit.bucket(voter) and is strictly positive (via autodeposit.Bridge.LookupBucket).
  2. The bucket at bucketID is native, active (not unstaked), has AutoStake set, and its Owner byte-equals voter (via autodeposit.IsBucketEligibleForCompound).

This function re-checks the owner match as a safety net and errors out otherwise — the check is cheap and the failure mode of quietly compounding into someone else's bucket is unacceptable.

State mutations mirror handleDepositToStake exactly:

  • bucket.StakedAmount += amount, persisted via csm.updateBucket
  • candidate weighted-vote recomputed (SubVote(prev) then AddVote(next))
  • candidate.SelfStake += amount when the bucket is a self-stake bucket (rare here — a voter compounding into their own self-stake bucket — but respected for parity)
  • bucket pool total grows by amount via DebitBucketPool

No transaction log is returned: the caller wraps the whole per-delegate distribution into a single DelegateVoterRewardsDistributed batched log, and the rewarding→bucket-pool token movement is captured in that batch's transactionLogs slice at the call site.

func (*Protocol) Commit

func (p *Protocol) Commit(ctx context.Context, sm protocol.StateManager) error

Commit commits the last change

func (*Protocol) ConstructExecution

func (p *Protocol) ConstructExecution(ctx context.Context, act *action.MigrateStake, nonce, gas uint64, gasPrice *big.Int, sr protocol.StateReader) (action.Envelope, error)

func (*Protocol) CreateGenesisStates

func (p *Protocol) CreateGenesisStates(
	ctx context.Context,
	sm protocol.StateManager,
) error

CreateGenesisStates is used to setup BootstrapCandidates from genesis config.

func (*Protocol) CreatePostSystemActions added in v2.4.0

func (p *Protocol) CreatePostSystemActions(ctx context.Context, sr protocol.StateReader) ([]action.Envelope, error)

func (*Protocol) CreatePreStates

func (p *Protocol) CreatePreStates(ctx context.Context, sm protocol.StateManager) error

CreatePreStates updates state manager

func (*Protocol) ForceRegister

func (p *Protocol) ForceRegister(r *protocol.Registry) error

ForceRegister registers the protocol with a unique ID and force replacing the previous protocol if it exists

func (*Protocol) Handle

func (p *Protocol) Handle(ctx context.Context, elp action.Envelope, sm protocol.StateManager) (receipt *action.Receipt, err error)

Handle handles a staking message

func (*Protocol) HandleReceipt added in v2.2.0

func (p *Protocol) HandleReceipt(ctx context.Context, elp action.Envelope, sm protocol.StateManager, receipt *action.Receipt) error

HandleReceipt handles a receipt

func (*Protocol) Name

func (p *Protocol) Name() string

Name returns the name of protocol

func (*Protocol) PreCommit

func (p *Protocol) PreCommit(ctx context.Context, sm protocol.StateManager) error

PreCommit performs pre-commit

func (*Protocol) ReadState

func (p *Protocol) ReadState(ctx context.Context, sr protocol.StateReader, method []byte, args ...[]byte) ([]byte, uint64, error)

ReadState read the state on blockchain via protocol

func (*Protocol) Register

func (p *Protocol) Register(r *protocol.Registry) error

Register registers the protocol with a unique ID

func (*Protocol) SlashCandidateByID added in v2.4.0

func (p *Protocol) SlashCandidateByID(
	ctx context.Context,
	sm protocol.StateManager,
	id address.Address,
	amount *big.Int,
) error

func (*Protocol) SlashCandidateByOperator added in v2.4.0

func (p *Protocol) SlashCandidateByOperator(
	ctx context.Context,
	sm protocol.StateManager,
	operator address.Address,
	amount *big.Int,
) error

func (*Protocol) Start

Start starts the protocol

func (*Protocol) Validate

func (p *Protocol) Validate(ctx context.Context, elp action.Envelope, sr protocol.StateReader) error

Validate validates a staking message

type ReadState

type ReadState interface {
	// contains filtered or unexported methods
}

ReadState related to read bucket and candidate by request

type ReceiptError

type ReceiptError interface {
	Error() string
	ReceiptStatus() uint64
}

ReceiptError indicates a non-critical error with corresponding receipt status

type RegistrationConsts

type RegistrationConsts struct {
	Fee          *big.Int
	MinSelfStake *big.Int
}

RegistrationConsts are the registration fee and min self stake

type ReviseConfig

type ReviseConfig struct {
	VoteWeight                  genesis.VoteWeightCalConsts
	ReviseHeights               []uint64
	CorrectCandsHeight          uint64
	SelfStakeBucketReviseHeight uint64
	CorrectCandSelfStakeHeight  uint64
}

VoteReviser is used to recalculate candidate votes.

type Snapshot added in v2.2.0

type Snapshot struct {
	// contains filtered or unexported fields
}

type TestOnlyPerfBenchSpec

type TestOnlyPerfBenchSpec struct {
	// NumDelegates is the count of delegates to plant. Each gets an
	// Candidate + self-stake bucket.
	NumDelegates int
	// NumVoters is the count of distinct voter buckets to plant. Voters
	// are distributed round-robin across the delegates.
	NumVoters int
	// NumNativeBuckets is the number of native voter buckets to plant across
	// NumVoters distinct owners. Zero preserves the original one-per-voter
	// fixture.
	NumNativeBuckets int
	// NumContractBuckets is the number of pre-activation contract-staking
	// buckets to plant. They are spread across ContractStakingAddresses and
	// deliberately written without a feature context, leaving owner indexes
	// absent for the activation backfill to build.
	NumContractBuckets int
	// ContractStakingAddresses are the contracts used for contract buckets.
	// At least one is required when NumContractBuckets is non-zero.
	ContractStakingAddresses []address.Address
	// SpreadVoterAddresses spreads voters across the full address key space.
	SpreadVoterAddresses bool
	// DeferContractBucketSeeding leaves contract bucket state for a harness to
	// plant after genesis while still including its weight in candidate totals.
	// This is needed by the real state factory, which filters contract-staking
	// namespaces from genesis before Xingu.
	DeferContractBucketSeeding bool
	// DelegateSelfStake is the self-stake amount for every planted
	// candidate. Must be at least the network's SelfStakingThreshold or
	// downstream vote-weight calculations behave oddly.
	DelegateSelfStake *big.Int
	// VoterStake is the staked amount for every planted voter bucket.
	VoterStake *big.Int
	// VoterStakedDurationDays is the duration (in days) for voter buckets.
	// A 30-day auto-stake bucket routes into the compound path in the
	// IIP-59 drain.
	VoterStakedDurationDays uint32
	// VoteWeightCalConsts controls per-bucket vote weight — pass the
	// active genesis's copy so weight math matches production.
	VoteWeightCalConsts genesis.VoteWeightCalConsts
	// BlockCommissionBasisPoints is the frozen block-side commission rate
	// planted into each candidate's CandidateRewardSnapshot. Downstream
	// GrantBlockReward reads this to split the base reward at block time.
	// Left at zero, the harness would route the full block reward straight
	// into the voter pool; that's rarely what a bench wants.
	BlockCommissionBasisPoints uint64
	// EpochCommissionBasisPoints is the frozen epoch-side commission rate
	// planted into each candidate's CandidateRewardSnapshot.
	EpochCommissionBasisPoints uint64
}

TestOnlyPerfBenchSpec configures TestOnlySeedPerfBenchState. Reachable only from e2etest's IIP-59 benches, which pass the seeder to a single server via WithGenesisStateSeeder — production must never construct one.

type VoteBucket

type VoteBucket struct {
	Index            uint64
	Candidate        address.Address
	Owner            address.Address
	StakedAmount     *big.Int
	StakedDuration   time.Duration
	CreateTime       time.Time
	StakeStartTime   time.Time
	UnstakeStartTime time.Time
	AutoStake        bool
	ContractAddress  string // Corresponding contract address; Empty if it's native staking
	// only used for contract staking buckets
	StakedDurationBlockNumber uint64
	CreateBlockHeight         uint64
	StakeStartBlockHeight     uint64
	UnstakeStartBlockHeight   uint64
	Timestamped               bool
}

VoteBucket represents a vote

func NewVoteBucket

func NewVoteBucket(cand, owner address.Address, amount *big.Int, duration uint32, ctime time.Time, autoStake bool) *VoteBucket

NewVoteBucket creates a new vote bucket

func (*VoteBucket) Decode added in v2.3.0

Decode decodes VoteBucket from generic value

func (*VoteBucket) Deserialize

func (vb *VoteBucket) Deserialize(buf []byte) error

Deserialize deserializes bytes into bucket

func (*VoteBucket) Encode added in v2.3.0

func (vb *VoteBucket) Encode() (systemcontracts.GenericValue, error)

Encode encodes VoteBucket into generic value

func (*VoteBucket) IsNative

func (vb *VoteBucket) IsNative() bool

IsNative reports whether the bucket is a native staking bucket (as opposed to a contract-staking bucket). LSD / contract-staking buckets are owned by the staking contract rather than the underlying holder, which is why IIP-59 compound routing excludes them.

func (*VoteBucket) IsUnstaked

func (vb *VoteBucket) IsUnstaked() bool

IsUnstaked exposes the internal isUnstaked check to callers outside the staking package. Consumers in the rewarding path (IIP-59 compound routing) need to gate compound-eligibility on the bucket still being active; this is that gate.

func (*VoteBucket) Serialize

func (vb *VoteBucket) Serialize() ([]byte, error)

Serialize serializes bucket into bytes

type VoteReviser

type VoteReviser struct {
	// contains filtered or unexported fields
}

VoteReviser is used to recalculate candidate votes.

func NewVoteReviser

func NewVoteReviser(cfg ReviseConfig) *VoteReviser

NewVoteReviser creates a VoteReviser.

func (*VoteReviser) NeedRevise

func (vr *VoteReviser) NeedRevise(height uint64) bool

NeedRevise returns true if height needs revise

func (*VoteReviser) Revise

func (vr *VoteReviser) Revise(ctx protocol.FeatureCtx, csm CandidateStateManager, height uint64) error

Revise recalculate candidate votes on preset revising height.

Directories

Path Synopsis
Package eracow implements the IIP-59 era copy-on-write layer.
Package eracow implements the IIP-59 era copy-on-write layer.
v1
v2
v3
v4
Package v4 historically hosts versioned bundled-struct getters (candidateByAddressV4, candidatesV4, ...).
Package v4 historically hosts versioned bundled-struct getters (candidateByAddressV4, candidatesV4, ...).
Package freezelog encodes the event emitted when an IIP-59 era freezes a delegate's reward configuration.
Package freezelog encodes the event emitted when an IIP-59 era freezes a delegate's reward configuration.

Jump to

Keyboard shortcuts

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