From 17c3b9c50015df386612d896e559cca63e5507ca Mon Sep 17 00:00:00 2001 From: daniel <4954577+jaensen@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:00:08 +0200 Subject: [PATCH] allow to query tables and columns by name --- Circles.Index/.dockerignore | 1 + Circles.Index/Data/Query/Query.cs | 2 +- Circles.Index/Program.cs | 107 ------------------------ Circles.Index/Readme.md | 30 ++----- Circles.Index/Rpc/CirclesRpcModule.cs | 16 ++-- Circles.Index/Rpc/ICirclesRpcModule.cs | 6 +- Circles.Index/docker-compose.chiado.yml | 96 +++++++++++++++++++++ 7 files changed, 120 insertions(+), 138 deletions(-) create mode 100644 Circles.Index/docker-compose.chiado.yml diff --git a/Circles.Index/.dockerignore b/Circles.Index/.dockerignore index ba5afe5..3ae8779 100644 --- a/Circles.Index/.dockerignore +++ b/Circles.Index/.dockerignore @@ -1,3 +1,4 @@ .container-state +.state circles-contracts circles-contracts-v2 \ No newline at end of file diff --git a/Circles.Index/Data/Query/Query.cs b/Circles.Index/Data/Query/Query.cs index 6e675b2..4253324 100644 --- a/Circles.Index/Data/Query/Query.cs +++ b/Circles.Index/Data/Query/Query.cs @@ -78,7 +78,7 @@ public static object Convert(object input, ValueTypes target) case ValueTypes.String: return input.ToString() ?? throw new ArgumentNullException(nameof(input)); case ValueTypes.Int: - return System.Convert.ToInt64(input); + return System.Convert.ToInt64(input?.ToString()); case ValueTypes.BigInt when input is string i: return BigInteger.Parse(i); case ValueTypes.BigInt when input is BigInteger: diff --git a/Circles.Index/Program.cs b/Circles.Index/Program.cs index 6a02010..8982095 100644 --- a/Circles.Index/Program.cs +++ b/Circles.Index/Program.cs @@ -1,115 +1,8 @@ -using System.Data.Common; -using Circles.Index.Data; -using Circles.Index.Data.Query; -using Circles.Index.Rpc; -using Newtonsoft.Json; -using Npgsql; - namespace Circles.Index; public static class Program { public static void Main() { - DbProviderFactory factory = NpgsqlFactory.Instance; - Query.Initialize(factory); - - - CirclesQuery q = new() - { - Table = Tables.Erc20Transfer, Columns = - [ - Columns.BlockNumber, - Columns.TransactionIndex, - Columns.LogIndex, - Columns.TransactionHash, - Columns.FromAddress, - Columns.ToAddress, - Columns.Amount - ], - Conditions = - { - new Expression - { - Type = "LessThan", - Column = Columns.Amount, - Value = "500000000000000000000000000000" - }, - new Expression - { - Type = "Equals", - Column = Columns.FromAddress, - Value = "0x0000000000000000000000000000000000000000" - } - } - }; - - var json = JsonConvert.SerializeObject(q); - Console.WriteLine(json); - - var result = circles_query(q); - - foreach (var row in result) - { - Console.WriteLine(string.Join(", ", row)); - } - - Console.WriteLine("Hello, Circles!"); - } - - - public static IEnumerable circles_query(CirclesQuery query) - { - using NpgsqlConnection connection = new("Host=localhost;Username=postgres;Database=postgres;Port=7432;Include Error Detail=true;"); - connection.Open(); - - Schema.Migrate(connection); - - var select = Query.Select(query.Table, - query.Columns ?? throw new InvalidOperationException("Columns are null")); - - if (query.Conditions.Any()) - { - foreach (var condition in query.Conditions) - { - select.Where(BuildCondition(query.Table, condition)); - } - } - - Console.WriteLine(select.ToString()); - - var result = Query.Execute(connection, select).ToList(); - - return result; - } - - private static IQuery BuildCondition(Tables table, Expression expression) - { - if (expression.Type == "Equals") - { - return Query.Equals(table, expression.Column!.Value, expression.Value!); - } - - if (expression.Type == "GreaterThan") - { - return Query.GreaterThan(table, expression.Column!.Value, expression.Value!); - } - - if (expression.Type == "LessThan") - { - return Query.LessThan(table, expression.Column!.Value, expression.Value!); - } - - if (expression.Type == "And") - { - return Query.And(expression.Elements!.Select(o => BuildCondition(table, o)).ToArray()); - } - - if (expression.Type == "Or") - { - return Query.Or(expression.Elements!.Select(o => BuildCondition(table, o)).ToArray()); - } - - throw new InvalidOperationException($"Unknown expression type: {expression.Type}"); } } \ No newline at end of file diff --git a/Circles.Index/Readme.md b/Circles.Index/Readme.md index 52675da..85ccce5 100644 --- a/Circles.Index/Readme.md +++ b/Circles.Index/Readme.md @@ -40,29 +40,15 @@ The plugin provides a JSON-RPC module to query the data. The following RPC metho "method":"circles_query", "id":1, "params": [{ - "Table": 12, + "Table": "CrcV1Signup", "Columns": [ - 1, - 36, - 30, - 6, - 11, - 34, - 24 - ], - "Conditions": [ - { - "Type": "LessThan", - "Column": 24, - "Value": "500000000000000000000", - "Elements": null - }, - { - "Type": "Equals", - "Column": 11, - "Value": "0x0000000000000000000000000000000000000000", - "Elements": null - } + "BlockNumber", + "Timestamp", + "TransactionIndex", + "LogIndex", + "TransactionHash", + "CirclesAddress", + "TokenAddress" ] }] }' -H "Content-Type: application/json" http://localhost:8545/ diff --git a/Circles.Index/Rpc/CirclesRpcModule.cs b/Circles.Index/Rpc/CirclesRpcModule.cs index fe1675e..23e19f5 100644 --- a/Circles.Index/Rpc/CirclesRpcModule.cs +++ b/Circles.Index/Rpc/CirclesRpcModule.cs @@ -132,8 +132,11 @@ public ResultWrapper> circles_query(CirclesQuery query) using NpgsqlConnection connection = new(_indexConnectionString); connection.Open(); - var select = Query.Select(query.Table, - query.Columns ?? throw new InvalidOperationException("Columns are null")); + Tables parsedTableName = Enum.Parse(query.Table); + + var select = Query.Select(parsedTableName, + query.Columns?.Select(c => Enum.Parse(c)) + ?? throw new InvalidOperationException("Columns are null")); Console.WriteLine(select.ToString()); @@ -157,17 +160,20 @@ private IQuery BuildCondition(Tables table, Expression expression) { if (expression.Type == "Equals") { - return Query.Equals(table, expression.Column!.Value, expression.Value); + Columns parsedColumnName = Enum.Parse(expression.Column!); + return Query.Equals(table, parsedColumnName, expression.Value); } if (expression.Type == "GreaterThan") { - return Query.GreaterThan(table, expression.Column!.Value, expression.Value); + Columns parsedColumnName = Enum.Parse(expression.Column!); + return Query.GreaterThan(table, parsedColumnName, expression.Value!); } if (expression.Type == "LessThan") { - return Query.LessThan(table, expression.Column!.Value, expression.Value); + Columns parsedColumnName = Enum.Parse(expression.Column!); + return Query.LessThan(table, parsedColumnName, expression.Value!); } if (expression.Type == "And") diff --git a/Circles.Index/Rpc/ICirclesRpcModule.cs b/Circles.Index/Rpc/ICirclesRpcModule.cs index 07bbc07..e782e16 100644 --- a/Circles.Index/Rpc/ICirclesRpcModule.cs +++ b/Circles.Index/Rpc/ICirclesRpcModule.cs @@ -25,15 +25,15 @@ public CirclesTokenBalance(Address token, string balance) public class CirclesQuery { - public Tables Table { get; set; } - public Columns[]? Columns { get; set; } + public string Table { get; set; } + public string[]? Columns { get; set; } public List Conditions { get; set; } = new(); } public class Expression { public string? Type { get; set; } // "Equals", "GreaterThan", "LessThan", "And", "Or" - public Columns? Column { get; set; } // Null for composite types like "And" and "Or" + public string? Column { get; set; } // Null for composite types like "And" and "Or" public object? Value { get; set; } // Null for composite types public List? Elements { get; set; } // Used only for "And" and "Or" } diff --git a/Circles.Index/docker-compose.chiado.yml b/Circles.Index/docker-compose.chiado.yml new file mode 100644 index 0000000..4f55482 --- /dev/null +++ b/Circles.Index/docker-compose.chiado.yml @@ -0,0 +1,96 @@ +services: + execution: + container_name: execution + #image: jaensen/nethermind-circlesubi:dev-x86_64 + build: + context: . + dockerfile: x64.Dockerfile + restart: unless-stopped + # network_mode: host + networks: + - circles + ports: + - 30303:30303/tcp # p2p + - 30303:30303/udp # p2p + - 8545:8545 + expose: + - 8551 # engine api + volumes: + - .state/execution:/data + - .state/jwtsecret/jwt.hex:/jwt.hex + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + command: | + --config=chiado + --datadir=/data + --log=INFO + --Sync.SnapSync=false + --JsonRpc.Enabled=true + --JsonRpc.Host=0.0.0.0 + --JsonRpc.Port=8545 + --JsonRpc.EnabledModules=[Web3,Eth,Subscribe,Net,Circles] + --JsonRpc.JwtSecretFile=/jwt.hex + --JsonRpc.EngineHost=0.0.0.0 + --JsonRpc.EnginePort=8551 + --Network.DiscoveryPort=30303 + --HealthChecks.Enabled=false + logging: + driver: "local" + environment: + - V1_HUB_ADDRESS=0xdbf22d4e8962db3b2f1d9ff55be728a887e47710 + - V2_HUB_ADDRESS=0xDA02CDB5279B3a1eF27Be3d91aE924495E6A5569 + - START_BLOCK=0 + - POSTGRES_CONNECTION_STRING=Server=db;Port=5432;User Id=postgres;Password=;Database=postgres; + + db: + image: postgres:16 + command: -c 'max_connections=100' + restart: unless-stopped + container_name: 'postgres' +# network_mode: host + networks: + - circles + environment: + POSTGRES_PASSWORD: '' + POSTGRES_USER: 'postgres' + POSTGRES_HOST_AUTH_METHOD: 'trust' + volumes: + - ./.state/postgres-data:/var/lib/postgresql/data + + consensus: + container_name: consensus + image: sigp/lighthouse:v5.0.0 + restart: always + # network_mode: host + networks: + - circles + ports: + - 9000:9000/tcp # p2p + - 9000:9000/udp # p2p + - 5054:5054/tcp # metrics + expose: + - 4000 # http + volumes: + - .state/consensus/data:/data + - .state/jwtsecret/jwt.hex:/jwt.hex + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + command: | + lighthouse + beacon_node + --network=chiado + --disable-upnp + --datadir=/data + --port=9000 + --http + --http-address=0.0.0.0 + --http-port=4000 + --execution-endpoint=http://execution:8551 + --execution-jwt=/jwt.hex + --checkpoint-sync-url=https://checkpoint.chiadochain.net/ + logging: + driver: "local" + +networks: + circles: + name: circles