syntax = "proto3";

import "proto/loom.proto";

message ValidatorV3 {
    bytes pub_key = 1;
    int64 power = 2 [jstype = JS_STRING];
}

enum LocktimeTier {
    TIER_ZERO = 0;
    TIER_ONE = 1;
    TIER_TWO = 2;
    TIER_THREE = 3;
}

enum DelegationState {
    BONDING = 0;
    BONDED = 1;
    UNBONDING = 2;
    REDELEGATING = 3;
}

enum CandidateState {
    REGISTERED = 0;
    UNREGISTERING = 1;
    ABOUT_TO_CHANGE_FEE = 2;
    CHANGING_FEE = 3;
}

message Params {
    uint64 validator_count = 1;
    int64 election_cycle_length = 2;
    Address coin_contract_address = 3;
    Address oracle_address = 4;
    BigUInt max_yearly_reward = 5;
    BigUInt registration_requirement = 6;
    BigUInt crash_slashing_percentage = 7;
    BigUInt byzantine_slashing_percentage = 8;
    uint64 min_candidate_fee = 9;
    uint64 downtime_period = 10;
}

message State {
    Params params = 1;
    repeated ValidatorV3 validators = 2;
    int64 last_election_time = 3;
    BigUInt total_validator_delegations = 4;
    BigUInt total_reward_distribution = 5;
}

message InitializationState {
    State state = 1;
    repeated CandidateV3 candidates = 2;
    repeated Delegation delegations = 3;
    repeated ValidatorStatistic statistics = 4;
}

message ValidatorStatistic {
    Address address = 1;
    BigUInt whitelist_amount = 2;
    LocktimeTier locktime_tier = 3;
    BigUInt delegation_total = 4;
    BigUInt slash_percentage = 5;
    uint64 recently_missed_blocks = 6;
    BigUInt update_whitelist_amount = 7;
    LocktimeTier update_locktime_tier = 8;
    bool jailed = 9;
}

message CandidateV3 {
    Address address = 1;
    bytes pub_key = 2;
    uint64 fee = 3;
    uint64 new_fee = 4;
    CandidateState state = 5;
    string name = 6;
    string description = 7;
    string website = 8;
    uint64 max_referral_percentage = 9;
}

message CandidateStatistic {
    ValidatorStatistic statistic = 1;
    CandidateV3          candidate = 2;
}

message CandidateListV3 {
    repeated CandidateV3 candidates = 1;
}

message Delegation {
    Address delegator = 1;

    Address validator = 2;
    Address update_validator = 3;

    uint64 index = 4;

    BigUInt amount = 6;
    BigUInt update_amount = 7;

    LocktimeTier locktime_tier = 8;
    LocktimeTier update_locktime_tier = 9;

    uint64 lock_time = 10;
    DelegationState state = 11;
    string referrer = 12;
}

message DelegationIndex {
    Address validator = 1;
    Address delegator = 2;
    uint64 index = 3;
}

message DelegationList {
    repeated DelegationIndex delegations = 1;
}

message DPOSInitRequest {
    Params params = 1;
    repeated ValidatorV3 validators = 2;
}

message DelegateRequest {
    Address validator_address = 1;
    BigUInt amount = 2;
    uint64 locktime_tier = 3;
    string referrer = 4; // wallet that sent the delegation
}

message RedelegateRequest {
    Address validator_address = 1;
    Address former_validator_address = 2;
    uint64 index = 3;
    BigUInt amount = 4;
    uint64 new_locktime_tier = 5;
    string referrer = 6; // wallet that sent the delegation
}

message ConsolidateDelegationsRequest {
    Address validator_address = 1;
}

message UnbondRequest {
    Address validator_address = 1;
    BigUInt amount = 2;
    uint64 index = 3;
}

message WhitelistCandidateRequest {
    Address candidate_address = 1;
    BigUInt amount = 2;
    LocktimeTier lock_time_tier = 3;
}

message RemoveWhitelistedCandidateRequest {
    Address candidate_address = 1;
}

message ChangeWhitelistInfoRequest {
    Address candidate_address = 1;
    BigUInt amount = 2;
    LocktimeTier lock_time_tier = 3;
}

message CheckDelegationRequest {
    Address validator_address = 1;
    Address delegator_address = 2;
}

message CheckDelegationResponse {
    BigUInt amount = 1;
    BigUInt weighted_amount = 2;
    repeated Delegation delegations = 3;
}

message CheckRewardsRequest {
}

message CheckRewardsResponse {
    BigUInt total_reward_distribution = 1;
}

message TotalDelegationRequestV3 {
    Address delegator_address = 1;
}

message TotalDelegationResponseV3 {
    BigUInt amount = 1;
    BigUInt weighted_amount = 2;
}

message CheckAllDelegationsRequestV3 {
    Address delegator_address = 1;
}

message CheckAllDelegationsResponseV3 {
    BigUInt amount = 1;
    BigUInt weighted_amount = 2;
    repeated Delegation delegations = 3;
}

message CheckRewardDelegationRequest {
    Address validator_address = 1;
}

message CheckRewardDelegationResponse {
    Delegation delegation = 1;
}

message DowntimeRecordRequest {
    Address validator = 1;
}

message DowntimeRecordResponse {
    repeated DowntimeRecord downtime_records = 1;
    uint64 period_length = 2;
}

message DowntimeRecord {
    Address validator = 1;
    repeated uint64 periods = 2;
}

message RegisterCandidateRequestV3 {
    bytes pub_key = 1;
    uint64 fee = 2;
    string name = 3;
    string description = 4;
    string website = 5;
    uint64 locktime_tier = 6;
    uint64 max_referral_percentage = 7;
}

message UpdateCandidateInfoRequestV3 {
    string name = 1;
    string description = 2;
    string website = 3;
    uint64 max_referral_percentage = 4;
}

message ChangeCandidateFeeRequestV3 {
    uint64 fee = 1;
}

message SetMinCandidateFeeRequest {
    uint64 min_candidate_fee = 1;
}

message UpdateCandidateInfoRequest {
    string name = 1;
    string description = 2;
    string website = 3;
    uint64 max_referral_percentage = 4;
}

message UnjailRequest {
    Address validator = 1;
}

message UnregisterCandidateRequestV3 {
}

message TimeUntilElectionRequestV3 {
}

message TimeUntilElectionResponseV3 {
    int64 time_until_election = 1;
}

message ListValidatorsRequest {
}

message ListValidatorsResponse {
    repeated ValidatorStatistic statistics = 1;
}

message ListCandidatesRequest {
}

message ListCandidatesResponse {
    repeated CandidateStatistic candidates = 1;
}

message ListDelegationsRequestV3 {
    Address candidate = 1;
}

message ListDelegationsResponseV3 {
    repeated Delegation delegations = 1;
    BigUInt delegation_total = 2;
}

message ListAllDelegationsRequestV3 {
}

message ListAllDelegationsResponseV3 {
    repeated ListDelegationsResponseV3 list_responses = 1;
}

// Oracle request batch
message BatchRequest {
    oneof payload {
        WhitelistCandidateRequest whitelist_candidate = 1;
    }
    BatchRequestMeta meta = 2;
}

message BatchRequestMeta {
    uint64 block_number = 1;
    uint64 tx_index = 2;
    uint64 log_index = 3;
}

message RequestBatchTally {
    uint64 last_seen_block_number = 1;
    uint64 last_seen_tx_index = 2;
    uint64 last_seen_log_index = 3;
}

message RequestBatch {
    repeated BatchRequest batch = 1;
}

message GetRequestBatchTallyRequest {
}

message RegisterReferrerRequest {
    string name = 1;
    Address address = 2;
}

message SetElectionCycleRequest {
    int64 election_cycle = 1;
}

message SetDowntimePeriodRequest {
    uint64 downtime_period = 1;
}

message SetMaxYearlyRewardRequest {
    BigUInt max_yearly_reward = 1;
}

message SetRegistrationRequirementRequest {
    BigUInt registration_requirement = 1;
}

message SetValidatorCountRequest {
    int64 validator_count = 1;
}

message SetOracleAddressRequest {
    Address oracle_address = 1;
}

message SetSlashingPercentagesRequest {
    BigUInt crash_slashing_percentage = 1;
    BigUInt byzantine_slashing_percentage = 2;
}

message GetStateRequest {
}

message GetStateResponse {
    State state = 1;
}

message ClaimDelegatorRewardsRequest {
}

message ClaimDelegatorRewardsResponse {
    BigUInt amount = 1;
}

message CheckDelegatorRewardsRequest {
    Address delegator = 1;
}

message CheckDelegatorRewardsResponse {
    BigUInt amount = 1;
}

// EVENTS

message DposElectionEvent {
    uint64 block_number = 1;
}

message DposSlashEvent {
    Address validator = 1;
    BigUInt slash_percentage = 2;
}

message DposUnjailEvent {
    Address validator = 1;
}

message DposCandidateRegistersEvent {
    Address address = 1;
    uint64 fee = 2;
}

message DposCandidateUnregistersEvent {
    Address address = 1;
}

message DposCandidateFeeChangeEvent {
    Address address = 1;
    uint64 new_fee = 2;
}

message DposUpdateCandidateInfoEvent {
    Address address = 1;
}

message DposDelegatorDelegatesEvent {
    Delegation delegation = 1;
}

message DposDelegatorRedelegatesEvent {
    Delegation delegation = 1;
}

message DposDelegatorConsolidatesEvent {
    Delegation new_delegation = 1;
    repeated Delegation consolidated_delegations = 2;
    int64 unconsolidated_delegations_count = 3;
}

message DposDelegatorUnbondsEvent {
    Delegation delegation = 1;
}

message DposReferrerRegistersEvent {
    string name = 1;
    Address address = 2;
}

message DposDelegatorClaimsRewardsEvent {
    Address delegator = 1;
    repeated Address validators = 2;
    repeated BigUInt amounts = 3;
    BigUInt total_rewards_claimed = 4;
}
