From 4b859fe625185a2df1ff5280680c8339d8e4e6ec Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 24 Jul 2024 15:31:45 +0800 Subject: [PATCH 01/10] Add nubit DA backend --- cmd/run_xlayer.go | 26 ++++ config/config.go | 3 + config/default.go | 9 ++ dataavailability/config.go | 2 + dataavailability/nubit/backend.go | 176 +++++++++++++++++++++++++ dataavailability/nubit/backend_test.go | 30 +++++ dataavailability/nubit/chain.go | 41 ++++++ dataavailability/nubit/config.go | 14 ++ dataavailability/nubit/nubit_test.go | 37 ++++++ dataavailability/nubit/types.go | 42 ++++++ go.mod | 13 +- go.sum | 17 ++- 12 files changed, 405 insertions(+), 5 deletions(-) create mode 100644 dataavailability/nubit/backend.go create mode 100644 dataavailability/nubit/backend_test.go create mode 100644 dataavailability/nubit/chain.go create mode 100644 dataavailability/nubit/config.go create mode 100644 dataavailability/nubit/nubit_test.go create mode 100644 dataavailability/nubit/types.go diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index 0df21fe55c..9e2629fb32 100644 --- a/cmd/run_xlayer.go +++ b/cmd/run_xlayer.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/config/apollo" "github.com/0xPolygonHermez/zkevm-node/dataavailability" "github.com/0xPolygonHermez/zkevm-node/dataavailability/datacommittee" + "github.com/0xPolygonHermez/zkevm-node/dataavailability/nubit" "github.com/0xPolygonHermez/zkevm-node/etherman" "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" "github.com/0xPolygonHermez/zkevm-node/event" @@ -123,6 +124,31 @@ func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Cl if err != nil { return nil, err } + case string(dataavailability.DataAvailabilityNubitDA): + var ( + pk *ecdsa.PrivateKey + err error + ) + if isSequenceSender { + _, pk, err = etherman.LoadAuthFromKeyStoreXLayer(c.SequenceSender.DAPermitApiPrivateKey.Path, c.SequenceSender.DAPermitApiPrivateKey.Password) + if err != nil { + return nil, err + } + log.Infof("from pk %s", crypto.PubkeyToAddress(pk.PublicKey)) + } + dacAddr, err := etherman.GetDAProtocolAddr() + if err != nil { + return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err) + } + daBackend, err = nubit.NewNubitDABackend( + c.Etherman.URL, + dacAddr, + pk, + &c.DataAvailability, + ) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unexpected / unsupported DA protocol: %s", daProtocolName) } diff --git a/config/config.go b/config/config.go index 4e7fb07b20..39cbb7523b 100644 --- a/config/config.go +++ b/config/config.go @@ -7,6 +7,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/aggregator" "github.com/0xPolygonHermez/zkevm-node/config/types" + "github.com/0xPolygonHermez/zkevm-node/dataavailability/nubit" "github.com/0xPolygonHermez/zkevm-node/db" "github.com/0xPolygonHermez/zkevm-node/etherman" "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" @@ -102,6 +103,8 @@ type Config struct { SequenceSender sequencesender.Config // Configuration of the aggregator service Aggregator aggregator.Config + // Configuration of the NubitDA data availability service + DataAvailability nubit.Config // Configuration of the genesis of the network. This is used to known the initial state of the network NetworkConfig NetworkConfig // Configuration of the gas price suggester service diff --git a/config/default.go b/config/default.go index d599016f28..8297e2df12 100644 --- a/config/default.go +++ b/config/default.go @@ -243,6 +243,15 @@ AggLayerTxTimeout = "5m" AggLayerURL = "" SequencerPrivateKey = {} +[DataAvailability] +NubitRpcURL = "" +NubitModularAppName = "" +NubitAuthKey = "" +NubitNamespace = "xlayer" +NubitMaxBatchesSize = "102400" +NubitGetProofMaxRetry = "10" +NubitGetProofWaitPeriod = "5s" + [L2GasPriceSuggester] Type = "follower" UpdatePeriod = "10s" diff --git a/dataavailability/config.go b/dataavailability/config.go index 8163e7bcf4..b0f6a0c85f 100644 --- a/dataavailability/config.go +++ b/dataavailability/config.go @@ -6,4 +6,6 @@ type DABackendType string const ( // DataAvailabilityCommittee is the DAC protocol backend DataAvailabilityCommittee DABackendType = "DataAvailabilityCommittee" + // DataAvailabilityNubitDA is the NubitDA protocol backend + DataAvailabilityNubitDA DABackendType = "NubitDA" ) diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go new file mode 100644 index 0000000000..b5db4cad55 --- /dev/null +++ b/dataavailability/nubit/backend.go @@ -0,0 +1,176 @@ +package nubit + +import ( + "context" + "crypto/ecdsa" + "encoding/hex" + "time" + + daTypes "github.com/0xPolygon/cdk-data-availability/types" + polygondatacommittee "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee_xlayer" + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/rollkit/go-da" + "github.com/rollkit/go-da/proxy" +) + +// NubitDABackend implements the DA integration with Nubit DA layer +type NubitDABackend struct { + dataCommitteeContract *polygondatacommittee.PolygondatacommitteeXlayer + client da.DA + config *Config + ns da.Namespace + privKey *ecdsa.PrivateKey + commitTime time.Time + batchesDataCache [][]byte + batchesDataSize uint64 +} + +// NewNubitDABackend is the factory method to create a new instance of NubitDABackend +func NewNubitDABackend( + l1RPCURL string, + dataCommitteeAddr common.Address, + privKey *ecdsa.PrivateKey, + cfg *Config, +) (*NubitDABackend, error) { + ethClient, err := ethclient.Dial(l1RPCURL) + if err != nil { + log.Errorf("error connecting to %s: %+v", l1RPCURL, err) + return nil, err + } + + log.Infof("NubitDABackend config: %#v ", cfg) + cn, err := proxy.NewClient(cfg.NubitRpcURL, cfg.NubitAuthKey) + if err != nil { + return nil, err + } + // TODO: Check if name byte array requires zero padding + name, err := hex.DecodeString(cfg.NubitNamespace) + if err != nil { + log.Errorf("error decoding NubitDA namespace config: %+v", err) + return nil, err + } + dataCommittee, err := polygondatacommittee.NewPolygondatacommitteeXlayer(dataCommitteeAddr, ethClient) + if err != nil { + return nil, err + } + log.Infof("NubitDABackend namespace: %s ", string(name)) + + return &NubitDABackend{ + dataCommitteeContract: dataCommittee, + config: cfg, + privKey: privKey, + ns: name, + client: cn, + commitTime: time.Now(), + batchesDataCache: [][]byte{}, + batchesDataSize: 0, + }, nil +} + +// Init initializes the NubitDA backend +func (backend *NubitDABackend) Init() error { + return nil +} + +// PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage +// as expected by the contract +func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error) { + encodedData, err := MarshalBatchData(batchesData) + if err != nil { + log.Errorf("Marshal batch data failed: %s", err) + return nil, err + } + + // Add to batches data cache + backend.batchesDataCache = append(backend.batchesDataCache, encodedData) + backend.batchesDataSize += uint64(len(encodedData)) + if backend.batchesDataSize < backend.config.NubitMaxBatchesSize { + log.Infof("Added batches data to NubitDABackend cache, current length: %+v", len(encodedData)) + return nil, nil + } + if time.Since(backend.commitTime) < 12*time.Second { + time.Sleep(time.Since(backend.commitTime)) + } + + data, err := MarshalBatchData(backend.batchesDataCache) + if err != nil { + log.Errorf("Marshal batch data failed: %s", err) + return nil, err + } + id, err := backend.client.Submit(ctx, [][]byte{data}, -1, backend.ns) + if err != nil { + log.Errorf("Submit batch data with NubitDA client failed: %s", err) + return nil, err + } + log.Infof("Data submitted to Nubit DA: %d bytes against namespace %v sent with id %#x", len(backend.batchesDataCache), backend.ns, id) + + // Reset batches data cache and DA commit time + backend.commitTime = time.Now() + backend.batchesDataCache = [][]byte{} + backend.batchesDataSize = 0 + + // Get proof + tries := uint64(0) + posted := false + for tries < backend.config.NubitGetProofMaxRetry { + dataProof, err := backend.client.GetProofs(ctx, id, backend.ns) + if err != nil { + log.Infof("Proof not available: %s", err) + } + if len(dataProof) > 0 { + log.Infof("Data proof from Nubit DA received: %+v", dataProof) + posted = true + break + } + + tries += 1 + time.Sleep(backend.config.NubitGetProofWaitPeriod) + } + if !posted { + log.Errorf("Get blob proof on Nubit DA failed: %s", err) + return nil, err + } + + // // TODO: use bridge API data + // batchDAData := BatchDAData{ID: id} + // log.Infof("Nubit DA data ID: %+v", batchDAData) + // returnData, err := batchDAData.Encode() + // if err != nil { + // return nil, fmt.Errorf("Encode batch data failed: %w", err) + // } + + // Sign sequence + sequence := daTypes.Sequence{} + for _, seq := range batchesData { + sequence = append(sequence, seq) + } + signedSequence, err := sequence.Sign(backend.privKey) + if err != nil { + log.Errorf("Failed to sign sequence with pk: %v", err) + return nil, err + } + signature := append(sequence.HashToSign(), signedSequence.Signature...) + + return signature, nil +} + +// GetSequence gets the sequence data from NubitDA layer +func (backend *NubitDABackend) GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) { + batchDAData := BatchDAData{} + err := batchDAData.Decode(dataAvailabilityMessage) + if err != nil { + log.Errorf("🏆 NubitDABackend.GetSequence.Decode:%s", err) + return nil, err + } + log.Infof("🏆 Nubit GetSequence batchDAData:%+v", batchDAData) + blob, err := backend.client.Get(ctx, batchDAData.ID, backend.ns) + if err != nil { + log.Errorf("🏆 NubitDABackend.GetSequence.Blob.Get:%s", err) + return nil, err + } + log.Infof("🏆 Nubit GetSequence blob.data:%+v", len(blob)) + + return blob, nil +} diff --git a/dataavailability/nubit/backend_test.go b/dataavailability/nubit/backend_test.go new file mode 100644 index 0000000000..53d7833200 --- /dev/null +++ b/dataavailability/nubit/backend_test.go @@ -0,0 +1,30 @@ +package nubit + +import ( + "crypto/ecdsa" + "encoding/hex" + "time" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/rollkit/go-da/proxy" +) + +func NewNubitDABackendTest(url string, authKey string, pk *ecdsa.PrivateKey) (*NubitDABackend, error) { + cn, err := proxy.NewClient(url, authKey) + if err != nil || cn == nil { + return nil, err + } + + name, err := hex.DecodeString("00000000000000000000000000000000000000000000706f6c79676f6e") + if err != nil { + return nil, err + } + + log.Infof("Nubit Namespace: %s ", string(name)) + return &NubitDABackend{ + ns: name, + client: cn, + privKey: pk, + commitTime: time.Now(), + }, nil +} diff --git a/dataavailability/nubit/chain.go b/dataavailability/nubit/chain.go new file mode 100644 index 0000000000..2bf1775c95 --- /dev/null +++ b/dataavailability/nubit/chain.go @@ -0,0 +1,41 @@ +package nubit + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// MarshalBatchData packs the batch data into ABI-encoded byte array +func MarshalBatchData(batchData [][]byte) ([]byte, error) { + byteArrayType, _ := abi.NewType("bytes[]", "", nil) + args := abi.Arguments{ + {Type: byteArrayType, Name: "batchData"}, + } + res, err := args.Pack(&batchData) + if err != nil { + return make([]byte, 0), fmt.Errorf("cannot pack batchData:%w", err) + } + return res, nil +} + +// UnmarshalBatchData unpacks the ABI-encoded byte array into batch data +func UnmarshalBatchData(encodedData []byte) ([][]byte, error) { + byteArrayType, _ := abi.NewType("bytes[]", "", nil) + args := abi.Arguments{ + {Type: byteArrayType, Name: "batchData"}, + } + res, err := args.Unpack(encodedData) + if err != nil { + return nil, fmt.Errorf("cannot unpack batchData: %w", err) + } + batchData := make([][]byte, len(res)) + for i, v := range res { + byteSlice, ok := v.([]byte) + if !ok { + return nil, fmt.Errorf("element at index %d is not a []byte", i) + } + batchData[i] = byteSlice + } + return batchData, nil +} diff --git a/dataavailability/nubit/config.go b/dataavailability/nubit/config.go new file mode 100644 index 0000000000..da5d2811a5 --- /dev/null +++ b/dataavailability/nubit/config.go @@ -0,0 +1,14 @@ +package nubit + +import "time" + +// Config is the NubitDA backend configurations +type Config struct { + NubitRpcURL string `mapstructure:"NubitRpcURL"` + NubitModularAppName string `mapstructure:"NubitModularAppName"` + NubitAuthKey string `mapstructure:"NubitAuthKey"` + NubitNamespace string `mapstructure:"NubitNamespace"` + NubitMaxBatchesSize uint64 `mapstructure:"NubitMaxBatchesSize"` + NubitGetProofMaxRetry uint64 `mapstructure:"NubitGetProofMaxRetry"` + NubitGetProofWaitPeriod time.Duration `mapstructure:"NubitGetProofWaitPeriod"` +} diff --git a/dataavailability/nubit/nubit_test.go b/dataavailability/nubit/nubit_test.go new file mode 100644 index 0000000000..826c0613e2 --- /dev/null +++ b/dataavailability/nubit/nubit_test.go @@ -0,0 +1,37 @@ +package nubit + +import ( + "context" + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestStoreDetailsOnChain(t *testing.T) { + pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + t.Fatal(err) + } + nubit, err := NewNubitDABackendTest("http://127.0.0.1:26658", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJwdWJsaWMiLCJyZWFkIiwid3JpdGUiLCJhZG1pbiJdfQ.DAMv0s7915Ahx-kDFSzDT1ATz4Q9WwktWcHmjp7_99Q", pk) + if err != nil { + t.Fatal(err) + } + var returnData []byte + for i := 0; i < 10; i++ { + txs := []byte("test txs") + r, err := nubit.PostSequence(context.TODO(), [][]byte{txs}) + require.NoError(t, err) + if r != nil { + returnData = r + } + time.Sleep(600 * time.Millisecond) + } + + _, err = nubit.GetSequence(context.TODO(), []common.Hash{}, returnData) + require.NoError(t, err) +} diff --git a/dataavailability/nubit/types.go b/dataavailability/nubit/types.go new file mode 100644 index 0000000000..b6f5f7f8e0 --- /dev/null +++ b/dataavailability/nubit/types.go @@ -0,0 +1,42 @@ +package nubit + +import ( + "encoding/json" + "reflect" + + "github.com/ethereum/go-ethereum/common" + "github.com/rollkit/go-da" +) + +// BatchDAData contains the batch information on NubitDA +type BatchDAData struct { + ID []da.ID `json:"id,omitempty"` +} + +// Encode encodes the BatchDAData into ABI-encoded bytes +func (b *BatchDAData) Encode() ([]byte, error) { + return json.Marshal(b) +} + +// Decode decodes the ABI-encoded bytes into BatchDAData +func (b *BatchDAData) Decode(data []byte) error { + return json.Unmarshal(data, &b) +} + +// IsEmpty checks i fthe BatchDAData is empty +func (b *BatchDAData) IsEmpty() bool { + return reflect.DeepEqual(b, BatchDAData{}) +} + +// DataCommitteeMember represents a member of the Data Committee +type DataCommitteeMember struct { + Addr common.Address + URL string +} + +// DataCommittee represents a specific committee +type DataCommittee struct { + AddressesHash common.Hash + Members []DataCommitteeMember + RequiredSignatures uint64 +} diff --git a/go.mod b/go.mod index 27fd9fa514..078ad5d560 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/0xPolygonHermez/zkevm-node -go 1.21 +go 1.21.1 + +toolchain go1.22.2 require ( github.com/0xPolygonHermez/zkevm-data-streamer v0.2.3-RC4 @@ -23,7 +25,7 @@ require ( github.com/rubenv/sql-migrate v1.6.1 github.com/spf13/afero v1.11.0 github.com/spf13/viper v1.18.2 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/umbracle/ethgo v0.1.4-0.20230712173909-df37dddf16f0 github.com/urfave/cli/v2 v2.26.0 go.uber.org/zap v1.26.0 @@ -68,6 +70,7 @@ require ( github.com/dlclark/regexp2 v1.7.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/filecoin-project/go-jsonrpc v0.3.1 // indirect github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect @@ -94,6 +97,7 @@ require ( github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/huin/goupnp v1.3.0 // indirect + github.com/ipfs/go-log/v2 v2.0.8 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -147,7 +151,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect @@ -158,12 +162,14 @@ require ( github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sys v0.16.0 // indirect golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.17.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect @@ -184,6 +190,7 @@ require ( github.com/fatih/color v1.16.0 github.com/nacos-group/nacos-sdk-go v1.1.4 github.com/prometheus/client_golang v1.18.0 + github.com/rollkit/go-da v0.5.0 github.com/segmentio/kafka-go v0.4.47 golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3 golang.org/x/time v0.5.0 diff --git a/go.sum b/go.sum index 77a22ca737..c0adc57ceb 100644 --- a/go.sum +++ b/go.sum @@ -217,6 +217,8 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/filecoin-project/go-jsonrpc v0.3.1 h1:qwvAUc5VwAkooquKJmfz9R2+F8znhiqcNHYjEp/NM10= +github.com/filecoin-project/go-jsonrpc v0.3.1/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -435,6 +437,8 @@ github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/C github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI= github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/ipfs/go-log/v2 v2.0.8 h1:3b3YNopMHlj4AvyhWAx0pDxqSQWYi4/WuWO7yRV6/Qg= +github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= @@ -701,6 +705,8 @@ github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4 github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rollkit/go-da v0.5.0 h1:sQpZricNS+2TLx3HMjNWhtRfqtvVC/U4pWHpfUz3eN4= +github.com/rollkit/go-da v0.5.0/go.mod h1:VsUeAoPvKl4Y8wWguu/VibscYiFFePkkrvZWyTjZHww= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -775,8 +781,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -787,8 +794,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= @@ -870,6 +878,8 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -887,6 +897,7 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= @@ -1226,6 +1237,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= From 6c66a7f14fc3598c842099607156287bd109b936 Mon Sep 17 00:00:00 2001 From: marvin Date: Wed, 24 Jul 2024 23:12:32 +0800 Subject: [PATCH 02/10] update nubit backend --- dataavailability/nubit/backend.go | 50 +++++-------------------------- 1 file changed, 8 insertions(+), 42 deletions(-) diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index b5db4cad55..10905a782c 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -4,9 +4,9 @@ import ( "context" "crypto/ecdsa" "encoding/hex" + "strings" "time" - daTypes "github.com/0xPolygon/cdk-data-availability/types" polygondatacommittee "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee_xlayer" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/ethereum/go-ethereum/common" @@ -46,7 +46,8 @@ func NewNubitDABackend( return nil, err } // TODO: Check if name byte array requires zero padding - name, err := hex.DecodeString(cfg.NubitNamespace) + hexStr := hex.EncodeToString([]byte(cfg.NubitModularAppName)) + name, err := hex.DecodeString(strings.Repeat("0", 29-len(hexStr)) + hexStr) if err != nil { log.Errorf("error decoding NubitDA namespace config: %+v", err) return nil, err @@ -83,34 +84,13 @@ func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][ return nil, err } - // Add to batches data cache - backend.batchesDataCache = append(backend.batchesDataCache, encodedData) - backend.batchesDataSize += uint64(len(encodedData)) - if backend.batchesDataSize < backend.config.NubitMaxBatchesSize { - log.Infof("Added batches data to NubitDABackend cache, current length: %+v", len(encodedData)) - return nil, nil - } - if time.Since(backend.commitTime) < 12*time.Second { - time.Sleep(time.Since(backend.commitTime)) - } - - data, err := MarshalBatchData(backend.batchesDataCache) - if err != nil { - log.Errorf("Marshal batch data failed: %s", err) - return nil, err - } - id, err := backend.client.Submit(ctx, [][]byte{data}, -1, backend.ns) + id, err := backend.client.Submit(ctx, [][]byte{encodedData}, -1, backend.ns) if err != nil { log.Errorf("Submit batch data with NubitDA client failed: %s", err) return nil, err } log.Infof("Data submitted to Nubit DA: %d bytes against namespace %v sent with id %#x", len(backend.batchesDataCache), backend.ns, id) - // Reset batches data cache and DA commit time - backend.commitTime = time.Now() - backend.batchesDataCache = [][]byte{} - backend.batchesDataSize = 0 - // Get proof tries := uint64(0) posted := false @@ -133,27 +113,13 @@ func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][ return nil, err } - // // TODO: use bridge API data - // batchDAData := BatchDAData{ID: id} - // log.Infof("Nubit DA data ID: %+v", batchDAData) - // returnData, err := batchDAData.Encode() - // if err != nil { - // return nil, fmt.Errorf("Encode batch data failed: %w", err) - // } - - // Sign sequence - sequence := daTypes.Sequence{} - for _, seq := range batchesData { - sequence = append(sequence, seq) - } - signedSequence, err := sequence.Sign(backend.privKey) + batchDAData := BatchDAData{} + batchDAData.ID = id + encode, err := batchDAData.Encode() if err != nil { - log.Errorf("Failed to sign sequence with pk: %v", err) return nil, err } - signature := append(sequence.HashToSign(), signedSequence.Signature...) - - return signature, nil + return encode, nil } // GetSequence gets the sequence data from NubitDA layer From 207913c95537d85cdc92221232b57eb9da5f41a9 Mon Sep 17 00:00:00 2001 From: marvin Date: Thu, 25 Jul 2024 15:21:47 +0800 Subject: [PATCH 03/10] update namespace --- dataavailability/nubit/backend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index 10905a782c..85a6b1d24d 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -47,7 +47,7 @@ func NewNubitDABackend( } // TODO: Check if name byte array requires zero padding hexStr := hex.EncodeToString([]byte(cfg.NubitModularAppName)) - name, err := hex.DecodeString(strings.Repeat("0", 29-len(hexStr)) + hexStr) + name, err := hex.DecodeString(strings.Repeat("0", 58-len(hexStr)) + hexStr) if err != nil { log.Errorf("error decoding NubitDA namespace config: %+v", err) return nil, err From a0a8dcf2bfbfa30bbdecee8ff019bba6cb9499cf Mon Sep 17 00:00:00 2001 From: marvin Date: Thu, 25 Jul 2024 16:55:42 +0800 Subject: [PATCH 04/10] set Nubit for daProtocolName --- cmd/run_xlayer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index 9e2629fb32..995c5b694d 100644 --- a/cmd/run_xlayer.go +++ b/cmd/run_xlayer.go @@ -94,6 +94,7 @@ func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Cl // Backend specific config daProtocolName, err := etherman.GetDAProtocolName() + daProtocolName = string(dataavailability.DataAvailabilityNubitDA) if err != nil { return nil, fmt.Errorf("error getting data availability protocol name: %v", err) } From d1de3e3d6951632966236b6197ed1e3a92787210 Mon Sep 17 00:00:00 2001 From: Niven Date: Mon, 29 Jul 2024 18:30:28 +0800 Subject: [PATCH 05/10] Revert fixes --- cmd/run_xlayer.go | 1 - dataavailability/nubit/backend.go | 2 +- dataavailability/nubit/config.go | 3 +++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index 995c5b694d..9e2629fb32 100644 --- a/cmd/run_xlayer.go +++ b/cmd/run_xlayer.go @@ -94,7 +94,6 @@ func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Cl // Backend specific config daProtocolName, err := etherman.GetDAProtocolName() - daProtocolName = string(dataavailability.DataAvailabilityNubitDA) if err != nil { return nil, fmt.Errorf("error getting data availability protocol name: %v", err) } diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index 85a6b1d24d..2fca34118b 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -47,7 +47,7 @@ func NewNubitDABackend( } // TODO: Check if name byte array requires zero padding hexStr := hex.EncodeToString([]byte(cfg.NubitModularAppName)) - name, err := hex.DecodeString(strings.Repeat("0", 58-len(hexStr)) + hexStr) + name, err := hex.DecodeString(strings.Repeat("0", NubitNamespaceBytesLength-len(hexStr)) + hexStr) if err != nil { log.Errorf("error decoding NubitDA namespace config: %+v", err) return nil, err diff --git a/dataavailability/nubit/config.go b/dataavailability/nubit/config.go index da5d2811a5..dbd406a916 100644 --- a/dataavailability/nubit/config.go +++ b/dataavailability/nubit/config.go @@ -2,6 +2,9 @@ package nubit import "time" +// NubitNamespaceBytesLength is the fixed-size bytes array. +const NubitNamespaceBytesLength = 58 + // Config is the NubitDA backend configurations type Config struct { NubitRpcURL string `mapstructure:"NubitRpcURL"` From 3611565450528b82b22c3376762b95776810fa30 Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 30 Jul 2024 16:00:21 +0800 Subject: [PATCH 06/10] Add nubit backend fixes --- cmd/run_xlayer.go | 11 +-- config/default.go | 4 +- dataavailability/nubit/abi.go | 28 ++++++ dataavailability/nubit/backend.go | 106 +++++++++++----------- dataavailability/nubit/backend_test.go | 116 +++++++++++++++++++++++- dataavailability/nubit/blob.go | 103 +++++++++++++++++++++ dataavailability/nubit/blob_test.go | 35 +++++++ dataavailability/nubit/chain.go | 41 --------- dataavailability/nubit/config.go | 5 +- dataavailability/nubit/encoding.go | 75 +++++++++++++++ dataavailability/nubit/encoding_test.go | 85 +++++++++++++++++ dataavailability/nubit/nubit_test.go | 37 -------- dataavailability/nubit/types.go | 42 --------- 13 files changed, 497 insertions(+), 191 deletions(-) create mode 100644 dataavailability/nubit/abi.go create mode 100644 dataavailability/nubit/blob.go create mode 100644 dataavailability/nubit/blob_test.go delete mode 100644 dataavailability/nubit/chain.go create mode 100644 dataavailability/nubit/encoding.go create mode 100644 dataavailability/nubit/encoding_test.go delete mode 100644 dataavailability/nubit/nubit_test.go delete mode 100644 dataavailability/nubit/types.go diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index 9e2629fb32..6d61a6b5ba 100644 --- a/cmd/run_xlayer.go +++ b/cmd/run_xlayer.go @@ -136,16 +136,7 @@ func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Cl } log.Infof("from pk %s", crypto.PubkeyToAddress(pk.PublicKey)) } - dacAddr, err := etherman.GetDAProtocolAddr() - if err != nil { - return nil, fmt.Errorf("error getting trusted sequencer URI. Error: %v", err) - } - daBackend, err = nubit.NewNubitDABackend( - c.Etherman.URL, - dacAddr, - pk, - &c.DataAvailability, - ) + daBackend, err = nubit.NewNubitDABackend(&c.DataAvailability, pk) if err != nil { return nil, err } diff --git a/config/default.go b/config/default.go index 8297e2df12..1bac8414bd 100644 --- a/config/default.go +++ b/config/default.go @@ -244,11 +244,9 @@ AggLayerURL = "" SequencerPrivateKey = {} [DataAvailability] -NubitRpcURL = "" -NubitModularAppName = "" +NubitRpcURL = "http://127.0.0.1:26658" NubitAuthKey = "" NubitNamespace = "xlayer" -NubitMaxBatchesSize = "102400" NubitGetProofMaxRetry = "10" NubitGetProofWaitPeriod = "5s" diff --git a/dataavailability/nubit/abi.go b/dataavailability/nubit/abi.go new file mode 100644 index 0000000000..e0e6f0db61 --- /dev/null +++ b/dataavailability/nubit/abi.go @@ -0,0 +1,28 @@ +package nubit + +const blobDataABI = `[ + { + "type": "function", + "name": "BlobData", + "inputs": [ + { + "name": "blobData", + "type": "tuple", + "internalType": "struct NubitDAVerifier.BlobData", + "components": [ + { + "name": "blobID", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "signature", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "stateMutability": "pure" + } +]` diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index 2fca34118b..8321af9aa1 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -7,66 +7,50 @@ import ( "strings" "time" - polygondatacommittee "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/polygondatacommittee_xlayer" + daTypes "github.com/0xPolygon/cdk-data-availability/types" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethclient" "github.com/rollkit/go-da" "github.com/rollkit/go-da/proxy" ) // NubitDABackend implements the DA integration with Nubit DA layer type NubitDABackend struct { - dataCommitteeContract *polygondatacommittee.PolygondatacommitteeXlayer - client da.DA - config *Config - ns da.Namespace - privKey *ecdsa.PrivateKey - commitTime time.Time - batchesDataCache [][]byte - batchesDataSize uint64 + client da.DA + config *Config + namespace da.Namespace + privKey *ecdsa.PrivateKey + commitTime time.Time } // NewNubitDABackend is the factory method to create a new instance of NubitDABackend func NewNubitDABackend( - l1RPCURL string, - dataCommitteeAddr common.Address, - privKey *ecdsa.PrivateKey, cfg *Config, + privKey *ecdsa.PrivateKey, ) (*NubitDABackend, error) { - ethClient, err := ethclient.Dial(l1RPCURL) - if err != nil { - log.Errorf("error connecting to %s: %+v", l1RPCURL, err) - return nil, err - } - log.Infof("NubitDABackend config: %#v ", cfg) cn, err := proxy.NewClient(cfg.NubitRpcURL, cfg.NubitAuthKey) if err != nil { return nil, err } - // TODO: Check if name byte array requires zero padding - hexStr := hex.EncodeToString([]byte(cfg.NubitModularAppName)) + + hexStr := hex.EncodeToString([]byte(cfg.NubitNamespace)) name, err := hex.DecodeString(strings.Repeat("0", NubitNamespaceBytesLength-len(hexStr)) + hexStr) if err != nil { log.Errorf("error decoding NubitDA namespace config: %+v", err) return nil, err } - dataCommittee, err := polygondatacommittee.NewPolygondatacommitteeXlayer(dataCommitteeAddr, ethClient) if err != nil { return nil, err } log.Infof("NubitDABackend namespace: %s ", string(name)) return &NubitDABackend{ - dataCommitteeContract: dataCommittee, - config: cfg, - privKey: privKey, - ns: name, - client: cn, - commitTime: time.Now(), - batchesDataCache: [][]byte{}, - batchesDataSize: 0, + config: cfg, + privKey: privKey, + namespace: name, + client: cn, + commitTime: time.Now(), }, nil } @@ -78,33 +62,40 @@ func (backend *NubitDABackend) Init() error { // PostSequence sends the sequence data to the data availability backend, and returns the dataAvailabilityMessage // as expected by the contract func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][]byte) ([]byte, error) { - encodedData, err := MarshalBatchData(batchesData) - if err != nil { - log.Errorf("Marshal batch data failed: %s", err) - return nil, err + // Check commit time interval validation + lastCommitTime := time.Since(backend.commitTime) + if lastCommitTime < NubitMinCommitTime { + time.Sleep(NubitMinCommitTime - lastCommitTime) } - id, err := backend.client.Submit(ctx, [][]byte{encodedData}, -1, backend.ns) - if err != nil { + // Encode NubitDA blob data + data := EncodeSequence(batchesData) + ids, err := backend.client.Submit(ctx, [][]byte{data}, -1, backend.namespace) + // Ensure only a single blob ID returned + if err != nil || len(ids) != 1 { log.Errorf("Submit batch data with NubitDA client failed: %s", err) return nil, err } - log.Infof("Data submitted to Nubit DA: %d bytes against namespace %v sent with id %#x", len(backend.batchesDataCache), backend.ns, id) + blobID := ids[0] + backend.commitTime = time.Now() + log.Infof("Data submitted to Nubit DA: %d bytes against namespace %v sent with id %#x", len(data), backend.namespace, blobID) - // Get proof + // Get proof of batches data on NubitDA layer tries := uint64(0) posted := false for tries < backend.config.NubitGetProofMaxRetry { - dataProof, err := backend.client.GetProofs(ctx, id, backend.ns) + dataProof, err := backend.client.GetProofs(ctx, [][]byte{blobID}, backend.namespace) if err != nil { log.Infof("Proof not available: %s", err) } - if len(dataProof) > 0 { + if len(dataProof) == 1 { + // TODO: add data proof to DA message log.Infof("Data proof from Nubit DA received: %+v", dataProof) posted = true break } + // Retries tries += 1 time.Sleep(backend.config.NubitGetProofWaitPeriod) } @@ -113,30 +104,39 @@ func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][ return nil, err } - batchDAData := BatchDAData{} - batchDAData.ID = id - encode, err := batchDAData.Encode() + // Get abi-encoded data availability message + sequence := daTypes.Sequence{} + for _, seq := range batchesData { + sequence = append(sequence, seq) + } + signedSequence, err := sequence.Sign(backend.privKey) if err != nil { + log.Errorf("Failed to sign sequence with pk: %v", err) return nil, err } - return encode, nil + signature := append(sequence.HashToSign(), signedSequence.Signature...) + blobData := BlobData{ + BlobID: blobID, + Signature: signature, + } + + return TryEncodeToDataAvailabilityMessage(blobData) } // GetSequence gets the sequence data from NubitDA layer func (backend *NubitDABackend) GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) { - batchDAData := BatchDAData{} - err := batchDAData.Decode(dataAvailabilityMessage) + blobData, err := TryDecodeFromDataAvailabilityMessage(dataAvailabilityMessage) if err != nil { - log.Errorf("🏆 NubitDABackend.GetSequence.Decode:%s", err) + log.Error("Error decoding from da message: ", err) return nil, err } - log.Infof("🏆 Nubit GetSequence batchDAData:%+v", batchDAData) - blob, err := backend.client.Get(ctx, batchDAData.ID, backend.ns) - if err != nil { - log.Errorf("🏆 NubitDABackend.GetSequence.Blob.Get:%s", err) + + reply, err := backend.client.Get(ctx, [][]byte{blobData.BlobID}, backend.namespace) + if err != nil || len(reply) != 1 { + log.Error("Error retrieving blob from NubitDA client: ", err) return nil, err } - log.Infof("🏆 Nubit GetSequence blob.data:%+v", len(blob)) - return blob, nil + batchesData, _ := DecodeSequence(reply[0]) + return batchesData, nil } diff --git a/dataavailability/nubit/backend_test.go b/dataavailability/nubit/backend_test.go index 53d7833200..121743c840 100644 --- a/dataavailability/nubit/backend_test.go +++ b/dataavailability/nubit/backend_test.go @@ -1,28 +1,138 @@ package nubit import ( + "context" "crypto/ecdsa" + "crypto/elliptic" + crand "crypto/rand" "encoding/hex" + "fmt" + "math/rand" + "testing" "time" "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/ethereum/go-ethereum/common" "github.com/rollkit/go-da/proxy" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func NewNubitDABackendTest(url string, authKey string, pk *ecdsa.PrivateKey) (*NubitDABackend, error) { +func TestOffchainPipeline(t *testing.T) { + cfg := Config{ + NubitRpcURL: "http://127.0.0.1:26658", + NubitAuthKey: "", + NubitNamespace: "xlayer", + NubitGetProofMaxRetry: 10, + NubitGetProofWaitPeriod: 5 * time.Second, + } + pk, err := ecdsa.GenerateKey(elliptic.P256(), crand.Reader) + require.NoError(t, err) + + backend, err := NewNubitDABackend(&cfg, pk) + require.NoError(t, err) + + // Generate mock string batch data + stringData := "hihihihihihihihihihihihihihihihihihi" + data := []byte(stringData) + + // Generate mock string sequence + mockBatches := [][]byte{} + for i := 0; i < 1; i++ { + mockBatches = append(mockBatches, data) + } + + msg, err := backend.PostSequence(context.Background(), mockBatches) + fmt.Println("DA msg: ", msg) + require.NoError(t, err) + time.Sleep(600 * time.Millisecond) + + blobData, err := TryDecodeFromDataAvailabilityMessage(msg) + require.NoError(t, err) + require.NotNil(t, blobData.BlobID) + require.NotNil(t, blobData.Signature) + require.NotZero(t, len(blobData.BlobID)) + require.NotZero(t, len(blobData.Signature)) + fmt.Println("Decoding DA msg successful") + + // Retrieve sequence with provider + returnData, err := backend.GetSequence(context.Background(), []common.Hash{}, msg) + + // Validate retrieved data + require.NoError(t, err) + require.Equal(t, 10, len(returnData)) + for _, batchData := range returnData { + assert.Equal(t, stringData, string(batchData)) + } +} + +func TestOffchainPipelineWithRandomData(t *testing.T) { + cfg := Config{ + NubitRpcURL: "http://127.0.0.1:26658", + NubitAuthKey: "", + NubitNamespace: "xlayer", + NubitGetProofMaxRetry: 10, + NubitGetProofWaitPeriod: 5 * time.Second, + } + pk, err := ecdsa.GenerateKey(elliptic.P256(), crand.Reader) + require.NoError(t, err) + + backend, err := NewNubitDABackend(&cfg, pk) + require.NoError(t, err) + + // Define Different DataSizes + dataSize := []int{100000, 200000, 1000, 80, 30000} + + // Disperse Blob with different DataSizes + rand.Seed(time.Now().UnixNano()) //nolint:gosec,staticcheck + data := make([]byte, dataSize[rand.Intn(len(dataSize))]) //nolint:gosec,staticcheck + _, err = rand.Read(data) //nolint:gosec,staticcheck + assert.NoError(t, err) + + // Generate mock string sequence + mockBatches := [][]byte{} + for i := 0; i < 10; i++ { + mockBatches = append(mockBatches, data) + } + + msg, err := backend.PostSequence(context.Background(), mockBatches) + fmt.Println("DA msg: ", msg) + require.NoError(t, err) + time.Sleep(600 * time.Millisecond) + + blobData, err := TryDecodeFromDataAvailabilityMessage(msg) + require.NoError(t, err) + require.NotNil(t, blobData.BlobID) + require.NotNil(t, blobData.Signature) + require.NotZero(t, len(blobData.BlobID)) + require.NotZero(t, len(blobData.Signature)) + fmt.Println("Decoding DA msg successful") + + // Retrieve sequence with provider + returnData, err := backend.GetSequence(context.Background(), []common.Hash{}, msg) + + // Validate retrieved data + require.NoError(t, err) + require.Equal(t, 10, len(returnData)) + for idx, batchData := range returnData { + assert.Equal(t, mockBatches[idx], batchData) + } +} + +func NewMockNubitDABackend(url string, authKey string, pk *ecdsa.PrivateKey) (*NubitDABackend, error) { cn, err := proxy.NewClient(url, authKey) if err != nil || cn == nil { return nil, err } - name, err := hex.DecodeString("00000000000000000000000000000000000000000000706f6c79676f6e") + name, err := hex.DecodeString("xlayer") if err != nil { return nil, err } log.Infof("Nubit Namespace: %s ", string(name)) return &NubitDABackend{ - ns: name, + namespace: name, client: cn, privKey: pk, commitTime: time.Now(), diff --git a/dataavailability/nubit/blob.go b/dataavailability/nubit/blob.go new file mode 100644 index 0000000000..19a74ac19d --- /dev/null +++ b/dataavailability/nubit/blob.go @@ -0,0 +1,103 @@ +package nubit + +import ( + "bytes" + "errors" + "fmt" + "reflect" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// ErrConvertFromABIInterface is used when there is a decoding error +var ErrConvertFromABIInterface = errors.New("conversion from abi interface error") + +// BlobData is the NubitDA blob data +type BlobData struct { + BlobID []byte `abi:"blobID"` + Signature []byte `abi:"signature"` +} + +// TryEncodeToDataAvailabilityMessage is a fallible encoding method to encode +// Nubit blob data into data availability message represented as byte array. +func TryEncodeToDataAvailabilityMessage(blobData BlobData) ([]byte, error) { + parsedABI, err := abi.JSON(bytes.NewReader([]byte(blobDataABI))) + if err != nil { + return nil, err + } + + // Encode the data + method, exist := parsedABI.Methods["BlobData"] + if !exist { + return nil, fmt.Errorf("abi error, BlobData method not found") + } + + encoded, err := method.Inputs.Pack(blobData) + if err != nil { + return nil, err + } + + return encoded, nil +} + +// TryDecodeFromDataAvailabilityMessage is a fallible decoding method to +// decode data availability message into Nubit blob data. +func TryDecodeFromDataAvailabilityMessage(msg []byte) (BlobData, error) { + // Parse the ABI + parsedABI, err := abi.JSON(bytes.NewReader([]byte(blobDataABI))) + if err != nil { + return BlobData{}, err + } + + // Decode the data + method, exist := parsedABI.Methods["BlobData"] + if !exist { + return BlobData{}, fmt.Errorf("abi error, BlobData method not found") + } + + unpackedMap := make(map[string]interface{}) + err = method.Inputs.UnpackIntoMap(unpackedMap, msg) + if err != nil { + return BlobData{}, err + } + unpacked, ok := unpackedMap["blobData"] + if !ok { + return BlobData{}, fmt.Errorf("abi error, failed to unpack to BlobData") + } + + val := reflect.ValueOf(unpacked) + typ := reflect.TypeOf(unpacked) + + blobData := BlobData{} + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + value := val.Field(i) + + switch field.Name { + case "BlobID": + blobData.BlobID, err = convertBlobID(value) + if err != nil { + return BlobData{}, ErrConvertFromABIInterface + } + case "Signature": + blobData.Signature, err = convertSignature(value) + if err != nil { + return BlobData{}, ErrConvertFromABIInterface + } + default: + return BlobData{}, ErrConvertFromABIInterface + } + } + + return blobData, nil +} + +// -------- Helper fallible conversion methods -------- +func convertBlobID(val reflect.Value) ([]byte, error) { + return val.Interface().([]byte), nil +} + +func convertSignature(val reflect.Value) ([]byte, error) { + return val.Interface().([]byte), nil +} diff --git a/dataavailability/nubit/blob_test.go b/dataavailability/nubit/blob_test.go new file mode 100644 index 0000000000..24f6898d70 --- /dev/null +++ b/dataavailability/nubit/blob_test.go @@ -0,0 +1,35 @@ +package nubit + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEncodeBlobData(t *testing.T) { + data := BlobData{ + BlobID: []byte{10}, + Signature: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, + } + msg, err := TryEncodeToDataAvailabilityMessage(data) + assert.NoError(t, err) + assert.NotNil(t, msg) + assert.NotEmpty(t, msg) +} + +func TestEncodeDecodeBlobData(t *testing.T) { + data := BlobData{ + BlobID: []byte{10}, + Signature: []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, + } + msg, err := TryEncodeToDataAvailabilityMessage(data) + assert.NoError(t, err) + assert.NotNil(t, msg) + assert.NotEmpty(t, msg) + + // Check blob ID + decoded_data, err := TryDecodeFromDataAvailabilityMessage(msg) + assert.NoError(t, err) + assert.Equal(t, data.BlobID, decoded_data.BlobID) + assert.Equal(t, data.Signature, decoded_data.Signature) +} diff --git a/dataavailability/nubit/chain.go b/dataavailability/nubit/chain.go deleted file mode 100644 index 2bf1775c95..0000000000 --- a/dataavailability/nubit/chain.go +++ /dev/null @@ -1,41 +0,0 @@ -package nubit - -import ( - "fmt" - - "github.com/ethereum/go-ethereum/accounts/abi" -) - -// MarshalBatchData packs the batch data into ABI-encoded byte array -func MarshalBatchData(batchData [][]byte) ([]byte, error) { - byteArrayType, _ := abi.NewType("bytes[]", "", nil) - args := abi.Arguments{ - {Type: byteArrayType, Name: "batchData"}, - } - res, err := args.Pack(&batchData) - if err != nil { - return make([]byte, 0), fmt.Errorf("cannot pack batchData:%w", err) - } - return res, nil -} - -// UnmarshalBatchData unpacks the ABI-encoded byte array into batch data -func UnmarshalBatchData(encodedData []byte) ([][]byte, error) { - byteArrayType, _ := abi.NewType("bytes[]", "", nil) - args := abi.Arguments{ - {Type: byteArrayType, Name: "batchData"}, - } - res, err := args.Unpack(encodedData) - if err != nil { - return nil, fmt.Errorf("cannot unpack batchData: %w", err) - } - batchData := make([][]byte, len(res)) - for i, v := range res { - byteSlice, ok := v.([]byte) - if !ok { - return nil, fmt.Errorf("element at index %d is not a []byte", i) - } - batchData[i] = byteSlice - } - return batchData, nil -} diff --git a/dataavailability/nubit/config.go b/dataavailability/nubit/config.go index dbd406a916..8230c23b89 100644 --- a/dataavailability/nubit/config.go +++ b/dataavailability/nubit/config.go @@ -5,13 +5,14 @@ import "time" // NubitNamespaceBytesLength is the fixed-size bytes array. const NubitNamespaceBytesLength = 58 +// NubitMinCommitTime is the minimum commit time interval between blob submissions to NubitDA. +const NubitMinCommitTime time.Duration = 12 * time.Second + // Config is the NubitDA backend configurations type Config struct { NubitRpcURL string `mapstructure:"NubitRpcURL"` - NubitModularAppName string `mapstructure:"NubitModularAppName"` NubitAuthKey string `mapstructure:"NubitAuthKey"` NubitNamespace string `mapstructure:"NubitNamespace"` - NubitMaxBatchesSize uint64 `mapstructure:"NubitMaxBatchesSize"` NubitGetProofMaxRetry uint64 `mapstructure:"NubitGetProofMaxRetry"` NubitGetProofWaitPeriod time.Duration `mapstructure:"NubitGetProofWaitPeriod"` } diff --git a/dataavailability/nubit/encoding.go b/dataavailability/nubit/encoding.go new file mode 100644 index 0000000000..9d56c2d9c2 --- /dev/null +++ b/dataavailability/nubit/encoding.go @@ -0,0 +1,75 @@ +package nubit + +import ( + "encoding/binary" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +// EncodeSequence is the helper function to encode sequence data and their metadata into 1D byte array. +// The encoding scheme is ensured to be lossless. +// +// When encoding the blob data, the first 8-bytes stores the size of the batches (n) in the sequence. The +// next n slots of sized 40 bytes stores the metadata of the batches data. +// The first 8-bytes of the batches metadata stores the batches data length, and the next 32-bytes stores +// the batches hash. +// +// The remaining n slots contains the batches data, each slot length is specified in the retrieved batch +// metadata. +func EncodeSequence(batchesData [][]byte) []byte { + sequence := []byte{} + metadata := []byte{} + n := uint64(len(batchesData)) + bn := make([]byte, 8) //nolint:gomnd + binary.BigEndian.PutUint64(bn, n) + metadata = append(metadata, bn...) + + for _, seq := range batchesData { + // Add batch data to byte array + sequence = append(sequence, seq...) + + // Add batch metadata to byte array + // Batch metadata contains the byte array length and the Keccak256 hash of the + // batch data + n := uint64(len(seq)) + bn := make([]byte, 8) //nolint:gomnd + binary.BigEndian.PutUint64(bn, n) + hash := crypto.Keccak256Hash(seq) + metadata = append(metadata, bn...) + metadata = append(metadata, hash.Bytes()...) + } + sequence = append(metadata, sequence...) + + return sequence +} + +// DecodeSequence is the helper function to decode the 1D byte array into sequence data and the batches +// metadata. The decoding sceheme is ensured to be lossless and follows the encoding scheme specified in +// the EncodeSequence function. +func DecodeSequence(blobData []byte) ([][]byte, []common.Hash) { + bn := blobData[:8] + n := binary.BigEndian.Uint64(bn) + // Each batch metadata contains the batch data byte array length (8 byte) and the + // batch data hash (32 byte) + metadata := blobData[8 : 40*n+8] + sequence := blobData[40*n+8:] + + batchesData := [][]byte{} + batchesHash := []common.Hash{} + idx := uint64(0) + for i := uint64(0); i < n; i++ { + // Get batch metadata + bn := metadata[40*i : 40*i+8] + n := binary.BigEndian.Uint64(bn) + + hash := common.BytesToHash(metadata[40*i+8 : 40*(i+1)]) + batchesHash = append(batchesHash, hash) + + // Get batch data + batchesData = append(batchesData, sequence[idx:idx+n]) + idx += n + } + + return batchesData, batchesHash +} diff --git a/dataavailability/nubit/encoding_test.go b/dataavailability/nubit/encoding_test.go new file mode 100644 index 0000000000..7d71f0c8ac --- /dev/null +++ b/dataavailability/nubit/encoding_test.go @@ -0,0 +1,85 @@ +package nubit + +import ( + "math/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/assert" +) + +func TestEncodeDecodeSequenceToAndFromStringBlob(t *testing.T) { + mock_string_data := "hihihihihihihihihihihihihihihihihihi" + data := []byte(mock_string_data) + hash := crypto.Keccak256Hash(data) + + // Generate mock sequence data + mockSeqData := [][]byte{} + for i := 0; i < 10; i++ { + mockSeqData = append(mockSeqData, data) + } + blob := EncodeSequence(mockSeqData) + + // Decode blob + decodedBatchesData, decodedBatchesHash := DecodeSequence(blob) + + // Assert decoded sequence length is correct + n_data := len(decodedBatchesData) + n_hash := len(decodedBatchesHash) + assert.Equal(t, 10, n_data) + assert.Equal(t, 10, n_hash) + + // Assert decoded sequence data is correct + for _, batchData := range decodedBatchesData { + data_decoded := string(batchData) + assert.Equal(t, mock_string_data, data_decoded) + } + + // Assert decoded batches' hash is correct + for _, batchHash := range decodedBatchesHash { + assert.Equal(t, hash, batchHash) + } +} + +func TestEncodeDecodeSequenceToAndFromRandomBlob(t *testing.T) { + // Define Different DataSizes + dataSize := []int{100000, 200000, 1000, 80, 30000} + + // Generate mock sequence data + mockSeqData := [][]byte{} + mockSeqHash := []common.Hash{} + for i := 0; i < 10; i++ { + // Disperse Blob with different DataSizes + rand.Seed(time.Now().UnixNano()) //nolint:gosec,staticcheck + data := make([]byte, dataSize[rand.Intn(len(dataSize))]) //nolint:gosec,staticcheck + _, err := rand.Read(data) //nolint:gosec,staticcheck + assert.NoError(t, err) + mockSeqData = append(mockSeqData, data) + + // Get batch hash + hash := crypto.Keccak256Hash(data) + mockSeqHash = append(mockSeqHash, hash) + } + blob := EncodeSequence(mockSeqData) + + // Decode blob + decodedBatchesData, decodedBatchesHash := DecodeSequence(blob) + + // Assert decoded sequence length is correct + n_data := len(decodedBatchesData) + n_hash := len(decodedBatchesHash) + assert.Equal(t, 10, n_data) + assert.Equal(t, 10, n_hash) + + // Assert decoded sequence data is correct + for i := 0; i < n_data; i++ { + assert.Equal(t, mockSeqData[i], decodedBatchesData[i]) + } + + // Assert decoded batches' hash is correct + for i := 0; i < n_hash; i++ { + assert.Equal(t, mockSeqHash[i], decodedBatchesHash[i]) + } +} diff --git a/dataavailability/nubit/nubit_test.go b/dataavailability/nubit/nubit_test.go deleted file mode 100644 index 826c0613e2..0000000000 --- a/dataavailability/nubit/nubit_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package nubit - -import ( - "context" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" -) - -func TestStoreDetailsOnChain(t *testing.T) { - pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - t.Fatal(err) - } - nubit, err := NewNubitDABackendTest("http://127.0.0.1:26658", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJwdWJsaWMiLCJyZWFkIiwid3JpdGUiLCJhZG1pbiJdfQ.DAMv0s7915Ahx-kDFSzDT1ATz4Q9WwktWcHmjp7_99Q", pk) - if err != nil { - t.Fatal(err) - } - var returnData []byte - for i := 0; i < 10; i++ { - txs := []byte("test txs") - r, err := nubit.PostSequence(context.TODO(), [][]byte{txs}) - require.NoError(t, err) - if r != nil { - returnData = r - } - time.Sleep(600 * time.Millisecond) - } - - _, err = nubit.GetSequence(context.TODO(), []common.Hash{}, returnData) - require.NoError(t, err) -} diff --git a/dataavailability/nubit/types.go b/dataavailability/nubit/types.go deleted file mode 100644 index b6f5f7f8e0..0000000000 --- a/dataavailability/nubit/types.go +++ /dev/null @@ -1,42 +0,0 @@ -package nubit - -import ( - "encoding/json" - "reflect" - - "github.com/ethereum/go-ethereum/common" - "github.com/rollkit/go-da" -) - -// BatchDAData contains the batch information on NubitDA -type BatchDAData struct { - ID []da.ID `json:"id,omitempty"` -} - -// Encode encodes the BatchDAData into ABI-encoded bytes -func (b *BatchDAData) Encode() ([]byte, error) { - return json.Marshal(b) -} - -// Decode decodes the ABI-encoded bytes into BatchDAData -func (b *BatchDAData) Decode(data []byte) error { - return json.Unmarshal(data, &b) -} - -// IsEmpty checks i fthe BatchDAData is empty -func (b *BatchDAData) IsEmpty() bool { - return reflect.DeepEqual(b, BatchDAData{}) -} - -// DataCommitteeMember represents a member of the Data Committee -type DataCommitteeMember struct { - Addr common.Address - URL string -} - -// DataCommittee represents a specific committee -type DataCommittee struct { - AddressesHash common.Hash - Members []DataCommitteeMember - RequiredSignatures uint64 -} From e891a10cb40d9be57b187200808e59bd95c85acb Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 30 Jul 2024 16:28:38 +0800 Subject: [PATCH 07/10] Fmt --- dataavailability/nubit/backend.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index 8321af9aa1..bd8b6e1349 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -28,7 +28,7 @@ func NewNubitDABackend( cfg *Config, privKey *ecdsa.PrivateKey, ) (*NubitDABackend, error) { - log.Infof("NubitDABackend config: %#v ", cfg) + log.Infof("NubitDABackend config: %#v", cfg) cn, err := proxy.NewClient(cfg.NubitRpcURL, cfg.NubitAuthKey) if err != nil { return nil, err @@ -43,7 +43,7 @@ func NewNubitDABackend( if err != nil { return nil, err } - log.Infof("NubitDABackend namespace: %s ", string(name)) + log.Infof("NubitDABackend namespace: %s", string(name)) return &NubitDABackend{ config: cfg, From d009c780c75ec282a17f81142cb6da3a1a0e4c3b Mon Sep 17 00:00:00 2001 From: Niven Date: Tue, 30 Jul 2024 17:22:12 +0800 Subject: [PATCH 08/10] Fix config --- dataavailability/nubit/backend.go | 2 +- dataavailability/nubit/config.go | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dataavailability/nubit/backend.go b/dataavailability/nubit/backend.go index bd8b6e1349..56561a1a8c 100644 --- a/dataavailability/nubit/backend.go +++ b/dataavailability/nubit/backend.go @@ -97,7 +97,7 @@ func (backend *NubitDABackend) PostSequence(ctx context.Context, batchesData [][ // Retries tries += 1 - time.Sleep(backend.config.NubitGetProofWaitPeriod) + time.Sleep(backend.config.NubitGetProofWaitPeriod.Duration) } if !posted { log.Errorf("Get blob proof on Nubit DA failed: %s", err) diff --git a/dataavailability/nubit/config.go b/dataavailability/nubit/config.go index 8230c23b89..81d5dde04a 100644 --- a/dataavailability/nubit/config.go +++ b/dataavailability/nubit/config.go @@ -1,6 +1,10 @@ package nubit -import "time" +import ( + "time" + + "github.com/0xPolygonHermez/zkevm-node/config/types" +) // NubitNamespaceBytesLength is the fixed-size bytes array. const NubitNamespaceBytesLength = 58 @@ -10,9 +14,9 @@ const NubitMinCommitTime time.Duration = 12 * time.Second // Config is the NubitDA backend configurations type Config struct { - NubitRpcURL string `mapstructure:"NubitRpcURL"` - NubitAuthKey string `mapstructure:"NubitAuthKey"` - NubitNamespace string `mapstructure:"NubitNamespace"` - NubitGetProofMaxRetry uint64 `mapstructure:"NubitGetProofMaxRetry"` - NubitGetProofWaitPeriod time.Duration `mapstructure:"NubitGetProofWaitPeriod"` + NubitRpcURL string `mapstructure:"NubitRpcURL"` + NubitAuthKey string `mapstructure:"NubitAuthKey"` + NubitNamespace string `mapstructure:"NubitNamespace"` + NubitGetProofMaxRetry uint64 `mapstructure:"NubitGetProofMaxRetry"` + NubitGetProofWaitPeriod types.Duration `mapstructure:"NubitGetProofWaitPeriod"` } From 404fc20bfd1349ca1504251c93891bbd48990db7 Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 31 Jul 2024 09:41:06 +0800 Subject: [PATCH 09/10] Fix lint --- dataavailability/nubit/backend_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dataavailability/nubit/backend_test.go b/dataavailability/nubit/backend_test.go index 121743c840..2d11921ae5 100644 --- a/dataavailability/nubit/backend_test.go +++ b/dataavailability/nubit/backend_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "github.com/0xPolygonHermez/zkevm-node/config/types" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/ethereum/go-ethereum/common" "github.com/rollkit/go-da/proxy" @@ -24,7 +25,7 @@ func TestOffchainPipeline(t *testing.T) { NubitAuthKey: "", NubitNamespace: "xlayer", NubitGetProofMaxRetry: 10, - NubitGetProofWaitPeriod: 5 * time.Second, + NubitGetProofWaitPeriod: types.NewDuration(5 * time.Second), } pk, err := ecdsa.GenerateKey(elliptic.P256(), crand.Reader) require.NoError(t, err) @@ -72,7 +73,7 @@ func TestOffchainPipelineWithRandomData(t *testing.T) { NubitAuthKey: "", NubitNamespace: "xlayer", NubitGetProofMaxRetry: 10, - NubitGetProofWaitPeriod: 5 * time.Second, + NubitGetProofWaitPeriod: types.NewDuration(5 * time.Second), } pk, err := ecdsa.GenerateKey(elliptic.P256(), crand.Reader) require.NoError(t, err) From e1cb81a33c8c04a2377668265306fc44d2322abc Mon Sep 17 00:00:00 2001 From: Niven Date: Wed, 31 Jul 2024 09:48:50 +0800 Subject: [PATCH 10/10] Fix docs --- docs/config-file/node-config-doc.html | 4 +- docs/config-file/node-config-doc.md | 328 ++++++++++++++--------- docs/config-file/node-config-schema.json | 32 +++ 3 files changed, 242 insertions(+), 122 deletions(-) diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 67e8abca6b..ca1afd876d 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -84,7 +84,9 @@
"300ms"
 

Default: "10m"Type: string

GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.


Default: 0Type: integer

GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.

ex:
gas estimation: 1000
gas offset: 100
final gas: 1100


Default: 0Type: integer

UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog


Default: 2Type: integer

BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch


Default: "l1"Type: string

SettlementBackend configuration defines how a final ZKP should be settled. Directly to L1 or over the Beethoven service.


Default: "5m0s"Type: string

AggLayerTxTimeout is the interval time to wait for a tx to be mined from the agglayer


Examples:

"1m"
 
"300ms"
-

Default: ""Type: string

AggLayerURL url of the agglayer service


SequencerPrivateKey Private key of the trusted sequencer
Default: ""Type: string

Path is the file path for the key store file


Default: ""Type: string

Password is the password to decrypt the key store file


Configuration of the genesis of the network. This is used to known the initial state of the network

L1: Configuration related to L1
Default: 0Type: integer

Chain ID of the L1 network


Type: array of integer

ZkEVMAddr Address of the L1 contract polygonZkEVMAddress

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

RollupManagerAddr Address of the L1 contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

PolAddr Address of the L1 Pol token Contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

L2: address of the PolygonZkEVMBridge proxy smart contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: 0Type: integer

RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1


Default: 0Type: integer

RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1


Type: array of integer

Root hash of the genesis block

Must contain a minimum of 32 items

Must contain a maximum of 32 items

Each item of this array must be:


Type: array of object

Actions is the data to populate into the state trie

Each item of this array must be:


Configuration of the gas price suggester service
Default: "follower"Type: string

Default: 2000000000Type: integer

DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.


Default: 0Type: integer

MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.


Default: 0Type: integer

Default: 0Type: integer

Default: "10s"Type: string

Examples:

"1m"
+

Default: ""Type: string

AggLayerURL url of the agglayer service


SequencerPrivateKey Private key of the trusted sequencer
Default: ""Type: string

Path is the file path for the key store file


Default: ""Type: string

Password is the password to decrypt the key store file


Configuration of the NubitDA data availability service
Default: "http://127.0.0.1:26658"Type: string

Default: ""Type: string

Default: "xlayer"Type: string

Default: 10Type: integer

Default: "5s"Type: string

Examples:

"1m"
+
"300ms"
+

Configuration of the genesis of the network. This is used to known the initial state of the network

L1: Configuration related to L1
Default: 0Type: integer

Chain ID of the L1 network


Type: array of integer

ZkEVMAddr Address of the L1 contract polygonZkEVMAddress

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

RollupManagerAddr Address of the L1 contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

PolAddr Address of the L1 Pol token Contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

L2: address of the PolygonZkEVMBridge proxy smart contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: 0Type: integer

RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1


Default: 0Type: integer

RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1


Type: array of integer

Root hash of the genesis block

Must contain a minimum of 32 items

Must contain a maximum of 32 items

Each item of this array must be:


Type: array of object

Actions is the data to populate into the state trie

Each item of this array must be:


Configuration of the gas price suggester service
Default: "follower"Type: string

Default: 2000000000Type: integer

DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.


Default: 0Type: integer

MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.


Default: 0Type: integer

Default: 0Type: integer

Default: "10s"Type: string

Examples:

"1m"
 
"300ms"
 

Default: "1h0m0s"Type: string

Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 607bda00b9..c44b565fc0 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -19,6 +19,7 @@
 | - [Sequencer](#Sequencer )                           | No      | object  | No         | -          | Configuration of the sequencer service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 | - [SequenceSender](#SequenceSender )                 | No      | object  | No         | -          | Configuration of the sequence sender service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
 | - [Aggregator](#Aggregator )                         | No      | object  | No         | -          | Configuration of the aggregator service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
+| - [DataAvailability](#DataAvailability )             | No      | object  | No         | -          | Configuration of the NubitDA data availability service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
 | - [NetworkConfig](#NetworkConfig )                   | No      | object  | No         | -          | Configuration of the genesis of the network. This is used to known the initial state of the network                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
 | - [L2GasPriceSuggester](#L2GasPriceSuggester )       | No      | object  | No         | -          | Configuration of the gas price suggester service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | - [Executor](#Executor )                             | No      | object  | No         | -          | Configuration of the executor service                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
@@ -4509,7 +4510,92 @@ Path=""
 Password=""
 ```
 
-## 13. `[NetworkConfig]`
+## 13. `[DataAvailability]`
+
+**Type:** : `object`
+**Description:** Configuration of the NubitDA data availability service
+
+| Property                                                                | Pattern | Type    | Deprecated | Definition | Title/Description |
+| ----------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- |
+| - [NubitRpcURL](#DataAvailability_NubitRpcURL )                         | No      | string  | No         | -          | -                 |
+| - [NubitAuthKey](#DataAvailability_NubitAuthKey )                       | No      | string  | No         | -          | -                 |
+| - [NubitNamespace](#DataAvailability_NubitNamespace )                   | No      | string  | No         | -          | -                 |
+| - [NubitGetProofMaxRetry](#DataAvailability_NubitGetProofMaxRetry )     | No      | integer | No         | -          | -                 |
+| - [NubitGetProofWaitPeriod](#DataAvailability_NubitGetProofWaitPeriod ) | No      | string  | No         | -          | Duration          |
+
+### 13.1. `DataAvailability.NubitRpcURL`
+
+**Type:** : `string`
+
+**Default:** `"http://127.0.0.1:26658"`
+
+**Example setting the default value** ("http://127.0.0.1:26658"):
+```
+[DataAvailability]
+NubitRpcURL="http://127.0.0.1:26658"
+```
+
+### 13.2. `DataAvailability.NubitAuthKey`
+
+**Type:** : `string`
+
+**Default:** `""`
+
+**Example setting the default value** (""):
+```
+[DataAvailability]
+NubitAuthKey=""
+```
+
+### 13.3. `DataAvailability.NubitNamespace`
+
+**Type:** : `string`
+
+**Default:** `"xlayer"`
+
+**Example setting the default value** ("xlayer"):
+```
+[DataAvailability]
+NubitNamespace="xlayer"
+```
+
+### 13.4. `DataAvailability.NubitGetProofMaxRetry`
+
+**Type:** : `integer`
+
+**Default:** `10`
+
+**Example setting the default value** (10):
+```
+[DataAvailability]
+NubitGetProofMaxRetry=10
+```
+
+### 13.5. `DataAvailability.NubitGetProofWaitPeriod`
+
+**Title:** Duration
+
+**Type:** : `string`
+
+**Default:** `"5s"`
+
+**Examples:** 
+
+```json
+"1m"
+```
+
+```json
+"300ms"
+```
+
+**Example setting the default value** ("5s"):
+```
+[DataAvailability]
+NubitGetProofWaitPeriod="5s"
+```
+
+## 14. `[NetworkConfig]`
 
 **Type:** : `object`
 **Description:** Configuration of the genesis of the network. This is used to known the initial state of the network
@@ -4520,7 +4606,7 @@ Password=""
 | - [L2BridgeAddr](#NetworkConfig_L2BridgeAddr ) | No      | array of integer | No         | -          | L2: address of the \`PolygonZkEVMBridge proxy\` smart contract |
 | - [Genesis](#NetworkConfig_Genesis )           | No      | object           | No         | -          | -                                                              |
 
-### 13.1. `[NetworkConfig.l1Config]`
+### 14.1. `[NetworkConfig.l1Config]`
 
 **Type:** : `object`
 **Description:** L1: Configuration related to L1
@@ -4533,7 +4619,7 @@ Password=""
 | - [polTokenAddress](#NetworkConfig_l1Config_polTokenAddress )                                     | No      | array of integer | No         | -          | PolAddr Address of the L1 Pol token Contract                               |
 | - [polygonZkEVMGlobalExitRootAddress](#NetworkConfig_l1Config_polygonZkEVMGlobalExitRootAddress ) | No      | array of integer | No         | -          | GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract |
 
-#### 13.1.1. `NetworkConfig.l1Config.chainId`
+#### 14.1.1. `NetworkConfig.l1Config.chainId`
 
 **Type:** : `integer`
 
@@ -4547,32 +4633,32 @@ Password=""
 chainId=0
 ```
 
-#### 13.1.2. `NetworkConfig.l1Config.polygonZkEVMAddress`
+#### 14.1.2. `NetworkConfig.l1Config.polygonZkEVMAddress`
 
 **Type:** : `array of integer`
 **Description:** ZkEVMAddr Address of the L1 contract polygonZkEVMAddress
 
-#### 13.1.3. `NetworkConfig.l1Config.polygonRollupManagerAddress`
+#### 14.1.3. `NetworkConfig.l1Config.polygonRollupManagerAddress`
 
 **Type:** : `array of integer`
 **Description:** RollupManagerAddr Address of the L1 contract
 
-#### 13.1.4. `NetworkConfig.l1Config.polTokenAddress`
+#### 14.1.4. `NetworkConfig.l1Config.polTokenAddress`
 
 **Type:** : `array of integer`
 **Description:** PolAddr Address of the L1 Pol token Contract
 
-#### 13.1.5. `NetworkConfig.l1Config.polygonZkEVMGlobalExitRootAddress`
+#### 14.1.5. `NetworkConfig.l1Config.polygonZkEVMGlobalExitRootAddress`
 
 **Type:** : `array of integer`
 **Description:** GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract
 
-### 13.2. `NetworkConfig.L2BridgeAddr`
+### 14.2. `NetworkConfig.L2BridgeAddr`
 
 **Type:** : `array of integer`
 **Description:** L2: address of the `PolygonZkEVMBridge proxy` smart contract
 
-### 13.3. `[NetworkConfig.Genesis]`
+### 14.3. `[NetworkConfig.Genesis]`
 
 **Type:** : `object`
 
@@ -4583,7 +4669,7 @@ chainId=0
 | - [Root](#NetworkConfig_Genesis_Root )                                         | No      | array of integer | No         | -          | Root hash of the genesis block                                                              |
 | - [Actions](#NetworkConfig_Genesis_Actions )                                   | No      | array of object  | No         | -          | Actions is the data to populate into the state trie                                         |
 
-#### 13.3.1. `NetworkConfig.Genesis.RollupBlockNumber`
+#### 14.3.1. `NetworkConfig.Genesis.RollupBlockNumber`
 
 **Type:** : `integer`
 
@@ -4597,7 +4683,7 @@ chainId=0
 RollupBlockNumber=0
 ```
 
-#### 13.3.2. `NetworkConfig.Genesis.RollupManagerBlockNumber`
+#### 14.3.2. `NetworkConfig.Genesis.RollupManagerBlockNumber`
 
 **Type:** : `integer`
 
@@ -4611,12 +4697,12 @@ RollupBlockNumber=0
 RollupManagerBlockNumber=0
 ```
 
-#### 13.3.3. `NetworkConfig.Genesis.Root`
+#### 14.3.3. `NetworkConfig.Genesis.Root`
 
 **Type:** : `array of integer`
 **Description:** Root hash of the genesis block
 
-#### 13.3.4. `NetworkConfig.Genesis.Actions`
+#### 14.3.4. `NetworkConfig.Genesis.Actions`
 
 **Type:** : `array of object`
 **Description:** Actions is the data to populate into the state trie
@@ -4633,7 +4719,7 @@ RollupManagerBlockNumber=0
 | ----------------------------------------------------- | ------------------------------------------------------------------------- |
 | [Actions items](#NetworkConfig_Genesis_Actions_items) | GenesisAction represents one of the values set on the SMT during genesis. |
 
-##### 13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
+##### 14.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
 
 **Type:** : `object`
 **Description:** GenesisAction represents one of the values set on the SMT during genesis.
@@ -4648,35 +4734,35 @@ RollupManagerBlockNumber=0
 | - [value](#NetworkConfig_Genesis_Actions_items_value )                     | No      | string  | No         | -          | -                 |
 | - [root](#NetworkConfig_Genesis_Actions_items_root )                       | No      | string  | No         | -          | -                 |
 
-##### 13.3.4.1.1. `NetworkConfig.Genesis.Actions.Actions items.address`
+##### 14.3.4.1.1. `NetworkConfig.Genesis.Actions.Actions items.address`
 
 **Type:** : `string`
 
-##### 13.3.4.1.2. `NetworkConfig.Genesis.Actions.Actions items.type`
+##### 14.3.4.1.2. `NetworkConfig.Genesis.Actions.Actions items.type`
 
 **Type:** : `integer`
 
-##### 13.3.4.1.3. `NetworkConfig.Genesis.Actions.Actions items.storagePosition`
+##### 14.3.4.1.3. `NetworkConfig.Genesis.Actions.Actions items.storagePosition`
 
 **Type:** : `string`
 
-##### 13.3.4.1.4. `NetworkConfig.Genesis.Actions.Actions items.bytecode`
+##### 14.3.4.1.4. `NetworkConfig.Genesis.Actions.Actions items.bytecode`
 
 **Type:** : `string`
 
-##### 13.3.4.1.5. `NetworkConfig.Genesis.Actions.Actions items.key`
+##### 14.3.4.1.5. `NetworkConfig.Genesis.Actions.Actions items.key`
 
 **Type:** : `string`
 
-##### 13.3.4.1.6. `NetworkConfig.Genesis.Actions.Actions items.value`
+##### 14.3.4.1.6. `NetworkConfig.Genesis.Actions.Actions items.value`
 
 **Type:** : `string`
 
-##### 13.3.4.1.7. `NetworkConfig.Genesis.Actions.Actions items.root`
+##### 14.3.4.1.7. `NetworkConfig.Genesis.Actions.Actions items.root`
 
 **Type:** : `string`
 
-## 14. `[L2GasPriceSuggester]`
+## 15. `[L2GasPriceSuggester]`
 
 **Type:** : `object`
 **Description:** Configuration of the gas price suggester service
@@ -4707,7 +4793,7 @@ RollupManagerBlockNumber=0
 | - [GasPriceUsdt](#L2GasPriceSuggester_GasPriceUsdt )                                       | No      | number  | No         | -          | -                                                                                                                                        |
 | - [EnableFollowerAdjustByL2L1Price](#L2GasPriceSuggester_EnableFollowerAdjustByL2L1Price ) | No      | boolean | No         | -          | EnableFollowerAdjustByL2L1Price is dynamic adjust the factor through the L1 and L2 coins price in follower strategy                      |
 
-### 14.1. `L2GasPriceSuggester.Type`
+### 15.1. `L2GasPriceSuggester.Type`
 
 **Type:** : `string`
 
@@ -4719,7 +4805,7 @@ RollupManagerBlockNumber=0
 Type="follower"
 ```
 
-### 14.2. `L2GasPriceSuggester.DefaultGasPriceWei`
+### 15.2. `L2GasPriceSuggester.DefaultGasPriceWei`
 
 **Type:** : `integer`
 
@@ -4733,7 +4819,7 @@ Type="follower"
 DefaultGasPriceWei=2000000000
 ```
 
-### 14.3. `L2GasPriceSuggester.MaxGasPriceWei`
+### 15.3. `L2GasPriceSuggester.MaxGasPriceWei`
 
 **Type:** : `integer`
 
@@ -4747,15 +4833,15 @@ DefaultGasPriceWei=2000000000
 MaxGasPriceWei=0
 ```
 
-### 14.4. `[L2GasPriceSuggester.MaxPrice]`
+### 15.4. `[L2GasPriceSuggester.MaxPrice]`
 
 **Type:** : `object`
 
-### 14.5. `[L2GasPriceSuggester.IgnorePrice]`
+### 15.5. `[L2GasPriceSuggester.IgnorePrice]`
 
 **Type:** : `object`
 
-### 14.6. `L2GasPriceSuggester.CheckBlocks`
+### 15.6. `L2GasPriceSuggester.CheckBlocks`
 
 **Type:** : `integer`
 
@@ -4767,7 +4853,7 @@ MaxGasPriceWei=0
 CheckBlocks=0
 ```
 
-### 14.7. `L2GasPriceSuggester.Percentile`
+### 15.7. `L2GasPriceSuggester.Percentile`
 
 **Type:** : `integer`
 
@@ -4779,7 +4865,7 @@ CheckBlocks=0
 Percentile=0
 ```
 
-### 14.8. `L2GasPriceSuggester.UpdatePeriod`
+### 15.8. `L2GasPriceSuggester.UpdatePeriod`
 
 **Title:** Duration
 
@@ -4803,7 +4889,7 @@ Percentile=0
 UpdatePeriod="10s"
 ```
 
-### 14.9. `L2GasPriceSuggester.CleanHistoryPeriod`
+### 15.9. `L2GasPriceSuggester.CleanHistoryPeriod`
 
 **Title:** Duration
 
@@ -4827,7 +4913,7 @@ UpdatePeriod="10s"
 CleanHistoryPeriod="1h0m0s"
 ```
 
-### 14.10. `L2GasPriceSuggester.CleanHistoryTimeRetention`
+### 15.10. `L2GasPriceSuggester.CleanHistoryTimeRetention`
 
 **Title:** Duration
 
@@ -4851,7 +4937,7 @@ CleanHistoryPeriod="1h0m0s"
 CleanHistoryTimeRetention="5m0s"
 ```
 
-### 14.11. `L2GasPriceSuggester.Factor`
+### 15.11. `L2GasPriceSuggester.Factor`
 
 **Type:** : `number`
 
@@ -4863,7 +4949,7 @@ CleanHistoryTimeRetention="5m0s"
 Factor=0.15
 ```
 
-### 14.12. `L2GasPriceSuggester.KafkaURL`
+### 15.12. `L2GasPriceSuggester.KafkaURL`
 
 **Type:** : `string`
 
@@ -4877,7 +4963,7 @@ Factor=0.15
 KafkaURL=""
 ```
 
-### 14.13. `L2GasPriceSuggester.Topic`
+### 15.13. `L2GasPriceSuggester.Topic`
 
 **Type:** : `string`
 
@@ -4889,7 +4975,7 @@ KafkaURL=""
 Topic=""
 ```
 
-### 14.14. `L2GasPriceSuggester.GroupID`
+### 15.14. `L2GasPriceSuggester.GroupID`
 
 **Type:** : `string`
 
@@ -4901,7 +4987,7 @@ Topic=""
 GroupID=""
 ```
 
-### 14.15. `L2GasPriceSuggester.Username`
+### 15.15. `L2GasPriceSuggester.Username`
 
 **Type:** : `string`
 
@@ -4913,7 +4999,7 @@ GroupID=""
 Username=""
 ```
 
-### 14.16. `L2GasPriceSuggester.Password`
+### 15.16. `L2GasPriceSuggester.Password`
 
 **Type:** : `string`
 
@@ -4925,7 +5011,7 @@ Username=""
 Password=""
 ```
 
-### 14.17. `L2GasPriceSuggester.RootCAPath`
+### 15.17. `L2GasPriceSuggester.RootCAPath`
 
 **Type:** : `string`
 
@@ -4937,7 +5023,7 @@ Password=""
 RootCAPath=""
 ```
 
-### 14.18. `L2GasPriceSuggester.L1CoinId`
+### 15.18. `L2GasPriceSuggester.L1CoinId`
 
 **Type:** : `integer`
 
@@ -4949,7 +5035,7 @@ RootCAPath=""
 L1CoinId=0
 ```
 
-### 14.19. `L2GasPriceSuggester.L2CoinId`
+### 15.19. `L2GasPriceSuggester.L2CoinId`
 
 **Type:** : `integer`
 
@@ -4961,7 +5047,7 @@ L1CoinId=0
 L2CoinId=0
 ```
 
-### 14.20. `L2GasPriceSuggester.DefaultL1CoinPrice`
+### 15.20. `L2GasPriceSuggester.DefaultL1CoinPrice`
 
 **Type:** : `number`
 
@@ -4975,7 +5061,7 @@ L2CoinId=0
 DefaultL1CoinPrice=0
 ```
 
-### 14.21. `L2GasPriceSuggester.DefaultL2CoinPrice`
+### 15.21. `L2GasPriceSuggester.DefaultL2CoinPrice`
 
 **Type:** : `number`
 
@@ -4989,7 +5075,7 @@ DefaultL1CoinPrice=0
 DefaultL2CoinPrice=0
 ```
 
-### 14.22. `L2GasPriceSuggester.GasPriceUsdt`
+### 15.22. `L2GasPriceSuggester.GasPriceUsdt`
 
 **Type:** : `number`
 
@@ -5001,7 +5087,7 @@ DefaultL2CoinPrice=0
 GasPriceUsdt=0
 ```
 
-### 14.23. `L2GasPriceSuggester.EnableFollowerAdjustByL2L1Price`
+### 15.23. `L2GasPriceSuggester.EnableFollowerAdjustByL2L1Price`
 
 **Type:** : `boolean`
 
@@ -5015,7 +5101,7 @@ GasPriceUsdt=0
 EnableFollowerAdjustByL2L1Price=false
 ```
 
-## 15. `[Executor]`
+## 16. `[Executor]`
 
 **Type:** : `object`
 **Description:** Configuration of the executor service
@@ -5027,7 +5113,7 @@ EnableFollowerAdjustByL2L1Price=false
 | - [WaitOnResourceExhaustion](#Executor_WaitOnResourceExhaustion )         | No      | string  | No         | -          | Duration                                                                                                                |
 | - [MaxGRPCMessageSize](#Executor_MaxGRPCMessageSize )                     | No      | integer | No         | -          | -                                                                                                                       |
 
-### 15.1. `Executor.URI`
+### 16.1. `Executor.URI`
 
 **Type:** : `string`
 
@@ -5039,7 +5125,7 @@ EnableFollowerAdjustByL2L1Price=false
 URI="xlayer-prover:50071"
 ```
 
-### 15.2. `Executor.MaxResourceExhaustedAttempts`
+### 16.2. `Executor.MaxResourceExhaustedAttempts`
 
 **Type:** : `integer`
 
@@ -5053,7 +5139,7 @@ URI="xlayer-prover:50071"
 MaxResourceExhaustedAttempts=3
 ```
 
-### 15.3. `Executor.WaitOnResourceExhaustion`
+### 16.3. `Executor.WaitOnResourceExhaustion`
 
 **Title:** Duration
 
@@ -5079,7 +5165,7 @@ MaxResourceExhaustedAttempts=3
 WaitOnResourceExhaustion="1s"
 ```
 
-### 15.4. `Executor.MaxGRPCMessageSize`
+### 16.4. `Executor.MaxGRPCMessageSize`
 
 **Type:** : `integer`
 
@@ -5091,7 +5177,7 @@ WaitOnResourceExhaustion="1s"
 MaxGRPCMessageSize=100000000
 ```
 
-## 16. `[MTClient]`
+## 17. `[MTClient]`
 
 **Type:** : `object`
 **Description:** Configuration of the merkle tree client service. Not use in the node, only for testing
@@ -5100,7 +5186,7 @@ MaxGRPCMessageSize=100000000
 | ----------------------- | ------- | ------ | ---------- | ---------- | ---------------------- |
 | - [URI](#MTClient_URI ) | No      | string | No         | -          | URI is the server URI. |
 
-### 16.1. `MTClient.URI`
+### 17.1. `MTClient.URI`
 
 **Type:** : `string`
 
@@ -5114,7 +5200,7 @@ MaxGRPCMessageSize=100000000
 URI="xlayer-prover:50061"
 ```
 
-## 17. `[Metrics]`
+## 18. `[Metrics]`
 
 **Type:** : `object`
 **Description:** Configuration of the metrics service, basically is where is going to publish the metrics
@@ -5128,7 +5214,7 @@ URI="xlayer-prover:50061"
 | - [ProfilingPort](#Metrics_ProfilingPort )       | No      | integer | No         | -          | ProfilingPort is the port to bind the profiling server              |
 | - [ProfilingEnabled](#Metrics_ProfilingEnabled ) | No      | boolean | No         | -          | ProfilingEnabled is the flag to enable/disable the profiling server |
 
-### 17.1. `Metrics.Host`
+### 18.1. `Metrics.Host`
 
 **Type:** : `string`
 
@@ -5142,7 +5228,7 @@ URI="xlayer-prover:50061"
 Host="0.0.0.0"
 ```
 
-### 17.2. `Metrics.Port`
+### 18.2. `Metrics.Port`
 
 **Type:** : `integer`
 
@@ -5156,7 +5242,7 @@ Host="0.0.0.0"
 Port=9091
 ```
 
-### 17.3. `Metrics.Enabled`
+### 18.3. `Metrics.Enabled`
 
 **Type:** : `boolean`
 
@@ -5170,7 +5256,7 @@ Port=9091
 Enabled=false
 ```
 
-### 17.4. `Metrics.ProfilingHost`
+### 18.4. `Metrics.ProfilingHost`
 
 **Type:** : `string`
 
@@ -5184,7 +5270,7 @@ Enabled=false
 ProfilingHost=""
 ```
 
-### 17.5. `Metrics.ProfilingPort`
+### 18.5. `Metrics.ProfilingPort`
 
 **Type:** : `integer`
 
@@ -5198,7 +5284,7 @@ ProfilingHost=""
 ProfilingPort=0
 ```
 
-### 17.6. `Metrics.ProfilingEnabled`
+### 18.6. `Metrics.ProfilingEnabled`
 
 **Type:** : `boolean`
 
@@ -5212,7 +5298,7 @@ ProfilingPort=0
 ProfilingEnabled=false
 ```
 
-## 18. `[EventLog]`
+## 19. `[EventLog]`
 
 **Type:** : `object`
 **Description:** Configuration of the event database connection
@@ -5221,7 +5307,7 @@ ProfilingEnabled=false
 | --------------------- | ------- | ------ | ---------- | ---------- | -------------------------------- |
 | - [DB](#EventLog_DB ) | No      | object | No         | -          | DB is the database configuration |
 
-### 18.1. `[EventLog.DB]`
+### 19.1. `[EventLog.DB]`
 
 **Type:** : `object`
 **Description:** DB is the database configuration
@@ -5236,7 +5322,7 @@ ProfilingEnabled=false
 | - [EnableLog](#EventLog_DB_EnableLog ) | No      | boolean | No         | -          | EnableLog                                                  |
 | - [MaxConns](#EventLog_DB_MaxConns )   | No      | integer | No         | -          | MaxConns is the maximum number of connections in the pool. |
 
-#### 18.1.1. `EventLog.DB.Name`
+#### 19.1.1. `EventLog.DB.Name`
 
 **Type:** : `string`
 
@@ -5250,7 +5336,7 @@ ProfilingEnabled=false
 Name=""
 ```
 
-#### 18.1.2. `EventLog.DB.User`
+#### 19.1.2. `EventLog.DB.User`
 
 **Type:** : `string`
 
@@ -5264,7 +5350,7 @@ Name=""
 User=""
 ```
 
-#### 18.1.3. `EventLog.DB.Password`
+#### 19.1.3. `EventLog.DB.Password`
 
 **Type:** : `string`
 
@@ -5278,7 +5364,7 @@ User=""
 Password=""
 ```
 
-#### 18.1.4. `EventLog.DB.Host`
+#### 19.1.4. `EventLog.DB.Host`
 
 **Type:** : `string`
 
@@ -5292,7 +5378,7 @@ Password=""
 Host=""
 ```
 
-#### 18.1.5. `EventLog.DB.Port`
+#### 19.1.5. `EventLog.DB.Port`
 
 **Type:** : `string`
 
@@ -5306,7 +5392,7 @@ Host=""
 Port=""
 ```
 
-#### 18.1.6. `EventLog.DB.EnableLog`
+#### 19.1.6. `EventLog.DB.EnableLog`
 
 **Type:** : `boolean`
 
@@ -5320,7 +5406,7 @@ Port=""
 EnableLog=false
 ```
 
-#### 18.1.7. `EventLog.DB.MaxConns`
+#### 19.1.7. `EventLog.DB.MaxConns`
 
 **Type:** : `integer`
 
@@ -5334,7 +5420,7 @@ EnableLog=false
 MaxConns=0
 ```
 
-## 19. `[HashDB]`
+## 20. `[HashDB]`
 
 **Type:** : `object`
 **Description:** Configuration of the hash database connection
@@ -5349,7 +5435,7 @@ MaxConns=0
 | - [EnableLog](#HashDB_EnableLog ) | No      | boolean | No         | -          | EnableLog                                                  |
 | - [MaxConns](#HashDB_MaxConns )   | No      | integer | No         | -          | MaxConns is the maximum number of connections in the pool. |
 
-### 19.1. `HashDB.Name`
+### 20.1. `HashDB.Name`
 
 **Type:** : `string`
 
@@ -5363,7 +5449,7 @@ MaxConns=0
 Name="prover_db"
 ```
 
-### 19.2. `HashDB.User`
+### 20.2. `HashDB.User`
 
 **Type:** : `string`
 
@@ -5377,7 +5463,7 @@ Name="prover_db"
 User="prover_user"
 ```
 
-### 19.3. `HashDB.Password`
+### 20.3. `HashDB.Password`
 
 **Type:** : `string`
 
@@ -5391,7 +5477,7 @@ User="prover_user"
 Password="prover_pass"
 ```
 
-### 19.4. `HashDB.Host`
+### 20.4. `HashDB.Host`
 
 **Type:** : `string`
 
@@ -5405,7 +5491,7 @@ Password="prover_pass"
 Host="xlayer-state-db"
 ```
 
-### 19.5. `HashDB.Port`
+### 20.5. `HashDB.Port`
 
 **Type:** : `string`
 
@@ -5419,7 +5505,7 @@ Host="xlayer-state-db"
 Port="5432"
 ```
 
-### 19.6. `HashDB.EnableLog`
+### 20.6. `HashDB.EnableLog`
 
 **Type:** : `boolean`
 
@@ -5433,7 +5519,7 @@ Port="5432"
 EnableLog=false
 ```
 
-### 19.7. `HashDB.MaxConns`
+### 20.7. `HashDB.MaxConns`
 
 **Type:** : `integer`
 
@@ -5447,7 +5533,7 @@ EnableLog=false
 MaxConns=200
 ```
 
-## 20. `[State]`
+## 21. `[State]`
 
 **Type:** : `object`
 **Description:** State service configuration
@@ -5468,7 +5554,7 @@ MaxConns=200
 | - [MaxNativeBlockHashBlockRange](#State_MaxNativeBlockHashBlockRange ) | No      | integer         | No         | -          | MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit | | - [AvoidForkIDInMemory](#State_AvoidForkIDInMemory ) | No | boolean | No | - | AvoidForkIDInMemory is a configuration that forces the ForkID information to be loaded
from the DB every time it's needed | -### 20.1. `State.MaxCumulativeGasUsed` +### 21.1. `State.MaxCumulativeGasUsed` **Type:** : `integer` @@ -5482,7 +5568,7 @@ MaxConns=200 MaxCumulativeGasUsed=0 ``` -### 20.2. `State.ChainID` +### 21.2. `State.ChainID` **Type:** : `integer` @@ -5496,7 +5582,7 @@ MaxCumulativeGasUsed=0 ChainID=0 ``` -### 20.3. `State.ForkIDIntervals` +### 21.3. `State.ForkIDIntervals` **Type:** : `array of object` **Description:** ForkIdIntervals is the list of fork id intervals @@ -5513,7 +5599,7 @@ ChainID=0 | ----------------------------------------------------- | ------------------------------------ | | [ForkIDIntervals items](#State_ForkIDIntervals_items) | ForkIDInterval is a fork id interval | -#### 20.3.1. [State.ForkIDIntervals.ForkIDIntervals items] +#### 21.3.1. [State.ForkIDIntervals.ForkIDIntervals items] **Type:** : `object` **Description:** ForkIDInterval is a fork id interval @@ -5526,27 +5612,27 @@ ChainID=0 | - [Version](#State_ForkIDIntervals_items_Version ) | No | string | No | - | - | | - [BlockNumber](#State_ForkIDIntervals_items_BlockNumber ) | No | integer | No | - | - | -##### 20.3.1.1. `State.ForkIDIntervals.ForkIDIntervals items.FromBatchNumber` +##### 21.3.1.1. `State.ForkIDIntervals.ForkIDIntervals items.FromBatchNumber` **Type:** : `integer` -##### 20.3.1.2. `State.ForkIDIntervals.ForkIDIntervals items.ToBatchNumber` +##### 21.3.1.2. `State.ForkIDIntervals.ForkIDIntervals items.ToBatchNumber` **Type:** : `integer` -##### 20.3.1.3. `State.ForkIDIntervals.ForkIDIntervals items.ForkId` +##### 21.3.1.3. `State.ForkIDIntervals.ForkIDIntervals items.ForkId` **Type:** : `integer` -##### 20.3.1.4. `State.ForkIDIntervals.ForkIDIntervals items.Version` +##### 21.3.1.4. `State.ForkIDIntervals.ForkIDIntervals items.Version` **Type:** : `string` -##### 20.3.1.5. `State.ForkIDIntervals.ForkIDIntervals items.BlockNumber` +##### 21.3.1.5. `State.ForkIDIntervals.ForkIDIntervals items.BlockNumber` **Type:** : `integer` -### 20.4. `State.MaxResourceExhaustedAttempts` +### 21.4. `State.MaxResourceExhaustedAttempts` **Type:** : `integer` @@ -5560,7 +5646,7 @@ ChainID=0 MaxResourceExhaustedAttempts=0 ``` -### 20.5. `State.WaitOnResourceExhaustion` +### 21.5. `State.WaitOnResourceExhaustion` **Title:** Duration @@ -5586,7 +5672,7 @@ MaxResourceExhaustedAttempts=0 WaitOnResourceExhaustion="0s" ``` -### 20.6. `State.ForkUpgradeBatchNumber` +### 21.6. `State.ForkUpgradeBatchNumber` **Type:** : `integer` @@ -5600,7 +5686,7 @@ WaitOnResourceExhaustion="0s" ForkUpgradeBatchNumber=0 ``` -### 20.7. `State.ForkUpgradeNewForkId` +### 21.7. `State.ForkUpgradeNewForkId` **Type:** : `integer` @@ -5614,7 +5700,7 @@ ForkUpgradeBatchNumber=0 ForkUpgradeNewForkId=0 ``` -### 20.8. `[State.DB]` +### 21.8. `[State.DB]` **Type:** : `object` **Description:** DB is the database configuration @@ -5629,7 +5715,7 @@ ForkUpgradeNewForkId=0 | - [EnableLog](#State_DB_EnableLog ) | No | boolean | No | - | EnableLog | | - [MaxConns](#State_DB_MaxConns ) | No | integer | No | - | MaxConns is the maximum number of connections in the pool. | -#### 20.8.1. `State.DB.Name` +#### 21.8.1. `State.DB.Name` **Type:** : `string` @@ -5643,7 +5729,7 @@ ForkUpgradeNewForkId=0 Name="state_db" ``` -#### 20.8.2. `State.DB.User` +#### 21.8.2. `State.DB.User` **Type:** : `string` @@ -5657,7 +5743,7 @@ Name="state_db" User="state_user" ``` -#### 20.8.3. `State.DB.Password` +#### 21.8.3. `State.DB.Password` **Type:** : `string` @@ -5671,7 +5757,7 @@ User="state_user" Password="state_password" ``` -#### 20.8.4. `State.DB.Host` +#### 21.8.4. `State.DB.Host` **Type:** : `string` @@ -5685,7 +5771,7 @@ Password="state_password" Host="xlayer-state-db" ``` -#### 20.8.5. `State.DB.Port` +#### 21.8.5. `State.DB.Port` **Type:** : `string` @@ -5699,7 +5785,7 @@ Host="xlayer-state-db" Port="5432" ``` -#### 20.8.6. `State.DB.EnableLog` +#### 21.8.6. `State.DB.EnableLog` **Type:** : `boolean` @@ -5713,7 +5799,7 @@ Port="5432" EnableLog=false ``` -#### 20.8.7. `State.DB.MaxConns` +#### 21.8.7. `State.DB.MaxConns` **Type:** : `integer` @@ -5727,7 +5813,7 @@ EnableLog=false MaxConns=200 ``` -### 20.9. `[State.Batch]` +### 21.9. `[State.Batch]` **Type:** : `object` **Description:** Configuration for the batch constraints @@ -5736,7 +5822,7 @@ MaxConns=200 | ------------------------------------------ | ------- | ------ | ---------- | ---------- | ----------------- | | - [Constraints](#State_Batch_Constraints ) | No | object | No | - | - | -#### 20.9.1. `[State.Batch.Constraints]` +#### 21.9.1. `[State.Batch.Constraints]` **Type:** : `object` @@ -5754,7 +5840,7 @@ MaxConns=200 | - [MaxSteps](#State_Batch_Constraints_MaxSteps ) | No | integer | No | - | - | | - [MaxSHA256Hashes](#State_Batch_Constraints_MaxSHA256Hashes ) | No | integer | No | - | - | -##### 20.9.1.1. `State.Batch.Constraints.MaxTxsPerBatch` +##### 21.9.1.1. `State.Batch.Constraints.MaxTxsPerBatch` **Type:** : `integer` @@ -5766,7 +5852,7 @@ MaxConns=200 MaxTxsPerBatch=300 ``` -##### 20.9.1.2. `State.Batch.Constraints.MaxBatchBytesSize` +##### 21.9.1.2. `State.Batch.Constraints.MaxBatchBytesSize` **Type:** : `integer` @@ -5778,7 +5864,7 @@ MaxTxsPerBatch=300 MaxBatchBytesSize=120000 ``` -##### 20.9.1.3. `State.Batch.Constraints.MaxCumulativeGasUsed` +##### 21.9.1.3. `State.Batch.Constraints.MaxCumulativeGasUsed` **Type:** : `integer` @@ -5790,7 +5876,7 @@ MaxBatchBytesSize=120000 MaxCumulativeGasUsed=1125899906842624 ``` -##### 20.9.1.4. `State.Batch.Constraints.MaxKeccakHashes` +##### 21.9.1.4. `State.Batch.Constraints.MaxKeccakHashes` **Type:** : `integer` @@ -5802,7 +5888,7 @@ MaxCumulativeGasUsed=1125899906842624 MaxKeccakHashes=2145 ``` -##### 20.9.1.5. `State.Batch.Constraints.MaxPoseidonHashes` +##### 21.9.1.5. `State.Batch.Constraints.MaxPoseidonHashes` **Type:** : `integer` @@ -5814,7 +5900,7 @@ MaxKeccakHashes=2145 MaxPoseidonHashes=252357 ``` -##### 20.9.1.6. `State.Batch.Constraints.MaxPoseidonPaddings` +##### 21.9.1.6. `State.Batch.Constraints.MaxPoseidonPaddings` **Type:** : `integer` @@ -5826,7 +5912,7 @@ MaxPoseidonHashes=252357 MaxPoseidonPaddings=135191 ``` -##### 20.9.1.7. `State.Batch.Constraints.MaxMemAligns` +##### 21.9.1.7. `State.Batch.Constraints.MaxMemAligns` **Type:** : `integer` @@ -5838,7 +5924,7 @@ MaxPoseidonPaddings=135191 MaxMemAligns=236585 ``` -##### 20.9.1.8. `State.Batch.Constraints.MaxArithmetics` +##### 21.9.1.8. `State.Batch.Constraints.MaxArithmetics` **Type:** : `integer` @@ -5850,7 +5936,7 @@ MaxMemAligns=236585 MaxArithmetics=236585 ``` -##### 20.9.1.9. `State.Batch.Constraints.MaxBinaries` +##### 21.9.1.9. `State.Batch.Constraints.MaxBinaries` **Type:** : `integer` @@ -5862,7 +5948,7 @@ MaxArithmetics=236585 MaxBinaries=473170 ``` -##### 20.9.1.10. `State.Batch.Constraints.MaxSteps` +##### 21.9.1.10. `State.Batch.Constraints.MaxSteps` **Type:** : `integer` @@ -5874,7 +5960,7 @@ MaxBinaries=473170 MaxSteps=7570538 ``` -##### 20.9.1.11. `State.Batch.Constraints.MaxSHA256Hashes` +##### 21.9.1.11. `State.Batch.Constraints.MaxSHA256Hashes` **Type:** : `integer` @@ -5886,7 +5972,7 @@ MaxSteps=7570538 MaxSHA256Hashes=1596 ``` -### 20.10. `State.MaxLogsCount` +### 21.10. `State.MaxLogsCount` **Type:** : `integer` @@ -5901,7 +5987,7 @@ in a single call to the state, if zero it means no limit MaxLogsCount=0 ``` -### 20.11. `State.MaxLogsBlockRange` +### 21.11. `State.MaxLogsBlockRange` **Type:** : `integer` @@ -5916,7 +6002,7 @@ logs in a single call to the state, if zero it means no limit MaxLogsBlockRange=0 ``` -### 20.12. `State.MaxNativeBlockHashBlockRange` +### 21.12. `State.MaxNativeBlockHashBlockRange` **Type:** : `integer` @@ -5931,7 +6017,7 @@ native block hashes in a single call to the state, if zero it means no limit MaxNativeBlockHashBlockRange=0 ``` -### 20.13. `State.AvoidForkIDInMemory` +### 21.13. `State.AvoidForkIDInMemory` **Type:** : `boolean` @@ -5946,7 +6032,7 @@ from the DB every time it's needed AvoidForkIDInMemory=false ``` -## 21. `[Apollo]` +## 22. `[Apollo]` **Type:** : `object` **Description:** Apollo configuration @@ -5958,7 +6044,7 @@ AvoidForkIDInMemory=false | - [AppID](#Apollo_AppID ) | No | string | No | - | - | | - [NamespaceName](#Apollo_NamespaceName ) | No | string | No | - | - | -### 21.1. `Apollo.Enable` +### 22.1. `Apollo.Enable` **Type:** : `boolean` @@ -5970,7 +6056,7 @@ AvoidForkIDInMemory=false Enable=false ``` -### 21.2. `Apollo.IP` +### 22.2. `Apollo.IP` **Type:** : `string` @@ -5982,7 +6068,7 @@ Enable=false IP="" ``` -### 21.3. `Apollo.AppID` +### 22.3. `Apollo.AppID` **Type:** : `string` @@ -5994,7 +6080,7 @@ IP="" AppID="" ``` -### 21.4. `Apollo.NamespaceName` +### 22.4. `Apollo.NamespaceName` **Type:** : `string` @@ -6006,7 +6092,7 @@ AppID="" NamespaceName="" ``` -## 22. `Fork9UpgradeBatch` +## 23. `Fork9UpgradeBatch` **Type:** : `integer` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 847d43b296..c8c0d21520 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -1761,6 +1761,38 @@ "type": "object", "description": "Configuration of the aggregator service" }, + "DataAvailability": { + "properties": { + "NubitRpcURL": { + "type": "string", + "default": "http://127.0.0.1:26658" + }, + "NubitAuthKey": { + "type": "string", + "default": "" + }, + "NubitNamespace": { + "type": "string", + "default": "xlayer" + }, + "NubitGetProofMaxRetry": { + "type": "integer", + "default": 10 + }, + "NubitGetProofWaitPeriod": { + "type": "string", + "title": "Duration", + "default": "5s", + "examples": [ + "1m", + "300ms" + ] + } + }, + "additionalProperties": false, + "type": "object", + "description": "Configuration of the NubitDA data availability service" + }, "NetworkConfig": { "properties": { "l1Config": {