Envío de blobs de datos a Celestia

Para enviar datos a Celestia, los usuarios envían transacciones blob (BlobTx). Las transacciones de Blob contienen dos componentes, una transacción estándar de Cosmos-SDK llamada MsgPayForBlobs y uno o más Blobs de datos.

Mercado de tarifas y mempool

Celestia hace uso de un mempool priorizado a precio de gas estándar. Por defecto, las transacciones con precios de gas más altos que los de otras transacciones en el mempool serán priorizadas por los validadores.

Tarifas y límites de gas

A partir de la versión v1.0.0 de la aplicación (celestia-app), no hay una tarifa mínima impuesta por el protocolo (similar a EIP-1559 en Ethereum). En cambio, cada nodo de consenso que ejecuta un mempool utiliza un umbral de precio de gas configurado localmente que debe cumplirse para que ese nodo acepte una transacción, ya sea directamente de un usuario o chismeado desde otro nodo, en su mempool.

A partir de la versión v1.0.0 de la aplicación (celestia-app), no se reembolsa el gas. En cambio, las tarifas de transacción se deducen por una tarifa plana, originalmente especificada por el usuario en su tx (donde las tarifas = gasLimit * gasPrice). Esto significa que los usuarios deben usar un valor límite de gas preciso si no desean pagar en exceso.

Bajo el capó, las tarifas se manejan actualmente especificando y deduciendo una tarifa plana. Sin embargo, el precio del gas a menudo es especificado por los usuarios en lugar de calcular la tarifa plana del gas utilizado y el precio del gas. Dado que la máquina estatal no reembolsa a los usuarios por gas no utilizado, el precio del gas se calcula dividiendo la tarifa total por el límite de gas.

Estimación de gas PFB

En general, el gas utilizado por una transacción PFB implica un costo fijo estático y un costo dinámico basado en el tamaño de cada gota en la transacción.

NOTA

Para un caso de uso general de una cuenta normal que envía un PFB, los costos estáticos pueden tratarse como tales. Sin embargo, debido a la descripción anterior de cómo funciona el gas en el Cosmos-SDK, este no es siempre el caso. En particular, si una cuenta de adjudicación o el feegrant se utilizan módulos, luego estos costos estáticos cambian.

El costo fijo es una aproximación del gas consumido por operaciones fuera de la función GasToConsume (por ejemplo, verificación de firma, tamaño de tx, acceso de lectura a cuentas), que tiene un valor predeterminado de 65,000 gas.

NOTA

La primera transacción enviada por una cuenta (número de secuencia == 0) tiene un costo adicional de gas único de 10,000 gas. Si este es el caso, esto debe tenerse en cuenta.

Cada gota en el PFB contribuye al costo total del gas en función de su tamaño. La función GasToConsume calcula el gas total consumido por todos los blobs involucrados en un PFB, donde el costo del gas de cada blob se calcula determinando primero cuántas acciones se necesitan para almacenar el tamaño del blob. Luego, calcula el producto del número de acciones, el número de bytes por acción y el gasPerByte parámetro. Finalmente, agrega una cantidad estática por blob.

El blob.GasPerBlobByte y auth.TxSizeCostPerByte son parámetros que potencialmente podrían ajustarse a través de los mecanismos de gobernanza del sistema. Por lo tanto, los costes reales pueden variar dependiendo del estado actual de estos parámetros.

Cálculo de la tarifa de gas

La tarifa total para una transacción se calcula como el producto del límite de gas para la transacción y el precio del gas establecido por el usuario:

Tarifa Total=Límite de Gas×Precio del Gas

El límite de gas para una transacción es la cantidad máxima de gas que un usuario está dispuesto a gastar en una transacción. Está determinado tanto por un costo fijo estático (FC) como por un costo dinámico variable basado en el tamaño de cada blob involucrado en la transacción:

Límite de Gas=FC+∑yo=1nSSN(Byo)×SS×GCPBB

Dónde:

  • FC= Costo fijo, es un valor estático (65,000 gas)

  • ∑yo=1nSSN(Byo)= SparseSharesNeeded para el yoth Blob, es el número de acciones necesarias para el yola burbuja en la transacción

  • SS= Share Size, es el tamaño de cada acción

  • GCPBB= Gas Cost Per Blob Byte, es un parámetro que potencialmente podría ajustarse a través de los mecanismos de gobierno del sistema.

La tarifa de gas es establecida por el usuario cuando envía una transacción. La tarifa a menudo es especificada por los usuarios directamente. El costo total de la transacción se calcula como el producto del límite estimado de gas y el precio del gas. Dado que la máquina estatal no reembolsa a los usuarios por el gas no utilizado, es importante que los usuarios estimen el límite de gas con precisión para evitar pagar de más.

Para obtener más detalles sobre cómo se calcula el gas por gota, consulte el PayForBlobs función eso consume gas en función de los tamaños de las gotas. Esta función utiliza el GasToConsume función para calcular el gas adicional cobrado para pagar un conjunto de blobs en un MsgPayForBlobs transacción. Esta función calcula las acciones totales utilizadas por todos los blobs y lo multiplica por el ShareSize y gasPerByte para conseguir que el gas total consuma.

Para estimar el gas total requerido para un conjunto de blobs, consulte el EstimateGas función. Esta función estima el gas basado en un modelo lineal que depende de los parámetros de gobernanza: gasPerByte y txSizeCost. Asume que otras variables son constantes, incluida la suposición de que el MsgPayForBlobs es el único mensaje en la transacción. El DefaultEstimateGas la función corre EstimateGas con los valores predeterminados del sistema.

Estimación de gas programáticamente

Los usuarios pueden estimar un límite de gas eficiente utilizando esta función:

ir

import (
    blobtypes "github.com/celestiaorg/celestia-app/x/blob/types"
)
gasLimit := blobtypes.DefaultEstimateGas([]uint32{uint32(sizeOfDataInBytes)})

Si usa un cliente de luz de nodo celestia, esta función se le solicita automáticamente al enviar una gota. Esta función funciona descomponiendo los componentes del cálculo del gas para una transacción de blob. Estos componentes consisten en costos planos para todos los PFB, el tamaño de cada gota y cuántas acciones utiliza cada uno y el parámetro para el gas utilizado por byte. Se puede encontrar más información sobre cómo se usa el gas en el especificaciones de gas y la fórmula exacta se puede encontrar en el módulo blob.

Enviar múltiples transacciones en un bloque desde la misma cuenta

El mempool Celestia utiliza obras manteniendo una bifurcación del estado canónico en cada bloque. Esto significa que cada vez que le enviemos una transacción, actualizará el número de secuencia (también conocido como nonce) para la cuenta que envió la transacción. Si los usuarios desean enviar una segunda transacción, pueden, pero deben especificar el nonce manualmente. Si esto no se hace, las nuevas transacciones no se podrán enviar hasta que la primera transacción se obtenga del mempool (es decir, se incluya en un bloque), y, o se cayó debido al tiempo de espera.

De forma predeterminada, los nodos soltarán una transacción si no se incluye en 5 bloques (aproximadamente 1 minuto). En este punto, el usuario debe volver a enviar su transacción si desea que finalmente se incluya.

A partir de v1.0.0 de la aplicación (celestia-app), los usuarios no pueden reemplazar una transacción existente por otra diferente con tarifas más altas. En su lugar, deben esperar 5 bloques desde el tiempo original enviado y luego volver a enviar la transacción. Una vez más, los miembros de la comunidad ya han sugerido soluciones y la voluntad de aceptar cambios para solucionar este problema.

API

Los usuarios pueden crear y enviar actualmente BlobTxs de cuatro maneras.

El nodo de consenso de celestia-app CLI

bash

celestia-appd tx blob PayForBlobs <hex-encoded namespace> <hex-encoded data> [flags]

El nodo de luz de nodo celestia CLI

Usando blob.Submit:

bash

celestia blob submit <hex-encoded namespace> <hex-encoded data>

Aprende más en el tutorial de nodo.

GRPC a un nodo de consenso a través del user paquete

ir

import (
    "context"
    "fmt"

    "github.com/celestiaorg/celestia-app/app"
    "github.com/celestiaorg/celestia-app/app/encoding"
    "github.com/celestiaorg/celestia-app/pkg/appconsts"
    "github.com/celestiaorg/celestia-app/pkg/namespace"
    "github.com/celestiaorg/celestia-app/pkg/user"
    blobtypes "github.com/celestiaorg/celestia-app/x/blob/types"
    "github.com/cosmos/cosmos-sdk/crypto/keyring"
    tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
)

// SubmitData is a demo function that shows how to use the signer to submit data
// to the blockchain directly via a celestia node. We can manage this keyring
// using the `celestia-appd keys` or `celestia keys` sub commands and load this
// keyring from a file and use it to programmatically sign transactions.
func DemoSubmitData(grpcAddr string, kr keyring.Keyring) error {
    // create an encoding config that can decode and encode all celestia-app
    // data structures.
    ecfg := encoding.MakeConfig(app.ModuleEncodingRegisters...)

    // create a connection to the grpc server on the consensus node.
    conn, err := grpc.Dial(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        return err
    }
    defer conn.Close()

    // get the address of the account we want to use to sign transactions.
    rec, err := kr.Key("accountName")
    if err != nil {
        return err
    }

    addr, err := rec.GetAddress()
    if err != nil {
        return err
    }

    // Setup the signer. This function will automatically query the relevant
    // account information such as sequence (nonce) and account number.
    signer, err := user.SetupSigner(context.TODO(), kr, conn, addr, ecfg)
    if err != nil {
        return err
    }

    ns := namespace.MustNewV0([]byte("1234567890"))

    fmt.Println("namepace", len(ns.Bytes()))

    blob, err := blobtypes.NewBlob(ns, []byte("some data"), appconsts.ShareVersionZero)
    if err != nil {
        return err
    }

    gasLimit := blobtypes.DefaultEstimateGas([]uint32{uint32(len(blob.Data))})

    options := []user.TxOption{
        // here we're setting estimating the gas limit from the above estimated
        // function, and then setting the gas price to 0.1utia per unit of gas.
        user.SetGasLimitAndFee(gasLimit, 0.1),
    }

    // this function will submit the transaction and block until a timeout is
    // reached or the transaction is committed.
    resp, err := signer.SubmitPayForBlob(context.TODO(), []*tmproto.Blob{blob}, options...)
    if err != nil {
        return err
    }

    // check the response code to see if the transaction was successful.
    if resp.Code != 0 {
        // handle code
        fmt.Println(resp.Code, resp.Codespace, resp.RawLog)
    }

    // if we don't want to wait for the transaction to be confirmed, we can
    // manually sign and submit the transaction using the same package.
    blobTx, err := signer.CreatePayForBlob([]*tmproto.Blob{blob}, options...)
    if err != nil {
        return err
    }

    resp, err = signer.BroadcastTx(context.TODO(), blobTx)
    if err != nil {
        return err
    }

    // check the response code to see if the transaction was successful. Note
    // that this time we're not waiting for the transaction to be committed.
    // Therefore the code here is only from the consensus node's mempool.
    if resp.Code != 0 {
        // handle code
        fmt.Println(resp.Code, resp.Codespace, resp.RawLog)
    }

    return err
}

RPC a un nodo celestia

Usando la API de JSON RPC, envíe datos utilizando los siguientes métodos:

Aprende más en el documentos API de Celestia-Node.

Last updated