syntax = "proto3";

import "blockchain.proto";

message ExecutedHeader {
    bytes prevhash = 1;
    uint64 timestamp = 2;
    uint64 height = 3;
    bytes state_root = 4;
    bytes transactions_root = 5;
    bytes receipts_root = 6;
    bytes log_bloom = 7;
    uint64 gas_used = 8;
    uint64 gas_limit = 9;
    bytes proposer = 10;
}

enum ReceiptError {
    //ExecutionError
    NotEnoughBaseQuota = 0;
    BlockQuotaLimitReached = 1;
    AccountQuotaLimitReached = 2;
    InvalidTransactionNonce = 3;
    NotEnoughCash = 4;
    NoTransactionPermission = 5;
    NoContractPermission = 6;
    NoCallPermission = 7;
    ExecutionInternal = 8;
    TransactionMalformed = 9;
    //EvmError
    OutOfQuota = 10;
    BadJumpDestination = 11;
    BadInstruction = 12;
    StackUnderflow = 13;
    OutOfStack = 14;
    Internal = 15;
    MutableCallInStaticContext = 16;
    OutOfBounds = 17;
    Reverted = 18;
}

message LogEntry {
    bytes address = 1;
    repeated bytes topics = 2;
    bytes data = 3;
}

message ReceiptErrorWithOption {
    ReceiptError error = 1;
}

message StateRoot {
    bytes state_root = 1;
}

message Receipt {
    StateRoot state_root = 1;
    string gas_used = 2;
    bytes log_bloom = 3;
    repeated LogEntry logs = 4;
    ReceiptErrorWithOption error = 5;
    uint64 account_nonce = 6;
    bytes transaction_hash = 7;
}

message ReceiptWithOption {
    Receipt receipt = 1;
}

message ExecutedInfo {
    ExecutedHeader header = 1;
    repeated ReceiptWithOption receipts = 3;
}

message ConsensusConfig {
    uint64 block_gas_limit = 1;
    AccountGasLimit account_gas_limit = 2;
    repeated bytes nodes = 3;
    uint64 block_interval = 4;
    bool check_quota = 5;
    bytes admin_address = 6;
}

message ExecutedResult {
    ExecutedInfo executed_info = 1;
    ConsensusConfig config = 2;
}

message RegisterRequest {
    string contract_address = 1;
    string ip = 2;
    string port = 3;
}

message RegisterResponse {
    string state = 1;
}

message LoadRequest {
    uint64 height = 1;
    string contract_address = 2;
    string key = 3;
}

message LoadResponse {
    string value = 1;
}

service ExecutorService {
    rpc Register(RegisterRequest) returns (RegisterResponse){}
    rpc Load(LoadRequest) returns (LoadResponse){}
}
