From 04f71b37b0e8803cd0291050df76d372fd078a5a Mon Sep 17 00:00:00 2001 From: dndll Date: Thu, 4 Apr 2024 10:32:14 +0100 Subject: [PATCH 1/5] feat: validium NEAR DA via sidecar --- cmd/run.go | 10 ++ dataavailability/config.go | 1 + dataavailability/near/near.go | 214 +++++++++++++++++++++++++++ dataavailability/near/near_test.go | 103 +++++++++++++ etherman/smartcontracts/nearda/TODO | 0 go.mod | 10 +- go.sum | 23 +-- test/Makefile | 43 +++++- test/config/test.node.config.toml | 196 ++++++++++++------------- test/contracts/auto/NearDa.sol | 0 test/docker-compose.yml | 100 +++++++++++++ test/e2e/nearda_test.go | 220 ++++++++++++++++++++++++++++ test/images/near-sandbox.Dockerfile | 15 ++ test/operations/manager.go | 10 ++ 14 files changed, 832 insertions(+), 113 deletions(-) create mode 100644 dataavailability/near/near.go create mode 100644 dataavailability/near/near_test.go create mode 100644 etherman/smartcontracts/nearda/TODO create mode 100644 test/contracts/auto/NearDa.sol create mode 100644 test/e2e/nearda_test.go create mode 100644 test/images/near-sandbox.Dockerfile diff --git a/cmd/run.go b/cmd/run.go index 28b3f3631b..36f87a5df8 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -21,6 +21,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/config" "github.com/0xPolygonHermez/zkevm-node/dataavailability" "github.com/0xPolygonHermez/zkevm-node/dataavailability/datacommittee" + "github.com/0xPolygonHermez/zkevm-node/dataavailability/near" "github.com/0xPolygonHermez/zkevm-node/db" "github.com/0xPolygonHermez/zkevm-node/etherman" "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" @@ -352,6 +353,15 @@ func newDataAvailability(c config.Config, st *state.State, etherman *etherman.Cl if err != nil { return nil, err } + case string(dataavailability.NearProtocol): + /// TODO: Feels like there should be more configuration here, but the key store is eth specific. + /// Since this is a configurable sidecar, it's valid to set this when it's running, but the sequencer + /// might want to update this in the future. + host := "http://near-da-sidecar:5888" + daBackend, err = near.New(host, nil) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unexpected / unsupported DA protocol: %s", daProtocolName) } diff --git a/dataavailability/config.go b/dataavailability/config.go index 8163e7bcf4..07744896bf 100644 --- a/dataavailability/config.go +++ b/dataavailability/config.go @@ -6,4 +6,5 @@ type DABackendType string const ( // DataAvailabilityCommittee is the DAC protocol backend DataAvailabilityCommittee DABackendType = "DataAvailabilityCommittee" + NearProtocol DABackendType = "NearProtocol" ) diff --git a/dataavailability/near/near.go b/dataavailability/near/near.go new file mode 100644 index 0000000000..7ef8879682 --- /dev/null +++ b/dataavailability/near/near.go @@ -0,0 +1,214 @@ +// Package near provides a backend implementation for interacting with the NEAR DA. +// +// The NEAR DA backend allows posting and retrieving sequences of batches using the Near blockchain. +// It utilizes the NEAR DA Sidecar service for submitting and retrieving data blobs. +// +// Usage: +// +// backend, err := near.New("http://localhost:5888", &sidecar.ConfigureClientRequest{...}) +// if err != nil { +// // Handle error +// } +// +// // Post a sequence of batches +// batchesData := [][]byte{...} +// transactionID, err := backend.PostSequence(context.Background(), batchesData) +// if err != nil { +// // Handle error +// } +// +// // Get a sequence of batches +// batchHashes := []common.Hash{...} +// dataAvailabilityMessage := []byte{...} +// batchData, err := backend.GetSequence(context.Background(), batchHashes, dataAvailabilityMessage) +// if err != nil { +// // Handle error +// } +// +// The package also provides logging functionality using the "github.com/0xPolygonHermez/zkevm-node/log" package. +// +// Dependencies: +// +// github.com/near/rollup-data-availability/gopkg/sidecar +package near + +import ( + "bytes" + "context" + "encoding/gob" + "fmt" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/ethereum/go-ethereum/common" + "github.com/near/rollup-data-availability/gopkg/sidecar" +) + +// NearProtocolBackend represents a backend for interacting with NEAR DA. +type NearProtocolBackend struct { + host string + Client *sidecar.Client + Config *sidecar.ConfigureClientRequest +} + +// New creates a new instance of the NearProtocolBackend. +// It takes the host and configuration as parameters and returns a pointer to the backend. +func New(host string, config *sidecar.ConfigureClientRequest) (*NearProtocolBackend, error) { + if config == nil { + log.Debug("no near config, assuming sidecar setup outside of CDK") + } + return &NearProtocolBackend{ + host: host, + Config: config, + }, nil +} + +// Init loads the DAC to be cached when needed +func (d *NearProtocolBackend) Init() error { + client, err := sidecar.NewClient(d.host, d.Config) + if err != nil { + return fmt.Errorf("error connecting to NEAR: %s", err) + } + + d.Client = client + return nil +} + +func ParseConfig(accountId, secretKey, contractId, network string) sidecar.ConfigureClientRequest { + sidecarConfig := sidecar.ConfigureClientRequest{ + AccountID: accountId, + SecretKey: secretKey, + ContractID: contractId, + Network: sidecar.Network(network), + } + return sidecarConfig +} + +type Sequence struct { + Batches [][]byte +} + +func hexEncode(b [][]byte) string { + var str string = "0x" + for _, batch := range b { + str += fmt.Sprintf("%x", batch) + } + return str +} + +func hexEncode2(b []byte) string { + return fmt.Sprintf("0x%x", b) +} + +// PostSequence posts a sequence of batches to the Near blockchain. +// It takes a context and a slice of byte slices representing the batches data. +// It returns the transaction ID of the submitted sequence and any error encountered. +func (n *NearProtocolBackend) PostSequence(ctx context.Context, batches [][]byte) ([]byte, error) { + const maxBatchSize = 4 * 1024 * 1024 // Max batch size is 4MB + log.Debugf("submitting batches %s", hexEncode(batches)) + + // count the size of all batches, overflowing batches into multiple sequences + var sequences []Sequence + size := 0 + seqIndex := 0 + for _, batch := range batches { + if len(sequences) == 0 { + sequences = append(sequences, Sequence{}) + } + + size += len(batch) + if size > maxBatchSize { + size = len(batch) + seqIndex++ + var seq Sequence + seq.Batches = append(seq.Batches, batch) + sequences = append(sequences, seq) + } else { + sequences[seqIndex].Batches = append(sequences[seqIndex].Batches, batch) + } + log.Debugf("Sequence %s", hexEncode(sequences[seqIndex].Batches)) + } + log.Debugf("Submitting %d sequences", len(sequences)) + + var blobRefs []byte + for _, seq := range sequences { + var buf bytes.Buffer + enc := gob.NewEncoder(&buf) + err := enc.Encode(seq) + if err != nil { + return nil, fmt.Errorf("error encoding sequence for NEAR: %s", err) + } + + blob := sidecar.Blob{ + Data: buf.Bytes(), + } + log.Debugf("Blob: %s", hexEncode2(blob.Data)) + + blobRef, err := n.Client.SubmitBlob(blob) + log.Debugf("Blob ref: %s", hexEncode2(blobRef.Deref())) + if err != nil { + return nil, fmt.Errorf("error submitting data to NEAR: %s", err) + } + blobRefs = append(blobRefs, blobRef.Deref()...) + } + return blobRefs, nil +} + +// GetSequence retrieves a sequence of batches from the Near blockchain. +// It takes a context, a slice of batch hashes, and a data availability message. +// It returns a slice of byte slices representing the retrieved batches data and any error encountered. +func (n *NearProtocolBackend) GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) { + var batchData [][]byte + + log.Debugf("Retrieving %d batches from dataAvailabilityMessage %s", len(batchHashes), hexEncode2(dataAvailabilityMessage)) + + // FIXME: define the size of the ref in the library + // Chunk the da message into references + for _, ref := range chunks(dataAvailabilityMessage, 32) { + blobRef, err := sidecar.NewBlobRef(ref) + if err != nil { + return nil, fmt.Errorf("error reading blob: %s", err) + } + + log.Debugf("Retrieving %s from %s", hexEncode2(blobRef.Deref()), n.host) + blob, err := n.Client.GetBlob(*blobRef) + if err != nil { + return nil, fmt.Errorf("error getting data from NEAR: %s", err) + } + log.Debugf("Retrieved blob %s", hexEncode2(blob.Data)) + + buf := bytes.NewReader(blob.Data) + codec := gob.NewDecoder(buf) + + var seq Sequence + err = codec.Decode(&seq) + if err != nil { + return nil, fmt.Errorf("error encoding sequence for NEAR: %s", err) + } + log.Debugf("Decoded sequence %s", seq) + + batchData = append(batchData, seq.Batches...) + } + + log.Debugf("Retrieved batches %s", batchData) + return batchData, nil +} + +func chunks(message []byte, chunkSize int) [][]byte { + var chunks [][]byte + for { + if len(message) == 0 { + break + } + + // necessary check to avoid slicing beyond + // slice capacity + if len(message) < chunkSize { + chunkSize = len(message) + } + + chunks = append(chunks, message[0:chunkSize]) + message = message[chunkSize:] + } + + return chunks +} diff --git a/dataavailability/near/near_test.go b/dataavailability/near/near_test.go new file mode 100644 index 0000000000..bb1369bb7a --- /dev/null +++ b/dataavailability/near/near_test.go @@ -0,0 +1,103 @@ +// Tests + +package near + +import ( + "context" + "encoding/hex" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/near/rollup-data-availability/gopkg/sidecar" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPostSequence(t *testing.T) { + // Set up a mock server + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/health": + w.WriteHeader(http.StatusOK) + case "/blob": + var blob sidecar.Blob + err := json.NewDecoder(r.Body).Decode(&blob) + require.NoError(t, err) + transactionID := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + w.Write([]byte(transactionID)) + default: + w.WriteHeader(http.StatusNotFound) + } + })) + defer mockServer.Close() + + backend, err := New(mockServer.URL, nil) + backend.Init() + require.NoError(t, err) + defer backend.Client.Close() + + // Test PostSequence + batchesData := GenerateRandomBatchesData(3, 10) + transactionID, err := backend.PostSequence(context.Background(), batchesData) + require.NoError(t, err) + expectedTransactionID, err := hex.DecodeString("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") + require.NoError(t, err) + assert.Equal(t, expectedTransactionID, transactionID) +} + +func TestGetSequence(t *testing.T) { + tx := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + data := []byte("test_data") + // Set up a mock server + mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/health": + w.WriteHeader(http.StatusOK) + case "/blob": + transactionID := r.URL.Query().Get("transaction_id") + assert.Equal(t, tx, transactionID) + blob := sidecar.Blob{Data: data} + jsonData, err := blob.MarshalJSON() + require.NoError(t, err) + w.Write(jsonData) + default: + w.WriteHeader(http.StatusNotFound) + } + })) + defer mockServer.Close() + + backend, err := New(mockServer.URL, nil) + require.NoError(t, err) + defer backend.Client.Close() + + batchHashes := []common.Hash{ + common.HexToHash(tx), + } + dataAvailabilityMessage := []byte("data_availability_message") + batchData, err := backend.GetSequence(context.Background(), batchHashes, dataAvailabilityMessage) + require.NoError(t, err) + assert.Equal(t, 1, len(batchData)) + assert.Equal(t, data, batchData[0]) + +} + +// GenerateRandomBlobData generates random blob data of the specified size. +func GenerateRandomBlobData(size int) []byte { + data := make([]byte, size) + for i := 0; i < size; i++ { + data[i] = byte(i % 256) + } + return data +} + +// GenerateRandomBatchesData generates a slice of random batch data. +func GenerateRandomBatchesData(numBatches, batchSize int) [][]byte { + batchesData := make([][]byte, numBatches) + for i := 0; i < numBatches; i++ { + batchesData[i] = GenerateRandomBlobData(batchSize) + } + return batchesData +} diff --git a/etherman/smartcontracts/nearda/TODO b/etherman/smartcontracts/nearda/TODO new file mode 100644 index 0000000000..e69de29bb2 diff --git a/go.mod b/go.mod index e3b99a3a5f..6cdc21b461 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/0xPolygonHermez/zkevm-data-streamer v0.1.18 github.com/didip/tollbooth/v6 v6.1.2 github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 - github.com/ethereum/go-ethereum v1.13.11 + github.com/ethereum/go-ethereum v1.13.14 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.11.0 github.com/gobuffalo/packr/v2 v2.8.3 @@ -67,7 +67,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/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect + github.com/fjl/memsize v0.0.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect @@ -89,7 +89,7 @@ require ( github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect @@ -134,7 +134,7 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/cast v1.6.0 // indirect @@ -175,7 +175,7 @@ require ( github.com/0xPolygon/agglayer v0.0.1 github.com/0xPolygon/cdk-data-availability v0.0.5 github.com/fatih/color v1.16.0 - github.com/joho/godotenv v1.5.1 + github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b github.com/prometheus/client_golang v1.18.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa ) diff --git a/go.sum b/go.sum index aa214a13e8..29254c8c21 100644 --- a/go.sum +++ b/go.sum @@ -206,15 +206,15 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.11 h1:b51Dsm+rEg7anFRUMGB8hODXHvNfcRKzz9vcj8wSdUs= -github.com/ethereum/go-ethereum v1.13.11/go.mod h1:gFtlVORuUcT+UUIcJ/veCNjkuOSujCi338uSHJrYAew= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 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/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/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -410,8 +410,8 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hermeznetwork/tracerr v0.3.2 h1:QB3TlQxO/4XHyixsg+nRZPuoel/FFQlQ7oAoHDD5l1c= github.com/hermeznetwork/tracerr v0.3.2/go.mod h1:nsWC1+tc4qUEbUGRv4DcPJJTjLsedlPajlFmpJoohK4= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= @@ -492,8 +492,6 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -616,6 +614,12 @@ github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5Vgl github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/near/rollup-data-availability v0.2.4-0.20240404102641-f35aaec024e4 h1:zCzJ9W/I11t4QM57gLTjz5jBA1JZ6vHVPV8H2m3YbXs= +github.com/near/rollup-data-availability v0.2.4-0.20240404102641-f35aaec024e4/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240410124327-96cbd87c2f54 h1:zRqefJckepehLq9QdljwgzaR1sZKbCJIYjOLVh1GPfI= +github.com/near/rollup-data-availability v0.2.4-0.20240410124327-96cbd87c2f54/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b h1:Wz79ek5EUmJPC1KVUj7bSwYegkzZf9PEdM8Pj77z8NI= +github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -715,8 +719,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/test/Makefile b/test/Makefile index ebe52591e2..80e816adfe 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,4 +1,4 @@ -DOCKERCOMPOSE := docker-compose -f docker-compose.yml +DOCKERCOMPOSE := docker compose -f docker-compose.yml DOCKERCOMPOSEAPPSEQ := zkevm-sequencer DOCKERCOMPOSEAPPSEQV1TOV2 := zkevm-sequencer-v1tov2 DOCKERCOMPOSEAPPSEQSENDER := zkevm-sequence-sender @@ -27,6 +27,7 @@ DOCKERCOMPOSEZKPROVER := zkevm-prover DOCKERCOMPOSEPERMISSIONLESSDB := zkevm-permissionless-db DOCKERCOMPOSEPERMISSIONLESSNODE := zkevm-permissionless-node DOCKERCOMPOSEPERMISSIONLESSNODEDAC := zkevm-node-forced-DAC +DOCKERCOMPOSEPERMISSIONLESSNODENEAR := zkevm-node-forced-near DOCKERCOMPOSEPERMISSIONLESSZKPROVER := zkevm-permissionless-prover DOCKERCOMPOSENODEAPPROVE := zkevm-approve DOCKERCOMPOSENODEAPPROVEV1TOV2 := zkevm-approve-v1tov2 @@ -64,6 +65,7 @@ RUNZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEZKPROVER) RUNPERMISSIONLESSDB := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSDB) RUNPERMISSIONLESSNODE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODE) RUNPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC) +RUNPERMISSIONLESSNODENEAR := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSNODENEAR) RUNPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) RUNAPPROVE := $(DOCKERCOMPOSE) up -d $(DOCKERCOMPOSENODEAPPROVE) @@ -104,6 +106,7 @@ STOPZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEZKPROVER) && $(DOCKERCOMPOS STOPPERMISSIONLESSDB := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSDB) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSDB) STOPPERMISSIONLESSNODE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODE) STOPPERMISSIONLESSNODEDAC := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODEDAC) +STOPPERMISSIONLESSNODENEAR := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSNODENEAR) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSNODENEAR) STOPPERMISSIONLESSZKPROVER := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSEPERMISSIONLESSZKPROVER) STOPAPPROVE := $(DOCKERCOMPOSE) stop $(DOCKERCOMPOSENODEAPPROVE) && $(DOCKERCOMPOSE) rm -f $(DOCKERCOMPOSENODEAPPROVE) @@ -600,6 +603,29 @@ run: ## Runs a full node $(RUNAGGREGATOR) $(RUNJSONRPC) +.PHONY: run-near +run-near: + $(RUNSTATEDB) + $(RUNPERMISSIONLESSDB) + $(RUNPOOLDB) + $(RUNEVENTDB) + $(RUNL1NETWORK) + sleep 1 + $(RUNZKPROVER) + $(RUNPERMISSIONLESSZKPROVER) + $(RUNAPPROVE) + NEWCONTRACT=$$(cd /home/common/projects/data-availability/rollup-data-availability/eth && forge script Deploy --fork-url local --broadcast --legacy --json | jq -R 'fromjson?' | jq -r '.returns.da.value') $(DOCKERCOMPOSE) up -d near-set-dap + $(RUNPERMISSIONLESSNODENEAR) + # sleep 3 + $(RUNSYNC) + sleep 4 + $(RUNETHTXMANAGER) + $(RUNSEQUENCER) + $(RUNSEQUENCESENDER) + $(RUNL2GASPRICER) + $(RUNAGGREGATOR) + $(RUNJSONRPC) + .PHONY: run-v1tov2 run-v1tov2: ## Runs a full node using v1tov2 network $(RUNSTATEDB) @@ -787,6 +813,21 @@ stop-permissionless-dac: ## Stops the permissionless node that is forced to sync $(STOPPERMISSIONLESSZKPROVER) $(STOPPERMISSIONLESSDB) + +.PHONY: run-permissionless-near +## Runs a permissionless node that is forced to sync through NEAR +run-permissionless-near: run-node run-permissionless-dependencies + # TODO: NEAR Localnet + $(RUNPERMISSIONLESSNODENEAR) + +.PHONY: stop-permissionless-near +stop-permissionless-near: ## Stops the permissionless node that is forced to sync through NEAR + $(STOPPERMISSIONLESSNODENEAR) + $(STOPPERMISSIONLESSZKPROVER) + # TODO: near localnet + + + .PHONY: compile-scs compile-scs: ## Compiles smart contracts, configuration in test/contracts/index.yaml go run ./scripts/cmd... compilesc --input ./contracts diff --git a/test/config/test.node.config.toml b/test/config/test.node.config.toml index 50c2d5dd0b..8f8665a3b8 100644 --- a/test/config/test.node.config.toml +++ b/test/config/test.node.config.toml @@ -6,65 +6,65 @@ Level = "debug" Outputs = ["stderr"] [State] - [State.DB] - User = "state_user" - Password = "state_password" - Name = "state_db" - Host = "zkevm-state-db" - Port = "5432" - EnableLog = false - MaxConns = 200 - [State.Batch] - [State.Batch.Constraints] - MaxTxsPerBatch = 300 - MaxBatchBytesSize = 120000 - MaxCumulativeGasUsed = 1125899906842624 - MaxKeccakHashes = 2145 - MaxPoseidonHashes = 252357 - MaxPoseidonPaddings = 135191 - MaxMemAligns = 236585 - MaxArithmetics = 236585 - MaxBinaries = 473170 - MaxSteps = 7570538 - MaxSHA256Hashes = 1596 +[State.DB] +User = "state_user" +Password = "state_password" +Name = "state_db" +Host = "zkevm-state-db" +Port = "5432" +EnableLog = false +MaxConns = 200 +[State.Batch] +[State.Batch.Constraints] +MaxTxsPerBatch = 300 +MaxBatchBytesSize = 120000 +MaxCumulativeGasUsed = 1125899906842624 +MaxKeccakHashes = 2145 +MaxPoseidonHashes = 252357 +MaxPoseidonPaddings = 135191 +MaxMemAligns = 236585 +MaxArithmetics = 236585 +MaxBinaries = 473170 +MaxSteps = 7570538 +MaxSHA256Hashes = 1596 [Pool] FreeClaimGasLimit = 1500000 IntervalToRefreshBlockedAddresses = "5m" IntervalToRefreshGasPrices = "5s" -MaxTxBytesSize=100132 -MaxTxDataBytesSize=100000 +MaxTxBytesSize = 100132 +MaxTxDataBytesSize = 100000 DefaultMinGasPriceAllowed = 1000000000 MinAllowedGasPriceInterval = "5m" PollMinAllowedGasPriceInterval = "15s" AccountQueue = 64 GlobalQueue = 1024 - [Pool.EffectiveGasPrice] - Enabled = false - L1GasPriceFactor = 0.25 - ByteGasCost = 16 - ZeroByteGasCost = 4 - NetProfit = 1 - BreakEvenFactor = 1.1 - FinalDeviationPct = 10 - EthTransferGasPrice = 0 - EthTransferL1GasPriceFactor = 0 - L2GasPriceSuggesterFactor = 0.5 - [Pool.DB] - User = "pool_user" - Password = "pool_password" - Name = "pool_db" - Host = "zkevm-pool-db" - Port = "5432" - EnableLog = false - MaxConns = 200 +[Pool.EffectiveGasPrice] +Enabled = false +L1GasPriceFactor = 0.25 +ByteGasCost = 16 +ZeroByteGasCost = 4 +NetProfit = 1 +BreakEvenFactor = 1.1 +FinalDeviationPct = 10 +EthTransferGasPrice = 0 +EthTransferL1GasPriceFactor = 0 +L2GasPriceSuggesterFactor = 0.5 +[Pool.DB] +User = "pool_user" +Password = "pool_password" +Name = "pool_db" +Host = "zkevm-pool-db" +Port = "5432" +EnableLog = false +MaxConns = 200 [Etherman] URL = "http://zkevm-mock-l1-network:8545" ForkIDChunkSize = 20000 MultiGasProvider = false - [Etherscan] - ApiKey = "" +[Etherscan] +ApiKey = "" [RPC] Host = "0.0.0.0" @@ -74,28 +74,28 @@ WriteTimeout = "60s" MaxRequestsPerIPAndSecond = 5000 SequencerNodeURI = "" EnableL2SuggestedGasPricePolling = true - [RPC.WebSockets] - Enabled = true - Port = 8133 +[RPC.WebSockets] +Enabled = true +Port = 8133 [Synchronizer] SyncInterval = "1s" SyncChunkSize = 100 -TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc. +TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc. L1SynchronizationMode = "sequential" - [Synchronizer.L1ParallelSynchronization] - MaxClients = 10 - MaxPendingNoProcessedBlocks = 25 - RequestLastBlockPeriod = "5s" - RequestLastBlockTimeout = "5s" - RequestLastBlockMaxRetries = 3 - StatisticsPeriod = "5m" - TimeoutMainLoop = "5m" - RollupInfoRetriesSpacing= "5s" - FallbackToSequentialModeOnSynchronized = false - [Synchronizer.L1ParallelSynchronization.PerformanceWarning] - AceptableInacctivityTime = "5s" - ApplyAfterNumRollupReceived = 10 +[Synchronizer.L1ParallelSynchronization] +MaxClients = 10 +MaxPendingNoProcessedBlocks = 25 +RequestLastBlockPeriod = "5s" +RequestLastBlockTimeout = "5s" +RequestLastBlockMaxRetries = 3 +StatisticsPeriod = "5m" +TimeoutMainLoop = "5m" +RollupInfoRetriesSpacing = "5s" +FallbackToSequentialModeOnSynchronized = false +[Synchronizer.L1ParallelSynchronization.PerformanceWarning] +AceptableInacctivityTime = "5s" +ApplyAfterNumRollupReceived = 10 [Sequencer] DeletePoolTxsL1BlockConfirmations = 100 @@ -104,29 +104,29 @@ TxLifetimeCheckInterval = "10m" TxLifetimeMax = "3h" LoadPoolTxsCheckInterval = "500ms" StateConsistencyCheckInterval = "5s" - [Sequencer.Finalizer] - NewTxsWaitInterval = "100ms" - ForcedBatchesTimeout = "5s" - ForcedBatchesL1BlockConfirmations = 0 - ForcedBatchesCheckInterval = "10s" - L1InfoTreeL1BlockConfirmations = 0 - L1InfoTreeCheckInterval = "10s" - BatchMaxDeltaTimestamp = "20s" - L2BlockMaxDeltaTimestamp = "4s" - ResourceExhaustedMarginPct = 10 - HaltOnBatchNumber = 0 - SequentialBatchSanityCheck = false - SequentialProcessL2Block = true - [Sequencer.Finalizer.Metrics] - Interval = "60m" - EnableLog = true - [Sequencer.StreamServer] - Port = 6900 - Filename = "/datastreamer/datastream.bin" - Version = 1 - ChainID = 1337 - Enabled = true - +[Sequencer.Finalizer] +NewTxsWaitInterval = "100ms" +ForcedBatchesTimeout = "5s" +ForcedBatchesL1BlockConfirmations = 0 +ForcedBatchesCheckInterval = "10s" +L1InfoTreeL1BlockConfirmations = 0 +L1InfoTreeCheckInterval = "10s" +BatchMaxDeltaTimestamp = "20s" +L2BlockMaxDeltaTimestamp = "4s" +ResourceExhaustedMarginPct = 10 +HaltOnBatchNumber = 0 +SequentialBatchSanityCheck = false +SequentialProcessL2Block = true +[Sequencer.Finalizer.Metrics] +Interval = "60m" +EnableLog = true +[Sequencer.StreamServer] +Port = 6900 +Filename = "/datastreamer/datastream.bin" +Version = 1 +ChainID = 1337 +Enabled = true + [SequenceSender] WaitPeriodSendSequence = "15s" @@ -134,9 +134,9 @@ LastBatchVirtualizationTimeMaxWaitPeriod = "10s" L1BlockTimestampMargin = "5s" MaxTxSizeForL1 = 131072 L2Coinbase = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266" -PrivateKey = {Path = "/pk/sequencer.keystore", Password = "testonly"} - [SequenceSender.StreamClient] - Server = "zkevm-sequencer:6900" +PrivateKey = { Path = "/pk/sequencer.keystore", Password = "testonly" } +[SequenceSender.StreamClient] +Server = "zkevm-sequencer:6900" [Aggregator] Host = "0.0.0.0" @@ -159,8 +159,8 @@ SequencerPrivateKey = {} [EthTxManager] ForcedGas = 0 PrivateKeys = [ - {Path = "/pk/sequencer.keystore", Password = "testonly"}, - {Path = "/pk/aggregator.keystore", Password = "testonly"} + { Path = "/pk/sequencer.keystore", Password = "testonly" }, + { Path = "/pk/aggregator.keystore", Password = "testonly" }, ] [L2GasPriceSuggester] @@ -171,7 +171,7 @@ DefaultGasPriceWei = 1000000000 MaxGasPriceWei = 0 [MTClient] -URI = "zkevm-prover:50061" +URI = "zkevm-prover:50061" [Executor] URI = "zkevm-prover:50071" @@ -186,14 +186,14 @@ ProfilingPort = 6060 ProfilingEnabled = true [EventLog] - [EventLog.DB] - User = "event_user" - Password = "event_password" - Name = "event_db" - Host = "zkevm-event-db" - Port = "5432" - EnableLog = false - MaxConns = 200 +[EventLog.DB] +User = "event_user" +Password = "event_password" +Name = "event_db" +Host = "zkevm-event-db" +Port = "5432" +EnableLog = false +MaxConns = 200 [HashDB] User = "prover_user" diff --git a/test/contracts/auto/NearDa.sol b/test/contracts/auto/NearDa.sol new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 80e25c9276..8600377b9f 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -688,3 +688,103 @@ services: - "postgres" - "-N" - "500" + + # TODO: actually force this to sync, how? + zkevm-node-forced-near: + container_name: zkevm-node-forced-near + image: zkevm-node + depends_on: + - near-da-sidecar + ports: + - 8125:8125 + environment: + - ZKEVM_NODE_ISTRUSTEDSEQUENCER=false + - ZKEVM_NODE_STATE_DB_USER=test_user + - ZKEVM_NODE_STATE_DB_PASSWORD=test_password + - ZKEVM_NODE_STATE_DB_NAME=state_db + - ZKEVM_NODE_STATE_DB_HOST=zkevm-permissionless-db + - ZKEVM_NODE_POOL_DB_USER=test_user + - ZKEVM_NODE_POOL_DB_PASSWORD=test_password + - ZKEVM_NODE_POOL_DB_NAME=pool_db + - ZKEVM_NODE_POOL_DB_HOST=zkevm-permissionless-db + - ZKEVM_NODE_RPC_PORT=8125 + - ZKEVM_NODE_RPC_SEQUENCERNODEURI=http://zkevm-json-rpc:8123 + - ZKEVM_NODE_SYNCHRONIZER_TRUSTEDSEQUENCERURL=http://you-cant-touch-this:8123 # This disallows any syncing from the trusted seq + - ZKEVM_NODE_MTCLIENT_URI=zkevm-permissionless-prover:50061 + - ZKEVM_NODE_EXECUTOR_URI=zkevm-permissionless-prover:50071 + volumes: + - ./config/test.node.config.toml:/app/config.toml + - ./config/test.genesis.config.json:/app/genesis.json + command: + - "/bin/sh" + - "-c" + - "/app/zkevm-node run --network custom --custom-network-file /app/genesis.json --cfg /app/config.toml --components \"rpc,synchronizer\"" + + near-da-sidecar: + container_name: near-da-sidecar + image: ghcr.io/near/rollup-data-availability/http-api:dev + restart: unless-stopped + depends_on: + - near-localnet + environment: + - RUST_LOG=debug + volumes: + - ./config/near-http-sidecar.json:/app/config.json + command: + - -c + - /app/config.json + # healthcheck: + # test: ["CMD-HTTP", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + # interval: 10s + # timeout: 5s + # retries: 5 + ports: + - 6565:5888 + + near-localnet-print-key: + container_name: near-localnet + build: + context: ./images + dockerfile: near-sandbox.Dockerfile + volumes: + - near-sandbox-data:/root/.near + ports: + - 3030:3030 + entrypoint: + - cat + - /root/.near/validator_key.json + + near-localnet: + container_name: near-localnet + build: + context: ./images + dockerfile: near-sandbox.Dockerfile + volumes: + - near-sandbox-data:/root/.near + ports: + - 3030:3030 + + near-set-dap: + container_name: near-set-dap + image: zkevm-node + environment: + - ZKEVM_NODE_STATE_DB_HOST=zkevm-state-db + - NEWCONTRACT=${NEWCONTRACT:-0x0000000000000000000000000000000000000000} + volumes: + - ./sequencer.keystore:/pk/sequencer.keystore + - ./config/test.node.config.toml:/app/config.toml + - ./config/test.genesis.config.json:/app/genesis.json + command: + - "/bin/sh" + - "-c" + - "/app/zkevm-node set-dap --da-addr $NEWCONTRACT --network custom --custom-network-file /app/genesis.json --key-store-path /pk/sequencer.keystore --pw testonly --cfg /app/config.toml" + +volumes: + near-sandbox-data: + + + + + + + diff --git a/test/e2e/nearda_test.go b/test/e2e/nearda_test.go new file mode 100644 index 0000000000..4dd58904c5 --- /dev/null +++ b/test/e2e/nearda_test.go @@ -0,0 +1,220 @@ +package e2e + +import ( + "context" + "crypto/ecdsa" + "encoding/json" + "fmt" + "math/big" + "os" + "os/exec" + "sort" + "strconv" + "strings" + "testing" + "time" + + cTypes "github.com/0xPolygon/cdk-data-availability/config/types" + "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevm" + "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/nearda" + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/test/operations" + "github.com/ethereum/go-ethereum" + eTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/near/rollup-data-availability/gopkg/sidecar" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/keystore" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + NearDaContract = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" // TODO: set a contract to be deployed at genesis + NearSK = "ed25519:4dagBsEqCv3Ao5wa4KKFa57xNAH4wuBjh9wdTNYeCqDSeA9zE7fCnHSvWpU8t68jUpcCGqgfYwcH68suPaqmdcgm" + NearAccount = "test.net" +) + +func TestNearDa(t *testing.T) { + const ( + ksFile = "/tmp/pkey" + ksPass = "pass" + cfgFile = "/tmp/neardanodeconfigfile.json" + nearDaSidecarImage = "ghcr.io/near/rollup-data-availability/http-api:dev" + ) + + // Setup + var err error + if testing.Short() { + t.Skip() + } + ctx := context.Background() + defer func() { + require.NoError(t, operations.Teardown()) + }() + err = operations.Teardown() + require.NoError(t, err) + opsCfg := operations.GetDefaultOperationsConfig() + opsCfg.State.MaxCumulativeGasUsed = 80000000000 + opsman, err := operations.NewManager(ctx, opsCfg) + require.NoError(t, err) + defer func() { + require.NoError(t, opsman.StopDACDB()) + }() + err = opsman.Setup() + require.NoError(t, err) + require.NoError(t, opsman.StartDACDB()) + time.Sleep(5 * time.Second) + + authL2, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID) + require.NoError(t, err) + + authL1, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID) + require.NoError(t, err) + + clientL2, err := ethclient.Dial(operations.DefaultL2NetworkURL) + require.NoError(t, err) + + clientL1, err := ethclient.Dial(operations.DefaultL1NetworkURL) + require.NoError(t, err) + + zkEVM, err := etrogpolygonzkevm.NewEtrogpolygonzkevm( + common.HexToAddress(operations.DefaultL1ZkEVMSmartContract), + clientL1, + ) + require.NoError(t, err) + + currentDAPAddr, err := zkEVM.DataAvailabilityProtocol(&bind.CallOpts{Pending: false}) + require.NoError(t, err) + require.Equal(t, common.HexToAddress(operations.DefaultL1DataCommitteeContract), currentDAPAddr) + + _, err = zkEVM.SetDataAvailabilityProtocol(authL1, "0xNearProtocol") + require.NoError(t, err) + + // TODO: SetDataAvailabilityProtocol on etrog + + // TODO: Ensure DA sidecar is setup + // TODO: Ensure contract is setup too + + // TODO: create dummy near accounts, get them funded by workspace node + + defer func() { + // Remove tmp files + assert.NoError(t, + exec.Command("rm", cfgFile).Run(), + ) + assert.NoError(t, + exec.Command("rmdir", ksFile+"_").Run(), + ) + assert.NoError(t, + exec.Command("rm", ksFile).Run(), + ) + // TODO: stop near localnet + assert.NoError(t, exec.Command( + "docker", "kill", "near-da-sidecar", + ).Run()) + assert.NoError(t, exec.Command( + "docker", "rm", "near-da-sidecar", + ).Run()) + // Stop permissionless node + require.NoError(t, opsman.StopPermissionlessNodeForcedToSyncThroughNear()) + }() + // Start permissionless node + require.NoError(t, opsman.StartPermissionlessNodeForcedToSyncThroughNear()) + + // Write config file + nearDaConfig := sidecar.ConfigureClientRequest{ + AccountID: NearAccount, + SecretKey: NearSK, + Network: "near-localnet:5888", // TODO: needs the arbitrary networks + Namespace: nil, + } + + file, err := json.MarshalIndent(nearDaConfig, "", " ") + require.NoError(t, err) + err = os.WriteFile(cfgFile, file, 0644) + require.NoError(t, err) + + // Run DAC node + cmd := exec.Command( + "docker", "run", "-d", + "--name", "near-da-sidecar", + "-v", cfgFile+":/var/config.json", + "--network", "zkevm", + nearDaSidecarImage, + "-c", "/var/config.json", + ) + out, err := cmd.CombinedOutput() + require.NoError(t, err, string(out)) + log.Infof("NEAR DA sidecar started") + time.Sleep(time.Second * 5) + + // Send txs + nTxs := 10 + amount := big.NewInt(10000) + toAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") + _, err = clientL2.BalanceAt(ctx, authL2.From, nil) + require.NoError(t, err) + _, err = clientL2.PendingNonceAt(ctx, authL2.From) + require.NoError(t, err) + + gasLimit, err := clientL2.EstimateGas(ctx, ethereum.CallMsg{From: authL2.From, To: &toAddress, Value: amount}) + require.NoError(t, err) + + gasPrice, err := clientL2.SuggestGasPrice(ctx) + require.NoError(t, err) + + nonce, err := clientL2.PendingNonceAt(ctx, authL2.From) + require.NoError(t, err) + + txs := make([]*eTypes.Transaction, 0, nTxs) + for i := 0; i < nTxs; i++ { + tx := eTypes.NewTransaction(nonce+uint64(i), toAddress, amount, gasLimit, gasPrice, nil) + log.Infof("generating tx %d / %d: %s", i+1, nTxs, tx.Hash().Hex()) + txs = append(txs, tx) + } + + // Wait for verification + _, err = operations.ApplyL2Txs(ctx, txs, authL2, clientL2, operations.VerifiedConfirmationLevel) + require.NoError(t, err) + + // Assert that he permissionless node is fully synced (through the DAC) + time.Sleep(30 * time.Second) // Give some time for the permissionless node to get synced + clientL2Permissionless, err := ethclient.Dial(operations.PermissionlessL2NetworkURL) + require.NoError(t, err) + expectedBlock, err := clientL2.BlockByNumber(ctx, nil) + require.NoError(t, err) + actualBlock, err := clientL2Permissionless.BlockByNumber(ctx, nil) + require.NoError(t, err) + // je, err := expectedBlock.Header().MarshalJSON() + // require.NoError(t, err) + // log.Info(string(je)) + // ja, err := actualBlock.Header().MarshalJSON() + // require.NoError(t, err) + // log.Info(string(ja)) + // require.Equal(t, string(je), string(ja)) + require.Equal(t, expectedBlock.Root().Hex(), actualBlock.Root().Hex()) +} + +func createKeyStore(pk *ecdsa.PrivateKey, outputDir, password string) error { + ks := keystore.NewKeyStore(outputDir+"_", keystore.StandardScryptN, keystore.StandardScryptP) + _, err := ks.ImportECDSA(pk, password) + if err != nil { + return err + } + fileNameB, err := exec.Command("ls", outputDir+"_/").CombinedOutput() + fileName := strings.TrimSuffix(string(fileNameB), "\n") + if err != nil { + fmt.Println(fileName) + return err + } + out, err := exec.Command("mv", outputDir+"_/"+fileName, outputDir).CombinedOutput() + if err != nil { + fmt.Println(string(out)) + return err + } + return nil +} diff --git a/test/images/near-sandbox.Dockerfile b/test/images/near-sandbox.Dockerfile new file mode 100644 index 0000000000..2531f11979 --- /dev/null +++ b/test/images/near-sandbox.Dockerfile @@ -0,0 +1,15 @@ +FROM debian:bookworm as builder +WORKDIR /usr/src/app +RUN apt-get update && apt-get install --assume-yes curl +RUN curl -LJO https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore/Linux-x86_64/master/d08187094a82b3bfab3b8b0fa076e71068f39cb7/near-sandbox.tar.gz +RUN tar -xf near-sandbox.tar.gz + +FROM debian:bookworm-slim as runtime +WORKDIR /usr/local/bin +COPY --from=builder /usr/src/app/Linux-x86_64/near-sandbox /usr/local/bin/near-sandbox +RUN apt-get update && apt-get install --assume-yes curl +RUN near-sandbox --home /root/.near init + +RUN cat /root/.near/validator_key.json + +ENTRYPOINT [ "near-sandbox", "--home", "/root/.near", "run" ] diff --git a/test/operations/manager.go b/test/operations/manager.go index 818587ef35..de8571d33a 100644 --- a/test/operations/manager.go +++ b/test/operations/manager.go @@ -673,6 +673,7 @@ func (m *Manager) StopDACDB() error { return StopComponent("dac-db") } +// TODO: start a node that is forced to sync with near-da // StartPermissionlessNodeForcedToSYncThroughDAC starts a permissionless node that is froced to sync through the DAC func (m *Manager) StartPermissionlessNodeForcedToSYncThroughDAC() error { return StartComponent("permissionless-dac", func() (bool, error) { return true, nil }) @@ -682,3 +683,12 @@ func (m *Manager) StartPermissionlessNodeForcedToSYncThroughDAC() error { func (m *Manager) StopPermissionlessNodeForcedToSYncThroughDAC() error { return StopComponent("permissionless-dac") } + +func (m *Manager) StartPermissionlessNodeForcedToSyncThroughNear() error { + return StartComponent("permissionless-near", func() (bool, error) { return true, nil }) +} + +// StopPermissionlessNodeForcedToSYncThroughDAC stops the permissionless node that is froced to sync through the DAC +func (m *Manager) StopPermissionlessNodeForcedToSyncThroughNear() error { + return StopComponent("permissionless-near") +} From f08b47fff04e240820ebbc1a828d3ad02282c0f9 Mon Sep 17 00:00:00 2001 From: dndll Date: Tue, 16 Apr 2024 17:26:02 +0100 Subject: [PATCH 2/5] test: add support for running localnet tests --- test/Makefile | 2 + test/config/near-http-sidecar.json | 7 ++ test/config/near/genesis.json | 175 ++++++++++++++++++++++++++++ test/config/near/http-sidecar.json | 7 ++ test/config/near/node_key.json | 5 + test/config/near/validator_key.json | 5 + test/docker-compose.yml | 14 +-- test/images/near-sandbox.Dockerfile | 6 +- 8 files changed, 212 insertions(+), 9 deletions(-) create mode 100644 test/config/near-http-sidecar.json create mode 100644 test/config/near/genesis.json create mode 100644 test/config/near/http-sidecar.json create mode 100644 test/config/near/node_key.json create mode 100644 test/config/near/validator_key.json diff --git a/test/Makefile b/test/Makefile index 80e816adfe..1aa0ac6253 100644 --- a/test/Makefile +++ b/test/Makefile @@ -610,7 +610,9 @@ run-near: $(RUNPOOLDB) $(RUNEVENTDB) $(RUNL1NETWORK) + $(DOCKERCOMPOSE) up -d --build near-localnet sleep 1 + $(DOCKERCOMPOSE) up near-localnet-print-key $(RUNZKPROVER) $(RUNPERMISSIONLESSZKPROVER) $(RUNAPPROVE) diff --git a/test/config/near-http-sidecar.json b/test/config/near-http-sidecar.json new file mode 100644 index 0000000000..0ccbf61750 --- /dev/null +++ b/test/config/near-http-sidecar.json @@ -0,0 +1,7 @@ +{ + "account_id": "test.near", + "secret_key": "HTTP_API_TEST_SECRET_KEY", + "contract_id": "test.near", + "network": "http://near-localnet:3030", + "namespace": null +} diff --git a/test/config/near/genesis.json b/test/config/near/genesis.json new file mode 100644 index 0000000000..f1af13d141 --- /dev/null +++ b/test/config/near/genesis.json @@ -0,0 +1,175 @@ +{ + "protocol_version": 65, + "genesis_time": "2024-04-16T16:12:12.528118425Z", + "chain_id": "test-chain-2ib9j", + "genesis_height": 57200, + "num_block_producer_seats": 50, + "num_block_producer_seats_per_shard": [ + 50 + ], + "avg_hidden_validator_seats_per_shard": [ + 0 + ], + "dynamic_resharding": false, + "protocol_upgrade_stake_threshold": [ + 4, + 5 + ], + "epoch_length": 500, + "gas_limit": 1000000000000000, + "min_gas_price": "100000000", + "max_gas_price": "10000000000000000000000", + "block_producer_kickout_threshold": 90, + "chunk_producer_kickout_threshold": 90, + "online_min_threshold": [ + 9, + 10 + ], + "online_max_threshold": [ + 99, + 100 + ], + "gas_price_adjustment_rate": [ + 1, + 100 + ], + "validators": [ + { + "account_id": "test.near", + "public_key": "ed25519:5qJULsTNSQT1R5FAacVKNk3R3sgh8rfpwnJcqLnC5u1F", + "amount": "52068636728713882428230045954576" + } + ], + "transaction_validity_period": 100, + "protocol_reward_rate": [ + 1, + 10 + ], + "max_inflation_rate": [ + 1, + 20 + ], + "total_supply": "2052069523631687992558491787878153", + "num_blocks_per_year": 31536000, + "protocol_treasury_account": "test.near", + "fishermen_threshold": "10000000000000000000000000", + "minimum_stake_divisor": 10, + "shard_layout": { + "V0": { + "num_shards": 1, + "version": 0 + } + }, + "num_chunk_only_producer_seats": 300, + "minimum_validators_per_shard": 1, + "max_kickout_stake_perc": 100, + "minimum_stake_ratio": [ + 1, + 6250 + ], + "use_production_config": false, + "records": [ + { + "Account": { + "account_id": "da.test.near", + "account": { + "amount": "15098813923077058800000000", + "locked": "0", + "code_hash": "DhvFqpsCzChWkrYeUrZJ6gWPjBU6Tth8i3BHsT8f7Vc8", + "storage_usage": 8544, + "version": "V1" + } + } + }, + { + "Account": { + "account_id": "near", + "account": { + "amount": "1000000000000000000000000000000000", + "locked": "0", + "code_hash": "11111111111111111111111111111111", + "storage_usage": 182, + "version": "V1" + } + } + }, + { + "Account": { + "account_id": "test.near", + "account": { + "amount": "1000000871804160187053202941923577", + "locked": "52068636728713882428230045954576", + "code_hash": "DhvFqpsCzChWkrYeUrZJ6gWPjBU6Tth8i3BHsT8f7Vc8", + "storage_usage": 8718, + "version": "V1" + } + } + }, + { + "Contract": { + "account_id": "da.test.near", + "code": "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AkACQCABDQBBASEDDAELIAFBf0wNASACQQhqIAEQpYCAgAAgAigCCCIDRQ0CCyAAIAE2AgQgACADNgIAIAJBEGokgICAgAAPCxCbgICAAAALAAAL/QEBAX8jgICAgABBEGsiBCSAgICAAAJAAkACQCABRQ0AIAJBf0wNAQJAAkAgAygCBEUNAAJAIANBCGooAgAiAQ0AIARBCGogAhClgICAACAEKAIMIQMgBCgCCCEBDAILIAMoAgAgASACEKaAgIAAIQEgAiEDDAELIAQgAhClgICAACAEKAIEIQMgBCgCACEBCwJAIAFFDQAgACABNgIEIABBCGogAzYCAEEAIQEMAwtBASEBIABBATYCBCAAQQhqIAI2AgAMAgsgAEEANgIEIABBCGogAjYCAEEBIQEMAQsgAEEANgIEQQEhAQsgACABNgIAIARBEGokgICAgAALTgEBfyOAgICAAEEgayIAJICAgIAAIABBFGpCADcCACAAQQE2AgwgAEHkgcCAADYCCCAAQYiGwIAANgIQIABBCGpB7IHAgAAQpICAgAAAC1QBAX8jgICAgABBIGsiAySAgICAACADQQxqQgA3AgAgA0EBNgIEIANBiIbAgAA2AgggAyABNgIcIAMgADYCGCADIANBGGo2AgAgAyACEKSAgIAAAAtWAQJ/I4CAgIAAQRBrIgAkgICAgAAQjYCAgAAgAEEEakGdgMCAABCRgICAACAAKAIEIgEgACgCDBCYgICAACABIAAoAggQi4CAgAAgAEEQaiSAgICAAAtWAQJ/I4CAgIAAQRBrIgAkgICAgAAQjYCAgAAgAEEEakHugMCAABCRgICAACAAKAIEIgEgACgCDBCYgICAACABIAAoAggQi4CAgAAgAEEQaiSAgICAAAuaAgEGfyOAgICAAEEgayIAJICAgIAAEI2AgIAAEKCAgIAAIABBCGoQlYCAgAAgACgCCCIBIAAoAhAQkICAgAAgAEEUahCXgICAAAJAIAAoAhQiAkUNACAAKAIYIQMCQAJAAkAgAiAAKAIcIgRB74DAgABBAhCSgICAAA0AAkAgBEEPSQ0AIAJB8YDAgABBDxC9gICAAA0AIARBb2oiBEF9Sw0AIAJBD2oiBSAEai8AAEGi+gFGDQILQdSAwIAAQRkQj4CAgAAAC0HugMCAABChgICAAAwBC0HugMCAACAFIAQQlICAgAALIAIgAxCMgICAACABIAAoAgwQjICAgAAgAEEgaiSAgICAAA8LQdSAwIAAQRkQj4CAgAAAC10BAX8jgICAgABBEGsiACSAgICAACAAQgA3AwggAEIANwMAIACtEIqAgIAAAkAgACkDAEIBhSAAKQMIhEIAUg0AIABBEGokgICAgAAPC0HYhcCAAEEwEI+AgIAAAAsZAAJAQgEgAK1CfhCIgICAAEICVA0AAAALC80BAQV/I4CAgIAAQSBrIgAkgICAgAAQjYCAgAAQoICAgAAgAEEIahCVgICAACAAQRRqQe6AwIAAEJGAgIAAAkACQCAAKAIUIgFFDQAgACgCGCECIAAoAggiAyAAKAIQIAEgACgCHCIEEJKAgIAADQFBgIHAgABBIhCPgICAAAALQaKBwIAAQRIQj4CAgAAAC0HugMCAABChgICAAEGdgMCAACABIAQQlICAgAAgASACEIyAgIAAIAMgACgCDBCMgICAACAAQSBqJICAgIAAC24BAn8jgICAgABBEGsiACSAgICAABCNgICAABCggICAACAAQQRqEJWAgIAAIAAoAgQiASAAKAIMEJCAgIAAQZ2AwIAAEKGAgIAAQe6AwIAAEKGAgIAAIAEgACgCCBCMgICAACAAQRBqJICAgIAAC0wBAX8jgICAgABBIGsiAiSAgICAACACQQE7ARwgAiABNgIYIAIgADYCFCACQfyBwIAANgIQIAJBiIbAgAA2AgwgAkEMahCpgICAAAALKAEBf0EALQCoi8CAABpBASABEKeAgIAAIQIgACABNgIEIAAgAjYCAAs3AQF/AkBBASACEKeAgIAAIgNFDQAgAyAAIAEgAiABIAJJGxC8gICAABogACABEKiAgIAACyADC5wBAQJ/I4CAgIAAQRBrIgIkgICAgAAgARCzgICAACEBIAJBACgCpIvAgAA2AgwCQCABIAAgAkEMahC3gICAACIDDQAgAiABIAAQtICAgABBACEDIAIoAgANACACKAIEIgMgAigCDDYCCCACIAM2AgwgASAAIAJBDGoQt4CAgAAhAwtBACACKAIMNgKki8CAACACQRBqJICAgIAAIAML6QEBA38gARCzgICAABogAEF4aiIBIAEoAgBBfnE2AgBBACgCpIvAgAAhAiABELiAgIAAGiAAQQA2AgACQAJAAkAgAUEE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AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwMDAwMDAwMDAwMDAwMDAwQEBAQEAAAAAAAAAAAAAAAAAAAAYXR0ZW1wdCB0byBhZGQgd2l0aCBvdmVyZmxvdy9ydXN0Yy84MmUxNjA4ZGZhNmUwYjU1NjkyMzI1NTllM2QzODVmZWE1YTkzMTEyL2xpYnJhcnkvY29yZS9zcmMvaXRlci90cmFpdHMvYWNjdW0ucnMAAAAsAhAAVQAAAJUAAAABAAAAUmVnaXN0ZXIgd2FzIGV4cGVjdGVkIHRvIGhhdmUgZGF0YSBiZWNhdXNlIHdlIGp1c3Qgd3JvdGUgaXQgaW50byBpdC5SZXF1aXJlcyBhdHRhY2hlZCBkZXBvc2l0IG9mIGV4YWN0bHkgMSB5b2N0b05FQVJjYWxsZWQgYE9wdGlvbjo6dW53cmFwKClgIG9uIGEgYE5vbmVgIHZhbHVlbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5ycwAzAxAAHAAAAIQCAAAeAAAAL2hvbWUvY29tbW9uLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvbWVtb3J5X3VuaXRzLTAuNC4wL3NyYy9saWIucnMAYAMQAF8AAACPAAAABgAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3dgAxAAXwAAAI8AAAAFAAAAAAAAAGF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvdwAAAGADEABfAAAAswAAAAUAAAAAAAAAAAAAAAAAAABhdHRlbXB0IHRvIG11bHRpcGx5IHdpdGggb3ZlcmZsb3cAAABgAxAAXwAAAK4AAAAFAAAAYAMQAF8AAACmAAAAAQAAAC9ob21lL2NvbW1vbi8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL3dlZV9hbGxvYy0wLjQuNS9zcmMvbGliLnJzhAQQAFwAAACeAQAADwAAAIQEEABcAAAAGQIAACEAAACEBBAAXAAAABwCAAAMAAAAhAQQAFwAAAAdAgAAIwAAAIQEEABcAAAAIQIAABsAAAAvaG9tZS9jb21tb24vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi93ZWVfYWxsb2MtMC40LjUvc3JjL2ltcF93YXNtMzIucnMAMAUQAGMAAAAMAAAAEwAAAA==" + } + }, + { + "Contract": { + "account_id": "test.near", + "code": "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AkACQCABDQBBASEDDAELIAFBf0wNASACQQhqIAEQpYCAgAAgAigCCCIDRQ0CCyAAIAE2AgQgACADNgIAIAJBEGokgICAgAAPCxCbgICAAAALAAAL/QEBAX8jgICAgABBEGsiBCSAgICAAAJAAkACQCABRQ0AIAJBf0wNAQJAAkAgAygCBEUNAAJAIANBCGooAgAiAQ0AIARBCGogAhClgICAACAEKAIMIQMgBCgCCCEBDAILIAMoAgAgASACEKaAgIAAIQEgAiEDDAELIAQgAhClgICAACAEKAIEIQMgBCgCACEBCwJAIAFFDQAgACABNgIEIABBCGogAzYCAEEAIQEMAwtBASEBIABBATYCBCAAQQhqIAI2AgAMAgsgAEEANgIEIABBCGogAjYCAEEBIQEMAQsgAEEANgIEQQEhAQsgACABNgIAIARBEGokgICAgAALTgEBfyOAgICAAEEgayIAJICAgIAAIABBFGpCADcCACAAQQE2AgwgAEHkgcCAADYCCCAAQYiGwIAANgIQIABBCGpB7IHAgAAQpICAgAAAC1QBAX8jgICAgABBIGsiAySAgICAACADQQxqQgA3AgAgA0EBNgIEIANBiIbAgAA2AgggAyABNgIcIAMgADYCGCADIANBGGo2AgAgAyACEKSAgIAAAAtWAQJ/I4CAgIAAQRBrIgAkgICAgAAQjYCAgAAgAEEEakGdgMCAABCRgICAACAAKAIEIgEgACgCDBCYgICAACABIAAoAggQi4CAgAAgAEEQaiSAgICAAAtWAQJ/I4CAgIAAQRBrIgAkgICAgAAQjYCAgAAgAEEEakHugMCAABCRgICAACAAKAIEIgEgACgCDBCYgICAACABIAAoAggQi4CAgAAgAEEQaiSAgICAAAuaAgEGfyOAgICAAEEgayIAJICAgIAAEI2AgIAAEKCAgIAAIABBCGoQlYCAgAAgACgCCCIBIAAoAhAQkICAgAAgAEEUahCXgICAAAJAIAAoAhQiAkUNACAAKAIYIQMCQAJAAkAgAiAAKAIcIgRB74DAgABBAhCSgICAAA0AAkAgBEEPSQ0AIAJB8YDAgABBDxC9gICAAA0AIARBb2oiBEF9Sw0AIAJBD2oiBSAEai8AAEGi+gFGDQILQdSAwIAAQRkQj4CAgAAAC0HugMCAABChgICAAAwBC0HugMCAACAFIAQQlICAgAALIAIgAxCMgICAACABIAAoAgwQjICAgAAgAEEgaiSAgICAAA8LQdSAwIAAQRkQj4CAgAAAC10BAX8jgICAgABBEGsiACSAgICAACAAQgA3AwggAEIANwMAIACtEIqAgIAAAkAgACkDAEIBhSAAKQMIhEIAUg0AIABBEGokgICAgAAPC0HYhcCAAEEwEI+AgIAAAAsZAAJAQgEgAK1CfhCIgICAAEICVA0AAAALC80BAQV/I4CAgIAAQSBrIgAkgICAgAAQjYCAgAAQoICAgAAgAEEIahCVgICAACAAQRRqQe6AwIAAEJGAgIAAAkACQCAAKAIUIgFFDQAgACgCGCECIAAoAggiAyAAKAIQIAEgACgCHCIEEJKAgIAADQFBgIHAgABBIhCPgICAAAALQaKBwIAAQRIQj4CAgAAAC0HugMCAABChgICAAEGdgMCAACABIAQQlICAgAAgASACEIyAgIAAIAMgACgCDBCMgICAACAAQSBqJICAgIAAC24BAn8jgICAgABBEGsiACSAgICAABCNgICAABCggICAACAAQQRqEJWAgIAAIAAoAgQiASAAKAIMEJCAgIAAQZ2AwIAAEKGAgIAAQe6AwIAAEKGAgIAAIAEgACgCCBCMgICAACAAQRBqJICAgIAAC0wBAX8jgICAgABBIGsiAiSAgICAACACQQE7ARwgAiABNgIYIAIgADYCFCACQfyBwIAANgIQIAJBiIbAgAA2AgwgAkEMahCpgICAAAALKAEBf0EALQCoi8CAABpBASABEKeAgIAAIQIgACABNgIEIAAgAjYCAAs3AQF/AkBBASACEKeAgIAAIgNFDQAgAyAAIAEgAiABIAJJGxC8gICAABogACABEKiAgIAACyADC5wBAQJ/I4CAgIAAQRBrIgIkgICAgAAgARCzgICAACEBIAJBACgCpIvAgAA2AgwCQCABIAAgAkEMahC3gICAACIDDQAgAiABIAAQtICAgABBACEDIAIoAgANACACKAIEIgMgAigCDDYCCCACIAM2AgwgASAAIAJBDGoQt4CAgAAhAwtBACACKAIMNgKki8CAACACQRBqJICAgIAAIAML6QEBA38gARCzgICAABogAEF4aiIBIAEoAgBBfnE2AgBBACgCpIvAgAAhAiABELiAgIAAGiAAQQA2AgACQAJAAkAgAUEE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AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwMDAwMDAwMDAwMDAwMDAwQEBAQEAAAAAAAAAAAAAAAAAAAAYXR0ZW1wdCB0byBhZGQgd2l0aCBvdmVyZmxvdy9ydXN0Yy84MmUxNjA4ZGZhNmUwYjU1NjkyMzI1NTllM2QzODVmZWE1YTkzMTEyL2xpYnJhcnkvY29yZS9zcmMvaXRlci90cmFpdHMvYWNjdW0ucnMAAAAsAhAAVQAAAJUAAAABAAAAUmVnaXN0ZXIgd2FzIGV4cGVjdGVkIHRvIGhhdmUgZGF0YSBiZWNhdXNlIHdlIGp1c3Qgd3JvdGUgaXQgaW50byBpdC5SZXF1aXJlcyBhdHRhY2hlZCBkZXBvc2l0IG9mIGV4YWN0bHkgMSB5b2N0b05FQVJjYWxsZWQgYE9wdGlvbjo6dW53cmFwKClgIG9uIGEgYE5vbmVgIHZhbHVlbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5ycwAzAxAAHAAAAIQCAAAeAAAAL2hvbWUvY29tbW9uLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvbWVtb3J5X3VuaXRzLTAuNC4wL3NyYy9saWIucnMAYAMQAF8AAACPAAAABgAAAGF0dGVtcHQgdG8gYWRkIHdpdGggb3ZlcmZsb3dgAxAAXwAAAI8AAAAFAAAAAAAAAGF0dGVtcHQgdG8gc3VidHJhY3Qgd2l0aCBvdmVyZmxvdwAAAGADEABfAAAAswAAAAUAAAAAAAAAAAAAAAAAAABhdHRlbXB0IHRvIG11bHRpcGx5IHdpdGggb3ZlcmZsb3cAAABgAxAAXwAAAK4AAAAFAAAAYAMQAF8AAACmAAAAAQAAAC9ob21lL2NvbW1vbi8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby02ZjE3ZDIyYmJhMTUwMDFmL3dlZV9hbGxvYy0wLjQuNS9zcmMvbGliLnJzhAQQAFwAAACeAQAADwAAAIQEEABcAAAAGQIAACEAAACEBBAAXAAAABwCAAAMAAAAhAQQAFwAAAAdAgAAIwAAAIQEEABcAAAAIQIAABsAAAAvaG9tZS9jb21tb24vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi93ZWVfYWxsb2MtMC40LjUvc3JjL2ltcF93YXNtMzIucnMAMAUQAGMAAAAMAAAAEwAAAA==" + } + }, + { + "AccessKey": { + "account_id": "da.test.near", + "public_key": "ed25519:HoYqPhyxiHsMARwuT5RvMZH3q9YoACMyvJWo3J8YqxYp", + "access_key": { + "nonce": 51698000003, + "permission": "FullAccess" + } + } + }, + { + "AccessKey": { + "account_id": "near", + "public_key": "ed25519:546XB2oHhj7PzUKHiH9Xve3Ze5q1JiW2WTh6abXFED3c", + "access_key": { + "nonce": 0, + "permission": "FullAccess" + } + } + }, + { + "AccessKey": { + "account_id": "test.near", + "public_key": "ed25519:rR32DunDCh9ArAFQW1xgJHxYEEbaCDCc88R3XwjD3j1", + "access_key": { + "nonce": 50240000014, + "permission": "FullAccess" + } + } + }, + { + "AccessKey": { + "account_id": "test.near", + "public_key": "ed25519:5qJULsTNSQT1R5FAacVKNk3R3sgh8rfpwnJcqLnC5u1F", + "access_key": { + "nonce": 2414, + "permission": "FullAccess" + } + } + }, + { + "Data": { + "account_id": "test.near", + "data_key": "AA==", + "value": "AQ==" + } + }, + { + "Data": { + "account_id": "test.near", + "data_key": "AQ==", + "value": "dGVzdC5uZWFy" + } + } + ] +} \ No newline at end of file diff --git a/test/config/near/http-sidecar.json b/test/config/near/http-sidecar.json new file mode 100644 index 0000000000..ce671076ec --- /dev/null +++ b/test/config/near/http-sidecar.json @@ -0,0 +1,7 @@ +{ + "account_id": "test.near", + "secret_key": "ed25519:4dagBsEqCv3Ao5wa4KKFa57xNAH4wuBjh9wdTNYeCqDSeA9zE7fCnHSvWpU8t68jUpcCGqgfYwcH68suPaqmdcgm", + "contract_id": "test.near", + "network": "http://near-localnet:3030", + "namespace": null +} diff --git a/test/config/near/node_key.json b/test/config/near/node_key.json new file mode 100644 index 0000000000..711479ac9c --- /dev/null +++ b/test/config/near/node_key.json @@ -0,0 +1,5 @@ +{ + "account_id": "node", + "public_key": "ed25519:7cPtaw4Q4Nn2d5SYZTz3JuHYojwxEPgRDeb5BRs5Buva", + "secret_key": "ed25519:3iu8Pb1ogb7eNEeS2iJth5SZqnz7y35VQ7HBpzqa7LPdUEuXXjoeT5DyHmR5ygmhY4z8i9eYBotHZUBTZb2Viubx" +} diff --git a/test/config/near/validator_key.json b/test/config/near/validator_key.json new file mode 100644 index 0000000000..caacf7c0ec --- /dev/null +++ b/test/config/near/validator_key.json @@ -0,0 +1,5 @@ +{ + "account_id": "test.near", + "public_key": "ed25519:5qJULsTNSQT1R5FAacVKNk3R3sgh8rfpwnJcqLnC5u1F", + "secret_key": "ed25519:4dagBsEqCv3Ao5wa4KKFa57xNAH4wuBjh9wdTNYeCqDSeA9zE7fCnHSvWpU8t68jUpcCGqgfYwcH68suPaqmdcgm" +} diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 8600377b9f..d21619d43a 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -742,17 +742,17 @@ services: - 6565:5888 near-localnet-print-key: - container_name: near-localnet + container_name: near-localnet-print-key build: - context: ./images - dockerfile: near-sandbox.Dockerfile + context: ./config/near + dockerfile: images/near-sandbox.Dockerfile volumes: - near-sandbox-data:/root/.near - ports: - - 3030:3030 + - ./config/near-http-sidecar.json:/config.json entrypoint: - - cat - - /root/.near/validator_key.json + - bash + - -c + - sed "s/HTTP_API_TEST_SECRET_KEY/`cat /root/.near/validator_key.json | jq -r '.secret_key'`/g" /config.json > /config2.json && cp /config2.json /config.json near-localnet: container_name: near-localnet diff --git a/test/images/near-sandbox.Dockerfile b/test/images/near-sandbox.Dockerfile index 2531f11979..80536e7ab4 100644 --- a/test/images/near-sandbox.Dockerfile +++ b/test/images/near-sandbox.Dockerfile @@ -1,15 +1,17 @@ FROM debian:bookworm as builder WORKDIR /usr/src/app RUN apt-get update && apt-get install --assume-yes curl -RUN curl -LJO https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore/Linux-x86_64/master/d08187094a82b3bfab3b8b0fa076e71068f39cb7/near-sandbox.tar.gz +RUN curl -LJO https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore/Linux-x86_64/1.38.0/aac5e42fe8975e27faca53e31f53f9c67a5b4e35/near-sandbox.tar.gz RUN tar -xf near-sandbox.tar.gz FROM debian:bookworm-slim as runtime WORKDIR /usr/local/bin COPY --from=builder /usr/src/app/Linux-x86_64/near-sandbox /usr/local/bin/near-sandbox -RUN apt-get update && apt-get install --assume-yes curl +RUN apt-get update && apt-get install --assume-yes curl jq RUN near-sandbox --home /root/.near init +COPY * /root/.near + RUN cat /root/.near/validator_key.json ENTRYPOINT [ "near-sandbox", "--home", "/root/.near", "run" ] From e9345d5affaf2f9db301f5892fabfbb9715356e3 Mon Sep 17 00:00:00 2001 From: dndll Date: Tue, 16 Apr 2024 17:26:22 +0100 Subject: [PATCH 3/5] test: mock e2e tests --- dataavailability/near/near.go | 123 ++++++++++--------- dataavailability/near/near_test.go | 185 +++++++++++++++++++++++------ go.mod | 2 +- go.sum | 8 ++ test/Makefile | 3 +- test/docker-compose.yml | 6 - 6 files changed, 225 insertions(+), 102 deletions(-) diff --git a/dataavailability/near/near.go b/dataavailability/near/near.go index 7ef8879682..4510312a04 100644 --- a/dataavailability/near/near.go +++ b/dataavailability/near/near.go @@ -87,70 +87,94 @@ type Sequence struct { Batches [][]byte } +func (s *Sequence) encode() (*sidecar.Blob, error) { + var buf bytes.Buffer + encoder := gob.NewEncoder(&buf) + err := encoder.Encode(s) + if err != nil { + return nil, fmt.Errorf("error encoding sequence for NEAR: %s", err) + } + blob := sidecar.Blob{ + Data: buf.Bytes(), + } + + return &blob, err +} + +func decode(b *sidecar.Blob) (*Sequence, error) { + var s Sequence + + buf := bytes.NewReader(b.Data) + codec := gob.NewDecoder(buf) + err := codec.Decode(&s) + if len(s.Batches) == 0 { + return nil, fmt.Errorf("sequence is empty") + } + return &s, err +} + func hexEncode(b [][]byte) string { - var str string = "0x" + var bytes []byte for _, batch := range b { - str += fmt.Sprintf("%x", batch) + bytes = append(bytes, batch...) } - return str + return common.Bytes2Hex(bytes) } func hexEncode2(b []byte) string { - return fmt.Sprintf("0x%x", b) + return common.Bytes2Hex(b) } +const MaxBatchSize = 4 * 1024 * 1024 // Max batch size is 4MB + // PostSequence posts a sequence of batches to the Near blockchain. // It takes a context and a slice of byte slices representing the batches data. // It returns the transaction ID of the submitted sequence and any error encountered. func (n *NearProtocolBackend) PostSequence(ctx context.Context, batches [][]byte) ([]byte, error) { - const maxBatchSize = 4 * 1024 * 1024 // Max batch size is 4MB - log.Debugf("submitting batches %s", hexEncode(batches)) + // count the size of all batches, overflowing batches into multiple sequences + sequences := ChunkedSequences(batches) + log.Debugf("Submitting %d sequences", len(sequences)) + var blobRefs []byte + // For each sequence weno + for _, seq := range sequences { + blob, err := seq.encode() + if err != nil { + return nil, err + } + + blobRef, err := n.Client.SubmitBlob(*blob) + if err != nil { + return nil, fmt.Errorf("error submitting data to NEAR: %s", err) + } + log.Debugf("Blob ref: %s", hexEncode2(blobRef.Deref())) + blobRefs = append(blobRefs, blobRef.Deref()...) + } + return blobRefs, nil +} + +func ChunkedSequences(batches [][]byte) []Sequence { // count the size of all batches, overflowing batches into multiple sequences var sequences []Sequence + sequences = append(sequences, Sequence{}) + size := 0 seqIndex := 0 for _, batch := range batches { - if len(sequences) == 0 { - sequences = append(sequences, Sequence{}) - } - size += len(batch) - if size > maxBatchSize { - size = len(batch) + + if size > MaxBatchSize { seqIndex++ + size = len(batch) + var seq Sequence seq.Batches = append(seq.Batches, batch) sequences = append(sequences, seq) } else { sequences[seqIndex].Batches = append(sequences[seqIndex].Batches, batch) } - log.Debugf("Sequence %s", hexEncode(sequences[seqIndex].Batches)) } - log.Debugf("Submitting %d sequences", len(sequences)) - - var blobRefs []byte - for _, seq := range sequences { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - err := enc.Encode(seq) - if err != nil { - return nil, fmt.Errorf("error encoding sequence for NEAR: %s", err) - } - - blob := sidecar.Blob{ - Data: buf.Bytes(), - } - log.Debugf("Blob: %s", hexEncode2(blob.Data)) - - blobRef, err := n.Client.SubmitBlob(blob) - log.Debugf("Blob ref: %s", hexEncode2(blobRef.Deref())) - if err != nil { - return nil, fmt.Errorf("error submitting data to NEAR: %s", err) - } - blobRefs = append(blobRefs, blobRef.Deref()...) - } - return blobRefs, nil + return sequences } // GetSequence retrieves a sequence of batches from the Near blockchain. @@ -159,41 +183,32 @@ func (n *NearProtocolBackend) PostSequence(ctx context.Context, batches [][]byte func (n *NearProtocolBackend) GetSequence(ctx context.Context, batchHashes []common.Hash, dataAvailabilityMessage []byte) ([][]byte, error) { var batchData [][]byte - log.Debugf("Retrieving %d batches from dataAvailabilityMessage %s", len(batchHashes), hexEncode2(dataAvailabilityMessage)) + log.Debugf("Retrieving %d batches from dataAvailabilityMessage %s: %d", len(batchHashes), hexEncode2(dataAvailabilityMessage), len(dataAvailabilityMessage)) - // FIXME: define the size of the ref in the library // Chunk the da message into references - for _, ref := range chunks(dataAvailabilityMessage, 32) { - blobRef, err := sidecar.NewBlobRef(ref) + for _, blobRef := range Chunks(dataAvailabilityMessage, sidecar.EncodedBlobRefSize) { + blobRef, err := sidecar.NewBlobRef(blobRef) if err != nil { - return nil, fmt.Errorf("error reading blob: %s", err) + return nil, fmt.Errorf("error reading blob reference: %s", err) } - log.Debugf("Retrieving %s from %s", hexEncode2(blobRef.Deref()), n.host) blob, err := n.Client.GetBlob(*blobRef) if err != nil { - return nil, fmt.Errorf("error getting data from NEAR: %s", err) + return nil, fmt.Errorf("error fetching blob %s: %s", hexEncode2(blobRef.Deref()), err) } - log.Debugf("Retrieved blob %s", hexEncode2(blob.Data)) - - buf := bytes.NewReader(blob.Data) - codec := gob.NewDecoder(buf) - var seq Sequence - err = codec.Decode(&seq) + seq, err := decode(blob) if err != nil { - return nil, fmt.Errorf("error encoding sequence for NEAR: %s", err) + return nil, fmt.Errorf("error decoding sequence from NEAR: %s", err) } - log.Debugf("Decoded sequence %s", seq) batchData = append(batchData, seq.Batches...) } - log.Debugf("Retrieved batches %s", batchData) return batchData, nil } -func chunks(message []byte, chunkSize int) [][]byte { +func Chunks(message []byte, chunkSize int) [][]byte { var chunks [][]byte for { if len(message) == 0 { diff --git a/dataavailability/near/near_test.go b/dataavailability/near/near_test.go index bb1369bb7a..489f5c76b4 100644 --- a/dataavailability/near/near_test.go +++ b/dataavailability/near/near_test.go @@ -4,6 +4,7 @@ package near import ( "context" + "crypto/rand" "encoding/hex" "encoding/json" "net/http" @@ -14,90 +15,196 @@ import ( "github.com/near/rollup-data-availability/gopkg/sidecar" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" ) -func TestPostSequence(t *testing.T) { - // Set up a mock server +// stub 32 byte tx id +const tx string = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + +var random = GenerateRandomBatchesData(1, 10) +var sequence = Sequence{Batches: random} + +func mocks(t *testing.T, sequenceMap map[string]*Sequence, refMap map[common.Hash]*string) (*NearProtocolBackend, *httptest.Server) { mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/health": w.WriteHeader(http.StatusOK) case "/blob": - var blob sidecar.Blob - err := json.NewDecoder(r.Body).Decode(&blob) - require.NoError(t, err) - transactionID := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - w.Write([]byte(transactionID)) + if r.Method == http.MethodPost { + var blob sidecar.Blob + err := json.NewDecoder(r.Body).Decode(&blob) + require.NoError(t, err) + + txId := tx + + maybeTx := refMap[common.BytesToHash(hash(blob.Data))] + if maybeTx != nil { + println("found tx: ", *maybeTx) + txId = *maybeTx + } + + blobRef, err := sidecar.NewBlobRef(common.FromHex(txId)) + require.NoError(t, err) + + jsonData, err := blobRef.MarshalJSON() + require.NoError(t, err) + + w.Write(jsonData) + } else if r.Method == http.MethodGet { + txId := r.URL.Query().Get("transaction_id") + + var seq = sequence + + maybeSequence := sequenceMap[txId] + if maybeSequence != nil { + seq = *maybeSequence + } + + blob, err := seq.encode() + require.NoError(t, err) + + jsonData, err := blob.MarshalJSON() + require.NoError(t, err) + w.Write(jsonData) + } default: w.WriteHeader(http.StatusNotFound) } })) - defer mockServer.Close() - backend, err := New(mockServer.URL, nil) backend.Init() require.NoError(t, err) + + return backend, mockServer +} + +func TestPostSequence(t *testing.T) { + backend, mockServer := mocks(t, nil, nil) defer backend.Client.Close() + defer mockServer.Close() // Test PostSequence batchesData := GenerateRandomBatchesData(3, 10) + println("test batches data: ", hexEncode(batchesData)) transactionID, err := backend.PostSequence(context.Background(), batchesData) require.NoError(t, err) - expectedTransactionID, err := hex.DecodeString("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef") + expectedTransactionID, err := hex.DecodeString(tx) require.NoError(t, err) + assert.Equal(t, expectedTransactionID, transactionID) + + // TODO: test overloadpostssequence } func TestGetSequence(t *testing.T) { - tx := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" - data := []byte("test_data") - // Set up a mock server - mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - switch r.URL.Path { - case "/health": - w.WriteHeader(http.StatusOK) - case "/blob": - transactionID := r.URL.Query().Get("transaction_id") - assert.Equal(t, tx, transactionID) - blob := sidecar.Blob{Data: data} - jsonData, err := blob.MarshalJSON() - require.NoError(t, err) - w.Write(jsonData) - default: - w.WriteHeader(http.StatusNotFound) - } - })) - defer mockServer.Close() - backend, err := New(mockServer.URL, nil) - require.NoError(t, err) + backend, mockServer := mocks(t, nil, nil) defer backend.Client.Close() + defer mockServer.Close() - batchHashes := []common.Hash{ - common.HexToHash(tx), + batchHashes := []common.Hash{} + for _, v := range sequence.Batches { + batchHashes = append(batchHashes, common.BytesToHash(v)) } - dataAvailabilityMessage := []byte("data_availability_message") + + dataAvailabilityMessage := common.Hex2Bytes(tx) batchData, err := backend.GetSequence(context.Background(), batchHashes, dataAvailabilityMessage) require.NoError(t, err) + assert.Equal(t, 1, len(batchData)) - assert.Equal(t, data, batchData[0]) + assert.Equal(t, sequence.Batches, batchData) + +} + +func TestLargeE2e(t *testing.T) { + numBatches := 10 + + batches := GenerateChunks(MaxBatchSize * numBatches) + sequences := ChunkedSequences(batches) + println("Expected sequences: ", len(sequences)) + + seqMap := map[string]*Sequence{} + refMap := map[common.Hash]*string{} + + var index byte = 0 + for _, v := range sequences { + // Populate blob ref + blobRef := hash([]byte{index}) + txId := hex.EncodeToString(blobRef[:]) + + // Encode the blob + encoded, err := v.encode() + require.NoError(t, err) + + seqMap[txId] = &v + refMap[common.BytesToHash(hash(encoded.Data))] = &txId + + index++ + } + backend, mockServer := mocks(t, seqMap, refMap) + defer backend.Client.Close() + defer mockServer.Close() + // Test PostSequence + transactionIds, err := backend.PostSequence(context.Background(), batches) + require.NoError(t, err) + + // Assert that all the transaction ids are the ones we know about + for _, v := range Chunks(transactionIds, sidecar.EncodedBlobRefSize) { + seq := seqMap[common.Bytes2Hex(v)] + require.NotNil(t, seq) + } + + batchHashes := []common.Hash{} + for _, v := range sequences { + var appended []byte + for _, b := range v.Batches { + appended = append(appended, b...) + } + batchHashes = append(batchHashes, common.BytesToHash(hash(appended))) + } + + batchData, err := backend.GetSequence(context.Background(), batchHashes, transactionIds) + require.NoError(t, err) + assert.Equal(t, len(batches), len(batchData)) +} + +func TestChunkedSequences(t *testing.T) { + batches := GenerateRandomBatchesData(4, MaxBatchSize+1) + sequences := ChunkedSequences(batches) + + // should be 5 sequences: 4 normals + overflow + assert.Equal(t, 5, len(sequences)) +} + +func hash(buf []byte) []byte { + sha := sha3.NewLegacyKeccak256() + sha.Write(buf[:]) + sha256 := sha.Sum(nil) + return sha256 } // GenerateRandomBlobData generates random blob data of the specified size. func GenerateRandomBlobData(size int) []byte { - data := make([]byte, size) - for i := 0; i < size; i++ { - data[i] = byte(i % 256) + blob := make([]byte, size) + _, err := rand.Read(blob) + if err != nil { + panic(err) } - return data + return blob } // GenerateRandomBatchesData generates a slice of random batch data. func GenerateRandomBatchesData(numBatches, batchSize int) [][]byte { + println("generate random batches data: ", numBatches, batchSize) batchesData := make([][]byte, numBatches) for i := 0; i < numBatches; i++ { batchesData[i] = GenerateRandomBlobData(batchSize) } return batchesData } + +func GenerateChunks(size int) [][]byte { + data := GenerateRandomBlobData(size) + return Chunks(data, MaxBatchSize) +} diff --git a/go.mod b/go.mod index 6cdc21b461..aca630b276 100644 --- a/go.mod +++ b/go.mod @@ -175,7 +175,7 @@ require ( github.com/0xPolygon/agglayer v0.0.1 github.com/0xPolygon/cdk-data-availability v0.0.5 github.com/fatih/color v1.16.0 - github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b + github.com/near/rollup-data-availability v0.2.4-0.20240416102651-87054f3724b7 github.com/prometheus/client_golang v1.18.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa ) diff --git a/go.sum b/go.sum index 29254c8c21..81ac322ef1 100644 --- a/go.sum +++ b/go.sum @@ -620,6 +620,14 @@ github.com/near/rollup-data-availability v0.2.4-0.20240410124327-96cbd87c2f54 h1 github.com/near/rollup-data-availability v0.2.4-0.20240410124327-96cbd87c2f54/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b h1:Wz79ek5EUmJPC1KVUj7bSwYegkzZf9PEdM8Pj77z8NI= github.com/near/rollup-data-availability v0.2.4-0.20240411160245-671f643e145b/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240415155120-71097ee4a400 h1:dkWHW01VyNLQZAtE1HvmIjfpXOW2DhTttpbnztH/KGE= +github.com/near/rollup-data-availability v0.2.4-0.20240415155120-71097ee4a400/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240416083204-3aedf5e83125 h1:A0UiStZvtbQWGAEuYWS6j0s23UUN1ZjNKHsdNHjYsks= +github.com/near/rollup-data-availability v0.2.4-0.20240416083204-3aedf5e83125/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240416083505-a9fbe6750496 h1:/OflcvSE8jYtIwNUeA52daLaGX9VzyvxbwEVpUR0Khs= +github.com/near/rollup-data-availability v0.2.4-0.20240416083505-a9fbe6750496/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= +github.com/near/rollup-data-availability v0.2.4-0.20240416102651-87054f3724b7 h1:AI+r0WU60BWxPB3eDP0QT6gcJCwW/Ufq9CKCbuIvRVs= +github.com/near/rollup-data-availability v0.2.4-0.20240416102651-87054f3724b7/go.mod h1:k8/pfs2vlJdpgeifiLQf62SQZYGJUev1T/iYfCVT16c= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= diff --git a/test/Makefile b/test/Makefile index 1aa0ac6253..789391512c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -616,6 +616,7 @@ run-near: $(RUNZKPROVER) $(RUNPERMISSIONLESSZKPROVER) $(RUNAPPROVE) + # state for this NEWCONTRACT=$$(cd /home/common/projects/data-availability/rollup-data-availability/eth && forge script Deploy --fork-url local --broadcast --legacy --json | jq -R 'fromjson?' | jq -r '.returns.da.value') $(DOCKERCOMPOSE) up -d near-set-dap $(RUNPERMISSIONLESSNODENEAR) # sleep 3 @@ -819,14 +820,12 @@ stop-permissionless-dac: ## Stops the permissionless node that is forced to sync .PHONY: run-permissionless-near ## Runs a permissionless node that is forced to sync through NEAR run-permissionless-near: run-node run-permissionless-dependencies - # TODO: NEAR Localnet $(RUNPERMISSIONLESSNODENEAR) .PHONY: stop-permissionless-near stop-permissionless-near: ## Stops the permissionless node that is forced to sync through NEAR $(STOPPERMISSIONLESSNODENEAR) $(STOPPERMISSIONLESSZKPROVER) - # TODO: near localnet diff --git a/test/docker-compose.yml b/test/docker-compose.yml index d21619d43a..87f5efc7b0 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -689,7 +689,6 @@ services: - "-N" - "500" - # TODO: actually force this to sync, how? zkevm-node-forced-near: container_name: zkevm-node-forced-near image: zkevm-node @@ -733,11 +732,6 @@ services: command: - -c - /app/config.json - # healthcheck: - # test: ["CMD-HTTP", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] - # interval: 10s - # timeout: 5s - # retries: 5 ports: - 6565:5888 From e30366002946b707b7989a7fd69440f3e9907a66 Mon Sep 17 00:00:00 2001 From: dndll Date: Wed, 17 Apr 2024 10:22:04 +0100 Subject: [PATCH 4/5] chore: bindings generation --- .../abi/neardataavailability.abi | 551 +++++ .../bin/neardataavailability.bin | 1 + etherman/smartcontracts/nearda/TODO | 0 .../neardataavailability.go | 1858 +++++++++++++++++ etherman/smartcontracts/script.sh | 1 + test/e2e/nearda_test.go | 220 -- 6 files changed, 2411 insertions(+), 220 deletions(-) create mode 100644 etherman/smartcontracts/abi/neardataavailability.abi create mode 100644 etherman/smartcontracts/bin/neardataavailability.bin delete mode 100644 etherman/smartcontracts/nearda/TODO create mode 100644 etherman/smartcontracts/neardataavailability/neardataavailability.go delete mode 100644 test/e2e/nearda_test.go diff --git a/etherman/smartcontracts/abi/neardataavailability.abi b/etherman/smartcontracts/abi/neardataavailability.abi new file mode 100644 index 0000000000..8833b91989 --- /dev/null +++ b/etherman/smartcontracts/abi/neardataavailability.abi @@ -0,0 +1,551 @@ +[ + { + "type": "constructor", + "inputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "_NOTIFIER", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "_STORED_BATCH_AMT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "_SUBMITTED_BATCH_AMT", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "_VERIFIER", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "batchInfo", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "id", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "verifyTxHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "submitTxId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "cancelOwnershipHandover", + "inputs": [], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "completeOwnershipHandover", + "inputs": [ + { + "name": "pendingOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "getProcotolName", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "string", + "internalType": "string" + } + ], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "grantRoles", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "hasAllRoles", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "hasAnyRole", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "initialOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "notifyAvailable", + "inputs": [ + { + "name": "verifiedBatch", + "type": "tuple", + "internalType": "struct VerifiedBatch", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "verifyTxHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "submitTxId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "notifySubmitted", + "inputs": [ + { + "name": "batches", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "owner", + "inputs": [], + "outputs": [ + { + "name": "result", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "ownershipHandoverExpiresAt", + "inputs": [ + { + "name": "pendingOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "result", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "renounceOwnership", + "inputs": [], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "renounceRoles", + "inputs": [ + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "requestOwnershipHandover", + "inputs": [], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "revokeRoles", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + }, + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "rolesOf", + "inputs": [ + { + "name": "user", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "roles", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "submittedBatches", + "inputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "transferOwnership", + "inputs": [ + { + "name": "newOwner", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "verifyMessage", + "inputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "dataAvailabilityBatch", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "view" + }, + { + "type": "event", + "name": "Initialized", + "inputs": [ + { + "name": "version", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "IsAvailable", + "inputs": [ + { + "name": "bucketIdx", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "batch", + "type": "tuple", + "indexed": false, + "internalType": "struct VerifiedBatch", + "components": [ + { + "name": "id", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "verifyTxHash", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "submitTxId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipHandoverCanceled", + "inputs": [ + { + "name": "pendingOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipHandoverRequested", + "inputs": [ + { + "name": "pendingOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnershipTransferred", + "inputs": [ + { + "name": "oldOwner", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "newOwner", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "RolesUpdated", + "inputs": [ + { + "name": "user", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "roles", + "type": "uint256", + "indexed": true, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "Submitted", + "inputs": [ + { + "name": "bucketIdx", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "submitTxId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "AlreadyInitialized", + "inputs": [] + }, + { + "type": "error", + "name": "InvalidInitialization", + "inputs": [] + }, + { + "type": "error", + "name": "NewOwnerIsZeroAddress", + "inputs": [] + }, + { + "type": "error", + "name": "NoHandoverRequest", + "inputs": [] + }, + { + "type": "error", + "name": "NotInitializing", + "inputs": [] + }, + { + "type": "error", + "name": "Unauthorized", + "inputs": [] + } +] diff --git a/etherman/smartcontracts/bin/neardataavailability.bin b/etherman/smartcontracts/bin/neardataavailability.bin new file mode 100644 index 0000000000..dffadd7fbf --- /dev/null +++ b/etherman/smartcontracts/bin/neardataavailability.bin @@ -0,0 +1 @@ +0x6080604052348015600f57600080fd5b506016601a565b60ca565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560695760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c75780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610f15806100d96000396000f3fe60806040526004361061018b5760003560e01c8063715018a6116100d6578063c4d66de81161007f578063f04e283e11610059578063f04e283e14610461578063f2fde38b14610474578063fee81cf41461048757600080fd5b8063c4d66de8146103d5578063d0262817146103f5578063e4f171201461041557600080fd5b8063adc31e01116100b0578063adc31e011461038a578063b62aa7f91461039f578063ba0d0ebc146103bf57600080fd5b8063715018a6146102f3578063815bda47146102fb5780638da5cb5b1461033657600080fd5b80633b51be4b11610138578063514e62fc11610112578063514e62fc1461029f57806354d1f13d146102d657806355731347146102de57600080fd5b80633b51be4b146102565780634a4ee7b114610276578063510586421461028957600080fd5b8063256929621161016957806325692962146101ed57806329afa6a3146101f55780632de948071461021557600080fd5b8063183a4f6e146101905780631c10893f146101a55780631cd64df4146101b8575b600080fd5b6101a361019e366004610baa565b6104ba565b005b6101a36101b3366004610bec565b6104c7565b3480156101c457600080fd5b506101d86101d3366004610bec565b6104dd565b60405190151581526020015b60405180910390f35b6101a36104fc565b34801561020157600080fd5b506101a3610210366004610c16565b61054c565b34801561022157600080fd5b50610248610230366004610c99565b638b78c6d8600c908152600091909152602090205490565b6040519081526020016101e4565b34801561026257600080fd5b506101a3610271366004610d04565b6105ba565b6101a3610284366004610bec565b610613565b34801561029557600080fd5b5061024861080081565b3480156102ab57600080fd5b506101d86102ba366004610bec565b638b78c6d8600c90815260009290925260209091205416151590565b6101a3610625565b3480156102ea57600080fd5b50610248608081565b6101a3610661565b34801561030757600080fd5b5061031b610316366004610baa565b610675565b604080519384526020840192909252908201526060016101e4565b34801561034257600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739275460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e4565b34801561039657600080fd5b50610248602081565b3480156103ab57600080fd5b506101a36103ba366004610d50565b61069c565b3480156103cb57600080fd5b5061024861040081565b3480156103e157600080fd5b506101a36103f0366004610c99565b610755565b34801561040157600080fd5b50610248610410366004610baa565b6108d4565b34801561042157600080fd5b50604080518082018252600c81527f4e65617250726f746f636f6c0000000000000000000000000000000000000000602082015290516101e49190610d92565b6101a361046f366004610c99565b6108eb565b6101a3610482366004610c99565b610928565b34801561049357600080fd5b506102486104a2366004610c99565b63389a75e1600c908152600091909152602090205490565b6104c4338261094f565b50565b6104cf61095b565b6104d98282610991565b5050565b638b78c6d8600c90815260008390526020902054811681145b92915050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b6108006105588161099d565b6000610563836109eb565b604080518281528551602080830191909152860151818301529085015160608201529091507f8985609fb3668d8b8e01db2e596eab8479f1e2447af72dab7baefdc1fd99d1bc9060800160405180910390a1505050565b6000806105c983850185610baa565b905060005b602081101561060b57600081602081106105ea576105ea610dff565b6003020192508183600001540361060357505050505050565b6001016105ce565b505050505050565b61061b61095b565b6104d9828261094f565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b61066961095b565b6106736000610a4b565b565b6000816020811061068557600080fd5b600302018054600182015460029092015490925083565b6104006106a88161099d565b602060006106b68285610e8c565b905060005b8181101561060b57600086866106d18685610ea0565b90866106de866001610eb7565b6106e89190610ea0565b926106f593929190610eca565b8101906107029190610baa565b9050600061070f82610ab1565b60408051828152602081018590529192507f465ddfeee4b3d0fb72ba16ca1e8d4ecf86373b44e51658af98043162de372b4c910160405180910390a150506001016106bb565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff166000811580156107a05750825b905060008267ffffffffffffffff1660011480156107bd5750303b155b9050811580156107cb575080155b15610802576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156108635784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b61086c86610aed565b831561060b5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a1505050505050565b606181608081106108e457600080fd5b0154905081565b6108f361095b565b63389a75e1600c52806000526020600c20805442111561091b57636f5e88186000526004601cfd5b600090556104c481610a4b565b61093061095b565b8060601b61094657637448fbae6000526004601cfd5b6104c481610a4b565b6104d982826000610b51565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610673576382b429006000526004601cfd5b6104d982826001610b51565b638b78c6d8600c5233600052806020600c2054166104c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739275433146104c4576382b429006000526004601cfd5b60605460009082828260208110610a0457610a04610dff565b600302016000820151816000015560208201518160010155604082015181600201559050506020816001610a389190610eb7565b610a429190610ef4565b60605592915050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60e1546000908260618260808110610acb57610acb610dff565b01556080610ada826001610eb7565b610ae49190610ef4565b60e15592915050565b73ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739278190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b638b78c6d8600c52826000526020600c20805483811783610b73575080841681185b80835580600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a3505050505050565b600060208284031215610bbc57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610be757600080fd5b919050565b60008060408385031215610bff57600080fd5b610c0883610bc3565b946020939093013593505050565b600060608284031215610c2857600080fd5b6040516060810181811067ffffffffffffffff82111715610c72577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80604052508235815260208301356020820152604083013560408201528091505092915050565b600060208284031215610cab57600080fd5b610cb482610bc3565b9392505050565b60008083601f840112610ccd57600080fd5b50813567ffffffffffffffff811115610ce557600080fd5b602083019150836020828501011115610cfd57600080fd5b9250929050565b600080600060408486031215610d1957600080fd5b83359250602084013567ffffffffffffffff811115610d3757600080fd5b610d4386828701610cbb565b9497909650939450505050565b60008060208385031215610d6357600080fd5b823567ffffffffffffffff811115610d7a57600080fd5b610d8685828601610cbb565b90969095509350505050565b60006020808352835180602085015260005b81811015610dc057858101830151858201604001528201610da4565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610e9b57610e9b610e2e565b500490565b80820281158282048414176104f6576104f6610e5d565b808201808211156104f6576104f6610e5d565b60008085851115610eda57600080fd5b83861115610ee757600080fd5b5050820193919092039150565b600082610f0357610f03610e2e565b50069056fea164736f6c6343000819000a diff --git a/etherman/smartcontracts/nearda/TODO b/etherman/smartcontracts/nearda/TODO deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/etherman/smartcontracts/neardataavailability/neardataavailability.go b/etherman/smartcontracts/neardataavailability/neardataavailability.go new file mode 100644 index 0000000000..1761e7adf6 --- /dev/null +++ b/etherman/smartcontracts/neardataavailability/neardataavailability.go @@ -0,0 +1,1858 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package neardataavailability + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription +) + +// VerifiedBatch is an auto generated low-level Go binding around an user-defined struct. +type VerifiedBatch struct { + Id [32]byte + VerifyTxHash [32]byte + SubmitTxId [32]byte +} + +// NeardataavailabilityMetaData contains all meta data concerning the Neardataavailability contract. +var NeardataavailabilityMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"_NOTIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"_STORED_BATCH_AMT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"_SUBMITTED_BATCH_AMT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"_VERIFIER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batchInfo\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifyTxHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"submitTxId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"cancelOwnershipHandover\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"completeOwnershipHandover\",\"inputs\":[{\"name\":\"pendingOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"getProcotolName\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"grantRoles\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"hasAllRoles\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"hasAnyRole\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"initialOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"notifyAvailable\",\"inputs\":[{\"name\":\"verifiedBatch\",\"type\":\"tuple\",\"internalType\":\"structVerifiedBatch\",\"components\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifyTxHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"submitTxId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"notifySubmitted\",\"inputs\":[{\"name\":\"batches\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"result\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownershipHandoverExpiresAt\",\"inputs\":[{\"name\":\"pendingOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"result\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"renounceRoles\",\"inputs\":[{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"requestOwnershipHandover\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"revokeRoles\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"rolesOf\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"roles\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submittedBatches\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"verifyMessage\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"dataAvailabilityBatch\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"IsAvailable\",\"inputs\":[{\"name\":\"bucketIdx\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"batch\",\"type\":\"tuple\",\"indexed\":false,\"internalType\":\"structVerifiedBatch\",\"components\":[{\"name\":\"id\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"verifyTxHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"submitTxId\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipHandoverCanceled\",\"inputs\":[{\"name\":\"pendingOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipHandoverRequested\",\"inputs\":[{\"name\":\"pendingOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"oldOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RolesUpdated\",\"inputs\":[{\"name\":\"user\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"roles\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Submitted\",\"inputs\":[{\"name\":\"bucketIdx\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"submitTxId\",\"type\":\"bytes32\",\"indexed\":false,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"AlreadyInitialized\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NewOwnerIsZeroAddress\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NoHandoverRequest\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"Unauthorized\",\"inputs\":[]}]", + Bin: "0x6080604052348015600f57600080fd5b506016601a565b60ca565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560695760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c75780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610f15806100d96000396000f3fe60806040526004361061018b5760003560e01c8063715018a6116100d6578063c4d66de81161007f578063f04e283e11610059578063f04e283e14610461578063f2fde38b14610474578063fee81cf41461048757600080fd5b8063c4d66de8146103d5578063d0262817146103f5578063e4f171201461041557600080fd5b8063adc31e01116100b0578063adc31e011461038a578063b62aa7f91461039f578063ba0d0ebc146103bf57600080fd5b8063715018a6146102f3578063815bda47146102fb5780638da5cb5b1461033657600080fd5b80633b51be4b11610138578063514e62fc11610112578063514e62fc1461029f57806354d1f13d146102d657806355731347146102de57600080fd5b80633b51be4b146102565780634a4ee7b114610276578063510586421461028957600080fd5b8063256929621161016957806325692962146101ed57806329afa6a3146101f55780632de948071461021557600080fd5b8063183a4f6e146101905780631c10893f146101a55780631cd64df4146101b8575b600080fd5b6101a361019e366004610baa565b6104ba565b005b6101a36101b3366004610bec565b6104c7565b3480156101c457600080fd5b506101d86101d3366004610bec565b6104dd565b60405190151581526020015b60405180910390f35b6101a36104fc565b34801561020157600080fd5b506101a3610210366004610c16565b61054c565b34801561022157600080fd5b50610248610230366004610c99565b638b78c6d8600c908152600091909152602090205490565b6040519081526020016101e4565b34801561026257600080fd5b506101a3610271366004610d04565b6105ba565b6101a3610284366004610bec565b610613565b34801561029557600080fd5b5061024861080081565b3480156102ab57600080fd5b506101d86102ba366004610bec565b638b78c6d8600c90815260009290925260209091205416151590565b6101a3610625565b3480156102ea57600080fd5b50610248608081565b6101a3610661565b34801561030757600080fd5b5061031b610316366004610baa565b610675565b604080519384526020840192909252908201526060016101e4565b34801561034257600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739275460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e4565b34801561039657600080fd5b50610248602081565b3480156103ab57600080fd5b506101a36103ba366004610d50565b61069c565b3480156103cb57600080fd5b5061024861040081565b3480156103e157600080fd5b506101a36103f0366004610c99565b610755565b34801561040157600080fd5b50610248610410366004610baa565b6108d4565b34801561042157600080fd5b50604080518082018252600c81527f4e65617250726f746f636f6c0000000000000000000000000000000000000000602082015290516101e49190610d92565b6101a361046f366004610c99565b6108eb565b6101a3610482366004610c99565b610928565b34801561049357600080fd5b506102486104a2366004610c99565b63389a75e1600c908152600091909152602090205490565b6104c4338261094f565b50565b6104cf61095b565b6104d98282610991565b5050565b638b78c6d8600c90815260008390526020902054811681145b92915050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b6108006105588161099d565b6000610563836109eb565b604080518281528551602080830191909152860151818301529085015160608201529091507f8985609fb3668d8b8e01db2e596eab8479f1e2447af72dab7baefdc1fd99d1bc9060800160405180910390a1505050565b6000806105c983850185610baa565b905060005b602081101561060b57600081602081106105ea576105ea610dff565b6003020192508183600001540361060357505050505050565b6001016105ce565b505050505050565b61061b61095b565b6104d9828261094f565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b61066961095b565b6106736000610a4b565b565b6000816020811061068557600080fd5b600302018054600182015460029092015490925083565b6104006106a88161099d565b602060006106b68285610e8c565b905060005b8181101561060b57600086866106d18685610ea0565b90866106de866001610eb7565b6106e89190610ea0565b926106f593929190610eca565b8101906107029190610baa565b9050600061070f82610ab1565b60408051828152602081018590529192507f465ddfeee4b3d0fb72ba16ca1e8d4ecf86373b44e51658af98043162de372b4c910160405180910390a150506001016106bb565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff166000811580156107a05750825b905060008267ffffffffffffffff1660011480156107bd5750303b155b9050811580156107cb575080155b15610802576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156108635784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b61086c86610aed565b831561060b5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a1505050505050565b606181608081106108e457600080fd5b0154905081565b6108f361095b565b63389a75e1600c52806000526020600c20805442111561091b57636f5e88186000526004601cfd5b600090556104c481610a4b565b61093061095b565b8060601b61094657637448fbae6000526004601cfd5b6104c481610a4b565b6104d982826000610b51565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927543314610673576382b429006000526004601cfd5b6104d982826001610b51565b638b78c6d8600c5233600052806020600c2054166104c4577fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739275433146104c4576382b429006000526004601cfd5b60605460009082828260208110610a0457610a04610dff565b600302016000820151816000015560208201518160010155604082015181600201559050506020816001610a389190610eb7565b610a429190610ef4565b60605592915050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60e1546000908260618260808110610acb57610acb610dff565b01556080610ada826001610eb7565b610ae49190610ef4565b60e15592915050565b73ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff748739278190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b638b78c6d8600c52826000526020600c20805483811783610b73575080841681185b80835580600c5160601c7f715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26600080a3505050505050565b600060208284031215610bbc57600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610be757600080fd5b919050565b60008060408385031215610bff57600080fd5b610c0883610bc3565b946020939093013593505050565b600060608284031215610c2857600080fd5b6040516060810181811067ffffffffffffffff82111715610c72577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80604052508235815260208301356020820152604083013560408201528091505092915050565b600060208284031215610cab57600080fd5b610cb482610bc3565b9392505050565b60008083601f840112610ccd57600080fd5b50813567ffffffffffffffff811115610ce557600080fd5b602083019150836020828501011115610cfd57600080fd5b9250929050565b600080600060408486031215610d1957600080fd5b83359250602084013567ffffffffffffffff811115610d3757600080fd5b610d4386828701610cbb565b9497909650939450505050565b60008060208385031215610d6357600080fd5b823567ffffffffffffffff811115610d7a57600080fd5b610d8685828601610cbb565b90969095509350505050565b60006020808352835180602085015260005b81811015610dc057858101830151858201604001528201610da4565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082610e9b57610e9b610e2e565b500490565b80820281158282048414176104f6576104f6610e5d565b808201808211156104f6576104f6610e5d565b60008085851115610eda57600080fd5b83861115610ee757600080fd5b5050820193919092039150565b600082610f0357610f03610e2e565b50069056fea164736f6c6343000819000a", +} + +// NeardataavailabilityABI is the input ABI used to generate the binding from. +// Deprecated: Use NeardataavailabilityMetaData.ABI instead. +var NeardataavailabilityABI = NeardataavailabilityMetaData.ABI + +// NeardataavailabilityBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NeardataavailabilityMetaData.Bin instead. +var NeardataavailabilityBin = NeardataavailabilityMetaData.Bin + +// DeployNeardataavailability deploys a new Ethereum contract, binding an instance of Neardataavailability to it. +func DeployNeardataavailability(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Neardataavailability, error) { + parsed, err := NeardataavailabilityMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NeardataavailabilityBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Neardataavailability{NeardataavailabilityCaller: NeardataavailabilityCaller{contract: contract}, NeardataavailabilityTransactor: NeardataavailabilityTransactor{contract: contract}, NeardataavailabilityFilterer: NeardataavailabilityFilterer{contract: contract}}, nil +} + +// Neardataavailability is an auto generated Go binding around an Ethereum contract. +type Neardataavailability struct { + NeardataavailabilityCaller // Read-only binding to the contract + NeardataavailabilityTransactor // Write-only binding to the contract + NeardataavailabilityFilterer // Log filterer for contract events +} + +// NeardataavailabilityCaller is an auto generated read-only Go binding around an Ethereum contract. +type NeardataavailabilityCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NeardataavailabilityTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NeardataavailabilityTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NeardataavailabilityFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NeardataavailabilityFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NeardataavailabilitySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NeardataavailabilitySession struct { + Contract *Neardataavailability // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NeardataavailabilityCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NeardataavailabilityCallerSession struct { + Contract *NeardataavailabilityCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NeardataavailabilityTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NeardataavailabilityTransactorSession struct { + Contract *NeardataavailabilityTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NeardataavailabilityRaw is an auto generated low-level Go binding around an Ethereum contract. +type NeardataavailabilityRaw struct { + Contract *Neardataavailability // Generic contract binding to access the raw methods on +} + +// NeardataavailabilityCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NeardataavailabilityCallerRaw struct { + Contract *NeardataavailabilityCaller // Generic read-only contract binding to access the raw methods on +} + +// NeardataavailabilityTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NeardataavailabilityTransactorRaw struct { + Contract *NeardataavailabilityTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNeardataavailability creates a new instance of Neardataavailability, bound to a specific deployed contract. +func NewNeardataavailability(address common.Address, backend bind.ContractBackend) (*Neardataavailability, error) { + contract, err := bindNeardataavailability(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Neardataavailability{NeardataavailabilityCaller: NeardataavailabilityCaller{contract: contract}, NeardataavailabilityTransactor: NeardataavailabilityTransactor{contract: contract}, NeardataavailabilityFilterer: NeardataavailabilityFilterer{contract: contract}}, nil +} + +// NewNeardataavailabilityCaller creates a new read-only instance of Neardataavailability, bound to a specific deployed contract. +func NewNeardataavailabilityCaller(address common.Address, caller bind.ContractCaller) (*NeardataavailabilityCaller, error) { + contract, err := bindNeardataavailability(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NeardataavailabilityCaller{contract: contract}, nil +} + +// NewNeardataavailabilityTransactor creates a new write-only instance of Neardataavailability, bound to a specific deployed contract. +func NewNeardataavailabilityTransactor(address common.Address, transactor bind.ContractTransactor) (*NeardataavailabilityTransactor, error) { + contract, err := bindNeardataavailability(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NeardataavailabilityTransactor{contract: contract}, nil +} + +// NewNeardataavailabilityFilterer creates a new log filterer instance of Neardataavailability, bound to a specific deployed contract. +func NewNeardataavailabilityFilterer(address common.Address, filterer bind.ContractFilterer) (*NeardataavailabilityFilterer, error) { + contract, err := bindNeardataavailability(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NeardataavailabilityFilterer{contract: contract}, nil +} + +// bindNeardataavailability binds a generic wrapper to an already deployed contract. +func bindNeardataavailability(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := abi.JSON(strings.NewReader(NeardataavailabilityABI)) + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Neardataavailability *NeardataavailabilityRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Neardataavailability.Contract.NeardataavailabilityCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Neardataavailability *NeardataavailabilityRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Neardataavailability.Contract.NeardataavailabilityTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Neardataavailability *NeardataavailabilityRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Neardataavailability.Contract.NeardataavailabilityTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Neardataavailability *NeardataavailabilityCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Neardataavailability.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Neardataavailability *NeardataavailabilityTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Neardataavailability.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Neardataavailability *NeardataavailabilityTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Neardataavailability.Contract.contract.Transact(opts, method, params...) +} + +// NOTIFIER is a free data retrieval call binding the contract method 0xba0d0ebc. +// +// Solidity: function _NOTIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCaller) NOTIFIER(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "_NOTIFIER") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// NOTIFIER is a free data retrieval call binding the contract method 0xba0d0ebc. +// +// Solidity: function _NOTIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilitySession) NOTIFIER() (*big.Int, error) { + return _Neardataavailability.Contract.NOTIFIER(&_Neardataavailability.CallOpts) +} + +// NOTIFIER is a free data retrieval call binding the contract method 0xba0d0ebc. +// +// Solidity: function _NOTIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCallerSession) NOTIFIER() (*big.Int, error) { + return _Neardataavailability.Contract.NOTIFIER(&_Neardataavailability.CallOpts) +} + +// STOREDBATCHAMT is a free data retrieval call binding the contract method 0xadc31e01. +// +// Solidity: function _STORED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCaller) STOREDBATCHAMT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "_STORED_BATCH_AMT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// STOREDBATCHAMT is a free data retrieval call binding the contract method 0xadc31e01. +// +// Solidity: function _STORED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilitySession) STOREDBATCHAMT() (*big.Int, error) { + return _Neardataavailability.Contract.STOREDBATCHAMT(&_Neardataavailability.CallOpts) +} + +// STOREDBATCHAMT is a free data retrieval call binding the contract method 0xadc31e01. +// +// Solidity: function _STORED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCallerSession) STOREDBATCHAMT() (*big.Int, error) { + return _Neardataavailability.Contract.STOREDBATCHAMT(&_Neardataavailability.CallOpts) +} + +// SUBMITTEDBATCHAMT is a free data retrieval call binding the contract method 0x55731347. +// +// Solidity: function _SUBMITTED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCaller) SUBMITTEDBATCHAMT(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "_SUBMITTED_BATCH_AMT") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// SUBMITTEDBATCHAMT is a free data retrieval call binding the contract method 0x55731347. +// +// Solidity: function _SUBMITTED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilitySession) SUBMITTEDBATCHAMT() (*big.Int, error) { + return _Neardataavailability.Contract.SUBMITTEDBATCHAMT(&_Neardataavailability.CallOpts) +} + +// SUBMITTEDBATCHAMT is a free data retrieval call binding the contract method 0x55731347. +// +// Solidity: function _SUBMITTED_BATCH_AMT() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCallerSession) SUBMITTEDBATCHAMT() (*big.Int, error) { + return _Neardataavailability.Contract.SUBMITTEDBATCHAMT(&_Neardataavailability.CallOpts) +} + +// VERIFIER is a free data retrieval call binding the contract method 0x51058642. +// +// Solidity: function _VERIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCaller) VERIFIER(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "_VERIFIER") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// VERIFIER is a free data retrieval call binding the contract method 0x51058642. +// +// Solidity: function _VERIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilitySession) VERIFIER() (*big.Int, error) { + return _Neardataavailability.Contract.VERIFIER(&_Neardataavailability.CallOpts) +} + +// VERIFIER is a free data retrieval call binding the contract method 0x51058642. +// +// Solidity: function _VERIFIER() view returns(uint256) +func (_Neardataavailability *NeardataavailabilityCallerSession) VERIFIER() (*big.Int, error) { + return _Neardataavailability.Contract.VERIFIER(&_Neardataavailability.CallOpts) +} + +// BatchInfo is a free data retrieval call binding the contract method 0x815bda47. +// +// Solidity: function batchInfo(uint256 ) view returns(bytes32 id, bytes32 verifyTxHash, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilityCaller) BatchInfo(opts *bind.CallOpts, arg0 *big.Int) (struct { + Id [32]byte + VerifyTxHash [32]byte + SubmitTxId [32]byte +}, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "batchInfo", arg0) + + outstruct := new(struct { + Id [32]byte + VerifyTxHash [32]byte + SubmitTxId [32]byte + }) + if err != nil { + return *outstruct, err + } + + outstruct.Id = *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + outstruct.VerifyTxHash = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.SubmitTxId = *abi.ConvertType(out[2], new([32]byte)).(*[32]byte) + + return *outstruct, err + +} + +// BatchInfo is a free data retrieval call binding the contract method 0x815bda47. +// +// Solidity: function batchInfo(uint256 ) view returns(bytes32 id, bytes32 verifyTxHash, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilitySession) BatchInfo(arg0 *big.Int) (struct { + Id [32]byte + VerifyTxHash [32]byte + SubmitTxId [32]byte +}, error) { + return _Neardataavailability.Contract.BatchInfo(&_Neardataavailability.CallOpts, arg0) +} + +// BatchInfo is a free data retrieval call binding the contract method 0x815bda47. +// +// Solidity: function batchInfo(uint256 ) view returns(bytes32 id, bytes32 verifyTxHash, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilityCallerSession) BatchInfo(arg0 *big.Int) (struct { + Id [32]byte + VerifyTxHash [32]byte + SubmitTxId [32]byte +}, error) { + return _Neardataavailability.Contract.BatchInfo(&_Neardataavailability.CallOpts, arg0) +} + +// GetProcotolName is a free data retrieval call binding the contract method 0xe4f17120. +// +// Solidity: function getProcotolName() pure returns(string) +func (_Neardataavailability *NeardataavailabilityCaller) GetProcotolName(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "getProcotolName") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// GetProcotolName is a free data retrieval call binding the contract method 0xe4f17120. +// +// Solidity: function getProcotolName() pure returns(string) +func (_Neardataavailability *NeardataavailabilitySession) GetProcotolName() (string, error) { + return _Neardataavailability.Contract.GetProcotolName(&_Neardataavailability.CallOpts) +} + +// GetProcotolName is a free data retrieval call binding the contract method 0xe4f17120. +// +// Solidity: function getProcotolName() pure returns(string) +func (_Neardataavailability *NeardataavailabilityCallerSession) GetProcotolName() (string, error) { + return _Neardataavailability.Contract.GetProcotolName(&_Neardataavailability.CallOpts) +} + +// HasAllRoles is a free data retrieval call binding the contract method 0x1cd64df4. +// +// Solidity: function hasAllRoles(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilityCaller) HasAllRoles(opts *bind.CallOpts, user common.Address, roles *big.Int) (bool, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "hasAllRoles", user, roles) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasAllRoles is a free data retrieval call binding the contract method 0x1cd64df4. +// +// Solidity: function hasAllRoles(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilitySession) HasAllRoles(user common.Address, roles *big.Int) (bool, error) { + return _Neardataavailability.Contract.HasAllRoles(&_Neardataavailability.CallOpts, user, roles) +} + +// HasAllRoles is a free data retrieval call binding the contract method 0x1cd64df4. +// +// Solidity: function hasAllRoles(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilityCallerSession) HasAllRoles(user common.Address, roles *big.Int) (bool, error) { + return _Neardataavailability.Contract.HasAllRoles(&_Neardataavailability.CallOpts, user, roles) +} + +// HasAnyRole is a free data retrieval call binding the contract method 0x514e62fc. +// +// Solidity: function hasAnyRole(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilityCaller) HasAnyRole(opts *bind.CallOpts, user common.Address, roles *big.Int) (bool, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "hasAnyRole", user, roles) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// HasAnyRole is a free data retrieval call binding the contract method 0x514e62fc. +// +// Solidity: function hasAnyRole(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilitySession) HasAnyRole(user common.Address, roles *big.Int) (bool, error) { + return _Neardataavailability.Contract.HasAnyRole(&_Neardataavailability.CallOpts, user, roles) +} + +// HasAnyRole is a free data retrieval call binding the contract method 0x514e62fc. +// +// Solidity: function hasAnyRole(address user, uint256 roles) view returns(bool) +func (_Neardataavailability *NeardataavailabilityCallerSession) HasAnyRole(user common.Address, roles *big.Int) (bool, error) { + return _Neardataavailability.Contract.HasAnyRole(&_Neardataavailability.CallOpts, user, roles) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address result) +func (_Neardataavailability *NeardataavailabilityCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "owner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address result) +func (_Neardataavailability *NeardataavailabilitySession) Owner() (common.Address, error) { + return _Neardataavailability.Contract.Owner(&_Neardataavailability.CallOpts) +} + +// Owner is a free data retrieval call binding the contract method 0x8da5cb5b. +// +// Solidity: function owner() view returns(address result) +func (_Neardataavailability *NeardataavailabilityCallerSession) Owner() (common.Address, error) { + return _Neardataavailability.Contract.Owner(&_Neardataavailability.CallOpts) +} + +// OwnershipHandoverExpiresAt is a free data retrieval call binding the contract method 0xfee81cf4. +// +// Solidity: function ownershipHandoverExpiresAt(address pendingOwner) view returns(uint256 result) +func (_Neardataavailability *NeardataavailabilityCaller) OwnershipHandoverExpiresAt(opts *bind.CallOpts, pendingOwner common.Address) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "ownershipHandoverExpiresAt", pendingOwner) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// OwnershipHandoverExpiresAt is a free data retrieval call binding the contract method 0xfee81cf4. +// +// Solidity: function ownershipHandoverExpiresAt(address pendingOwner) view returns(uint256 result) +func (_Neardataavailability *NeardataavailabilitySession) OwnershipHandoverExpiresAt(pendingOwner common.Address) (*big.Int, error) { + return _Neardataavailability.Contract.OwnershipHandoverExpiresAt(&_Neardataavailability.CallOpts, pendingOwner) +} + +// OwnershipHandoverExpiresAt is a free data retrieval call binding the contract method 0xfee81cf4. +// +// Solidity: function ownershipHandoverExpiresAt(address pendingOwner) view returns(uint256 result) +func (_Neardataavailability *NeardataavailabilityCallerSession) OwnershipHandoverExpiresAt(pendingOwner common.Address) (*big.Int, error) { + return _Neardataavailability.Contract.OwnershipHandoverExpiresAt(&_Neardataavailability.CallOpts, pendingOwner) +} + +// RolesOf is a free data retrieval call binding the contract method 0x2de94807. +// +// Solidity: function rolesOf(address user) view returns(uint256 roles) +func (_Neardataavailability *NeardataavailabilityCaller) RolesOf(opts *bind.CallOpts, user common.Address) (*big.Int, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "rolesOf", user) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// RolesOf is a free data retrieval call binding the contract method 0x2de94807. +// +// Solidity: function rolesOf(address user) view returns(uint256 roles) +func (_Neardataavailability *NeardataavailabilitySession) RolesOf(user common.Address) (*big.Int, error) { + return _Neardataavailability.Contract.RolesOf(&_Neardataavailability.CallOpts, user) +} + +// RolesOf is a free data retrieval call binding the contract method 0x2de94807. +// +// Solidity: function rolesOf(address user) view returns(uint256 roles) +func (_Neardataavailability *NeardataavailabilityCallerSession) RolesOf(user common.Address) (*big.Int, error) { + return _Neardataavailability.Contract.RolesOf(&_Neardataavailability.CallOpts, user) +} + +// SubmittedBatches is a free data retrieval call binding the contract method 0xd0262817. +// +// Solidity: function submittedBatches(uint256 ) view returns(bytes32) +func (_Neardataavailability *NeardataavailabilityCaller) SubmittedBatches(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "submittedBatches", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SubmittedBatches is a free data retrieval call binding the contract method 0xd0262817. +// +// Solidity: function submittedBatches(uint256 ) view returns(bytes32) +func (_Neardataavailability *NeardataavailabilitySession) SubmittedBatches(arg0 *big.Int) ([32]byte, error) { + return _Neardataavailability.Contract.SubmittedBatches(&_Neardataavailability.CallOpts, arg0) +} + +// SubmittedBatches is a free data retrieval call binding the contract method 0xd0262817. +// +// Solidity: function submittedBatches(uint256 ) view returns(bytes32) +func (_Neardataavailability *NeardataavailabilityCallerSession) SubmittedBatches(arg0 *big.Int) ([32]byte, error) { + return _Neardataavailability.Contract.SubmittedBatches(&_Neardataavailability.CallOpts, arg0) +} + +// VerifyMessage is a free data retrieval call binding the contract method 0x3b51be4b. +// +// Solidity: function verifyMessage(bytes32 , bytes dataAvailabilityBatch) view returns() +func (_Neardataavailability *NeardataavailabilityCaller) VerifyMessage(opts *bind.CallOpts, arg0 [32]byte, dataAvailabilityBatch []byte) error { + var out []interface{} + err := _Neardataavailability.contract.Call(opts, &out, "verifyMessage", arg0, dataAvailabilityBatch) + + if err != nil { + return err + } + + return err + +} + +// VerifyMessage is a free data retrieval call binding the contract method 0x3b51be4b. +// +// Solidity: function verifyMessage(bytes32 , bytes dataAvailabilityBatch) view returns() +func (_Neardataavailability *NeardataavailabilitySession) VerifyMessage(arg0 [32]byte, dataAvailabilityBatch []byte) error { + return _Neardataavailability.Contract.VerifyMessage(&_Neardataavailability.CallOpts, arg0, dataAvailabilityBatch) +} + +// VerifyMessage is a free data retrieval call binding the contract method 0x3b51be4b. +// +// Solidity: function verifyMessage(bytes32 , bytes dataAvailabilityBatch) view returns() +func (_Neardataavailability *NeardataavailabilityCallerSession) VerifyMessage(arg0 [32]byte, dataAvailabilityBatch []byte) error { + return _Neardataavailability.Contract.VerifyMessage(&_Neardataavailability.CallOpts, arg0, dataAvailabilityBatch) +} + +// CancelOwnershipHandover is a paid mutator transaction binding the contract method 0x54d1f13d. +// +// Solidity: function cancelOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) CancelOwnershipHandover(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "cancelOwnershipHandover") +} + +// CancelOwnershipHandover is a paid mutator transaction binding the contract method 0x54d1f13d. +// +// Solidity: function cancelOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilitySession) CancelOwnershipHandover() (*types.Transaction, error) { + return _Neardataavailability.Contract.CancelOwnershipHandover(&_Neardataavailability.TransactOpts) +} + +// CancelOwnershipHandover is a paid mutator transaction binding the contract method 0x54d1f13d. +// +// Solidity: function cancelOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) CancelOwnershipHandover() (*types.Transaction, error) { + return _Neardataavailability.Contract.CancelOwnershipHandover(&_Neardataavailability.TransactOpts) +} + +// CompleteOwnershipHandover is a paid mutator transaction binding the contract method 0xf04e283e. +// +// Solidity: function completeOwnershipHandover(address pendingOwner) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) CompleteOwnershipHandover(opts *bind.TransactOpts, pendingOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "completeOwnershipHandover", pendingOwner) +} + +// CompleteOwnershipHandover is a paid mutator transaction binding the contract method 0xf04e283e. +// +// Solidity: function completeOwnershipHandover(address pendingOwner) payable returns() +func (_Neardataavailability *NeardataavailabilitySession) CompleteOwnershipHandover(pendingOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.CompleteOwnershipHandover(&_Neardataavailability.TransactOpts, pendingOwner) +} + +// CompleteOwnershipHandover is a paid mutator transaction binding the contract method 0xf04e283e. +// +// Solidity: function completeOwnershipHandover(address pendingOwner) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) CompleteOwnershipHandover(pendingOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.CompleteOwnershipHandover(&_Neardataavailability.TransactOpts, pendingOwner) +} + +// GrantRoles is a paid mutator transaction binding the contract method 0x1c10893f. +// +// Solidity: function grantRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) GrantRoles(opts *bind.TransactOpts, user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "grantRoles", user, roles) +} + +// GrantRoles is a paid mutator transaction binding the contract method 0x1c10893f. +// +// Solidity: function grantRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilitySession) GrantRoles(user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.GrantRoles(&_Neardataavailability.TransactOpts, user, roles) +} + +// GrantRoles is a paid mutator transaction binding the contract method 0x1c10893f. +// +// Solidity: function grantRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) GrantRoles(user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.GrantRoles(&_Neardataavailability.TransactOpts, user, roles) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address initialOwner) returns() +func (_Neardataavailability *NeardataavailabilityTransactor) Initialize(opts *bind.TransactOpts, initialOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "initialize", initialOwner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address initialOwner) returns() +func (_Neardataavailability *NeardataavailabilitySession) Initialize(initialOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.Initialize(&_Neardataavailability.TransactOpts, initialOwner) +} + +// Initialize is a paid mutator transaction binding the contract method 0xc4d66de8. +// +// Solidity: function initialize(address initialOwner) returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) Initialize(initialOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.Initialize(&_Neardataavailability.TransactOpts, initialOwner) +} + +// NotifyAvailable is a paid mutator transaction binding the contract method 0x29afa6a3. +// +// Solidity: function notifyAvailable((bytes32,bytes32,bytes32) verifiedBatch) returns() +func (_Neardataavailability *NeardataavailabilityTransactor) NotifyAvailable(opts *bind.TransactOpts, verifiedBatch VerifiedBatch) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "notifyAvailable", verifiedBatch) +} + +// NotifyAvailable is a paid mutator transaction binding the contract method 0x29afa6a3. +// +// Solidity: function notifyAvailable((bytes32,bytes32,bytes32) verifiedBatch) returns() +func (_Neardataavailability *NeardataavailabilitySession) NotifyAvailable(verifiedBatch VerifiedBatch) (*types.Transaction, error) { + return _Neardataavailability.Contract.NotifyAvailable(&_Neardataavailability.TransactOpts, verifiedBatch) +} + +// NotifyAvailable is a paid mutator transaction binding the contract method 0x29afa6a3. +// +// Solidity: function notifyAvailable((bytes32,bytes32,bytes32) verifiedBatch) returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) NotifyAvailable(verifiedBatch VerifiedBatch) (*types.Transaction, error) { + return _Neardataavailability.Contract.NotifyAvailable(&_Neardataavailability.TransactOpts, verifiedBatch) +} + +// NotifySubmitted is a paid mutator transaction binding the contract method 0xb62aa7f9. +// +// Solidity: function notifySubmitted(bytes batches) returns() +func (_Neardataavailability *NeardataavailabilityTransactor) NotifySubmitted(opts *bind.TransactOpts, batches []byte) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "notifySubmitted", batches) +} + +// NotifySubmitted is a paid mutator transaction binding the contract method 0xb62aa7f9. +// +// Solidity: function notifySubmitted(bytes batches) returns() +func (_Neardataavailability *NeardataavailabilitySession) NotifySubmitted(batches []byte) (*types.Transaction, error) { + return _Neardataavailability.Contract.NotifySubmitted(&_Neardataavailability.TransactOpts, batches) +} + +// NotifySubmitted is a paid mutator transaction binding the contract method 0xb62aa7f9. +// +// Solidity: function notifySubmitted(bytes batches) returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) NotifySubmitted(batches []byte) (*types.Transaction, error) { + return _Neardataavailability.Contract.NotifySubmitted(&_Neardataavailability.TransactOpts, batches) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) RenounceOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "renounceOwnership") +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() payable returns() +func (_Neardataavailability *NeardataavailabilitySession) RenounceOwnership() (*types.Transaction, error) { + return _Neardataavailability.Contract.RenounceOwnership(&_Neardataavailability.TransactOpts) +} + +// RenounceOwnership is a paid mutator transaction binding the contract method 0x715018a6. +// +// Solidity: function renounceOwnership() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) RenounceOwnership() (*types.Transaction, error) { + return _Neardataavailability.Contract.RenounceOwnership(&_Neardataavailability.TransactOpts) +} + +// RenounceRoles is a paid mutator transaction binding the contract method 0x183a4f6e. +// +// Solidity: function renounceRoles(uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) RenounceRoles(opts *bind.TransactOpts, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "renounceRoles", roles) +} + +// RenounceRoles is a paid mutator transaction binding the contract method 0x183a4f6e. +// +// Solidity: function renounceRoles(uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilitySession) RenounceRoles(roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.RenounceRoles(&_Neardataavailability.TransactOpts, roles) +} + +// RenounceRoles is a paid mutator transaction binding the contract method 0x183a4f6e. +// +// Solidity: function renounceRoles(uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) RenounceRoles(roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.RenounceRoles(&_Neardataavailability.TransactOpts, roles) +} + +// RequestOwnershipHandover is a paid mutator transaction binding the contract method 0x25692962. +// +// Solidity: function requestOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) RequestOwnershipHandover(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "requestOwnershipHandover") +} + +// RequestOwnershipHandover is a paid mutator transaction binding the contract method 0x25692962. +// +// Solidity: function requestOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilitySession) RequestOwnershipHandover() (*types.Transaction, error) { + return _Neardataavailability.Contract.RequestOwnershipHandover(&_Neardataavailability.TransactOpts) +} + +// RequestOwnershipHandover is a paid mutator transaction binding the contract method 0x25692962. +// +// Solidity: function requestOwnershipHandover() payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) RequestOwnershipHandover() (*types.Transaction, error) { + return _Neardataavailability.Contract.RequestOwnershipHandover(&_Neardataavailability.TransactOpts) +} + +// RevokeRoles is a paid mutator transaction binding the contract method 0x4a4ee7b1. +// +// Solidity: function revokeRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) RevokeRoles(opts *bind.TransactOpts, user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "revokeRoles", user, roles) +} + +// RevokeRoles is a paid mutator transaction binding the contract method 0x4a4ee7b1. +// +// Solidity: function revokeRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilitySession) RevokeRoles(user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.RevokeRoles(&_Neardataavailability.TransactOpts, user, roles) +} + +// RevokeRoles is a paid mutator transaction binding the contract method 0x4a4ee7b1. +// +// Solidity: function revokeRoles(address user, uint256 roles) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) RevokeRoles(user common.Address, roles *big.Int) (*types.Transaction, error) { + return _Neardataavailability.Contract.RevokeRoles(&_Neardataavailability.TransactOpts, user, roles) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactor) TransferOwnership(opts *bind.TransactOpts, newOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.contract.Transact(opts, "transferOwnership", newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) payable returns() +func (_Neardataavailability *NeardataavailabilitySession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.TransferOwnership(&_Neardataavailability.TransactOpts, newOwner) +} + +// TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. +// +// Solidity: function transferOwnership(address newOwner) payable returns() +func (_Neardataavailability *NeardataavailabilityTransactorSession) TransferOwnership(newOwner common.Address) (*types.Transaction, error) { + return _Neardataavailability.Contract.TransferOwnership(&_Neardataavailability.TransactOpts, newOwner) +} + +// NeardataavailabilityInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Neardataavailability contract. +type NeardataavailabilityInitializedIterator struct { + Event *NeardataavailabilityInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityInitialized represents a Initialized event raised by the Neardataavailability contract. +type NeardataavailabilityInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterInitialized(opts *bind.FilterOpts) (*NeardataavailabilityInitializedIterator, error) { + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NeardataavailabilityInitializedIterator{contract: _Neardataavailability.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityInitialized) (event.Subscription, error) { + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityInitialized) + if err := _Neardataavailability.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseInitialized(log types.Log) (*NeardataavailabilityInitialized, error) { + event := new(NeardataavailabilityInitialized) + if err := _Neardataavailability.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilityIsAvailableIterator is returned from FilterIsAvailable and is used to iterate over the raw logs and unpacked data for IsAvailable events raised by the Neardataavailability contract. +type NeardataavailabilityIsAvailableIterator struct { + Event *NeardataavailabilityIsAvailable // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityIsAvailableIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityIsAvailable) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityIsAvailable) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityIsAvailableIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityIsAvailableIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityIsAvailable represents a IsAvailable event raised by the Neardataavailability contract. +type NeardataavailabilityIsAvailable struct { + BucketIdx *big.Int + Batch VerifiedBatch + Raw types.Log // Blockchain specific contextual infos +} + +// FilterIsAvailable is a free log retrieval operation binding the contract event 0x8985609fb3668d8b8e01db2e596eab8479f1e2447af72dab7baefdc1fd99d1bc. +// +// Solidity: event IsAvailable(uint256 bucketIdx, (bytes32,bytes32,bytes32) batch) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterIsAvailable(opts *bind.FilterOpts) (*NeardataavailabilityIsAvailableIterator, error) { + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "IsAvailable") + if err != nil { + return nil, err + } + return &NeardataavailabilityIsAvailableIterator{contract: _Neardataavailability.contract, event: "IsAvailable", logs: logs, sub: sub}, nil +} + +// WatchIsAvailable is a free log subscription operation binding the contract event 0x8985609fb3668d8b8e01db2e596eab8479f1e2447af72dab7baefdc1fd99d1bc. +// +// Solidity: event IsAvailable(uint256 bucketIdx, (bytes32,bytes32,bytes32) batch) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchIsAvailable(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityIsAvailable) (event.Subscription, error) { + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "IsAvailable") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityIsAvailable) + if err := _Neardataavailability.contract.UnpackLog(event, "IsAvailable", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseIsAvailable is a log parse operation binding the contract event 0x8985609fb3668d8b8e01db2e596eab8479f1e2447af72dab7baefdc1fd99d1bc. +// +// Solidity: event IsAvailable(uint256 bucketIdx, (bytes32,bytes32,bytes32) batch) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseIsAvailable(log types.Log) (*NeardataavailabilityIsAvailable, error) { + event := new(NeardataavailabilityIsAvailable) + if err := _Neardataavailability.contract.UnpackLog(event, "IsAvailable", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilityOwnershipHandoverCanceledIterator is returned from FilterOwnershipHandoverCanceled and is used to iterate over the raw logs and unpacked data for OwnershipHandoverCanceled events raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipHandoverCanceledIterator struct { + Event *NeardataavailabilityOwnershipHandoverCanceled // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityOwnershipHandoverCanceledIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipHandoverCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipHandoverCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityOwnershipHandoverCanceledIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityOwnershipHandoverCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityOwnershipHandoverCanceled represents a OwnershipHandoverCanceled event raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipHandoverCanceled struct { + PendingOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipHandoverCanceled is a free log retrieval operation binding the contract event 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92. +// +// Solidity: event OwnershipHandoverCanceled(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterOwnershipHandoverCanceled(opts *bind.FilterOpts, pendingOwner []common.Address) (*NeardataavailabilityOwnershipHandoverCanceledIterator, error) { + + var pendingOwnerRule []interface{} + for _, pendingOwnerItem := range pendingOwner { + pendingOwnerRule = append(pendingOwnerRule, pendingOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "OwnershipHandoverCanceled", pendingOwnerRule) + if err != nil { + return nil, err + } + return &NeardataavailabilityOwnershipHandoverCanceledIterator{contract: _Neardataavailability.contract, event: "OwnershipHandoverCanceled", logs: logs, sub: sub}, nil +} + +// WatchOwnershipHandoverCanceled is a free log subscription operation binding the contract event 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92. +// +// Solidity: event OwnershipHandoverCanceled(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchOwnershipHandoverCanceled(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityOwnershipHandoverCanceled, pendingOwner []common.Address) (event.Subscription, error) { + + var pendingOwnerRule []interface{} + for _, pendingOwnerItem := range pendingOwner { + pendingOwnerRule = append(pendingOwnerRule, pendingOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "OwnershipHandoverCanceled", pendingOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityOwnershipHandoverCanceled) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipHandoverCanceled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipHandoverCanceled is a log parse operation binding the contract event 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92. +// +// Solidity: event OwnershipHandoverCanceled(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseOwnershipHandoverCanceled(log types.Log) (*NeardataavailabilityOwnershipHandoverCanceled, error) { + event := new(NeardataavailabilityOwnershipHandoverCanceled) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipHandoverCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilityOwnershipHandoverRequestedIterator is returned from FilterOwnershipHandoverRequested and is used to iterate over the raw logs and unpacked data for OwnershipHandoverRequested events raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipHandoverRequestedIterator struct { + Event *NeardataavailabilityOwnershipHandoverRequested // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityOwnershipHandoverRequestedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipHandoverRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipHandoverRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityOwnershipHandoverRequestedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityOwnershipHandoverRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityOwnershipHandoverRequested represents a OwnershipHandoverRequested event raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipHandoverRequested struct { + PendingOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipHandoverRequested is a free log retrieval operation binding the contract event 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d. +// +// Solidity: event OwnershipHandoverRequested(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterOwnershipHandoverRequested(opts *bind.FilterOpts, pendingOwner []common.Address) (*NeardataavailabilityOwnershipHandoverRequestedIterator, error) { + + var pendingOwnerRule []interface{} + for _, pendingOwnerItem := range pendingOwner { + pendingOwnerRule = append(pendingOwnerRule, pendingOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "OwnershipHandoverRequested", pendingOwnerRule) + if err != nil { + return nil, err + } + return &NeardataavailabilityOwnershipHandoverRequestedIterator{contract: _Neardataavailability.contract, event: "OwnershipHandoverRequested", logs: logs, sub: sub}, nil +} + +// WatchOwnershipHandoverRequested is a free log subscription operation binding the contract event 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d. +// +// Solidity: event OwnershipHandoverRequested(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchOwnershipHandoverRequested(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityOwnershipHandoverRequested, pendingOwner []common.Address) (event.Subscription, error) { + + var pendingOwnerRule []interface{} + for _, pendingOwnerItem := range pendingOwner { + pendingOwnerRule = append(pendingOwnerRule, pendingOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "OwnershipHandoverRequested", pendingOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityOwnershipHandoverRequested) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipHandoverRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipHandoverRequested is a log parse operation binding the contract event 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d. +// +// Solidity: event OwnershipHandoverRequested(address indexed pendingOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseOwnershipHandoverRequested(log types.Log) (*NeardataavailabilityOwnershipHandoverRequested, error) { + event := new(NeardataavailabilityOwnershipHandoverRequested) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipHandoverRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilityOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipTransferredIterator struct { + Event *NeardataavailabilityOwnershipTransferred // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityOwnershipTransferredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityOwnershipTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityOwnershipTransferred represents a OwnershipTransferred event raised by the Neardataavailability contract. +type NeardataavailabilityOwnershipTransferred struct { + OldOwner common.Address + NewOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterOwnershipTransferred is a free log retrieval operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed oldOwner, address indexed newOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, oldOwner []common.Address, newOwner []common.Address) (*NeardataavailabilityOwnershipTransferredIterator, error) { + + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "OwnershipTransferred", oldOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return &NeardataavailabilityOwnershipTransferredIterator{contract: _Neardataavailability.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +// WatchOwnershipTransferred is a free log subscription operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed oldOwner, address indexed newOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityOwnershipTransferred, oldOwner []common.Address, newOwner []common.Address) (event.Subscription, error) { + + var oldOwnerRule []interface{} + for _, oldOwnerItem := range oldOwner { + oldOwnerRule = append(oldOwnerRule, oldOwnerItem) + } + var newOwnerRule []interface{} + for _, newOwnerItem := range newOwner { + newOwnerRule = append(newOwnerRule, newOwnerItem) + } + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "OwnershipTransferred", oldOwnerRule, newOwnerRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityOwnershipTransferred) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseOwnershipTransferred is a log parse operation binding the contract event 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0. +// +// Solidity: event OwnershipTransferred(address indexed oldOwner, address indexed newOwner) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseOwnershipTransferred(log types.Log) (*NeardataavailabilityOwnershipTransferred, error) { + event := new(NeardataavailabilityOwnershipTransferred) + if err := _Neardataavailability.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilityRolesUpdatedIterator is returned from FilterRolesUpdated and is used to iterate over the raw logs and unpacked data for RolesUpdated events raised by the Neardataavailability contract. +type NeardataavailabilityRolesUpdatedIterator struct { + Event *NeardataavailabilityRolesUpdated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilityRolesUpdatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityRolesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilityRolesUpdated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilityRolesUpdatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilityRolesUpdatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilityRolesUpdated represents a RolesUpdated event raised by the Neardataavailability contract. +type NeardataavailabilityRolesUpdated struct { + User common.Address + Roles *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterRolesUpdated is a free log retrieval operation binding the contract event 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26. +// +// Solidity: event RolesUpdated(address indexed user, uint256 indexed roles) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterRolesUpdated(opts *bind.FilterOpts, user []common.Address, roles []*big.Int) (*NeardataavailabilityRolesUpdatedIterator, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var rolesRule []interface{} + for _, rolesItem := range roles { + rolesRule = append(rolesRule, rolesItem) + } + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "RolesUpdated", userRule, rolesRule) + if err != nil { + return nil, err + } + return &NeardataavailabilityRolesUpdatedIterator{contract: _Neardataavailability.contract, event: "RolesUpdated", logs: logs, sub: sub}, nil +} + +// WatchRolesUpdated is a free log subscription operation binding the contract event 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26. +// +// Solidity: event RolesUpdated(address indexed user, uint256 indexed roles) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchRolesUpdated(opts *bind.WatchOpts, sink chan<- *NeardataavailabilityRolesUpdated, user []common.Address, roles []*big.Int) (event.Subscription, error) { + + var userRule []interface{} + for _, userItem := range user { + userRule = append(userRule, userItem) + } + var rolesRule []interface{} + for _, rolesItem := range roles { + rolesRule = append(rolesRule, rolesItem) + } + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "RolesUpdated", userRule, rolesRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilityRolesUpdated) + if err := _Neardataavailability.contract.UnpackLog(event, "RolesUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseRolesUpdated is a log parse operation binding the contract event 0x715ad5ce61fc9595c7b415289d59cf203f23a94fa06f04af7e489a0a76e1fe26. +// +// Solidity: event RolesUpdated(address indexed user, uint256 indexed roles) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseRolesUpdated(log types.Log) (*NeardataavailabilityRolesUpdated, error) { + event := new(NeardataavailabilityRolesUpdated) + if err := _Neardataavailability.contract.UnpackLog(event, "RolesUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NeardataavailabilitySubmittedIterator is returned from FilterSubmitted and is used to iterate over the raw logs and unpacked data for Submitted events raised by the Neardataavailability contract. +type NeardataavailabilitySubmittedIterator struct { + Event *NeardataavailabilitySubmitted // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NeardataavailabilitySubmittedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilitySubmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NeardataavailabilitySubmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NeardataavailabilitySubmittedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NeardataavailabilitySubmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NeardataavailabilitySubmitted represents a Submitted event raised by the Neardataavailability contract. +type NeardataavailabilitySubmitted struct { + BucketIdx *big.Int + SubmitTxId [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSubmitted is a free log retrieval operation binding the contract event 0x465ddfeee4b3d0fb72ba16ca1e8d4ecf86373b44e51658af98043162de372b4c. +// +// Solidity: event Submitted(uint256 bucketIdx, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilityFilterer) FilterSubmitted(opts *bind.FilterOpts) (*NeardataavailabilitySubmittedIterator, error) { + + logs, sub, err := _Neardataavailability.contract.FilterLogs(opts, "Submitted") + if err != nil { + return nil, err + } + return &NeardataavailabilitySubmittedIterator{contract: _Neardataavailability.contract, event: "Submitted", logs: logs, sub: sub}, nil +} + +// WatchSubmitted is a free log subscription operation binding the contract event 0x465ddfeee4b3d0fb72ba16ca1e8d4ecf86373b44e51658af98043162de372b4c. +// +// Solidity: event Submitted(uint256 bucketIdx, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilityFilterer) WatchSubmitted(opts *bind.WatchOpts, sink chan<- *NeardataavailabilitySubmitted) (event.Subscription, error) { + + logs, sub, err := _Neardataavailability.contract.WatchLogs(opts, "Submitted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NeardataavailabilitySubmitted) + if err := _Neardataavailability.contract.UnpackLog(event, "Submitted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSubmitted is a log parse operation binding the contract event 0x465ddfeee4b3d0fb72ba16ca1e8d4ecf86373b44e51658af98043162de372b4c. +// +// Solidity: event Submitted(uint256 bucketIdx, bytes32 submitTxId) +func (_Neardataavailability *NeardataavailabilityFilterer) ParseSubmitted(log types.Log) (*NeardataavailabilitySubmitted, error) { + event := new(NeardataavailabilitySubmitted) + if err := _Neardataavailability.contract.UnpackLog(event, "Submitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/etherman/smartcontracts/script.sh b/etherman/smartcontracts/script.sh index fea535224a..bb7628490d 100755 --- a/etherman/smartcontracts/script.sh +++ b/etherman/smartcontracts/script.sh @@ -28,3 +28,4 @@ gen mockverifier gen polygondatacommittee genNoBin dataavailabilityprotocol gen proxy +gen neardataavailability # github.com/near/rollup-data-availability/eth && just gen-cdk diff --git a/test/e2e/nearda_test.go b/test/e2e/nearda_test.go deleted file mode 100644 index 4dd58904c5..0000000000 --- a/test/e2e/nearda_test.go +++ /dev/null @@ -1,220 +0,0 @@ -package e2e - -import ( - "context" - "crypto/ecdsa" - "encoding/json" - "fmt" - "math/big" - "os" - "os/exec" - "sort" - "strconv" - "strings" - "testing" - "time" - - cTypes "github.com/0xPolygon/cdk-data-availability/config/types" - "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevm" - "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/nearda" - "github.com/0xPolygonHermez/zkevm-node/log" - "github.com/0xPolygonHermez/zkevm-node/test/operations" - "github.com/ethereum/go-ethereum" - eTypes "github.com/ethereum/go-ethereum/core/types" - "github.com/near/rollup-data-availability/gopkg/sidecar" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/accounts/keystore" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -const ( - NearDaContract = "0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE" // TODO: set a contract to be deployed at genesis - NearSK = "ed25519:4dagBsEqCv3Ao5wa4KKFa57xNAH4wuBjh9wdTNYeCqDSeA9zE7fCnHSvWpU8t68jUpcCGqgfYwcH68suPaqmdcgm" - NearAccount = "test.net" -) - -func TestNearDa(t *testing.T) { - const ( - ksFile = "/tmp/pkey" - ksPass = "pass" - cfgFile = "/tmp/neardanodeconfigfile.json" - nearDaSidecarImage = "ghcr.io/near/rollup-data-availability/http-api:dev" - ) - - // Setup - var err error - if testing.Short() { - t.Skip() - } - ctx := context.Background() - defer func() { - require.NoError(t, operations.Teardown()) - }() - err = operations.Teardown() - require.NoError(t, err) - opsCfg := operations.GetDefaultOperationsConfig() - opsCfg.State.MaxCumulativeGasUsed = 80000000000 - opsman, err := operations.NewManager(ctx, opsCfg) - require.NoError(t, err) - defer func() { - require.NoError(t, opsman.StopDACDB()) - }() - err = opsman.Setup() - require.NoError(t, err) - require.NoError(t, opsman.StartDACDB()) - time.Sleep(5 * time.Second) - - authL2, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID) - require.NoError(t, err) - - authL1, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL1ChainID) - require.NoError(t, err) - - clientL2, err := ethclient.Dial(operations.DefaultL2NetworkURL) - require.NoError(t, err) - - clientL1, err := ethclient.Dial(operations.DefaultL1NetworkURL) - require.NoError(t, err) - - zkEVM, err := etrogpolygonzkevm.NewEtrogpolygonzkevm( - common.HexToAddress(operations.DefaultL1ZkEVMSmartContract), - clientL1, - ) - require.NoError(t, err) - - currentDAPAddr, err := zkEVM.DataAvailabilityProtocol(&bind.CallOpts{Pending: false}) - require.NoError(t, err) - require.Equal(t, common.HexToAddress(operations.DefaultL1DataCommitteeContract), currentDAPAddr) - - _, err = zkEVM.SetDataAvailabilityProtocol(authL1, "0xNearProtocol") - require.NoError(t, err) - - // TODO: SetDataAvailabilityProtocol on etrog - - // TODO: Ensure DA sidecar is setup - // TODO: Ensure contract is setup too - - // TODO: create dummy near accounts, get them funded by workspace node - - defer func() { - // Remove tmp files - assert.NoError(t, - exec.Command("rm", cfgFile).Run(), - ) - assert.NoError(t, - exec.Command("rmdir", ksFile+"_").Run(), - ) - assert.NoError(t, - exec.Command("rm", ksFile).Run(), - ) - // TODO: stop near localnet - assert.NoError(t, exec.Command( - "docker", "kill", "near-da-sidecar", - ).Run()) - assert.NoError(t, exec.Command( - "docker", "rm", "near-da-sidecar", - ).Run()) - // Stop permissionless node - require.NoError(t, opsman.StopPermissionlessNodeForcedToSyncThroughNear()) - }() - // Start permissionless node - require.NoError(t, opsman.StartPermissionlessNodeForcedToSyncThroughNear()) - - // Write config file - nearDaConfig := sidecar.ConfigureClientRequest{ - AccountID: NearAccount, - SecretKey: NearSK, - Network: "near-localnet:5888", // TODO: needs the arbitrary networks - Namespace: nil, - } - - file, err := json.MarshalIndent(nearDaConfig, "", " ") - require.NoError(t, err) - err = os.WriteFile(cfgFile, file, 0644) - require.NoError(t, err) - - // Run DAC node - cmd := exec.Command( - "docker", "run", "-d", - "--name", "near-da-sidecar", - "-v", cfgFile+":/var/config.json", - "--network", "zkevm", - nearDaSidecarImage, - "-c", "/var/config.json", - ) - out, err := cmd.CombinedOutput() - require.NoError(t, err, string(out)) - log.Infof("NEAR DA sidecar started") - time.Sleep(time.Second * 5) - - // Send txs - nTxs := 10 - amount := big.NewInt(10000) - toAddress := common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8") - _, err = clientL2.BalanceAt(ctx, authL2.From, nil) - require.NoError(t, err) - _, err = clientL2.PendingNonceAt(ctx, authL2.From) - require.NoError(t, err) - - gasLimit, err := clientL2.EstimateGas(ctx, ethereum.CallMsg{From: authL2.From, To: &toAddress, Value: amount}) - require.NoError(t, err) - - gasPrice, err := clientL2.SuggestGasPrice(ctx) - require.NoError(t, err) - - nonce, err := clientL2.PendingNonceAt(ctx, authL2.From) - require.NoError(t, err) - - txs := make([]*eTypes.Transaction, 0, nTxs) - for i := 0; i < nTxs; i++ { - tx := eTypes.NewTransaction(nonce+uint64(i), toAddress, amount, gasLimit, gasPrice, nil) - log.Infof("generating tx %d / %d: %s", i+1, nTxs, tx.Hash().Hex()) - txs = append(txs, tx) - } - - // Wait for verification - _, err = operations.ApplyL2Txs(ctx, txs, authL2, clientL2, operations.VerifiedConfirmationLevel) - require.NoError(t, err) - - // Assert that he permissionless node is fully synced (through the DAC) - time.Sleep(30 * time.Second) // Give some time for the permissionless node to get synced - clientL2Permissionless, err := ethclient.Dial(operations.PermissionlessL2NetworkURL) - require.NoError(t, err) - expectedBlock, err := clientL2.BlockByNumber(ctx, nil) - require.NoError(t, err) - actualBlock, err := clientL2Permissionless.BlockByNumber(ctx, nil) - require.NoError(t, err) - // je, err := expectedBlock.Header().MarshalJSON() - // require.NoError(t, err) - // log.Info(string(je)) - // ja, err := actualBlock.Header().MarshalJSON() - // require.NoError(t, err) - // log.Info(string(ja)) - // require.Equal(t, string(je), string(ja)) - require.Equal(t, expectedBlock.Root().Hex(), actualBlock.Root().Hex()) -} - -func createKeyStore(pk *ecdsa.PrivateKey, outputDir, password string) error { - ks := keystore.NewKeyStore(outputDir+"_", keystore.StandardScryptN, keystore.StandardScryptP) - _, err := ks.ImportECDSA(pk, password) - if err != nil { - return err - } - fileNameB, err := exec.Command("ls", outputDir+"_/").CombinedOutput() - fileName := strings.TrimSuffix(string(fileNameB), "\n") - if err != nil { - fmt.Println(fileName) - return err - } - out, err := exec.Command("mv", outputDir+"_/"+fileName, outputDir).CombinedOutput() - if err != nil { - fmt.Println(string(out)) - return err - } - return nil -} From 7e30b5a620e8a6d4ad0c4da284592dc0db808402 Mon Sep 17 00:00:00 2001 From: dndll Date: Wed, 17 Apr 2024 11:12:06 +0100 Subject: [PATCH 5/5] test: automatically set DAP for run-near --- test/Makefile | 9 +- .../near/sandbox.Dockerfile} | 0 test/docker-compose.yml | 10 +- test/scripts/nearda/main.go | 124 ++++++++++++++++++ 4 files changed, 135 insertions(+), 8 deletions(-) rename test/{images/near-sandbox.Dockerfile => config/near/sandbox.Dockerfile} (100%) create mode 100644 test/scripts/nearda/main.go diff --git a/test/Makefile b/test/Makefile index 789391512c..6ce1874290 100644 --- a/test/Makefile +++ b/test/Makefile @@ -612,12 +612,11 @@ run-near: $(RUNL1NETWORK) $(DOCKERCOMPOSE) up -d --build near-localnet sleep 1 - $(DOCKERCOMPOSE) up near-localnet-print-key + $(DOCKERCOMPOSE) up near-localnet-set-key $(RUNZKPROVER) $(RUNPERMISSIONLESSZKPROVER) $(RUNAPPROVE) - # state for this - NEWCONTRACT=$$(cd /home/common/projects/data-availability/rollup-data-availability/eth && forge script Deploy --fork-url local --broadcast --legacy --json | jq -R 'fromjson?' | jq -r '.returns.da.value') $(DOCKERCOMPOSE) up -d near-set-dap + make deploy-nearda $(RUNPERMISSIONLESSNODENEAR) # sleep 3 $(RUNSYNC) @@ -690,6 +689,10 @@ send-transfers: ## sends some ETH transfers txs to test the network deploy-uniswap: ## deploy the uniswap environment to the network go run ./scripts/uniswap/main.go . +.PHONY: deploy-nearda +deploy-nearda: + go run ./scripts/nearda/main.go . + .PHONY: run-db-scripts run-db-scripts: ## Executes scripts on the db after it has been initialized, potentially using info from the environment ./scripts/postgres/run.sh diff --git a/test/images/near-sandbox.Dockerfile b/test/config/near/sandbox.Dockerfile similarity index 100% rename from test/images/near-sandbox.Dockerfile rename to test/config/near/sandbox.Dockerfile diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 87f5efc7b0..4b345d26d0 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -735,11 +735,11 @@ services: ports: - 6565:5888 - near-localnet-print-key: - container_name: near-localnet-print-key + near-localnet-set-key: + container_name: near-localnet-set-key build: context: ./config/near - dockerfile: images/near-sandbox.Dockerfile + dockerfile: sandbox.Dockerfile volumes: - near-sandbox-data:/root/.near - ./config/near-http-sidecar.json:/config.json @@ -751,8 +751,8 @@ services: near-localnet: container_name: near-localnet build: - context: ./images - dockerfile: near-sandbox.Dockerfile + context: ./config/near + dockerfile: sandbox.Dockerfile volumes: - near-sandbox-data:/root/.near ports: diff --git a/test/scripts/nearda/main.go b/test/scripts/nearda/main.go new file mode 100644 index 0000000000..90e6a6c616 --- /dev/null +++ b/test/scripts/nearda/main.go @@ -0,0 +1,124 @@ +package main + +import ( + "context" + "fmt" + + etrog "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevm" + nearda "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/neardataavailability" + + "math/big" + "strings" + "time" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/test/operations" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" +) + +const () + +var ( + executedTransctionsCount uint64 = 0 +) + +const ( + txTimeout = 60 * time.Second + // if you want to test using goerli network + // replace this by your goerli infura url + //networkURL = "http://localhost:8123" + networkURL = "http://localhost:8545" + //pk = "0xdfd01798f92667dbf91df722434e8fbe96af0211d4d1b82bbbbc8f1def7a814f" + pk = operations.DefaultSequencerPrivateKey + zkEvmAddr = operations.DefaultL1ZkEVMSmartContract +) + +type Deployments struct { + NearDA *nearda.Neardataavailability + NearDAAddr common.Address +} + +func main() { + ctx := context.Background() + log.Infof("connecting to %v", networkURL) + client, err := ethclient.Dial(networkURL) + ChkErr(err) + + log.Infof("connected") + chainID, err := client.ChainID(ctx) + ChkErr(err) + + log.Infof("chainID: %v", chainID) + auth := GetAuth(ctx, client, pk) + fmt.Println() + deployments := DeployContractsAndSetDap(client, auth) + log.Infof("deployed: %v", deployments.NearDAAddr.Hex()) +} + +func DeployContractsAndSetDap(client *ethclient.Client, auth *bind.TransactOpts) Deployments { + ctx := context.Background() + fmt.Println() + addr, tx, neardataavailability, err := nearda.DeployNeardataavailability(auth, client) + fmt.Println() + err = WaitForTransactionAndIncrementNonce(client, auth, err, ctx, tx) + log.Debugf("Deploy tx: %v", tx.Hash().Hex()) + log.Debugf("Addr: %v", addr.Hex()) + fmt.Println() + ChkErr(err) + // Set DAP + log.Debugf("Setting DAP on %v to %v", zkEvmAddr, addr) + etrog, err := etrog.NewEtrogpolygonzkevm(common.HexToAddress(zkEvmAddr), client) + etrog.SetDataAvailabilityProtocol(auth, addr) + fmt.Println() + ChkErr(err) + + return Deployments{ + NearDA: neardataavailability, + NearDAAddr: addr, + } +} + +func WaitForTransactionAndIncrementNonce(l2Client *ethclient.Client, auth *bind.TransactOpts, err error, ctx context.Context, tx *types.Transaction) error { + ChkErr(err) + err = operations.WaitTxToBeMined(ctx, l2Client, tx, txTimeout) + ChkErr(err) + executedTransctionsCount++ + auth.Nonce = nil + auth.Value = nil + + return err +} + +func GetAuth(ctx context.Context, client *ethclient.Client, pkHex string) *bind.TransactOpts { + chainID, err := client.ChainID(ctx) + ChkErr(err) + privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(pkHex, "0x")) + ChkErr(err) + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) + ChkErr(err) + senderNonce, err := client.PendingNonceAt(ctx, auth.From) + if err != nil { + panic(err) + } + auth.Nonce = big.NewInt(int64(senderNonce)) + return auth +} + +func ChkErr(err error) { + if err != nil { + log.Fatal(err) + } +} + +func GetExecutedTransactionsCount() uint64 { + return executedTransctionsCount +} + +func getDeadline() *big.Int { + const deadLinelimit = 5 * time.Minute + return big.NewInt(time.Now().UTC().Add(deadLinelimit).Unix()) +}