Skip to main content
Version: Next

Protobuf Documentation

📝 Description

This module implements a Prolog logic interpreter (go-native) and its unification algorithm to evaluate logical expressions against the current state of the blockchain.

This distinctive module allows for the creation of advanced, goal-oriented queries and logical systems that can be applied to a wide range of use cases, while still maintaining the determinism and predictability of blockchain technology. It also features a collection of predefined, blockchain-specific predicates that can be used to access information about the state of the blockchain.

Concepts

Program

A program is a text that is parsed and compiled by the interpreter. A program is composed of a set of predicates, which are defined by the user and can be used to express the desired query logic.

Predicate

A predicate is a statement that describes a relationship between one or more variables or constants. A predicate consists of a name followed by zero or more arguments.

Rule & Fact

A rule is a statement that describes a relationship between one or more variables or constants, similar to a predicate. However, unlike a predicate, a rule also specifies one or more conditions that must be true in order for the relationship described by the rule to hold.

A rule has the following format:

head :- body.

The symbol :- is called the "if-then" operator, and it means that the relationship described in the head of the rule holds only if the conditions in the body are true.

For example:

grandfather(X,Y) :- father(X,Z), father(Z,Y). # X is the grandfather of Y if X is the father of Z and Z is the father of Y.

A fact is a special type of rule that has no body (with no :- and no conditions). A fact has the following format:

head.

For instance:

father(john, mary). # john is the father of mary.

Variable

A variable is a predicate argument that is used as a placeholder for a value. It can represent any type of data, such as numbers, strings, or lists.

Variables are denoted by a name that starts with an uppercase letter, for example X or Foo.

For instance:

father(X, mary). # ask for all X that are the father of mary.

Query

A query is a statement used to retrieve information from the blockchain. It can be sent against a program, but this is optional. The interpreter evaluates the query and returns the result to the caller. Queries can be submitted to a module using the Ask message.

Ask

The Ask message is used to submit a query to the module. It has the following format:

{
string Program
string Query
}

The Program field is optional. If it is not specified, the query is just evaluated against the current state of the blockchain. If it is specified, the query is evaluated against the program that is passed as an argument.

For instance:

{
Program: "father(john, mary)."
Query: "father(X, mary)."
}

Gives:

{
"height": "7235",
"gas_used": "9085",
"answer": {
"has_more": false,
"variables": [
"X"
],
"results": [
{
"substitutions": [
{
"variable": "X",
"expression": "john"
}
]
}
]
}
}

The logic module supports chain-specific predicates that can be used to query the state of the blockchain. For example, the chain_id predicate can be used to retrieve the chain ID of the current blockchain. Several other predicates are available, such as block_height, block_time... Please refer to the go documentation for the full list of available predicates.

For instance:

chain_id(X). # ask for the chain ID.

Response

The response is an object that contains the following fields:

  • height: the height of the block at which the query was evaluated.
  • gas_used: the amount of gas used to evaluate the query.
  • answer: the result of the query. It is an object that contains the following fields:
    • has_more: a boolean that indicates whether there are more results to be retrieved. It's just informative since no more results can be retrieved.
    • variables: an array of strings that contains the names of the variables that were used in the query.
    • results: an array of objects that contains the solutions of the query. Each result is an object that contains the following fields:
      • error: an optional string that contains an error message if the query failed for the current solution.
      • substitutions: an array of objects that contains the substitutions that were made to satisfy the query. A substitution is a set of variable-value pairs that is used to replace variables with constants. A substitution is the result of unification. A substitution is used to replace variables with constants when evaluating a rule.

Performance

The performance of the logic module is closely tied to the complexity of the query and the size of the program. To optimize performance, especially in a constrained environment like the blockchain, it is important to minimize the size of the program. Keep in mind that he module uses backtracking to search for solutions, making it most effective when used for queries that are satisfiable. Indeed, if the query is not satisfiable, the module will attempt to find a solution by backtracking and searching through possible solutions for an extended period before ultimately being canceled.

Gas

The Ask message incurs gas consumption, which is calculated as the sum of the gas used to evaluate each predicate during the query evaluation process. Each predicate has a fixed gas cost that is based on its complexity.

While querying the module does not require any fees, the use of gas serves as a mechanism to limit the size and complexity of the query, ensuring optimal performance and fairness.

Security

The logic module is a deterministic program that is executed in a sandboxed environment and does not have the ability to submit transactions or make changes to the blockchain's state. It is therefore safe to use.

To control the cpu and memory usage of the module, the module is limited by several different mechanisms:

  • max_size: the maximum size of the program that can be evaluated.
  • max_result_count: the maximum number of results that can be returned by a query.

The existing query-gas-limit configuration present in the app.toml can be used to constraint gas usage when not used in the context of a transaction.

Additional limitations are being considered for the future, such as restricting the number of variables that can be utilized within a query, or limiting the depth of the backtracking algorithm.

Table of Contents

Top

logic/v1beta2/params.proto

Filter

Filter defines the parameters for filtering the set of strings which can designate anything. The filter is used to whitelist or blacklist strings.

FieldTypeLabelDescription
whiteliststringrepeatedwhitelist specifies a list of strings that are allowed. If this field is not specified, all strings (in the context of the filter) are allowed.
blackliststringrepeatedblacklist specifies a list of strings that are excluded from the set of allowed strings. If a string is included in both whitelist and blacklist, it will be excluded. This means that blacklisted strings prevails over whitelisted ones. If this field is not specified, no strings are excluded.

GasPolicy

GasPolicy defines the policy for calculating predicate invocation costs and the resulting gas consumption. The gas policy is defined as a list of predicates and their associated unit costs, a default unit cost for predicates if not specified in the list, and a weighting factor that is applied to the unit cost of each predicate to yield.

FieldTypeLabelDescription
weighting_factorstringWeightingFactor is the factor that is applied to the unit cost of each predicate to yield the gas value. If not provided or set to 0, the value is set to 1.
default_predicate_coststringDefaultPredicateCost is the default unit cost of a predicate when not specified in the PredicateCosts list. If not provided or set to 0, the value is set to 1.
predicate_costsPredicateCostrepeatedPredicateCosts is the list of predicates and their associated unit costs.

Interpreter

Interpreter defines the various parameters for the interpreter.

FieldTypeLabelDescription
predicates_filterFilterpredicates_filter specifies the filter for the predicates that are allowed to be used by the interpreter. The filter is used to whitelist or blacklist predicates represented as <predicate_name>/[<arity>], for example: findall/3, or call. If a predicate name without arity is included in the filter, then all predicates with that name will be considered regardless of arity. For example, if call is included in the filter, then all predicates call/1, call/2, call/3... will be allowed.
bootstrapstringbootstrap specifies the initial program to run when booting the logic interpreter. If not specified, the default boot sequence will be executed.
virtual_files_filterFiltervirtual_files_filter specifies the filter for the virtual files that are allowed to be used by the interpreter. The filter is used to whitelist or blacklist virtual files represented as URI, for example: file:///path/to/file, cosmwasm:cw-storage:axone...?query=foo The filter is applied to the components of the URI, for example: file:///path/to/file -> file, /path/to/file cosmwasm:cw-storage:axone...?query=foo -> cosmwasm, cw-storage, axone..., query=foo If a component is included in the filter, then all components with that name will be considered, starting from the beginning of the URI. For example, if file is included in the filter, then all URIs that start with file will be allowed, regardless of the rest of the components. But file2 will not be allowed. If the component is not included in the filter, then the component is ignored and the next component is considered.

Limits

Limits defines the limits of the logic module.

FieldTypeLabelDescription
max_sizestringmax_size specifies the maximum size, in bytes, that is accepted for a program. nil value or 0 value remove size limitation.
max_result_countstringmax_result_count specifies the maximum number of results that can be requested for a query. nil value or 0 value remove max result count limitation.
max_user_output_sizestringmax_user_output_size specifies the maximum number of bytes to keep in the user output. If the user output exceeds this size, the interpreter will overwrite the oldest bytes with the new ones to keep the size constant. nil value or 0 value means that no user output is used at all.
max_variablesstringmax_variables specifies the maximum number of variables that can be create by the interpreter. nil value or 0 value means that no limit is set.

Params

Params defines all the configuration parameters of the "logic" module.

FieldTypeLabelDescription
interpreterInterpreterInterpreter specifies the parameter for the logic interpreter.
limitsLimitsLimits defines the limits of the logic module. The limits are used to prevent the interpreter from running for too long. If the interpreter runs for too long, the execution will be aborted.
gas_policyGasPolicyGasPolicy defines the parameters for calculating predicate invocation costs.

PredicateCost

PredicateCost defines the unit cost of a predicate during its invocation by the interpreter.

FieldTypeLabelDescription
predicatestringPredicate is the name of the predicate, optionally followed by its arity (e.g. "findall/3"). If no arity is specified, the unit cost is applied to all predicates with the same name.
coststringCost is the unit cost of the predicate.

Top

logic/v1beta2/genesis.proto

GenesisState

GenesisState defines the logic module's genesis state.

FieldTypeLabelDescription
paramsParamsThe state parameters for the logic module.

Top

logic/v1beta2/types.proto

Answer

Answer represents the answer to a logic query.

FieldTypeLabelDescription
has_moreboolhas_more specifies if there are more solutions than the ones returned.
variablesstringrepeatedvariables represent all the variables in the query.
resultsResultrepeatedresults represent all the results of the query.

Result

Result represents the result of a query.

FieldTypeLabelDescription
errorstringerror specifies the error message if the query caused an error.
substitutionsSubstitutionrepeatedsubstitutions represent all the substitutions made to the variables in the query to obtain the answer.

Substitution

Substitution represents a substitution made to the variables in the query to obtain the answer.

FieldTypeLabelDescription
variablestringvariable is the name of the variable.
expressionstringexpression is the value substituted for the variable, represented directly as a Prolog term (e.g., atom, number, compound).

Top

logic/v1beta2/query.proto

QueryServiceAskRequest

QueryServiceAskRequest is request type for the QueryService/Ask RPC method.

FieldTypeLabelDescription
programstringprogram is the logic program to be queried.
querystringquery is the query string to be executed.
limitstringlimit specifies the maximum number of solutions to be returned. This field is governed by max_result_count, which defines the upper limit of results that may be requested per query. If this field is not explicitly set, a default value of 1 is applied.

QueryServiceAskResponse

QueryServiceAskResponse is response type for the QueryService/Ask RPC method.

FieldTypeLabelDescription
heightuint64height is the block height at which the query was executed.
gas_useduint64gas_used is the amount of gas used to execute the query.
answerAnsweranswer is the answer to the query.
user_outputstringuser_output is the output of the query execution, if any. the length of the output is limited by the max_query_output_size parameter.

QueryServiceParamsRequest

QueryServiceParamsRequest is request type for the QueryService/Params RPC method.

QueryServiceParamsResponse

QueryServiceParamsResponse is response type for the QueryService/Params RPC method.

FieldTypeLabelDescription
paramsParamsparams holds all the parameters of this module.

QueryService

QueryService defines the gRPC querier service.

Method NameRequest TypeResponse TypeDescriptionHTTP VerbEndpoint
ParamsQueryServiceParamsRequestQueryServiceParamsResponseParams queries all parameters for the logic module.GET/axone-protocol/axoned/logic/params
AskQueryServiceAskRequestQueryServiceAskResponseAsk executes a logic query and returns the solutions found. Since the query is without any side-effect, the query is not executed in the context of a transaction and no fee is charged for this, but the execution is constrained by the current limits configured in the module.GET/axone-protocol/axoned/logic/ask

Top

logic/v1beta2/tx.proto

MsgUpdateParams

MsgUpdateParams defines a Msg for updating the x/logic module parameters.

FieldTypeLabelDescription
authoritystringauthority is the address of the governance account.
paramsParamsparams defines the x/logic parameters to update. NOTE: All parameters must be supplied.

MsgUpdateParamsResponse

MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message.

MsgService

MsgService defines the service for the logic module. Do nothing for now as the service is without any side effects.

Method NameRequest TypeResponse TypeDescriptionHTTP VerbEndpoint
UpdateParamsMsgUpdateParamsMsgUpdateParamsResponseUpdateParams defined a governance operation for updating the x/logic module parameters. The authority is hard-coded to the Cosmos SDK x/gov module account

Scalar Value Types

.proto TypeNotesC++JavaPythonGoC#PHPRuby
doubledoubledoublefloatfloat64doublefloatFloat
floatfloatfloatfloatfloat32floatfloatFloat
int32Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead.int32intintint32intintegerBignum or Fixnum (as required)
int64Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead.int64longint/longint64longinteger/stringBignum
uint32Uses variable-length encoding.uint32intint/longuint32uintintegerBignum or Fixnum (as required)
uint64Uses variable-length encoding.uint64longint/longuint64ulonginteger/stringBignum or Fixnum (as required)
sint32Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s.int32intintint32intintegerBignum or Fixnum (as required)
sint64Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s.int64longint/longint64longinteger/stringBignum
fixed32Always four bytes. More efficient than uint32 if values are often greater than 2^28.uint32intintuint32uintintegerBignum or Fixnum (as required)
fixed64Always eight bytes. More efficient than uint64 if values are often greater than 2^56.uint64longint/longuint64ulonginteger/stringBignum
sfixed32Always four bytes.int32intintint32intintegerBignum or Fixnum (as required)
sfixed64Always eight bytes.int64longint/longint64longinteger/stringBignum
boolboolbooleanbooleanboolboolbooleanTrueClass/FalseClass
stringA string must always contain UTF-8 encoded or 7-bit ASCII text.stringStringstr/unicodestringstringstringString (UTF-8)
bytesMay contain any arbitrary sequence of bytes.stringByteStringstr[]byteByteStringstringString (ASCII-8BIT)