diff --git a/cmd/run_xlayer.go b/cmd/run_xlayer.go index 0df21fe55c..6d61a6b5ba 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,22 @@ 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)) + } + daBackend, err = nubit.NewNubitDABackend(&c.DataAvailability, pk) + 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 254f4695b4..85c649c948 100644 --- a/config/default.go +++ b/config/default.go @@ -245,6 +245,13 @@ AggLayerTxTimeout = "5m" AggLayerURL = "" SequencerPrivateKey = {} +[DataAvailability] +NubitRpcURL = "http://127.0.0.1:26658" +NubitAuthKey = "" +NubitNamespace = "xlayer" +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/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 new file mode 100644 index 0000000000..56561a1a8c --- /dev/null +++ b/dataavailability/nubit/backend.go @@ -0,0 +1,142 @@ +package nubit + +import ( + "context" + "crypto/ecdsa" + "encoding/hex" + "strings" + "time" + + daTypes "github.com/0xPolygon/cdk-data-availability/types" + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/ethereum/go-ethereum/common" + "github.com/rollkit/go-da" + "github.com/rollkit/go-da/proxy" +) + +// NubitDABackend implements the DA integration with Nubit DA layer +type NubitDABackend struct { + 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( + cfg *Config, + privKey *ecdsa.PrivateKey, +) (*NubitDABackend, error) { + log.Infof("NubitDABackend config: %#v", cfg) + cn, err := proxy.NewClient(cfg.NubitRpcURL, cfg.NubitAuthKey) + if err != nil { + return nil, err + } + + 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 + } + if err != nil { + return nil, err + } + log.Infof("NubitDABackend namespace: %s", string(name)) + + return &NubitDABackend{ + config: cfg, + privKey: privKey, + namespace: name, + client: cn, + commitTime: time.Now(), + }, 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) { + // Check commit time interval validation + lastCommitTime := time.Since(backend.commitTime) + if lastCommitTime < NubitMinCommitTime { + time.Sleep(NubitMinCommitTime - lastCommitTime) + } + + // 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 + } + 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 of batches data on NubitDA layer + tries := uint64(0) + posted := false + for tries < backend.config.NubitGetProofMaxRetry { + dataProof, err := backend.client.GetProofs(ctx, [][]byte{blobID}, backend.namespace) + if err != nil { + log.Infof("Proof not available: %s", err) + } + 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.Duration) + } + if !posted { + log.Errorf("Get blob proof on Nubit DA failed: %s", err) + return nil, err + } + + // 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 + } + 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) { + blobData, err := TryDecodeFromDataAvailabilityMessage(dataAvailabilityMessage) + if err != nil { + log.Error("Error decoding from da message: ", err) + return nil, 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 + } + + batchesData, _ := DecodeSequence(reply[0]) + return batchesData, nil +} diff --git a/dataavailability/nubit/backend_test.go b/dataavailability/nubit/backend_test.go new file mode 100644 index 0000000000..2d11921ae5 --- /dev/null +++ b/dataavailability/nubit/backend_test.go @@ -0,0 +1,141 @@ +package nubit + +import ( + "context" + "crypto/ecdsa" + "crypto/elliptic" + crand "crypto/rand" + "encoding/hex" + "fmt" + "math/rand" + "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" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestOffchainPipeline(t *testing.T) { + cfg := Config{ + NubitRpcURL: "http://127.0.0.1:26658", + NubitAuthKey: "", + NubitNamespace: "xlayer", + NubitGetProofMaxRetry: 10, + NubitGetProofWaitPeriod: types.NewDuration(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: types.NewDuration(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("xlayer") + if err != nil { + return nil, err + } + + log.Infof("Nubit Namespace: %s ", string(name)) + return &NubitDABackend{ + namespace: name, + client: cn, + privKey: pk, + commitTime: time.Now(), + }, nil +} 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/config.go b/dataavailability/nubit/config.go new file mode 100644 index 0000000000..81d5dde04a --- /dev/null +++ b/dataavailability/nubit/config.go @@ -0,0 +1,22 @@ +package nubit + +import ( + "time" + + "github.com/0xPolygonHermez/zkevm-node/config/types" +) + +// 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"` + NubitAuthKey string `mapstructure:"NubitAuthKey"` + NubitNamespace string `mapstructure:"NubitNamespace"` + NubitGetProofMaxRetry uint64 `mapstructure:"NubitGetProofMaxRetry"` + NubitGetProofWaitPeriod types.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/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index e825ebd042..f24e0c9d35 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -88,7 +88,9 @@
"300ms"
GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.
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
UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog
BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch
SettlementBackend configuration defines how a final ZKP should be settled. Directly to L1 or over the Beethoven service.
AggLayerTxTimeout is the interval time to wait for a tx to be mined from the agglayer
"1m"
"300ms"
-
AggLayerURL url of the agglayer service
Path is the file path for the key store file
Password is the password to decrypt the key store file
Chain ID of the L1 network
ZkEVMAddr Address of the L1 contract polygonZkEVMAddress
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupManagerAddr Address of the L1 contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
PolAddr Address of the L1 Pol token Contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
L2: address of the PolygonZkEVMBridge proxy
smart contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1
RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1
Root hash of the genesis block
Must contain a minimum of 32
items
Must contain a maximum of 32
items
Actions is the data to populate into the state trie
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.
MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.
"1m"
+
AggLayerURL url of the agglayer service
Path is the file path for the key store file
Password is the password to decrypt the key store file
"1m"
+
"300ms"
+
Chain ID of the L1 network
ZkEVMAddr Address of the L1 contract polygonZkEVMAddress
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupManagerAddr Address of the L1 contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
PolAddr Address of the L1 Pol token Contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
L2: address of the PolygonZkEVMBridge proxy
smart contract
Must contain a minimum of 20
items
Must contain a maximum of 20
items
RollupBlockNumber is the block number where the polygonZKEVM smc was deployed on L1
RollupManagerBlockNumber is the block number where the RollupManager smc was deployed on L1
Root hash of the genesis block
Must contain a minimum of 32
items
Must contain a maximum of 32
items
Actions is the data to populate into the state trie
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.
MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.
"1m"
"300ms"
"1m"
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index cf6cba6a3a..b72f2a5341 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 |
@@ -4629,7 +4630,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
@@ -4640,7 +4726,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
@@ -4653,7 +4739,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`
@@ -4667,32 +4753,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`
@@ -4703,7 +4789,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`
@@ -4717,7 +4803,7 @@ chainId=0
RollupBlockNumber=0
```
-#### 13.3.2. `NetworkConfig.Genesis.RollupManagerBlockNumber`
+#### 14.3.2. `NetworkConfig.Genesis.RollupManagerBlockNumber`
**Type:** : `integer`
@@ -4731,12 +4817,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
@@ -4753,7 +4839,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.
@@ -4768,35 +4854,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
@@ -4827,7 +4913,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`
@@ -4839,7 +4925,7 @@ RollupManagerBlockNumber=0
Type="follower"
```
-### 14.2. `L2GasPriceSuggester.DefaultGasPriceWei`
+### 15.2. `L2GasPriceSuggester.DefaultGasPriceWei`
**Type:** : `integer`
@@ -4853,7 +4939,7 @@ Type="follower"
DefaultGasPriceWei=2000000000
```
-### 14.3. `L2GasPriceSuggester.MaxGasPriceWei`
+### 15.3. `L2GasPriceSuggester.MaxGasPriceWei`
**Type:** : `integer`
@@ -4867,15 +4953,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`
@@ -4887,7 +4973,7 @@ MaxGasPriceWei=0
CheckBlocks=0
```
-### 14.7. `L2GasPriceSuggester.Percentile`
+### 15.7. `L2GasPriceSuggester.Percentile`
**Type:** : `integer`
@@ -4899,7 +4985,7 @@ CheckBlocks=0
Percentile=0
```
-### 14.8. `L2GasPriceSuggester.UpdatePeriod`
+### 15.8. `L2GasPriceSuggester.UpdatePeriod`
**Title:** Duration
@@ -4923,7 +5009,7 @@ Percentile=0
UpdatePeriod="10s"
```
-### 14.9. `L2GasPriceSuggester.CleanHistoryPeriod`
+### 15.9. `L2GasPriceSuggester.CleanHistoryPeriod`
**Title:** Duration
@@ -4947,7 +5033,7 @@ UpdatePeriod="10s"
CleanHistoryPeriod="1h0m0s"
```
-### 14.10. `L2GasPriceSuggester.CleanHistoryTimeRetention`
+### 15.10. `L2GasPriceSuggester.CleanHistoryTimeRetention`
**Title:** Duration
@@ -4971,7 +5057,7 @@ CleanHistoryPeriod="1h0m0s"
CleanHistoryTimeRetention="5m0s"
```
-### 14.11. `L2GasPriceSuggester.Factor`
+### 15.11. `L2GasPriceSuggester.Factor`
**Type:** : `number`
@@ -4983,7 +5069,7 @@ CleanHistoryTimeRetention="5m0s"
Factor=0.15
```
-### 14.12. `L2GasPriceSuggester.KafkaURL`
+### 15.12. `L2GasPriceSuggester.KafkaURL`
**Type:** : `string`
@@ -4997,7 +5083,7 @@ Factor=0.15
KafkaURL=""
```
-### 14.13. `L2GasPriceSuggester.Topic`
+### 15.13. `L2GasPriceSuggester.Topic`
**Type:** : `string`
@@ -5009,7 +5095,7 @@ KafkaURL=""
Topic=""
```
-### 14.14. `L2GasPriceSuggester.GroupID`
+### 15.14. `L2GasPriceSuggester.GroupID`
**Type:** : `string`
@@ -5021,7 +5107,7 @@ Topic=""
GroupID=""
```
-### 14.15. `L2GasPriceSuggester.Username`
+### 15.15. `L2GasPriceSuggester.Username`
**Type:** : `string`
@@ -5033,7 +5119,7 @@ GroupID=""
Username=""
```
-### 14.16. `L2GasPriceSuggester.Password`
+### 15.16. `L2GasPriceSuggester.Password`
**Type:** : `string`
@@ -5045,7 +5131,7 @@ Username=""
Password=""
```
-### 14.17. `L2GasPriceSuggester.RootCAPath`
+### 15.17. `L2GasPriceSuggester.RootCAPath`
**Type:** : `string`
@@ -5057,7 +5143,7 @@ Password=""
RootCAPath=""
```
-### 14.18. `L2GasPriceSuggester.L1CoinId`
+### 15.18. `L2GasPriceSuggester.L1CoinId`
**Type:** : `integer`
@@ -5069,7 +5155,7 @@ RootCAPath=""
L1CoinId=0
```
-### 14.19. `L2GasPriceSuggester.L2CoinId`
+### 15.19. `L2GasPriceSuggester.L2CoinId`
**Type:** : `integer`
@@ -5081,7 +5167,7 @@ L1CoinId=0
L2CoinId=0
```
-### 14.20. `L2GasPriceSuggester.DefaultL1CoinPrice`
+### 15.20. `L2GasPriceSuggester.DefaultL1CoinPrice`
**Type:** : `number`
@@ -5095,7 +5181,7 @@ L2CoinId=0
DefaultL1CoinPrice=0
```
-### 14.21. `L2GasPriceSuggester.DefaultL2CoinPrice`
+### 15.21. `L2GasPriceSuggester.DefaultL2CoinPrice`
**Type:** : `number`
@@ -5109,7 +5195,7 @@ DefaultL1CoinPrice=0
DefaultL2CoinPrice=0
```
-### 14.22. `L2GasPriceSuggester.GasPriceUsdt`
+### 15.22. `L2GasPriceSuggester.GasPriceUsdt`
**Type:** : `number`
@@ -5121,7 +5207,7 @@ DefaultL2CoinPrice=0
GasPriceUsdt=0
```
-### 14.23. `L2GasPriceSuggester.EnableFollowerAdjustByL2L1Price`
+### 15.23. `L2GasPriceSuggester.EnableFollowerAdjustByL2L1Price`
**Type:** : `boolean`
@@ -5135,7 +5221,7 @@ GasPriceUsdt=0
EnableFollowerAdjustByL2L1Price=false
```
-## 15. `[Executor]`
+## 16. `[Executor]`
**Type:** : `object`
**Description:** Configuration of the executor service
@@ -5147,7 +5233,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`
@@ -5159,7 +5245,7 @@ EnableFollowerAdjustByL2L1Price=false
URI="xlayer-prover:50071"
```
-### 15.2. `Executor.MaxResourceExhaustedAttempts`
+### 16.2. `Executor.MaxResourceExhaustedAttempts`
**Type:** : `integer`
@@ -5173,7 +5259,7 @@ URI="xlayer-prover:50071"
MaxResourceExhaustedAttempts=3
```
-### 15.3. `Executor.WaitOnResourceExhaustion`
+### 16.3. `Executor.WaitOnResourceExhaustion`
**Title:** Duration
@@ -5199,7 +5285,7 @@ MaxResourceExhaustedAttempts=3
WaitOnResourceExhaustion="1s"
```
-### 15.4. `Executor.MaxGRPCMessageSize`
+### 16.4. `Executor.MaxGRPCMessageSize`
**Type:** : `integer`
@@ -5211,7 +5297,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
@@ -5220,7 +5306,7 @@ MaxGRPCMessageSize=100000000
| ----------------------- | ------- | ------ | ---------- | ---------- | ---------------------- |
| - [URI](#MTClient_URI ) | No | string | No | - | URI is the server URI. |
-### 16.1. `MTClient.URI`
+### 17.1. `MTClient.URI`
**Type:** : `string`
@@ -5234,7 +5320,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
@@ -5248,7 +5334,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`
@@ -5262,7 +5348,7 @@ URI="xlayer-prover:50061"
Host="0.0.0.0"
```
-### 17.2. `Metrics.Port`
+### 18.2. `Metrics.Port`
**Type:** : `integer`
@@ -5276,7 +5362,7 @@ Host="0.0.0.0"
Port=9091
```
-### 17.3. `Metrics.Enabled`
+### 18.3. `Metrics.Enabled`
**Type:** : `boolean`
@@ -5290,7 +5376,7 @@ Port=9091
Enabled=false
```
-### 17.4. `Metrics.ProfilingHost`
+### 18.4. `Metrics.ProfilingHost`
**Type:** : `string`
@@ -5304,7 +5390,7 @@ Enabled=false
ProfilingHost=""
```
-### 17.5. `Metrics.ProfilingPort`
+### 18.5. `Metrics.ProfilingPort`
**Type:** : `integer`
@@ -5318,7 +5404,7 @@ ProfilingHost=""
ProfilingPort=0
```
-### 17.6. `Metrics.ProfilingEnabled`
+### 18.6. `Metrics.ProfilingEnabled`
**Type:** : `boolean`
@@ -5332,7 +5418,7 @@ ProfilingPort=0
ProfilingEnabled=false
```
-## 18. `[EventLog]`
+## 19. `[EventLog]`
**Type:** : `object`
**Description:** Configuration of the event database connection
@@ -5341,7 +5427,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
@@ -5356,7 +5442,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`
@@ -5370,7 +5456,7 @@ ProfilingEnabled=false
Name=""
```
-#### 18.1.2. `EventLog.DB.User`
+#### 19.1.2. `EventLog.DB.User`
**Type:** : `string`
@@ -5384,7 +5470,7 @@ Name=""
User=""
```
-#### 18.1.3. `EventLog.DB.Password`
+#### 19.1.3. `EventLog.DB.Password`
**Type:** : `string`
@@ -5398,7 +5484,7 @@ User=""
Password=""
```
-#### 18.1.4. `EventLog.DB.Host`
+#### 19.1.4. `EventLog.DB.Host`
**Type:** : `string`
@@ -5412,7 +5498,7 @@ Password=""
Host=""
```
-#### 18.1.5. `EventLog.DB.Port`
+#### 19.1.5. `EventLog.DB.Port`
**Type:** : `string`
@@ -5426,7 +5512,7 @@ Host=""
Port=""
```
-#### 18.1.6. `EventLog.DB.EnableLog`
+#### 19.1.6. `EventLog.DB.EnableLog`
**Type:** : `boolean`
@@ -5440,7 +5526,7 @@ Port=""
EnableLog=false
```
-#### 18.1.7. `EventLog.DB.MaxConns`
+#### 19.1.7. `EventLog.DB.MaxConns`
**Type:** : `integer`
@@ -5454,7 +5540,7 @@ EnableLog=false
MaxConns=0
```
-## 19. `[HashDB]`
+## 20. `[HashDB]`
**Type:** : `object`
**Description:** Configuration of the hash database connection
@@ -5469,7 +5555,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`
@@ -5483,7 +5569,7 @@ MaxConns=0
Name="prover_db"
```
-### 19.2. `HashDB.User`
+### 20.2. `HashDB.User`
**Type:** : `string`
@@ -5497,7 +5583,7 @@ Name="prover_db"
User="prover_user"
```
-### 19.3. `HashDB.Password`
+### 20.3. `HashDB.Password`
**Type:** : `string`
@@ -5511,7 +5597,7 @@ User="prover_user"
Password="prover_pass"
```
-### 19.4. `HashDB.Host`
+### 20.4. `HashDB.Host`
**Type:** : `string`
@@ -5525,7 +5611,7 @@ Password="prover_pass"
Host="xlayer-state-db"
```
-### 19.5. `HashDB.Port`
+### 20.5. `HashDB.Port`
**Type:** : `string`
@@ -5539,7 +5625,7 @@ Host="xlayer-state-db"
Port="5432"
```
-### 19.6. `HashDB.EnableLog`
+### 20.6. `HashDB.EnableLog`
**Type:** : `boolean`
@@ -5553,7 +5639,7 @@ Port="5432"
EnableLog=false
```
-### 19.7. `HashDB.MaxConns`
+### 20.7. `HashDB.MaxConns`
**Type:** : `integer`
@@ -5567,7 +5653,7 @@ EnableLog=false
MaxConns=200
```
-## 20. `[State]`
+## 21. `[State]`
**Type:** : `object`
**Description:** State service configuration
@@ -5588,7 +5674,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`
@@ -5602,7 +5688,7 @@ MaxConns=200
MaxCumulativeGasUsed=0
```
-### 20.2. `State.ChainID`
+### 21.2. `State.ChainID`
**Type:** : `integer`
@@ -5616,7 +5702,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
@@ -5646,27 +5732,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`
@@ -5680,7 +5766,7 @@ ChainID=0
MaxResourceExhaustedAttempts=0
```
-### 20.5. `State.WaitOnResourceExhaustion`
+### 21.5. `State.WaitOnResourceExhaustion`
**Title:** Duration
@@ -5706,7 +5792,7 @@ MaxResourceExhaustedAttempts=0
WaitOnResourceExhaustion="0s"
```
-### 20.6. `State.ForkUpgradeBatchNumber`
+### 21.6. `State.ForkUpgradeBatchNumber`
**Type:** : `integer`
@@ -5720,7 +5806,7 @@ WaitOnResourceExhaustion="0s"
ForkUpgradeBatchNumber=0
```
-### 20.7. `State.ForkUpgradeNewForkId`
+### 21.7. `State.ForkUpgradeNewForkId`
**Type:** : `integer`
@@ -5734,7 +5820,7 @@ ForkUpgradeBatchNumber=0
ForkUpgradeNewForkId=0
```
-### 20.8. `[State.DB]`
+### 21.8. `[State.DB]`
**Type:** : `object`
**Description:** DB is the database configuration
@@ -5749,7 +5835,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`
@@ -5763,7 +5849,7 @@ ForkUpgradeNewForkId=0
Name="state_db"
```
-#### 20.8.2. `State.DB.User`
+#### 21.8.2. `State.DB.User`
**Type:** : `string`
@@ -5777,7 +5863,7 @@ Name="state_db"
User="state_user"
```
-#### 20.8.3. `State.DB.Password`
+#### 21.8.3. `State.DB.Password`
**Type:** : `string`
@@ -5791,7 +5877,7 @@ User="state_user"
Password="state_password"
```
-#### 20.8.4. `State.DB.Host`
+#### 21.8.4. `State.DB.Host`
**Type:** : `string`
@@ -5805,7 +5891,7 @@ Password="state_password"
Host="xlayer-state-db"
```
-#### 20.8.5. `State.DB.Port`
+#### 21.8.5. `State.DB.Port`
**Type:** : `string`
@@ -5819,7 +5905,7 @@ Host="xlayer-state-db"
Port="5432"
```
-#### 20.8.6. `State.DB.EnableLog`
+#### 21.8.6. `State.DB.EnableLog`
**Type:** : `boolean`
@@ -5833,7 +5919,7 @@ Port="5432"
EnableLog=false
```
-#### 20.8.7. `State.DB.MaxConns`
+#### 21.8.7. `State.DB.MaxConns`
**Type:** : `integer`
@@ -5847,7 +5933,7 @@ EnableLog=false
MaxConns=200
```
-### 20.9. `[State.Batch]`
+### 21.9. `[State.Batch]`
**Type:** : `object`
**Description:** Configuration for the batch constraints
@@ -5856,7 +5942,7 @@ MaxConns=200
| ------------------------------------------ | ------- | ------ | ---------- | ---------- | ----------------- |
| - [Constraints](#State_Batch_Constraints ) | No | object | No | - | - |
-#### 20.9.1. `[State.Batch.Constraints]`
+#### 21.9.1. `[State.Batch.Constraints]`
**Type:** : `object`
@@ -5874,7 +5960,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`
@@ -5886,7 +5972,7 @@ MaxConns=200
MaxTxsPerBatch=300
```
-##### 20.9.1.2. `State.Batch.Constraints.MaxBatchBytesSize`
+##### 21.9.1.2. `State.Batch.Constraints.MaxBatchBytesSize`
**Type:** : `integer`
@@ -5898,7 +5984,7 @@ MaxTxsPerBatch=300
MaxBatchBytesSize=120000
```
-##### 20.9.1.3. `State.Batch.Constraints.MaxCumulativeGasUsed`
+##### 21.9.1.3. `State.Batch.Constraints.MaxCumulativeGasUsed`
**Type:** : `integer`
@@ -5910,7 +5996,7 @@ MaxBatchBytesSize=120000
MaxCumulativeGasUsed=1125899906842624
```
-##### 20.9.1.4. `State.Batch.Constraints.MaxKeccakHashes`
+##### 21.9.1.4. `State.Batch.Constraints.MaxKeccakHashes`
**Type:** : `integer`
@@ -5922,7 +6008,7 @@ MaxCumulativeGasUsed=1125899906842624
MaxKeccakHashes=2145
```
-##### 20.9.1.5. `State.Batch.Constraints.MaxPoseidonHashes`
+##### 21.9.1.5. `State.Batch.Constraints.MaxPoseidonHashes`
**Type:** : `integer`
@@ -5934,7 +6020,7 @@ MaxKeccakHashes=2145
MaxPoseidonHashes=252357
```
-##### 20.9.1.6. `State.Batch.Constraints.MaxPoseidonPaddings`
+##### 21.9.1.6. `State.Batch.Constraints.MaxPoseidonPaddings`
**Type:** : `integer`
@@ -5946,7 +6032,7 @@ MaxPoseidonHashes=252357
MaxPoseidonPaddings=135191
```
-##### 20.9.1.7. `State.Batch.Constraints.MaxMemAligns`
+##### 21.9.1.7. `State.Batch.Constraints.MaxMemAligns`
**Type:** : `integer`
@@ -5958,7 +6044,7 @@ MaxPoseidonPaddings=135191
MaxMemAligns=236585
```
-##### 20.9.1.8. `State.Batch.Constraints.MaxArithmetics`
+##### 21.9.1.8. `State.Batch.Constraints.MaxArithmetics`
**Type:** : `integer`
@@ -5970,7 +6056,7 @@ MaxMemAligns=236585
MaxArithmetics=236585
```
-##### 20.9.1.9. `State.Batch.Constraints.MaxBinaries`
+##### 21.9.1.9. `State.Batch.Constraints.MaxBinaries`
**Type:** : `integer`
@@ -5982,7 +6068,7 @@ MaxArithmetics=236585
MaxBinaries=473170
```
-##### 20.9.1.10. `State.Batch.Constraints.MaxSteps`
+##### 21.9.1.10. `State.Batch.Constraints.MaxSteps`
**Type:** : `integer`
@@ -5994,7 +6080,7 @@ MaxBinaries=473170
MaxSteps=7570538
```
-##### 20.9.1.11. `State.Batch.Constraints.MaxSHA256Hashes`
+##### 21.9.1.11. `State.Batch.Constraints.MaxSHA256Hashes`
**Type:** : `integer`
@@ -6006,7 +6092,7 @@ MaxSteps=7570538
MaxSHA256Hashes=1596
```
-### 20.10. `State.MaxLogsCount`
+### 21.10. `State.MaxLogsCount`
**Type:** : `integer`
@@ -6021,7 +6107,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`
@@ -6036,7 +6122,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`
@@ -6051,7 +6137,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`
@@ -6066,7 +6152,7 @@ from the DB every time it's needed
AvoidForkIDInMemory=false
```
-## 21. `[Apollo]`
+## 22. `[Apollo]`
**Type:** : `object`
**Description:** Apollo configuration
@@ -6078,7 +6164,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`
@@ -6090,7 +6176,7 @@ AvoidForkIDInMemory=false
Enable=false
```
-### 21.2. `Apollo.IP`
+### 22.2. `Apollo.IP`
**Type:** : `string`
@@ -6102,7 +6188,7 @@ Enable=false
IP=""
```
-### 21.3. `Apollo.AppID`
+### 22.3. `Apollo.AppID`
**Type:** : `string`
@@ -6114,7 +6200,7 @@ IP=""
AppID=""
```
-### 21.4. `Apollo.NamespaceName`
+### 22.4. `Apollo.NamespaceName`
**Type:** : `string`
@@ -6126,7 +6212,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 052ef87908..2c5e37120e 100644
--- a/docs/config-file/node-config-schema.json
+++ b/docs/config-file/node-config-schema.json
@@ -1821,6 +1821,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": {
diff --git a/go.mod b/go.mod
index 7859439cf6..ccafa3e025 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
@@ -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
@@ -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 325ccd703e..068d3473e8 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=
@@ -872,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=
@@ -889,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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@@ -1228,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=