diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 4c38f4c7..37343253 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22.7" - name: Checkout uses: actions/checkout@v4 - name: GolangCI Lint diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 80aaca35..54c2fc37 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -35,7 +35,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22.7" - name: Checkout uses: actions/checkout@v4 - name: Test diff --git a/Dockerfile b/Dockerfile index 91c6b27f..0906a3b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/rss3-network/go-image/go-builder:main-4782eed AS base +FROM ghcr.io/rss3-network/go-image/go-builder:main-230cb74 AS base WORKDIR /root/node @@ -19,7 +19,7 @@ ENV CGO_ENABLED=0 RUN --mount=type=cache,target=/go/pkg/mod/ \ make build -FROM ghcr.io/rss3-network/go-image/go-runtime:main-4782eed AS runner +FROM ghcr.io/rss3-network/go-image/go-builder:main-230cb74 AS runner WORKDIR /root/node diff --git a/docs/api.yaml b/docs/api.yaml index ce9c05b4..228aab05 100644 --- a/docs/api.yaml +++ b/docs/api.yaml @@ -27,6 +27,8 @@ paths: $ref: "./path/decentralized/network.yaml" /decentralized/platform/{platform}: $ref: "./path/decentralized/platform.yaml" + /decentralized/metadata: + $ref: "./path/decentralized/metadata.yaml" /federated/tx/{id}: $ref: "./path/federated/tx.yaml" diff --git a/docs/generated.go b/docs/generated.go index cf18a90a..dda0002c 100644 --- a/docs/generated.go +++ b/docs/generated.go @@ -19,6 +19,7 @@ import ( "github.com/rss3-network/node/schema/worker/federated" "github.com/rss3-network/protocol-go/schema" activityx "github.com/rss3-network/protocol-go/schema/activity" + "github.com/rss3-network/protocol-go/schema/metadata" "github.com/rss3-network/protocol-go/schema/network" "github.com/rss3-network/protocol-go/schema/tag" ) @@ -59,6 +60,34 @@ type PostDecentralizedAccountsJSONBody struct { UntilTimestamp *uint64 `json:"until_timestamp,omitempty"` } +// PostDecentralizedMetadataJSONBody defines parameters for PostDecentralizedMetadata. +type PostDecentralizedMetadataJSONBody struct { + Accounts []string `json:"accounts,omitempty"` + + // ActionLimit Specify the number of actions within the activity to retrieve + ActionLimit *int `default:"10" json:"action_limit,omitempty" validate:"min=1,max=20"` + + // Cursor Specify the cursor used for pagination + Cursor *string `json:"cursor,omitempty"` + + // Limit Specify the number of activities to retrieve + Limit *int `default:"100" json:"limit,omitempty" validate:"min=1,max=100"` + Metadata *metadata.Metadata `json:"metadata,omitempty" validate:"required"` + Network *network.Network `json:"network,omitempty" validate:"required"` + Platform *decentralized.Platform `json:"platform,omitempty"` + + // SinceTimestamp The timestamp of when the activity occurred. + SinceTimestamp *uint64 `json:"since_timestamp,omitempty"` + + // Status Retrieve activities based on success status + Status *bool `json:"success,omitempty"` + Tag *tag.Tag `json:"tag,omitempty" validate:"required"` + Type *schema.Type `json:"type,omitempty" validate:"required"` + + // UntilTimestamp The timestamp of when the activity occurred. + UntilTimestamp *uint64 `json:"until_timestamp,omitempty"` +} + // GetDecentralizedNetworkParams defines parameters for GetDecentralizedNetwork. type GetDecentralizedNetworkParams struct { // Limit Specify the number of activities to retrieve. @@ -316,6 +345,9 @@ type GetFederatedAccountParams struct { // PostDecentralizedAccountsJSONRequestBody defines body for PostDecentralizedAccounts for application/json ContentType. type PostDecentralizedAccountsJSONRequestBody PostDecentralizedAccountsJSONBody +// PostDecentralizedMetadataJSONRequestBody defines body for PostDecentralizedMetadata for application/json ContentType. +type PostDecentralizedMetadataJSONRequestBody PostDecentralizedMetadataJSONBody + // PostFederatedAccountsJSONRequestBody defines body for PostFederatedAccounts for application/json ContentType. type PostFederatedAccountsJSONRequestBody PostFederatedAccountsJSONBody @@ -324,6 +356,9 @@ type ServerInterface interface { // Batch Get Accounts Activities // (POST /decentralized/accounts) PostDecentralizedAccounts(ctx echo.Context) error + // Batch Get Activities By Metadata + // (POST /decentralized/metadata) + PostDecentralizedMetadata(ctx echo.Context) error // Get Network Activities // (GET /decentralized/network/{network}) GetDecentralizedNetwork(ctx echo.Context, network network.Network, params GetDecentralizedNetworkParams) error @@ -387,6 +422,17 @@ func (w *ServerInterfaceWrapper) PostDecentralizedAccounts(ctx echo.Context) err return err } +// PostDecentralizedMetadata converts echo context to params. +func (w *ServerInterfaceWrapper) PostDecentralizedMetadata(ctx echo.Context) error { + var err error + + ctx.Set(BearerAuthScopes, []string{}) + + // Invoke the callback with all the unmarshaled arguments + err = w.Handler.PostDecentralizedMetadata(ctx) + return err +} + // GetDecentralizedNetwork converts echo context to params. func (w *ServerInterfaceWrapper) GetDecentralizedNetwork(ctx echo.Context) error { var err error @@ -715,6 +761,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL } router.POST(baseURL+"/decentralized/accounts", wrapper.PostDecentralizedAccounts) + router.POST(baseURL+"/decentralized/metadata", wrapper.PostDecentralizedMetadata) router.GET(baseURL+"/decentralized/network/:network", wrapper.GetDecentralizedNetwork) router.GET(baseURL+"/decentralized/platform/:platform", wrapper.GetDecentralizedPlatform) router.GET(baseURL+"/decentralized/tx/:id", wrapper.GetDecentralizedTxID) @@ -736,175 +783,178 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "/5e+BJ6WJgEA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/docs/path/decentralized/metadata.yaml b/docs/path/decentralized/metadata.yaml new file mode 100644 index 00000000..61b5d257 --- /dev/null +++ b/docs/path/decentralized/metadata.yaml @@ -0,0 +1,17 @@ +post: + operationId: PostDecentralizedMetadata + summary: Batch Get Activities By Metadata + description: Retrieve a batch of activities associated with multiple specified metadata in the decentralized system. You can use various query parameters to filter and paginate the results, including limits on the number of activities and actions, timestamps, success status, direction, and more. + tags: + - Decentralized + security: + - bearerAuth: [ ] + requestBody: + $ref: "../../requestBody/BatchGetDecentralizedMetadataActivities.yaml" + responses: + '200': + $ref: "../../responses/DecentralizedActivitiesResponse.yaml" + '400': + $ref: "../../responses/BadRequest.yaml" + '500': + $ref: "../../responses/InternalError.yaml" diff --git a/docs/requestBody/BatchGetDecentralizedMetadataActivities.yaml b/docs/requestBody/BatchGetDecentralizedMetadataActivities.yaml new file mode 100644 index 00000000..10610f71 --- /dev/null +++ b/docs/requestBody/BatchGetDecentralizedMetadataActivities.yaml @@ -0,0 +1,50 @@ +description: Request body for batch retrieving activities for specified metadata, network and tag and type is required +required: true +content: + application/json: + schema: + type: object + properties: + accounts: + type: array + items: + $ref: "../schemas/DecentralizedAccount.yaml" + x-go-type-skip-optional-pointer: true + limit: + $ref: "../schemas/Limit.yaml" + action_limit: + $ref: "../schemas/ActionLimit.yaml" + cursor: + $ref: "../schemas/Cursor.yaml" + since_timestamp: + $ref: "../schemas/Timestamp.yaml" + until_timestamp: + $ref: "../schemas/Timestamp.yaml" + success: + $ref: "../schemas/Success.yaml" + network: + type: object + allOf: + - $ref: "../schemas/ProtocolNetwork.yaml" + x-oapi-codegen-extra-tags: + validate: "required" + tag: + type: object + allOf: + - $ref: "../schemas/ProtocolTag.yaml" + x-oapi-codegen-extra-tags: + validate: "required" + type: + type: string + allOf: + - $ref: "../schemas/ProtocolType.yaml" + x-oapi-codegen-extra-tags: + validate: "required" + platform: + $ref: "../schemas/DecentralizedPlatform.yaml" + metadata: + type: object + allOf: + - $ref: "../schemas/ProtocolMetadata.yaml" + x-oapi-codegen-extra-tags: + validate: "required" diff --git a/docs/schemas/DecentralizedPlatform.yaml b/docs/schemas/DecentralizedPlatform.yaml index 67f608e1..47375d30 100644 --- a/docs/schemas/DecentralizedPlatform.yaml +++ b/docs/schemas/DecentralizedPlatform.yaml @@ -37,6 +37,5 @@ enum: - VSL - Zerion x-go-type: decentralized.Platform -x-go-type-skip-optional-pointer: true x-go-type-import: - path: github.com/rss3-network/node/schema/worker/decentralized \ No newline at end of file + path: github.com/rss3-network/node/schema/worker/decentralized diff --git a/docs/schemas/ProtocolMetadata.yaml b/docs/schemas/ProtocolMetadata.yaml index 16682d6b..eff9c530 100644 --- a/docs/schemas/ProtocolMetadata.yaml +++ b/docs/schemas/ProtocolMetadata.yaml @@ -3,6 +3,5 @@ type: object allOf: - $ref: "https://raw.githubusercontent.com/RSS3-Network/Protocol-Go/refs/heads/main/openapi/Metadata.yaml" - x-go-type: metadata.Metadata - x-go-type-skip-optional-pointer: true x-go-type-import: - path: github.com/rss3-network/protocol-go/schema/metadata \ No newline at end of file + path: github.com/rss3-network/protocol-go/schema/metadata diff --git a/docs/schemas/ProtocolNetwork.yaml b/docs/schemas/ProtocolNetwork.yaml index db868505..d943f656 100644 --- a/docs/schemas/ProtocolNetwork.yaml +++ b/docs/schemas/ProtocolNetwork.yaml @@ -1,3 +1,4 @@ allOf: - $ref: "https://raw.githubusercontent.com/RSS3-Network/Protocol-Go/refs/heads/main/openapi/enum/Network.yaml" -# - x-go-type: string \ No newline at end of file +# - x-go-type: string +x-go-type-skip-optional-pointer: true \ No newline at end of file diff --git a/docs/schemas/ProtocolTag.yaml b/docs/schemas/ProtocolTag.yaml index 03cfc451..95bf6716 100644 --- a/docs/schemas/ProtocolTag.yaml +++ b/docs/schemas/ProtocolTag.yaml @@ -1,2 +1,3 @@ allOf: - - $ref: "https://raw.githubusercontent.com/RSS3-Network/Protocol-Go/refs/heads/main/openapi/enum/Tag.yaml" \ No newline at end of file + - $ref: "https://raw.githubusercontent.com/RSS3-Network/Protocol-Go/refs/heads/main/openapi/enum/Tag.yaml" +x-go-type-skip-optional-pointer: true \ No newline at end of file diff --git a/docs/schemas/ProtocolType.yaml b/docs/schemas/ProtocolType.yaml index a8f8be55..98d06137 100644 --- a/docs/schemas/ProtocolType.yaml +++ b/docs/schemas/ProtocolType.yaml @@ -1,6 +1,6 @@ allOf: - $ref: "https://raw.githubusercontent.com/RSS3-Network/Protocol-Go/refs/heads/main/openapi/Type.yaml" - x-go-type: schema.Type - x-go-type-skip-optional-pointer: true x-go-type-import: path: github.com/rss3-network/protocol-go/schema +x-go-type-skip-optional-pointer: true \ No newline at end of file diff --git a/go.mod b/go.mod index fc5f8388..94113927 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,6 @@ module github.com/rss3-network/node -go 1.22.4 -toolchain go1.22.10 +go 1.22.7 replace ( github.com/chenzhuoyu/iasm => github.com/cloudwego/iasm v0.2.0 @@ -40,15 +39,15 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/twmb/franz-go v1.18.0 github.com/twmb/franz-go/pkg/kadm v1.14.0 - go.opentelemetry.io/otel v1.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 - go.opentelemetry.io/otel/exporters/prometheus v0.55.0 + go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 + go.opentelemetry.io/otel/exporters/prometheus v0.54.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 - go.opentelemetry.io/otel/metric v1.33.0 - go.opentelemetry.io/otel/sdk v1.33.0 - go.opentelemetry.io/otel/sdk/metric v1.33.0 - go.opentelemetry.io/otel/trace v1.33.0 + go.opentelemetry.io/otel/metric v1.32.0 + go.opentelemetry.io/otel/sdk v1.32.0 + go.opentelemetry.io/otel/sdk/metric v1.32.0 + go.opentelemetry.io/otel/trace v1.32.0 go.uber.org/zap v1.27.0 golang.org/x/sync v0.10.0 gopkg.in/yaml.v3 v3.0.1 // indirect @@ -133,7 +132,7 @@ require ( github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -215,7 +214,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/reiver/go-atproto v0.0.0-20240906195827-a1832b0df821 // indirect github.com/reiver/go-cast v0.0.0-20240904124821-be0103637c3f // indirect @@ -253,9 +252,8 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect - go.opentelemetry.io/proto/otlp v1.4.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.30.0 // indirect @@ -266,10 +264,10 @@ require ( golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect - google.golang.org/grpc v1.68.1 // indirect - google.golang.org/protobuf v1.35.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index 795f56ba..6a25a6a8 100644 --- a/go.sum +++ b/go.sum @@ -216,8 +216,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -251,8 +249,8 @@ github.com/grafana/pyroscope-go v1.2.0 h1:aILLKjTj8CS8f/24OPMGPewQSYlhmdQMBmol1d github.com/grafana/pyroscope-go v1.2.0/go.mod h1:2GHr28Nr05bg2pElS+dDsc98f3JTUh2f6Fz1hWXrqwk= github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hamba/avro v1.8.0 h1:eCVrLX7UYThA3R3yBZ+rpmafA5qTc3ZjpTz6gYJoVGU= github.com/hamba/avro v1.8.0/go.mod h1:NiGUcrLLT+CKfGu5REWQtD9OVPPYUGMVFiC+DE0lQfY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -567,8 +565,8 @@ github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+ github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= +github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= @@ -756,30 +754,28 @@ gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRyS gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8= gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q= gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= -go.opentelemetry.io/otel/exporters/prometheus v0.55.0 h1:sSPw658Lk2NWAv74lkD3B/RSDb+xRFx46GjkrL3VUZo= -go.opentelemetry.io/otel/exporters/prometheus v0.55.0/go.mod h1:nC00vyCmQixoeaxF6KNyP42II/RHa9UdruK02qBmHvI= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= +go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU= +go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/metric v1.33.0 h1:Gs5VK9/WUJhNXZgn8MR6ITatvAmKeIuCtNbsP3JkNqU= -go.opentelemetry.io/otel/sdk/metric v1.33.0/go.mod h1:dL5ykHZmm1B1nVRk9dDjChwDmt81MjVp3gLkQRwKf/Q= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= -go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= -go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -937,12 +933,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -951,8 +947,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/database/client.go b/internal/database/client.go index e5b5fe78..45779818 100644 --- a/internal/database/client.go +++ b/internal/database/client.go @@ -31,6 +31,7 @@ type Client interface { SaveActivities(ctx context.Context, activities []*activityx.Activity, lowPriority bool) error FindActivity(ctx context.Context, query model.ActivityQuery) (*activityx.Activity, *int, error) FindActivities(ctx context.Context, query model.ActivitiesQuery) ([]*activityx.Activity, error) + FindActivitiesMetadata(ctx context.Context, query model.ActivitiesMetadataQuery) ([]*activityx.Activity, error) DeleteExpiredActivities(ctx context.Context, network network.Network, timestamp time.Time) error } diff --git a/internal/database/dialer/postgres/client.go b/internal/database/dialer/postgres/client.go index 8a7e78f9..3821bc62 100644 --- a/internal/database/dialer/postgres/client.go +++ b/internal/database/dialer/postgres/client.go @@ -331,6 +331,15 @@ func (c *client) FindActivities(ctx context.Context, query model.ActivitiesQuery return nil, fmt.Errorf("not implemented") } +// FindActivitiesMetadata finds Activities by metadata. +func (c *client) FindActivitiesMetadata(ctx context.Context, query model.ActivitiesMetadataQuery) ([]*activityx.Activity, error) { + if c.partition { + return c.findActivitiesMetadataPartitioned(ctx, query) + } + + return nil, fmt.Errorf("not implemented") +} + // DeleteExpiredActivities deletes expired activities. func (c *client) DeleteExpiredActivities(ctx context.Context, network networkx.Network, timestamp time.Time) error { if c.partition { @@ -573,7 +582,7 @@ func Dial(ctx context.Context, dataSourceName string, partition bool) (database. } if instance.partition { - instance.loadIndexesPartitionTables(ctx) + instance.loadPartitionTables(ctx) } return &instance, nil diff --git a/internal/database/dialer/postgres/client_partitioned.go b/internal/database/dialer/postgres/client_partitioned.go index b81b1df7..f8f724e7 100644 --- a/internal/database/dialer/postgres/client_partitioned.go +++ b/internal/database/dialer/postgres/client_partitioned.go @@ -12,6 +12,7 @@ import ( "github.com/rss3-network/node/internal/database/dialer/postgres/table" "github.com/rss3-network/node/internal/database/model" activityx "github.com/rss3-network/protocol-go/schema/activity" + "github.com/rss3-network/protocol-go/schema/metadata" "github.com/rss3-network/protocol-go/schema/network" "github.com/samber/lo" "github.com/sourcegraph/conc/pool" @@ -23,6 +24,8 @@ import ( var indexesTables sync.Map +var activitiesTables sync.Map + // createPartitionTable creates a partition table. func (c *client) createPartitionTable(ctx context.Context, name, template string) error { statement := fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "%s" (LIKE "%s" INCLUDING ALL);`, name, template) @@ -39,6 +42,10 @@ func (c *client) createPartitionTable(ctx context.Context, name, template string indexesTables.Store(name, struct{}{}) } + if template == (*table.Activity).TableName(nil) { + activitiesTables.Store(name, struct{}{}) + } + zap.L().Debug("successfully created partition table", zap.String("statement", statement)) @@ -101,8 +108,61 @@ func (c *client) findIndexesPartitionTables(_ context.Context, index table.Index return partitionedNames } -// loadIndexesPartitionTables loads indexes partition tables. -func (c *client) loadIndexesPartitionTables(ctx context.Context) { +// findActivitiesPartitionTables finds activities partition tables. +func (c *client) findActivitiesPartitionTables(_ context.Context, query model.ActivitiesMetadataQuery) []string { + if query.Network == nil { + return nil + } + + timestamp := time.Now() + + if query.EndTimestamp != nil && *query.EndTimestamp > 0 && *query.EndTimestamp < uint64(time.Now().Unix()) { + timestamp = time.Unix(int64(lo.FromPtr(query.EndTimestamp)), 0) + } + + if query.Cursor != nil && query.Cursor.Timestamp < uint64(timestamp.Unix()) { + timestamp = time.Unix(int64(query.Cursor.Timestamp), 0) + } + + zap.L().Debug("finding activities partition tables", + zap.String("network", query.Network.String()), + zap.Time("timestamp", timestamp)) + + partitionedNames := make([]string, 0) + + for i := 0; i <= 4; i++ { + activityTable := table.Activity{ + Network: lo.FromPtr(query.Network), + Timestamp: timestamp, + } + + if timestamp.Unix() < time.Now().AddDate(-1, 0, 0).Unix() { + zap.L().Debug("timestamp is older than 1 year, stopping search", + zap.Time("timestamp", timestamp)) + break + } + + if _, exists := activitiesTables.Load(activityTable.PartitionName(nil)); exists { + partitionedNames = append(partitionedNames, activityTable.PartitionName(nil)) + } + + year := timestamp.Year() + month := timestamp.Month() + + timestamp = time.Date(lo.Ternary(month < 3, year-1, year), lo.Ternary(month < 3, month+9, month-3), timestamp.Day(), 23, 59, 59, 1e9-1, time.Local) + + zap.L().Debug("updated timestamp for next iteration", + zap.Time("new_timestamp", timestamp)) + } + + zap.L().Debug("completed finding activities partition tables", + zap.Any("found_tables", partitionedNames)) + + return partitionedNames +} + +// loadPartitionTables loads partition tables. +func (c *client) loadPartitionTables(ctx context.Context) { result := make([]string, 0) if err := c.database.WithContext(ctx).Table("pg_tables").Where("tablename LIKE ?", fmt.Sprintf("%s_%%", (*table.Index).TableName(nil))).Pluck("tablename", &result).Error; err != nil { @@ -112,6 +172,14 @@ func (c *client) loadIndexesPartitionTables(ctx context.Context) { for _, tableName := range result { indexesTables.Store(tableName, struct{}{}) } + + if err := c.database.WithContext(ctx).Table("pg_tables").Where("tablename LIKE ?", fmt.Sprintf("%s_%%", (*table.Activity).TableName(nil))).Pluck("tablename", &result).Error; err != nil { + zap.L().Error("failed to load activities partition tables", zap.Error(err)) + } + + for _, tableName := range result { + activitiesTables.Store(tableName, struct{}{}) + } } // saveActivitiesPartitioned saves Activities in partitioned tables. @@ -260,6 +328,104 @@ func (c *client) findActivityPartitioned(ctx context.Context, query model.Activi return result, lo.ToPtr(int(page)), nil } +// findActivitiesMetadataPartitioned finds activities metadata. +func (c *client) findActivitiesMetadataPartitioned(ctx context.Context, query model.ActivitiesMetadataQuery) ([]*activityx.Activity, error) { + partitionedNames := c.findActivitiesPartitionTables(ctx, query) + + if len(partitionedNames) == 0 { + return nil, nil + } + + ctx, cancel := context.WithCancel(ctx) + errorGroup, errorContext := errgroup.WithContext(ctx) + activities := make([]table.Activities, len(partitionedNames)) + resultChan := make(chan int, len(partitionedNames)) + errorChan := make(chan error) + stopChan := make(chan struct{}) + + var mutex sync.RWMutex + + for partitionedIndex, partitionedName := range partitionedNames { + partitionedIndex, partitionedName := partitionedIndex, partitionedName + + errorGroup.Go(func() error { + var result table.Activities + + databaseStatement := c.buildFindActivitiesStatement(errorContext, partitionedName, query) + + if err := databaseStatement.Find(&result).Error; err != nil { + return fmt.Errorf("failed to find activities metadata: %w", err) + } + + mutex.Lock() + activities[partitionedIndex] = result + mutex.Unlock() + + select { + case <-stopChan: + return nil + case resultChan <- partitionedIndex: + return nil + } + }) + } + + go func() { + defer close(errorChan) + + errorChan <- errorGroup.Wait() + }() + + defer func() { + cancel() + }() + + for { + select { + case err := <-errorChan: + if err != nil { + return nil, fmt.Errorf("failed to wait result: %w", err) + } + case <-resultChan: + result := make(table.Activities, 0, query.Limit) + flag := true + + mutex.RLock() + + for _, data := range activities { + data := data + + if data == nil { + flag = false + break + } + + result = append(result, data...) + + if len(result) >= query.Limit { + zap.L().Debug("found indexes up to limit", + zap.Int("count", query.Limit)) + close(stopChan) + mutex.RUnlock() + + data := result[:query.Limit] + + return data.Export() + } + } + + mutex.RUnlock() + + if flag { + zap.L().Debug("successfully found all indexes", + zap.Int("count", len(result))) + + return result.Export() + } + } + } +} + // findActivitiesPartitioned finds activities. func (c *client) findActivitiesPartitioned(ctx context.Context, query model.ActivitiesQuery) ([]*activityx.Activity, error) { zap.L().Debug("finding activities in partitioned tables", @@ -844,6 +1010,67 @@ func (c *client) buildFindIndexesStatement(ctx context.Context, partition string return databaseStatement.Order("timestamp DESC, index DESC").Limit(query.Limit) } +// buildFindActivitiesStatement builds the query activities statement. +func (c *client) buildFindActivitiesStatement(ctx context.Context, partitionedName string, query model.ActivitiesMetadataQuery) *gorm.DB { + databaseStatement := c.database.WithContext(ctx).Table(partitionedName).Debug() + + if query.Platform != nil { + databaseStatement = databaseStatement.Where("platform = ?", query.Platform) + } + + if query.Tag != nil { + databaseStatement = databaseStatement.Where("tag = ?", query.Tag) + } + + if query.Type != nil { + databaseStatement = databaseStatement.Where("type = ?", query.Type) + } + + if query.StartTimestamp != nil && *query.StartTimestamp > 0 { + databaseStatement = databaseStatement.Where("timestamp >= ?", time.Unix(int64(*query.StartTimestamp), 0)) + } + + if query.EndTimestamp != nil && *query.EndTimestamp > 0 { + databaseStatement = databaseStatement.Where("timestamp <= ?", time.Unix(int64(*query.EndTimestamp), 0)) + } + + if query.Accounts != nil { + databaseStatement = databaseStatement.Where("from IN (?) OR to IN (?)", query.Accounts, query.Accounts) + } + + if query.Cursor != nil && query.Cursor.Timestamp > 0 { + databaseStatement = databaseStatement.Where("timestamp < ? OR (timestamp = ? AND index < ?)", time.Unix(int64(query.Cursor.Timestamp), 0), time.Unix(int64(query.Cursor.Timestamp), 0), query.Cursor.Index) + } + + if query.Metadata != nil { + databaseStatement = c.buildFindActivitiesMetadataStatement(ctx, databaseStatement, lo.FromPtr(query.Metadata)) + } + + return databaseStatement.Order("timestamp DESC, index DESC").Limit(query.Limit) +} + +// buildFindActivitiesMetadataStatement builds the query metadata statement. +func (c *client) buildFindActivitiesMetadataStatement(_ context.Context, databaseStatement *gorm.DB, meta metadata.Metadata) *gorm.DB { + statement := databaseStatement.Session(&gorm.Session{}) + + statement = statement.Joins("CROSS JOIN LATERAL jsonb_array_elements(actions::jsonb) AS action_element") + + switch data := meta.(type) { + case *metadata.ExchangeSwap: + if data.From.Address != nil { + statement = statement.Where("action_element -> 'metadata' -> 'from' ->> 'address' = ?", data.From.Address) + } + + if data.To.Address != nil { + statement = statement.Where("action_element -> 'metadata' -> 'to' ->> 'address' = ?", data.To.Address) + } + default: + return databaseStatement + } + + return statement +} + // buildActivitiesTableNames builds the activities table names. func (c *client) buildActivitiesTableNames(network network.Network, timestamp time.Time) string { return fmt.Sprintf("%s_%s_%d_q%d", (*table.Activity).TableName(nil), network, timestamp.Year(), int(timestamp.Month()-1)/3+1) diff --git a/internal/database/dialer/postgres/migration/20241218042140_add_activities_indexes.sql b/internal/database/dialer/postgres/migration/20241218042140_add_activities_indexes.sql new file mode 100644 index 00000000..a3851806 --- /dev/null +++ b/internal/database/dialer/postgres/migration/20241218042140_add_activities_indexes.sql @@ -0,0 +1,11 @@ +-- +goose Up +-- +goose StatementBegin +CREATE INDEX IF NOT EXISTS activities_id_platform_index ON public.activities (platform); +CREATE INDEX IF NOT EXISTS activities_id_tag_and_type_index ON public.activities (tag, type); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP INDEX IF EXISTS public.activities_id_platform_index; +DROP INDEX IF EXISTS public.activities_id_tag_and_type_index; +-- +goose StatementEnd diff --git a/internal/database/model/activity.go b/internal/database/model/activity.go index df87f55f..9f209388 100644 --- a/internal/database/model/activity.go +++ b/internal/database/model/activity.go @@ -1,8 +1,10 @@ package model import ( + "github.com/rss3-network/node/schema/worker/decentralized" "github.com/rss3-network/protocol-go/schema" activityx "github.com/rss3-network/protocol-go/schema/activity" + "github.com/rss3-network/protocol-go/schema/metadata" "github.com/rss3-network/protocol-go/schema/network" "github.com/rss3-network/protocol-go/schema/tag" ) @@ -33,3 +35,18 @@ type ActivitiesQuery struct { Limit int ActionLimit int } + +type ActivitiesMetadataQuery struct { + Network *network.Network + Platform *decentralized.Platform + Tag *tag.Tag + Type *schema.Type + Accounts []string + Cursor *activityx.Activity + Status *bool + StartTimestamp *uint64 + EndTimestamp *uint64 + Limit int + ActionLimit int + Metadata *metadata.Metadata +} diff --git a/internal/node/component/aggregator/compoent.go b/internal/node/component/aggregator/component.go similarity index 96% rename from internal/node/component/aggregator/compoent.go rename to internal/node/component/aggregator/component.go index ba53930b..c96696e6 100644 --- a/internal/node/component/aggregator/compoent.go +++ b/internal/node/component/aggregator/component.go @@ -27,6 +27,10 @@ func (c Component) PostDecentralizedAccounts(ctx echo.Context) error { return c.Decentralized.BatchGetAccountsActivities(ctx) } +func (c Component) PostDecentralizedMetadata(ctx echo.Context) error { + return c.Decentralized.BatchGetMetadataActivities(ctx) +} + func (c Component) GetDecentralizedNetwork(ctx echo.Context, network network.Network, params docs.GetDecentralizedNetworkParams) error { return c.Decentralized.GetNetworkActivities(ctx, network, params) } diff --git a/internal/node/component/decentralized/data.go b/internal/node/component/decentralized/data.go index ef07c68e..e068058a 100644 --- a/internal/node/component/decentralized/data.go +++ b/internal/node/component/decentralized/data.go @@ -29,6 +29,20 @@ func (c *Component) getActivities(ctx context.Context, request model.ActivitiesQ return nil, "", nil } +func (c *Component) getActivitiesMetadata(ctx context.Context, request model.ActivitiesMetadataQuery) ([]*activityx.Activity, string, error) { + activities, err := c.databaseClient.FindActivitiesMetadata(ctx, request) + if err != nil { + return nil, "", fmt.Errorf("failed to find activities: %w", err) + } + + last, exist := lo.Last(activities) + if exist { + return activities, c.transformCursor(ctx, last), nil + } + + return nil, "", nil +} + func (c *Component) getCursor(ctx context.Context, cursor *string) (*activityx.Activity, error) { if cursor == nil { return nil, nil diff --git a/internal/node/component/decentralized/handler_metadata.go b/internal/node/component/decentralized/handler_metadata.go new file mode 100644 index 00000000..0d319529 --- /dev/null +++ b/internal/node/component/decentralized/handler_metadata.go @@ -0,0 +1,114 @@ +package decentralized + +import ( + "encoding/json" + "fmt" + "net/http" + "strconv" + + "github.com/creasty/defaults" + "github.com/ethereum/go-ethereum/common" + "github.com/labstack/echo/v4" + "github.com/rss3-network/node/common/http/response" + "github.com/rss3-network/node/docs" + "github.com/rss3-network/node/internal/database/model" + "github.com/rss3-network/protocol-go/schema" + "github.com/rss3-network/protocol-go/schema/metadata" + "github.com/samber/lo" + "go.uber.org/zap" +) + +// BatchGetMetadataActivities returns the activities of specified decentralized metadata +func (c *Component) BatchGetMetadataActivities(ctx echo.Context) (err error) { + request := struct { + docs.PostDecentralizedMetadataJSONBody + RawType string `json:"type"` + RawMetadata json.RawMessage `json:"metadata"` + }{} + + if err = ctx.Bind(&request); err != nil { + return response.BadRequestError(ctx, err) + } + + if len(request.RawType) == 0 || request.Tag == nil { + return response.BadRequestError(ctx, fmt.Errorf("empty tag or type")) + } + + typex, err := schema.ParseTypeFromString(lo.FromPtr(request.Tag), request.RawType) + if err != nil { + return response.BadRequestError(ctx, fmt.Errorf("invalid type: %s", request.RawType)) + } + + request.Type = lo.ToPtr(typex) + + meta, err := metadata.Unmarshal(typex, request.RawMetadata) + if err != nil { + return response.BadRequestError(ctx, fmt.Errorf("failed to unmarshal metadata: %w", err)) + } + + request.Metadata = lo.ToPtr(meta) + + for i := range request.Accounts { + if common.IsHexAddress(request.Accounts[i]) { + request.Accounts[i] = common.HexToAddress(request.Accounts[i]).String() + } + } + + if err = defaults.Set(&request); err != nil { + return response.BadRequestError(ctx, err) + } + + if err = ctx.Validate(&request); err != nil { + return response.ValidationFailedError(ctx, err) + } + + go c.CollectTrace(ctx.Request().Context(), ctx.Request().RequestURI, strconv.Itoa(len(request.Accounts))) + + go c.CollectMetric(ctx.Request().Context(), ctx.Request().RequestURI, strconv.Itoa(len(request.Accounts))) + + addRecentRequest(ctx.Request().RequestURI) + + zap.L().Debug("processing batch get decentralized accounts activities request", + zap.Any("request", request)) + + cursor, err := c.getCursor(ctx.Request().Context(), request.Cursor) + if err != nil { + zap.L().Error("failed to get decentralized accounts activities cursor", + zap.String("cursor", lo.FromPtr(request.Cursor)), + zap.Error(err)) + + return response.BadRequestError(ctx, fmt.Errorf("invalid cursor: %w", err)) + } + + databaseRequest := model.ActivitiesMetadataQuery{ + Cursor: cursor, + StartTimestamp: request.SinceTimestamp, + EndTimestamp: request.UntilTimestamp, + Limit: lo.FromPtr(request.Limit), + ActionLimit: lo.FromPtr(request.ActionLimit), + Accounts: request.Accounts, + Platform: request.Platform, + Status: request.Status, + Network: request.Network, + Metadata: request.Metadata, + } + + activities, last, err := c.getActivitiesMetadata(ctx.Request().Context(), databaseRequest) + if err != nil { + zap.L().Error("failed to get activities", + zap.Error(err)) + + return response.InternalError(ctx) + } + + zap.L().Info("successfully retrieved decentralized metadata activities", + zap.Int("accounts_count", len(request.Accounts)), + zap.Int("count", len(activities))) + + return ctx.JSON(http.StatusOK, ActivitiesResponse{ + Data: c.TransformActivities(ctx.Request().Context(), activities), + Meta: lo.Ternary(len(activities) < databaseRequest.Limit, nil, &MetaCursor{ + Cursor: last, + }), + }) +} diff --git a/internal/node/component/decentralized/transformer_activity.go b/internal/node/component/decentralized/transformer_activity.go index 62a64f18..14d8e692 100644 --- a/internal/node/component/decentralized/transformer_activity.go +++ b/internal/node/component/decentralized/transformer_activity.go @@ -32,7 +32,7 @@ func (c *Component) TransformActivity(ctx context.Context, activity *activityx.A case tag.Social: *activity.Actions[index], err = c.TransformSocialType(ctx, activity.Network, activity.Platform, *actionPtr) default: - zap.L().Debug("unknown action tag, keeping original action", + zap.L().Debug("keeping original action", zap.String("id", activity.ID), zap.String("tag", action.Tag.String())) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 710ffdf7..93ab1801 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -1,10 +1,12 @@ package utils import ( + "encoding/json" "fmt" "math/big" "github.com/rss3-network/protocol-go/schema" + "github.com/rss3-network/protocol-go/schema/metadata" "github.com/rss3-network/protocol-go/schema/tag" ) @@ -47,3 +49,17 @@ func ParseTypes(types []string, tags []tag.Tag) ([]schema.Type, error) { return schemaTypes, nil } + +// ParseMetadata parses the metadata and returns the schema metadata +func ParseMetadata(metadataJSON json.RawMessage, typex schema.Type) (metadata.Metadata, error) { + if len(metadataJSON) == 0 { + return nil, nil + } + + value, err := metadata.Unmarshal(typex, metadataJSON) + if err != nil { + return nil, err + } + + return value, nil +}