diff --git a/.bettercodehub.yml b/.bettercodehub.yml index 4ace3ad3ba..d1a64f481a 100644 --- a/.bettercodehub.yml +++ b/.bettercodehub.yml @@ -1,4 +1,6 @@ +# Depth of components to analyze (2 levels deep) component_depth: 2 +# Programming languages to analyze languages: - csharp diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6e4b2c3526..ea59817cf7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,31 +1,33 @@ --- -name: Bug report -about: Create a report to help us improve +name: 👾 Bug Report +about: Report a bug or issue with the project. title: '' -labels: '' +labels: 'bug' assignees: '' --- -**Describe the bug** +### Description A clear and concise description of what the bug is. -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error +### Steps To Reproduce +1. Log in... +2. Ensure that... +3. Allow a long period of inactivity to pass... +4. Observe that... +5. Attempt to log in... -**Expected behavior** -A clear and concise description of what you expected to happen. +### Current Behavior +- After the period of inactivity... +- When the user tries to log in using another method... +- This causes a bug due to... -**Screenshots** -If applicable, add screenshots to help explain your problem. +### Expected Behavior +- After a long period of inactivity... +- When a user logs in successfully... +- This ensures that only... -**Environment (please complete the following information):** - - OS and version: [e.g. Ubuntu 18.04] - - Dotnet core version [e.g. 2.2.106] - -**Additional context** -Add any other context about the problem here. +### Environment +- Platform: PC +- Node: v18.18.0 +- Browser: Chrome 126.0.6478.56 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..163c1c437c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,10 @@ +blank_issues_enabled: false +issue_template: + - name: 👾 Bug Report + description: Report a bug or issue with the project. + labels: ["bug"] + template: bug_report.md + - name: 💡 Feature Request + description: Create a new ticket for a new feature request. + labels: ["enhancement"] + template: feature_request.md \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d61..a4b817533a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,20 +1,27 @@ --- -name: Feature request -about: Suggest an idea for this project +name: 💡 Feature Request +about: Create a new ticket for a new feature request title: '' -labels: '' +labels: 'enhancement' assignees: '' --- -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] +### Expected Behavior +Describe the expected behavior here. -**Describe the solution you'd like** -A clear and concise description of what you want to happen. +### Specifications +As a `user`, I would like to `action` so that `reason`. -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. +**Features:** +- describe feature details here. -**Additional context** -Add any other context or screenshots about the feature request here. +**Development Tasks:** +- [ ] Task 1 +- [ ] Task 2 + +### Dependencies +List any dependencies that are required for this feature by providing links to the issues or repositories. + +### References +List any references that are related to this feature request. \ No newline at end of file diff --git a/.github/workflows/benchmark_action.yml b/.github/workflows/benchmark_action.yml new file mode 100644 index 0000000000..304c497745 --- /dev/null +++ b/.github/workflows/benchmark_action.yml @@ -0,0 +1,48 @@ +name: benchmark_action +on: + push: + tags: + - '**' + branches: + - '**' + + + +env: + DOTNET_INSTALL_DIR: "./.dotnet" + Solution_Name: AElf.All.sln + Service_Name: AELF + +jobs: + test: + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + + - name: 'Download AElf build tools' + run: bash scripts/download_binary.sh + + - name: 'Install protobuf' + run: bash scripts/install_protobuf.sh + + - name: Install dependencies + run: dotnet restore bench/AElf.Benchmark/AElf.Benchmark.csproj --verbosity quiet + + - name: BenchMark + run: | + cd bench/AElf.Benchmark + dotnet run --filter '*MinerTests*' + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ env.Service_Name }} + path: bench/AElf.Benchmark/BenchmarkDotNet.Artifacts/results + retention-days: 30 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..00541ec3bc --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,35 @@ +name: Build +on: + push: + branches: + - dev + - master + - feature/use-github-actions + +env: + DOTNET_INSTALL_DIR: "./.dotnet" + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + + - name: Download AElf build tools + run: bash scripts/download_binary.sh + + - name: Install Protobuf + run: bash scripts/install_protobuf.sh + + - name: Build Solution + run: bash scripts/build.sh + diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml new file mode 100644 index 0000000000..dbfca652b6 --- /dev/null +++ b/.github/workflows/sonarqube.yaml @@ -0,0 +1,49 @@ +on: + pull_request: + types: [opened, synchronize, reopened] + +name: PR Static Code Analysis +jobs: + static-code-analysis: + runs-on: ubuntu-latest + steps: + - name: Code Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0' + - name: Create temporary global.json + run: echo '{"sdk":{"version":"8.0.303"}}' > ./global.json + - name: Set up JDK 17 + uses: actions/setup-java@v1 + with: + java-version: 17 + - name: Cache SonarQube packages + uses: actions/cache@v1 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + - name: Cache SonarQube scanner + id: cache-sonar-scanner + uses: actions/cache@v1 + with: + path: ./.sonar/scanner + key: ${{ runner.os }}-sonar-scanner + restore-keys: ${{ runner.os }}-sonar-scanner + - name: Install SonarScanner for .NET + run: dotnet tool update dotnet-sonarscanner --tool-path ./.sonar/scanner + - name: Add .NET global tools to PATH + run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH + - name: Install protobuf + run: sudo apt-get update && sudo apt-get install -y protobuf-compiler + - name: Begin SonarQube analysis + run: | + ./.sonar/scanner/dotnet-sonarscanner begin /k:"AElf" /d:sonar.host.url="${{ secrets.SONAR_HOST_URL }}" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" + dotnet build AElf.All.sln + ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" + + + \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000..a0076d5ca5 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,22 @@ +name: Test +on: + push: + branches: + - dev + - master + - feature/use-github-actions + +jobs: + build-and-test: + runs-on: ubuntu-latest + permissions: + pull-requests: write + contents: write + steps: + - name: Run dotnet ci action + uses: AElfProject/dotnet-ci-action@v0.0.1 + with: + commit-token: ${{ secrets.COMMIT_TOKEN }} + codecov-token: ${{ secrets.CODECOV_TOKEN }} + branch-name: "feature/badge-json" + solution-name: "AElf.All.sln" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 04d0c6ea86..5170707db2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ *.userprefs # Build results +build/ [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ @@ -312,4 +313,4 @@ tools .idea/.idea.AElf/.idea/projectSettingsUpdater.xml .idea/.idea.AElf/.idea/vcs.xml .idea/.idea.AElf/.idea/workspace.xml -.idea/.idea.AElf/riderModule.iml +.idea/.idea.AElf/riderModule.iml \ No newline at end of file diff --git a/.readthedocs.yml b/.readthedocs.yml index 56b2002e45..c717656544 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,7 +14,7 @@ sphinx: # Optionally build your docs in additional formats such as PDF and ePub formats: all -# Optionally set the version of Python and requirements required to build your docs +# Optionally set the version of python and requirements required to build your docs python: version: 3.7 install: diff --git a/AElf.All.sln b/AElf.All.sln index 29841070b8..c61cdc1c57 100644 --- a/AElf.All.sln +++ b/AElf.All.sln @@ -383,6 +383,22 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZkWasmVerifier", "contract\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZkWasmVerifier.Tests", "test\ZkWasmVerifier.Tests\ZkWasmVerifier.Tests.csproj", "{8054502F-2594-4028-8109-A024DF7C82FA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZkWasmGame", "contract\ZkWasmGame\ZkWasmGame.csproj", "{B859C137-D581-47B8-A588-B37673FAF000}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Kernel.FeatureDisable", "src\AElf.Kernel.FeatureDisable\AElf.Kernel.FeatureDisable.csproj", "{A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Kernel.FeatureDisable.Tests", "test\AElf.Kernel.FeatureDisable.Tests\AElf.Kernel.FeatureDisable.Tests.csproj", "{8C0D86A4-D1A7-4B61-AC44-755F5AC75D67}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Kernel.FeatureDisable.Core", "src\AElf.Kernel.FeatureDisable.Core\AElf.Kernel.FeatureDisable.Core.csproj", "{659A7C7A-44C9-424E-B4F6-D1D3656F7AD4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Sdk.CSharp.Spec", "src\AElf.Sdk.CSharp.Spec\AElf.Sdk.CSharp.Spec.csproj", "{45A77C41-142E-4296-A14A-D53067EC8B75}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AElf.Sdk.CSharp.Internal", "src\AElf.Sdk.CSharp.Internal\AElf.Sdk.CSharp.Internal.csproj", "{A77380A7-E425-45A3-BF3F-F865DA4F3F4E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZkTreeVerifier", "contract\ZkTreeVerifier\ZkTreeVerifier.csproj", "{F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZkTreeVerifier.Tests", "test\ZkTreeVerifier.Tests\ZkTreeVerifier.Tests.csproj", "{6BA638C7-CADB-4672-A2A4-765FAE2DF702}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1101,6 +1117,38 @@ Global {8054502F-2594-4028-8109-A024DF7C82FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {8054502F-2594-4028-8109-A024DF7C82FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {8054502F-2594-4028-8109-A024DF7C82FA}.Release|Any CPU.Build.0 = Release|Any CPU + {B859C137-D581-47B8-A588-B37673FAF000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B859C137-D581-47B8-A588-B37673FAF000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B859C137-D581-47B8-A588-B37673FAF000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B859C137-D581-47B8-A588-B37673FAF000}.Release|Any CPU.Build.0 = Release|Any CPU + {A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E}.Release|Any CPU.Build.0 = Release|Any CPU + {8C0D86A4-D1A7-4B61-AC44-755F5AC75D67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C0D86A4-D1A7-4B61-AC44-755F5AC75D67}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C0D86A4-D1A7-4B61-AC44-755F5AC75D67}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C0D86A4-D1A7-4B61-AC44-755F5AC75D67}.Release|Any CPU.Build.0 = Release|Any CPU + {659A7C7A-44C9-424E-B4F6-D1D3656F7AD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {659A7C7A-44C9-424E-B4F6-D1D3656F7AD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {659A7C7A-44C9-424E-B4F6-D1D3656F7AD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {659A7C7A-44C9-424E-B4F6-D1D3656F7AD4}.Release|Any CPU.Build.0 = Release|Any CPU + {45A77C41-142E-4296-A14A-D53067EC8B75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {45A77C41-142E-4296-A14A-D53067EC8B75}.Debug|Any CPU.Build.0 = Debug|Any CPU + {45A77C41-142E-4296-A14A-D53067EC8B75}.Release|Any CPU.ActiveCfg = Release|Any CPU + {45A77C41-142E-4296-A14A-D53067EC8B75}.Release|Any CPU.Build.0 = Release|Any CPU + {A77380A7-E425-45A3-BF3F-F865DA4F3F4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A77380A7-E425-45A3-BF3F-F865DA4F3F4E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A77380A7-E425-45A3-BF3F-F865DA4F3F4E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A77380A7-E425-45A3-BF3F-F865DA4F3F4E}.Release|Any CPU.Build.0 = Release|Any CPU + {F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6}.Release|Any CPU.Build.0 = Release|Any CPU + {6BA638C7-CADB-4672-A2A4-765FAE2DF702}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6BA638C7-CADB-4672-A2A4-765FAE2DF702}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6BA638C7-CADB-4672-A2A4-765FAE2DF702}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6BA638C7-CADB-4672-A2A4-765FAE2DF702}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1294,5 +1342,13 @@ Global {6981684D-450C-412B-9082-0B0A67A679B9} = {D3950CC9-808F-4ED8-946A-79A992F3F8EF} {DD4B2603-902F-41FE-A85F-F952957FAFA3} = {9AA521A5-80BF-4D20-9339-31D7E86D5868} {8054502F-2594-4028-8109-A024DF7C82FA} = {D3950CC9-808F-4ED8-946A-79A992F3F8EF} + {B859C137-D581-47B8-A588-B37673FAF000} = {9AA521A5-80BF-4D20-9339-31D7E86D5868} + {A4ACE6D2-4CF8-4B52-93C9-BB8BEC0C098E} = {90B310B4-C2DB-419E-B5EE-97FA096B62CC} + {8C0D86A4-D1A7-4B61-AC44-755F5AC75D67} = {4E54480A-D155-43ED-9736-1A5BE7957211} + {659A7C7A-44C9-424E-B4F6-D1D3656F7AD4} = {90B310B4-C2DB-419E-B5EE-97FA096B62CC} + {45A77C41-142E-4296-A14A-D53067EC8B75} = {798BAA50-825B-4DD9-83E2-77A9EE6EBE09} + {A77380A7-E425-45A3-BF3F-F865DA4F3F4E} = {798BAA50-825B-4DD9-83E2-77A9EE6EBE09} + {F4BA0EFB-9D98-4AFE-BC4B-3B4CC527D4A6} = {9AA521A5-80BF-4D20-9339-31D7E86D5868} + {6BA638C7-CADB-4672-A2A4-765FAE2DF702} = {D3950CC9-808F-4ED8-946A-79A992F3F8EF} EndGlobalSection EndGlobal diff --git a/AElf.ContractTools.targets b/AElf.ContractTools.targets index 3c3608d258..86de821de0 100644 --- a/AElf.ContractTools.targets +++ b/AElf.ContractTools.targets @@ -32,7 +32,8 @@ - + + $(ProjectDir)/Protobuf diff --git a/AElf.Contracts.sln b/AElf.Contracts.sln index ac50a9f51e..486a48541b 100644 --- a/AElf.Contracts.sln +++ b/AElf.Contracts.sln @@ -1,5 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "contract", "contract", "{651F0F6E-86CF-42D2-9110-5F3EAE5704F0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{26990847-E0A2-4FCC-8C71-267CA77557CD}" diff --git a/AElf.sln.DotSettings b/AElf.sln.DotSettings index 04a90e14d0..f728bd7795 100644 --- a/AElf.sln.DotSettings +++ b/AElf.sln.DotSettings @@ -1,14 +1,17 @@ - + False - JS - True - True - True - True - True - True - True - True - True - True - True + JS + True + True + True + True + True + True + True + True + True + True + True diff --git a/CodeCoverage.runsettings b/CodeCoverage.runsettings index 609fa6a0a2..bf1e25abec 100644 --- a/CodeCoverage.runsettings +++ b/CodeCoverage.runsettings @@ -1,4 +1,5 @@ + diff --git a/README.md b/README.md index 616aa7f841..6399c11634 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,45 @@ -# AElf - A Decentralized Cloud Computing Blockchain Network +# aelf - A Decentralized Cloud Computing Blockchain Network [![GitHub closed issues](https://img.shields.io/github/issues-closed/aelfproject/aelf.svg)](https://app.gitkraken.com/glo/board/XKsOZJarBgAPseno) [![lisence](https://img.shields.io/github/license/AElfProject/AElf.svg)](https://github.com/AElfProject/AElf/blob/dev/LICENSE) [![Nuget](https://img.shields.io/nuget/v/AElf.OS.svg)](https://www.nuget.org/packages?q=aelf) -[![MyGet (with prereleases)](https://img.shields.io/myget/aelf-project-dev/vpre/aelf.os.svg?label=myget)](https://www.myget.org/gallery/aelf-project-dev) +[![MyGet (with prereleases)](https://img.shields.io/myget/aelf-project/vpre/aelf.os.svg?label=myget)](https://www.myget.org/gallery/aelf-project) [![Twitter Follow](https://img.shields.io/twitter/follow/aelfblockchain.svg?label=%40aelfblockchain&style=social)](https://twitter.com/aelfblockchain) [![Telegram](https://badgen.net/badge/telegram/join/blue?icon=telegram)](https://t.me/aelfdeveloper) - BRANCH | AZURE PIPELINES | TESTS | CODE COVERAGE - ------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ - MASTER | [![Build Status](https://dev.azure.com/AElfProject/AElf/_apis/build/status/AElfProject.AElf?branchName=master)](https://dev.azure.com/AElfProject/AElf/_build/latest?definitionId=1&branchName=master) | [![Test Status](https://img.shields.io/azure-devops/tests/AElfProject/AElf/1/master)](https://dev.azure.com/AElfProject/AElf/_build/latest?definitionId=1&branchName=master) | [![codecov](https://codecov.io/gh/AElfProject/AElf/branch/master/graph/badge.svg)](https://codecov.io/gh/AElfProject/AElf) - DEV | [![Build Status](https://dev.azure.com/AElfProject/AElf/_apis/build/status/AElfProject.AElf?branchName=dev)](https://dev.azure.com/AElfProject/AElf/_build/latest?definitionId=1&branchName=dev) | [![Test Status](https://img.shields.io/azure-devops/tests/AElfProject/AElf/1/dev)](https://dev.azure.com/AElfProject/AElf/_build/latest?definitionId=1&branchName=dev) | [![codecov](https://codecov.io/gh/AElfProject/AElf/branch/dev/graph/badge.svg)](https://codecov.io/gh/AElfProject/AElf) +BRANCH | GITHUB ACTIONS BUILD | TESTS | CODE COVERAGE +------ |--------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------------------------------------------------------ +MASTER | ![GitHub Workflow Build Status](https://github.com/AElfProject/AElf/actions/workflows/build.yml/badge.svg?branch=master) | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/AElf/feature/badge-json/master-test-results.json) | [![codecov](https://codecov.io/gh/AElfProject/AElf/branch/master/graph/badge.svg)](https://codecov.io/gh/AElfProject/AElf) +DEV | ![GitHub Workflow Build Status](https://github.com/AElfProject/AElf/actions/workflows/build.yml/badge.svg?branch=dev) | ![GitHub Workflow Test Status](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/AElfProject/AElf/feature/badge-json/dev-test-results.json) | [![codecov](https://codecov.io/gh/AElfProject/AElf/branch/dev/graph/badge.svg)](https://codecov.io/gh/AElfProject/AElf) -Welcome to AElf's official GitHub repo ! -AElf is a blockchain system aiming to achieve scalability and extensibility through the use of side-chains and a flexible design. To support multiple use cases AElf makes it as easy as possible to extend/customize the system by providing easy to use tools and frameworks in order to customize the chains and write smart contracts. AElf will eventually support various languages that will let developers choose the one they are the most comfortable with. +Welcome to aelf's official GitHub repo ! + +aelf is a blockchain system aiming to achieve scalability and extensibility through the use of side-chains and a flexible design. To support multiple use cases aelf makes it as easy as possible to extend/customize the system by providing easy to use tools and frameworks in order to customize the chains and write smart contracts. aelf will eventually support various languages that will let developers choose the one they are the most comfortable with. For more information you can follow these links: -* [Official website](https://aelf.io) -* [Documentation](https://docs.aelf.io/en/latest/) - * [Environment setup](https://docs.aelf.io/en/latest/getting_started/development-environment/index.html) - * [Running a node](https://docs.aelf.io/en/latest/getting_started/development-environment/node.html) - * [Smart contract development](https://docs.aelf.io/en/latest/getting_started/smart_contracts/index.html) - * [Web Api](https://docs.aelf.io/en/latest/reference/web-api/web-api.html) - * [Testnet](https://docs.aelf.io/en/latest/tutorials/testnet.html) -* [White Paper](https://aelf.com/gridcn/aelf_whitepaper_v1.7_en.pdf) - -This repository contains the code that runs an AElf node, you'll find bellow other important repositories in the AElf +* [Official website](https://aelf.com/) +* [Documentation](https://docs.aelf.com/) +* [White Paper](https://docs.aelf.com/resources/whitepaper-2/) + +This repository contains the code that runs an aelf node, you'll find below other important repositories in the aelf ecosystem: TOOL/LIBRARY | description -------------|------------- -[aelf-sdk.js](https://docs.aelf.io/en/latest/reference/chain-sdk/javascript/js-sdk.html) | Javascript development kit for interacting with an AElf node, useful for dApp developers. -[aelf-command](https://docs.aelf.io/en/latest/reference/cli/methods.html) | CLI tool for interacting with an AElf node and wallet. -[aelf-boilerplate](https://aelf-boilerplate-docs.readthedocs.io/en/latest/) | framework for smart contract and dApp development. +[aelf-sdk.js](https://docs.aelf.com/tools/chain-sdk/javascript-sdk/) | Javascript development kit for interacting with an aelf node, useful for dApp developers. +[aelf-command](https://docs.aelf.com/tools/aelf-cli/introduction/) | CLI tool for interacting with an aelf node and wallet. +[aelf-contract-templates](https://docs.aelf.com/tools/smart-contract-templates/developing-smart-contracts/) | framework for smart contract and dApp development. ## Getting Started ### This repository -This repo is where you will find the code that can use to run an AElf node. It also contains a **tests** folder that centralizes all the unit tests. +This repo is where you will find the code that can use to run an aelf node. It also contains a **tests** folder that centralizes all the unit tests. ### Documentation -We strongly recommend you follow official documentation that will guide you through installing dependencies and running the node, -these two guides will get you started: -* [Environment setup](https://docs.aelf.io/en/latest/getting_started/development-environment/index.html) -* [Running a node](https://docs.aelf.io/en/latest/getting_started/development-environment/node.html) +We strongly recommend you follow [official documentation](https://docs.aelf.com/) that will guide you through installing dependencies and running the node. ## Contributing @@ -62,11 +55,11 @@ We currently only use GitHub for tracking issues, feature request and pull reque If you think you have found a bug in our system feel free to open a GitHub issue, but first: - check with GitHub's search engine that the bug doesn't already exist. -- in the request give as much information as possible such as: the OS, the version of AElf, how to reproduce... +- in the request give as much information as possible such as: the OS, the version of aelf, how to reproduce... #### Missing feature -We also use the GitHub issue tracker for features. If you think that some piece of functionality is missing in AElf, you can open an issue with the following in mind: +We also use the GitHub issue tracker for features. If you think that some piece of functionality is missing in aelf, you can open an issue with the following in mind: - check for similare feature requests already open. - provide as much detail and context as possible. - be as convincing as possible as to why we need this feature and how everybody can benefit from it. @@ -83,8 +76,8 @@ When you are ready for a review by the core team, just remove ```[WIP]``` from y ## Versioning -We use Semantic Versioning (SemVer) for versioning, if you're intereted in closely following AElf's developement please check out the [SemVer docs](https://semver.org/). +We use Semantic Versioning (SemVer) for versioning, if you're intereted in closely following aelf's developement please check out the [SemVer docs](https://semver.org/). ## License -AElf is licenced under [MIT](https://github.com/AElfProject/AElf/blob/dev/LICENSE) +aelf is licenced under [MIT](https://github.com/AElfProject/AElf/blob/dev/LICENSE) diff --git a/appveyor.yml b/appveyor.yml index 7be64af079..8239ba530d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,4 @@ +# appveyor configuration file version: 1.0.0.{build} skip_tags: true os: Windows Server 2012 R2 diff --git a/azure-myget-publish.yml b/azure-myget-publish.yml index d271eb5595..9a404026cb 100644 --- a/azure-myget-publish.yml +++ b/azure-myget-publish.yml @@ -1,3 +1,4 @@ + # Azure DevOps pipeline configuration for publishing NuGet packages to MyGet pool: vmImage: ubuntu-latest pr: none diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c7761f5875..ab968a5312 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,4 +1,4 @@ -# File: azure-pipelines.yml +# Azure Pipelines configuration file jobs: - template: templates/build-template-window.yml parameters: diff --git a/bench/AElf.BenchBase/AElf.BenchBase.csproj b/bench/AElf.BenchBase/AElf.BenchBase.csproj index 64d89d764d..a94ad8e78b 100644 --- a/bench/AElf.BenchBase/AElf.BenchBase.csproj +++ b/bench/AElf.BenchBase/AElf.BenchBase.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false diff --git a/bench/AElf.Benchmark.PerformanceTestContract/AElf.Benchmark.PerformanceTestContract.csproj b/bench/AElf.Benchmark.PerformanceTestContract/AElf.Benchmark.PerformanceTestContract.csproj index 15c160229f..d8a7b2261b 100644 --- a/bench/AElf.Benchmark.PerformanceTestContract/AElf.Benchmark.PerformanceTestContract.csproj +++ b/bench/AElf.Benchmark.PerformanceTestContract/AElf.Benchmark.PerformanceTestContract.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false true diff --git a/bench/AElf.Benchmark/AElf.Benchmark.csproj b/bench/AElf.Benchmark/AElf.Benchmark.csproj index d24e1eafc6..431fb96346 100644 --- a/bench/AElf.Benchmark/AElf.Benchmark.csproj +++ b/bench/AElf.Benchmark/AElf.Benchmark.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false Exe diff --git a/bench/AElf.Benchmark/HtmlSummaryExporter.cs b/bench/AElf.Benchmark/HtmlSummaryExporter.cs new file mode 100644 index 0000000000..1b9f7756c1 --- /dev/null +++ b/bench/AElf.Benchmark/HtmlSummaryExporter.cs @@ -0,0 +1,82 @@ +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Loggers; +using BenchmarkDotNet.Reports; + +using System.Collections.Generic; +using System.IO; + + +public class HtmlSummaryExporter : IExporter +{ + public string Name => nameof(HtmlSummaryExporter); + + public void ExportToLog(Summary summary, ILogger logger) + { + + } + + public IEnumerable ExportToFiles(Summary summary, ILogger consoleLogger) + { + string directoryPath = summary.ResultsDirectoryPath; + string outputPath = Path.Combine(directoryPath, "Summary.html"); + + var htmlFiles = Directory.GetFiles(directoryPath, "*.html"); + + using (StreamWriter writer = new StreamWriter(outputPath)) + { + writer.WriteLine(""); + writer.WriteLine(""); + writer.WriteLine("Benchmark Summary"); + + writer.WriteLine(""); + + writer.WriteLine(""); + writer.WriteLine(""); + + foreach (var file in htmlFiles) + { + string fileName = Path.GetFileName(file); + writer.WriteLine($"

{fileName}

"); + string content = File.ReadAllText(file); + string bodyContent = GetBodyContent(content); + writer.WriteLine(bodyContent); + } + + writer.WriteLine(""); + writer.WriteLine(""); + } + + consoleLogger.WriteLine($"Summary HTML file created successfully at {outputPath}."); + + return new[] { outputPath }; + } + + private string GetBodyContent(string html) + { + int bodyStartIndex = html.IndexOf("") + "".Length; + int bodyEndIndex = html.IndexOf(""); + if (bodyStartIndex >= 0 && bodyEndIndex >= 0) + { + return html.Substring(bodyStartIndex, bodyEndIndex - bodyStartIndex); + } + return string.Empty; + } + + private string GetStyleContent(string html) + { + int styleStartIndex = html.IndexOf(""); + if (styleStartIndex >= 0 && styleEndIndex >= 0) + { + return html.Substring(styleStartIndex, styleEndIndex - styleStartIndex); + } + return string.Empty; + } +} \ No newline at end of file diff --git a/bench/AElf.Benchmark/Program.cs b/bench/AElf.Benchmark/Program.cs index bc0d10d859..9d71a23611 100644 --- a/bench/AElf.Benchmark/Program.cs +++ b/bench/AElf.Benchmark/Program.cs @@ -2,6 +2,10 @@ using System.IO; using System.Reflection; using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Exporters.Csv; +using BenchmarkDotNet.Exporters.Xml; +using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; using Volo.Abp; @@ -18,8 +22,13 @@ private static void Main(string[] args) })) { application.Initialize(); - BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig()); - } + var config = new DebugInProcessConfig() + .WithSummaryStyle(SummaryStyle.Default.WithMaxParameterColumnWidth(50)) + .AddExporter(XmlExporter.Default) + .AddExporter(HtmlExporter.Default) + .AddExporter(new HtmlSummaryExporter()) + .AddExporter(CsvExporter.Default); + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); } } private static void RegisterAssemblyResolveEvent() diff --git a/bench/AElf.Database.Benches/AElf.Database.Benches.csproj b/bench/AElf.Database.Benches/AElf.Database.Benches.csproj index 21a43a9247..43f5236477 100644 --- a/bench/AElf.Database.Benches/AElf.Database.Benches.csproj +++ b/bench/AElf.Database.Benches/AElf.Database.Benches.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false xUnit1013 diff --git a/build.cake b/build.cake index 11219ab033..e32a698f15 100755 --- a/build.cake +++ b/build.cake @@ -112,7 +112,6 @@ Task("Test-with-Codecov") actions.Add(action); } - var options = new ParallelOptions { MaxDegreeOfParallelism = 1, //CancellationToken = cancellationToken diff --git a/build.config b/build.config index 015ef8eca4..b55ec20ed7 100644 --- a/build.config +++ b/build.config @@ -1,3 +1,3 @@ #!/usr/bin/env bash CAKE_VERSION=0.37.0 -DOTNET_VERSION=6.0.300 +DOTNET_VERSION=8.0.303 \ No newline at end of file diff --git a/build.ps1 b/build.ps1 index e48d09a09c..cb56d5562f 100644 --- a/build.ps1 +++ b/build.ps1 @@ -6,6 +6,7 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent [string] $CakeVersion = '' [string] $DotNetVersion= '' + foreach($line in Get-Content (Join-Path $PSScriptRoot 'build.config')) { if ($line -like 'CAKE_VERSION=*') { diff --git a/build.sh b/build.sh index 06bcee8070..4f00fd2e4e 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Define varibles +# Define variables SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) source $SCRIPT_DIR/build.config TOOLS_DIR=$SCRIPT_DIR/tools diff --git a/common.props b/common.props index 4438867f30..1534ffaa8a 100644 --- a/common.props +++ b/common.props @@ -11,4 +11,4 @@ - +
\ No newline at end of file diff --git a/contract/AElf.Contracts.Association/AElf.Contracts.Association.csproj b/contract/AElf.Contracts.Association/AElf.Contracts.Association.csproj index 0d2c24b45d..cafcb3417b 100644 --- a/contract/AElf.Contracts.Association/AElf.Contracts.Association.csproj +++ b/contract/AElf.Contracts.Association/AElf.Contracts.Association.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Association true Association is a contract that enables the creation of organizations and approvals. diff --git a/contract/AElf.Contracts.Association/Association.cs b/contract/AElf.Contracts.Association/Association.cs index db9a2d81dd..f00b978f27 100644 --- a/contract/AElf.Contracts.Association/Association.cs +++ b/contract/AElf.Contracts.Association/Association.cs @@ -35,7 +35,9 @@ public override ProposalOutput GetProposal(Hash proposalId) ToBeReleased = readyToRelease, ApprovalCount = proposal.Approvals.Count, RejectionCount = proposal.Rejections.Count, - AbstentionCount = proposal.Abstentions.Count + AbstentionCount = proposal.Abstentions.Count, + Title = proposal.Title, + Description = proposal.Description }; } diff --git a/contract/AElf.Contracts.Association/AssociationConstants.cs b/contract/AElf.Contracts.Association/AssociationConstants.cs new file mode 100644 index 0000000000..d2afee8e13 --- /dev/null +++ b/contract/AElf.Contracts.Association/AssociationConstants.cs @@ -0,0 +1,8 @@ +namespace AElf.Contracts.Association; + +public static class AssociationConstants +{ + public const int MaxLengthForTitle = 255; + public const int MaxLengthForDescription = 10200; + public const int MaxLengthForProposalDescriptionUrl = 255; +} \ No newline at end of file diff --git a/contract/AElf.Contracts.Association/Association_Helper.cs b/contract/AElf.Contracts.Association/Association_Helper.cs index c246df26ee..cc1a7d0643 100644 --- a/contract/AElf.Contracts.Association/Association_Helper.cs +++ b/contract/AElf.Contracts.Association/Association_Helper.cs @@ -144,6 +144,7 @@ private Hash GenerateProposalId(CreateProposalInput input) private Hash CreateNewProposal(CreateProposalInput input) { + CheckCreateProposalInput(input); var proposalId = GenerateProposalId(input); var proposal = new ProposalInfo { @@ -154,7 +155,9 @@ private Hash CreateNewProposal(CreateProposalInput input) OrganizationAddress = input.OrganizationAddress, ProposalId = proposalId, Proposer = Context.Sender, - ProposalDescriptionUrl = input.ProposalDescriptionUrl + ProposalDescriptionUrl = input.ProposalDescriptionUrl, + Title = input.Title, + Description = input.Description }; Assert(Validate(proposal), "Invalid proposal."); Assert(State.Proposals[proposalId] == null, "Proposal already exists."); @@ -162,8 +165,21 @@ private Hash CreateNewProposal(CreateProposalInput input) Context.Fire(new ProposalCreated { ProposalId = proposalId, - OrganizationAddress = input.OrganizationAddress + OrganizationAddress = input.OrganizationAddress, + Title = input.Title, + Description = input.Description }); return proposalId; } + + private void CheckCreateProposalInput(CreateProposalInput input) + { + // Check the length of title + Assert(input.Title.Length <= AssociationConstants.MaxLengthForTitle, "Title is too long."); + // Check the length of description + Assert(input.Description.Length <= AssociationConstants.MaxLengthForDescription, "Description is too long."); + // Check the length of description url + Assert(input.ProposalDescriptionUrl.Length <= AssociationConstants.MaxLengthForProposalDescriptionUrl, + "Description url is too long."); + } } \ No newline at end of file diff --git a/contract/AElf.Contracts.Configuration/AElf.Contracts.Configuration.csproj b/contract/AElf.Contracts.Configuration/AElf.Contracts.Configuration.csproj index 414dc60419..e06e6e236c 100644 --- a/contract/AElf.Contracts.Configuration/AElf.Contracts.Configuration.csproj +++ b/contract/AElf.Contracts.Configuration/AElf.Contracts.Configuration.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Configuration true Configuration is a contract used for changing configurable aspects of the chain, like for example diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContractConstants.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContractConstants.cs index 9c4f4c1599..8fd009bab6 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContractConstants.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContractConstants.cs @@ -12,4 +12,5 @@ public static class AEDPoSContractConstants public const string SideChainShareProfitsTokenSymbol = "SHARE"; public const string PayTxFeeSymbolListName = "SymbolListToPayTxFee"; public const string PayRentalSymbolListName = "SymbolListToPayRental"; + public const string SecretSharingEnabledConfigurationKey = "SecretSharingEnabled"; } \ No newline at end of file diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ACS11_CrossChainInformationProvider.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ACS11_CrossChainInformationProvider.cs index 0b7fd8af6b..bb05712a7c 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ACS11_CrossChainInformationProvider.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ACS11_CrossChainInformationProvider.cs @@ -57,7 +57,7 @@ public override Empty UpdateInformationFromCrossChain(BytesValue input) var minersKeys = consensusInformation.Round.RealTimeMinersInformation.Keys; State.MainChainCurrentMinerList.Value = new MinerList { - Pubkeys = { minersKeys.Select(ByteStringHelper.FromHexString) } + Pubkeys = { minersKeys.Select(k => ByteStringHelper.FromHexString(k)) } }; return new Empty(); diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_GetConsensusBlockExtraData.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_GetConsensusBlockExtraData.cs index bbbce356a4..70d9a25596 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_GetConsensusBlockExtraData.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_GetConsensusBlockExtraData.cs @@ -118,7 +118,11 @@ private AElfConsensusHeaderInformation GetConsensusExtraDataToPublishOutValue(Ro updatedRound.RealTimeMinersInformation[pubkey].ImpliedIrreversibleBlockHeight = Context.CurrentHeight; // Update secret pieces of latest in value. - UpdateLatestSecretPieces(updatedRound, pubkey, triggerInformation); + + if (IsSecretSharingEnabled()) + { + UpdateLatestSecretPieces(updatedRound, pubkey, triggerInformation); + } // To publish Out Value. return new AElfConsensusHeaderInformation diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs index fd1e42e738..88632c10ff 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ProcessConsensusInformation.cs @@ -184,7 +184,7 @@ private void ProcessNextTerm(NextTermInput input) // Update miners list. var miners = new MinerList(); - miners.Pubkeys.AddRange(nextRound.RealTimeMinersInformation.Keys.Select(ByteStringHelper.FromHexString)); + miners.Pubkeys.AddRange(nextRound.RealTimeMinersInformation.Keys.Select(k => ByteStringHelper.FromHexString(k))); if (!SetMinerList(miners, nextRound.TermNumber)) Assert(false, "Failed to update miner list."); // Update term number lookup. (Using term number to get first round number of related term.) @@ -249,7 +249,10 @@ private void ProcessUpdateValue(UpdateValueInput updateValueInput) minerInRound.ProducedBlocks = minerInRound.ProducedBlocks.Add(1); minerInRound.ProducedTinyBlocks = minerInRound.ProducedTinyBlocks.Add(1); - PerformSecretSharing(updateValueInput, minerInRound, currentRound, _processingBlockMinerPubkey); + if (IsSecretSharingEnabled()) + { + PerformSecretSharing(updateValueInput, minerInRound, currentRound, _processingBlockMinerPubkey); + } foreach (var tuneOrder in updateValueInput.TuneOrderInformation) currentRound.RealTimeMinersInformation[tuneOrder.Key].FinalOrderOfNextRound = tuneOrder.Value; diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_SecretSharing.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_SecretSharing.cs index 57f132e0de..7fafcc8d67 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_SecretSharing.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_SecretSharing.cs @@ -1,6 +1,9 @@ using System.Linq; using AElf.Cryptography.SecretSharing; using AElf.CSharp.Core; +using AElf.Sdk.CSharp; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; namespace AElf.Contracts.Consensus.AEDPoS; @@ -49,4 +52,28 @@ private void RevealSharedInValues(Round currentRound, string publicKey) currentRound.RealTimeMinersInformation[publicKeyOfAnotherMiner].PreviousInValue = revealedInValue; } } + + private bool IsSecretSharingEnabled() + { + if (State.ConfigurationContract.Value == null) + { + var configurationContractAddress = + Context.GetContractAddressByName(SmartContractConstants.ConfigurationContractSystemName); + if (configurationContractAddress == null) + { + // Which means Configuration Contract hasn't been deployed yet. + return false; + } + + State.ConfigurationContract.Value = configurationContractAddress; + } + + var secretSharingEnabled = new BoolValue(); + secretSharingEnabled.MergeFrom(State.ConfigurationContract.GetConfiguration.Call(new StringValue + { + Value = AEDPoSContractConstants.SecretSharingEnabledConfigurationKey + }).Value); + + return secretSharingEnabled.Value; + } } \ No newline at end of file diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ViewMethods.cs b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ViewMethods.cs index 02fcd80818..ed6e0e0092 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ViewMethods.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AEDPoSContract_ViewMethods.cs @@ -35,7 +35,7 @@ public override MinerList GetCurrentMinerList(Empty input) { Pubkeys = { - round.RealTimeMinersInformation.Keys.Select(ByteStringHelper.FromHexString) + round.RealTimeMinersInformation.Keys.Select(k => ByteStringHelper.FromHexString(k)) } } : new MinerList(); @@ -236,7 +236,7 @@ private Round GenerateFirstRoundOfNextTerm(string senderPubkey, int miningInterv // Miners of new round are same with current round. var miners = new MinerList(); miners.Pubkeys.AddRange( - currentRound.RealTimeMinersInformation.Keys.Select(ByteStringHelper.FromHexString)); + currentRound.RealTimeMinersInformation.Keys.Select(k => ByteStringHelper.FromHexString(k))); newRound = miners.GenerateFirstRoundOfNewTerm(currentRound.GetMiningInterval(), Context.CurrentBlockTime, currentRound); } diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/AElf.Contracts.Consensus.AEDPoS.csproj b/contract/AElf.Contracts.Consensus.AEDPoS/AElf.Contracts.Consensus.AEDPoS.csproj index e197019f68..49c8eed8af 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/AElf.Contracts.Consensus.AEDPoS.csproj +++ b/contract/AElf.Contracts.Consensus.AEDPoS/AElf.Contracts.Consensus.AEDPoS.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Consensus.AEDPoS true Consensus is a contract that implements AElf’s DPoS consensus protocol. @@ -47,6 +47,9 @@ Protobuf\Proto\reference\profit_contract.proto + + Protobuf\Proto\reference\configuration_contract.proto + diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/ContractsReferences.cs b/contract/AElf.Contracts.Consensus.AEDPoS/ContractsReferences.cs index 48852984c8..19274e6b45 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/ContractsReferences.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/ContractsReferences.cs @@ -1,3 +1,4 @@ +using AElf.Contracts.Configuration; using AElf.Contracts.Election; using AElf.Contracts.MultiToken; using AElf.Contracts.Parliament; @@ -15,4 +16,5 @@ public partial class AEDPoSContractState internal TokenContractContainer.TokenContractReferenceState TokenContract { get; set; } internal TokenHolderContractContainer.TokenHolderContractReferenceState TokenHolderContract { get; set; } internal ParliamentContractContainer.ParliamentContractReferenceState ParliamentContract { get; set; } + internal ConfigurationContainer.ConfigurationReferenceState ConfigurationContract { get; set; } } \ No newline at end of file diff --git a/contract/AElf.Contracts.Consensus.AEDPoS/Types/Round.cs b/contract/AElf.Contracts.Consensus.AEDPoS/Types/Round.cs index b062d408e9..ca45dec196 100644 --- a/contract/AElf.Contracts.Consensus.AEDPoS/Types/Round.cs +++ b/contract/AElf.Contracts.Consensus.AEDPoS/Types/Round.cs @@ -130,7 +130,7 @@ public MinerList GetMinerList() { return new MinerList { - Pubkeys = { RealTimeMinersInformation.Keys.Select(ByteStringHelper.FromHexString) } + Pubkeys = { RealTimeMinersInformation.Keys.Select(k => ByteStringHelper.FromHexString(k)) } }; } diff --git a/contract/AElf.Contracts.CrossChain/AElf.Contracts.CrossChain.csproj b/contract/AElf.Contracts.CrossChain/AElf.Contracts.CrossChain.csproj index e4a88d7962..285afe7876 100644 --- a/contract/AElf.Contracts.CrossChain/AElf.Contracts.CrossChain.csproj +++ b/contract/AElf.Contracts.CrossChain/AElf.Contracts.CrossChain.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 AElf.Contracts.CrossChain true CrossChain is a contract that implements cross-chain related features, especially diff --git a/contract/AElf.Contracts.Economic/AElf.Contracts.Economic.csproj b/contract/AElf.Contracts.Economic/AElf.Contracts.Economic.csproj index 0ec68211bf..2bb0f5fc48 100644 --- a/contract/AElf.Contracts.Economic/AElf.Contracts.Economic.csproj +++ b/contract/AElf.Contracts.Economic/AElf.Contracts.Economic.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Economic true Economic is a contract that implements the basic functionality used to manage the economic diff --git a/contract/AElf.Contracts.Election/AElf.Contracts.Election.csproj b/contract/AElf.Contracts.Election/AElf.Contracts.Election.csproj index 30187f8423..563a7d8083 100644 --- a/contract/AElf.Contracts.Election/AElf.Contracts.Election.csproj +++ b/contract/AElf.Contracts.Election/AElf.Contracts.Election.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Election true Election is a contract that implements voting. diff --git a/contract/AElf.Contracts.Election/ElectionContract_Maintainence.cs b/contract/AElf.Contracts.Election/ElectionContract_Maintainence.cs index 2ffc98c8e3..429db8c92f 100644 --- a/contract/AElf.Contracts.Election/ElectionContract_Maintainence.cs +++ b/contract/AElf.Contracts.Election/ElectionContract_Maintainence.cs @@ -33,7 +33,8 @@ public override Empty InitialElectionContract(InitialElectionContractInput input State.MinersCount.Value = input.MinerList.Count; State.InitialMiners.Value = new PubkeyList { - Value = { input.MinerList.Select(ByteStringHelper.FromHexString) } + // ReSharper disable once ConvertClosureToMethodGroup + Value = { input.MinerList.Select(m => ByteStringHelper.FromHexString(m)) } }; foreach (var pubkey in input.MinerList) State.CandidateInformationMap[pubkey] = new CandidateInformation diff --git a/contract/AElf.Contracts.Election/ViewMethods.cs b/contract/AElf.Contracts.Election/ViewMethods.cs index ef8735b3d5..00dd4d4e25 100644 --- a/contract/AElf.Contracts.Election/ViewMethods.cs +++ b/contract/AElf.Contracts.Election/ViewMethods.cs @@ -62,7 +62,7 @@ private List GetVictories(List currentMiners) if (diff > 0) { victories = - new List(validCandidates.Select(ByteStringHelper.FromHexString)); + new List(validCandidates.Select(v => ByteStringHelper.FromHexString(v))); var backups = currentMiners.Where(k => !validCandidates.Contains(k)).ToList(); if (State.InitialMiners.Value != null) backups.AddRange( @@ -70,7 +70,8 @@ private List GetVictories(List currentMiners) victories.AddRange(backups.OrderBy(p => p) .Take(Math.Min(diff, currentMiners.Count)) - .Select(ByteStringHelper.FromHexString)); + // ReSharper disable once ConvertClosureToMethodGroup + .Select(v => ByteStringHelper.FromHexString(v))); Context.LogDebug(() => string.Join("\n", victories.Select(v => v.ToHex().Substring(0, 10)).ToList())); return victories; } diff --git a/contract/AElf.Contracts.Genesis/AElf.Contracts.Genesis.csproj b/contract/AElf.Contracts.Genesis/AElf.Contracts.Genesis.csproj index 7310f1b799..91356b10eb 100644 --- a/contract/AElf.Contracts.Genesis/AElf.Contracts.Genesis.csproj +++ b/contract/AElf.Contracts.Genesis/AElf.Contracts.Genesis.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 AElf.Contracts.Genesis true Genesis is a contract that implements base functionality of the chain such as contract proposal diff --git a/contract/AElf.Contracts.Genesis/BasicContractZero.cs b/contract/AElf.Contracts.Genesis/BasicContractZero.cs index d673fbf306..536bc87bb6 100644 --- a/contract/AElf.Contracts.Genesis/BasicContractZero.cs +++ b/contract/AElf.Contracts.Genesis/BasicContractZero.cs @@ -84,6 +84,12 @@ public override Int32Value GetContractProposalExpirationTimePeriod(Empty input) return new Int32Value { Value = expirationTimePeriod }; } + public override Int32Value GetCodeCheckProposalExpirationTimePeriod(Empty input) + { + var expirationTimePeriod = GetCodeCheckProposalExpirationTimePeriod(); + return new Int32Value { Value = expirationTimePeriod }; + } + public override Address GetSigner(Address input) { return State.SignerMap[input]; @@ -245,7 +251,7 @@ public override Hash ProposeContractCodeCheck(ContractCodeCheckInput input) ContractMethodName = input.CodeCheckReleaseMethod, Params = input.ContractInput, OrganizationAddress = codeCheckController.OwnerAddress, - ExpiredTime = Context.CurrentBlockTime.AddSeconds(CodeCheckProposalExpirationTimePeriod) + ExpiredTime = Context.CurrentBlockTime.AddSeconds(GetCodeCheckProposalExpirationTimePeriod()) }, OriginProposer = proposedInfo.Proposer }; @@ -392,6 +398,14 @@ public override Empty SetContractProposalExpirationTimePeriod(SetContractProposa return new Empty(); } + public override Empty SetCodeCheckProposalExpirationTimePeriod(Int32Value input) + { + AssertSenderAddressWith(State.ContractDeploymentController.Value.OwnerAddress); + Assert(input.Value > 0, "Invalid expiration time period."); + State.CodeCheckProposalExpirationTimePeriod.Value = input.Value; + return new Empty(); + } + public override DeployUserSmartContractOutput DeployUserSmartContract(UserContractDeploymentInput input) { AssertInlineDeployOrUpdateUserContract(); diff --git a/contract/AElf.Contracts.Genesis/BasicContractZeroState.cs b/contract/AElf.Contracts.Genesis/BasicContractZeroState.cs index 4e6a5dc8a6..8324b35afe 100644 --- a/contract/AElf.Contracts.Genesis/BasicContractZeroState.cs +++ b/contract/AElf.Contracts.Genesis/BasicContractZeroState.cs @@ -36,4 +36,7 @@ public partial class BasicContractZeroState : ContractState public SingletonState ContractProposalExpirationTimePeriod { get; set; } public MappedState SignerMap { get; set; } + + public SingletonState CodeCheckProposalExpirationTimePeriod { get; set; } + } \ No newline at end of file diff --git a/contract/AElf.Contracts.Genesis/BasicContractZero_Constants.cs b/contract/AElf.Contracts.Genesis/BasicContractZero_Constants.cs index 6ed4e650d4..03911596ef 100644 --- a/contract/AElf.Contracts.Genesis/BasicContractZero_Constants.cs +++ b/contract/AElf.Contracts.Genesis/BasicContractZero_Constants.cs @@ -3,7 +3,7 @@ namespace AElf.Contracts.Genesis; public partial class BasicContractZero { public const int ContractProposalExpirationTimePeriod = 259200; // 60 * 60 * 72 - public const int CodeCheckProposalExpirationTimePeriod = 600; // 60 * 10 + public const int DefaultCodeCheckProposalExpirationTimePeriod = 900; // 60 * 15 private const int MinimalApprovalThreshold = 6667; private const int MaximalAbstentionThreshold = 1000; private const int MaximalRejectionThreshold = 1000; diff --git a/contract/AElf.Contracts.Genesis/BasicContractZero_Helper.cs b/contract/AElf.Contracts.Genesis/BasicContractZero_Helper.cs index b82fd27996..edbd094793 100644 --- a/contract/AElf.Contracts.Genesis/BasicContractZero_Helper.cs +++ b/contract/AElf.Contracts.Genesis/BasicContractZero_Helper.cs @@ -286,6 +286,13 @@ private int GetCurrentContractProposalExpirationTimePeriod() : State.ContractProposalExpirationTimePeriod.Value; } + private int GetCodeCheckProposalExpirationTimePeriod() + { + return State.CodeCheckProposalExpirationTimePeriod.Value == 0 + ? DefaultCodeCheckProposalExpirationTimePeriod + : State.CodeCheckProposalExpirationTimePeriod.Value; + } + private void AssertCurrentMiner() { RequireConsensusContractStateSet(); @@ -310,7 +317,7 @@ private void SendUserContractProposal(Hash proposingInputHash, string releaseMet { Proposer = Context.Self, Status = ContractProposingInputStatus.CodeCheckProposed, - ExpiredTime = Context.CurrentBlockTime.AddSeconds(CodeCheckProposalExpirationTimePeriod), + ExpiredTime = Context.CurrentBlockTime.AddSeconds(GetCodeCheckProposalExpirationTimePeriod()), Author = Context.Sender }; State.ContractProposingInputMap[proposingInputHash] = proposedInfo; diff --git a/contract/AElf.Contracts.MultiToken/AElf.Contracts.MultiToken.csproj b/contract/AElf.Contracts.MultiToken/AElf.Contracts.MultiToken.csproj index 44d6ef3422..bb668e4b2a 100644 --- a/contract/AElf.Contracts.MultiToken/AElf.Contracts.MultiToken.csproj +++ b/contract/AElf.Contracts.MultiToken/AElf.Contracts.MultiToken.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.MultiToken true MultiToken is a contract that implements token functionality like creation, issuance and diff --git a/contract/AElf.Contracts.MultiToken/TokenContractConstants.cs b/contract/AElf.Contracts.MultiToken/TokenContractConstants.cs index a14a4e9496..50e0c8c092 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContractConstants.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContractConstants.cs @@ -14,6 +14,7 @@ public static class TokenContractConstants public const string LockCallbackExternalInfoKey = "aelf_lock_callback"; public const string UnlockCallbackExternalInfoKey = "aelf_unlock_callback"; public const string LogEventExternalInfoKey = "aelf_log_event"; + public const string TokenAliasExternalInfoKey = "aelf_token_alias"; public const int DELEGATEE_MAX_COUNT = 24; public const char NFTSymbolSeparator = '-'; public const int NFTSymbolMaxLength = 30; @@ -22,4 +23,8 @@ public static class TokenContractConstants public const string SeedCollectionSymbol = "SEED-0"; public const string SeedOwnedSymbolExternalInfoKey = "__seed_owned_symbol"; public const string SeedExpireTimeExternalInfoKey = "__seed_exp_time"; + public const string NftCreateChainIdExternalInfoKey = "__nft_create_chain_id"; + public const int DefaultMaxBatchApproveCount = 100; + public const char AllSymbolIdentifier = '*'; + } \ No newline at end of file diff --git a/contract/AElf.Contracts.MultiToken/TokenContractState.cs b/contract/AElf.Contracts.MultiToken/TokenContractState.cs index 92da423908..6627c3625b 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContractState.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContractState.cs @@ -8,7 +8,13 @@ public partial class TokenContractState : ContractState public StringState NativeTokenSymbol { get; set; } public StringState ChainPrimaryTokenSymbol { get; set; } + + /// + /// WARNING: Use GetTokenInfo & SetTokenInfo to operate TokenInfos + /// due to token symbol alias feature. + /// public MappedState TokenInfos { get; set; } + public MappedState InsensitiveTokenExisting { get; set; } public MappedState SymbolSeedMap { get; set; } public MappedState Balances { get; set; } public MappedState Allowances { get; set; } @@ -63,4 +69,11 @@ public partial class TokenContractState : ContractState public SingletonState
ElectionContractAddress { get; set; } public SingletonState
VoteContractAddress { get; set; } + + public SingletonState TokenIssuerAndOwnerModificationDisabled { get; set; } + + public SingletonState MaxBatchApproveCount { get; set; } + + // Alias -> Actual Symbol + public MappedState SymbolAliasMap { get; set; } } \ No newline at end of file diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_ACS1_MethodFeeProvider.cs b/contract/AElf.Contracts.MultiToken/TokenContract_ACS1_MethodFeeProvider.cs index 9ef198b39c..e24c2d8acc 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_ACS1_MethodFeeProvider.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_ACS1_MethodFeeProvider.cs @@ -123,9 +123,12 @@ private bool CheckOrganizationExist(AuthorityInfo authorityInfo) private void AssertValidFeeToken(string symbol, long amount) { AssertValidSymbolAndAmount(symbol, amount); - if (State.TokenInfos[symbol] == null) + var tokenInfo = GetTokenInfo(symbol); + if (tokenInfo == null) + { throw new AssertionException("Token is not found"); - Assert(State.TokenInfos[symbol].IsBurnable, $"Token {symbol} cannot set as method fee."); + } + Assert(tokenInfo.IsBurnable, $"Token {symbol} cannot set as method fee."); } #endregion diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_ACS2_StatePathsProvider.cs b/contract/AElf.Contracts.MultiToken/TokenContract_ACS2_StatePathsProvider.cs index 8d12f604e1..79f26a4f3b 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_ACS2_StatePathsProvider.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_ACS2_StatePathsProvider.cs @@ -44,8 +44,6 @@ public override ResourceInfo GetResourceInfo(Transaction txn) { WritePaths = { - GetPath(nameof(TokenContractState.Allowances), args.From.ToString(), txn.From.ToString(), - args.Symbol), GetPath(nameof(TokenContractState.Balances), args.From.ToString(), args.Symbol), GetPath(nameof(TokenContractState.Balances), args.To.ToString(), args.Symbol), GetPath(nameof(TokenContractState.LockWhiteLists), args.Symbol, txn.From.ToString()) @@ -57,7 +55,7 @@ public override ResourceInfo GetResourceInfo(Transaction txn) GetPath(nameof(TokenContractState.TransactionFeeFreeAllowancesSymbolList)) } }; - + AddPathForAllowance(resourceInfo, args.From.ToString(), txn.From.ToString(), args.Symbol); AddPathForTransactionFee(resourceInfo, txn.From.ToString(), txn.MethodName); AddPathForDelegatees(resourceInfo, txn.From, txn.To, txn.MethodName); AddPathForTransactionFeeFreeAllowance(resourceInfo, txn.From); @@ -70,6 +68,18 @@ public override ResourceInfo GetResourceInfo(Transaction txn) } } + private void AddPathForAllowance(ResourceInfo resourceInfo, string from, string spender, string symbol) + { + resourceInfo.WritePaths.Add(GetPath(nameof(TokenContractState.Allowances), from, spender, symbol)); + resourceInfo.WritePaths.Add(GetPath(nameof(TokenContractState.Allowances), from, spender, + GetAllSymbolIdentifier())); + var symbolType = GetSymbolType(symbol); + if (symbolType == SymbolType.Nft || symbolType == SymbolType.NftCollection) + { + resourceInfo.WritePaths.Add(GetPath(nameof(TokenContractState.Allowances), from, spender, + GetNftCollectionAllSymbolIdentifier(symbol))); + } + } private void AddPathForTransactionFee(ResourceInfo resourceInfo, string from, string methodName) { @@ -108,7 +118,7 @@ private void AddPathForDelegatees(ResourceInfo resourceInfo, Address from, Addre if (delegateeList.Count <= 0) return; var secondDelegateeList = new List(); //get and add second-level delegatee list - foreach (var delegateeAddress in delegateeList.Select(Address.FromBase58)) + foreach (var delegateeAddress in delegateeList.Select(a => Address.FromBase58(a))) { //delegatee of the first-level delegate is delegator of the second-level delegate secondDelegateeList.AddRange(GetDelegateeList(delegateeAddress, to, methodName)); diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs index 483f073b54..6adcf01a2a 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_Actions.cs @@ -32,9 +32,7 @@ public override Empty InitializeFromParentChain(InitializeFromParentChainInput i /// public override Empty Create(CreateInput input) { - // can not call create on side chain - Assert(State.SideChainCreator.Value == null, "Failed to create token if side chain creator already set."); - var inputSymbolType = GetCreateInputSymbolType(input.Symbol); + var inputSymbolType = GetSymbolType(input.Symbol); if (input.Owner == null) { input.Owner = input.Issuer; @@ -52,10 +50,13 @@ private Empty CreateToken(CreateInput input, SymbolType symbolType = SymbolType. AssertValidCreateInput(input, symbolType); if (symbolType == SymbolType.Token || symbolType == SymbolType.NftCollection) { + // can not call create on side chain + Assert(State.SideChainCreator.Value == null, + "Failed to create token if side chain creator already set."); if (!IsAddressInCreateWhiteList(Context.Sender) && input.Symbol != TokenContractConstants.SeedCollectionSymbol) { - var symbolSeed = State.SymbolSeedMap[input.Symbol]; + var symbolSeed = State.SymbolSeedMap[input.Symbol.ToUpper()]; CheckSeedNFT(symbolSeed, input.Symbol); // seed nft for one-time use only long balance = State.Balances[Context.Sender][symbolSeed]; @@ -76,6 +77,14 @@ private Empty CreateToken(CreateInput input, SymbolType symbolType = SymbolType. ExternalInfo = input.ExternalInfo ?? new ExternalInfo(), Owner = input.Owner }; + + if (IsAliasSettingExists(tokenInfo)) + { + Assert(symbolType == SymbolType.NftCollection, "Token alias can only be set for NFT Item."); + SetTokenAlias(tokenInfo); + } + + CheckTokenExists(tokenInfo.Symbol); RegisterTokenInfo(tokenInfo); if (string.IsNullOrEmpty(State.NativeTokenSymbol.Value)) { @@ -109,7 +118,7 @@ private Empty CreateToken(CreateInput input, SymbolType symbolType = SymbolType. private void CheckSeedNFT(string symbolSeed, String symbol) { Assert(!string.IsNullOrEmpty(symbolSeed), "Seed NFT does not exist."); - var tokenInfo = State.TokenInfos[symbolSeed]; + var tokenInfo = GetTokenInfo(symbolSeed); Assert(tokenInfo != null, "Seed NFT does not exist."); Assert(State.Balances[Context.Sender][symbolSeed] > 0, "Seed NFT balance is not enough."); Assert(tokenInfo.ExternalInfo != null && tokenInfo.ExternalInfo.Value.TryGetValue( @@ -130,7 +139,7 @@ private void CheckSeedNFT(string symbolSeed, String symbol) public override Empty SetPrimaryTokenSymbol(SetPrimaryTokenSymbolInput input) { Assert(State.ChainPrimaryTokenSymbol.Value == null, "Failed to set primary token symbol."); - Assert(!string.IsNullOrWhiteSpace(input.Symbol) && State.TokenInfos[input.Symbol] != null, "Invalid input symbol."); + Assert(!string.IsNullOrWhiteSpace(input.Symbol) && GetTokenInfo(input.Symbol) != null, "Invalid input symbol."); State.ChainPrimaryTokenSymbol.Value = input.Symbol; Context.Fire(new ChainPrimaryTokenSymbolSet { TokenSymbol = input.Symbol }); @@ -155,7 +164,7 @@ public override Empty Issue(IssueInput input) tokenInfo.Supply = tokenInfo.Supply.Add(input.Amount); Assert(tokenInfo.Issued <= tokenInfo.TotalSupply, "Total supply exceeded"); - State.TokenInfos[input.Symbol] = tokenInfo; + SetTokenInfo(tokenInfo); ModifyBalance(input.To, input.Symbol, input.Amount); Context.Fire(new Issued @@ -170,14 +179,14 @@ public override Empty Issue(IssueInput input) public override Empty Transfer(TransferInput input) { - AssertValidToken(input.Symbol, input.Amount); - DoTransfer(Context.Sender, input.To, input.Symbol, input.Amount, input.Memo); + var tokenInfo = AssertValidToken(input.Symbol, input.Amount); + DoTransfer(Context.Sender, input.To, tokenInfo.Symbol, input.Amount, input.Memo); DealWithExternalInfoDuringTransfer(new TransferFromInput { From = Context.Sender, To = input.To, Amount = input.Amount, - Symbol = input.Symbol, + Symbol = tokenInfo.Symbol, Memo = input.Memo }); return new Empty(); @@ -244,38 +253,63 @@ public override Empty Unlock(UnlockInput input) public override Empty TransferFrom(TransferFromInput input) { - AssertValidToken(input.Symbol, input.Amount); - DoTransferFrom(input.From, input.To, Context.Sender, input.Symbol, input.Amount, input.Memo); + var tokenInfo = AssertValidToken(input.Symbol, input.Amount); + DoTransferFrom(input.From, input.To, Context.Sender, tokenInfo.Symbol, input.Amount, input.Memo); return new Empty(); } public override Empty Approve(ApproveInput input) { AssertValidInputAddress(input.Spender); - AssertValidToken(input.Symbol, input.Amount); - State.Allowances[Context.Sender][input.Spender][input.Symbol] = input.Amount; + var actualSymbol = GetActualTokenSymbol(input.Symbol); + AssertValidApproveTokenAndAmount(actualSymbol, input.Amount); + Approve(input.Spender, actualSymbol, input.Amount); + return new Empty(); + } + + private void Approve(Address spender, string symbol, long amount) + { + var actualSymbol = GetActualTokenSymbol(symbol); + State.Allowances[Context.Sender][spender][actualSymbol] = amount; Context.Fire(new Approved { Owner = Context.Sender, - Spender = input.Spender, - Symbol = input.Symbol, - Amount = input.Amount + Spender = spender, + Symbol = actualSymbol, + Amount = amount }); + } + + public override Empty BatchApprove(BatchApproveInput input) + { + Assert(input != null && input.Value != null && input.Value.Count > 0, "Invalid input ."); + Assert(input.Value.Count <= GetMaxBatchApproveCount(), "Exceeds the max batch approve count."); + foreach (var approve in input.Value) + { + AssertValidInputAddress(approve.Spender); + var actualSymbol = GetActualTokenSymbol(approve.Symbol); + AssertValidApproveTokenAndAmount(actualSymbol, approve.Amount); + } + var approveInputList = input.Value.GroupBy(approve => approve.Symbol + approve.Spender, approve => approve) + .Select(approve => approve.Last()).ToList(); + foreach (var approve in approveInputList) + Approve(approve.Spender, approve.Symbol, approve.Amount); return new Empty(); } public override Empty UnApprove(UnApproveInput input) { AssertValidInputAddress(input.Spender); - AssertValidToken(input.Symbol, input.Amount); - var oldAllowance = State.Allowances[Context.Sender][input.Spender][input.Symbol]; + var symbol = GetActualTokenSymbol(input.Symbol); + AssertValidApproveTokenAndAmount(symbol, input.Amount); + var oldAllowance = State.Allowances[Context.Sender][input.Spender][symbol]; var amountOrAll = Math.Min(input.Amount, oldAllowance); - State.Allowances[Context.Sender][input.Spender][input.Symbol] = oldAllowance.Sub(amountOrAll); + State.Allowances[Context.Sender][input.Spender][symbol] = oldAllowance.Sub(amountOrAll); Context.Fire(new UnApproved { Owner = Context.Sender, Spender = input.Spender, - Symbol = input.Symbol, + Symbol = symbol, Amount = amountOrAll }); return new Empty(); @@ -404,7 +438,7 @@ public override Empty TakeResourceTokenBack(TakeResourceTokenBackInput input) public override Empty ValidateTokenInfoExists(ValidateTokenInfoExistsInput input) { Assert(!string.IsNullOrWhiteSpace(input.Symbol), "Invalid input symbol."); - var tokenInfo = State.TokenInfos[input.Symbol]; + var tokenInfo = GetTokenInfo(input.Symbol); if (tokenInfo == null) throw new AssertionException("Token validation failed."); var validationResult = tokenInfo.TokenName == input.TokenName && @@ -467,20 +501,34 @@ public override Empty CrossChainCreateToken(CrossChainCreateTokenInput input) ExternalInfo = new ExternalInfo { Value = { validateTokenInfoExistsInput.ExternalInfo } }, Owner = validateTokenInfoExistsInput.Owner ?? validateTokenInfoExistsInput.Issuer }; - RegisterTokenInfo(tokenInfo); - Context.Fire(new TokenCreated + var isSymbolAliasSet = SyncSymbolAliasFromTokenInfo(tokenInfo); + if (State.TokenInfos[tokenInfo.Symbol] == null) { - Symbol = validateTokenInfoExistsInput.Symbol, - TokenName = validateTokenInfoExistsInput.TokenName, - TotalSupply = validateTokenInfoExistsInput.TotalSupply, - Decimals = validateTokenInfoExistsInput.Decimals, - Issuer = validateTokenInfoExistsInput.Issuer, - IsBurnable = validateTokenInfoExistsInput.IsBurnable, - IssueChainId = validateTokenInfoExistsInput.IssueChainId, - ExternalInfo = new ExternalInfo { Value = { validateTokenInfoExistsInput.ExternalInfo } }, - Owner = tokenInfo.Owner - }); + RegisterTokenInfo(tokenInfo); + Context.Fire(new TokenCreated + { + Symbol = validateTokenInfoExistsInput.Symbol, + TokenName = validateTokenInfoExistsInput.TokenName, + TotalSupply = validateTokenInfoExistsInput.TotalSupply, + Decimals = validateTokenInfoExistsInput.Decimals, + Issuer = validateTokenInfoExistsInput.Issuer, + IsBurnable = validateTokenInfoExistsInput.IsBurnable, + IssueChainId = validateTokenInfoExistsInput.IssueChainId, + ExternalInfo = new ExternalInfo { Value = { validateTokenInfoExistsInput.ExternalInfo } }, + Owner = tokenInfo.Owner, + }); + } + else + { + if (isSymbolAliasSet && + validateTokenInfoExistsInput.ExternalInfo.TryGetValue(TokenContractConstants.TokenAliasExternalInfoKey, + out var tokenAliasSetting)) + { + State.TokenInfos[tokenInfo.Symbol].ExternalInfo.Value + .Add(TokenContractConstants.TokenAliasExternalInfoKey, tokenAliasSetting); + } + } return new Empty(); } @@ -511,21 +559,21 @@ public override Empty RegisterCrossChainTokenContractAddress(RegisterCrossChainT /// public override Empty CrossChainTransfer(CrossChainTransferInput input) { - AssertValidToken(input.Symbol, input.Amount); + var tokenInfo = AssertValidToken(input.Symbol, input.Amount); AssertValidMemo(input.Memo); - var issueChainId = GetIssueChainId(input.Symbol); + var issueChainId = GetIssueChainId(tokenInfo.Symbol); Assert(issueChainId == input.IssueChainId, "Incorrect issue chain id."); var burnInput = new BurnInput { Amount = input.Amount, - Symbol = input.Symbol + Symbol = tokenInfo.Symbol }; Burn(burnInput); Context.Fire(new CrossChainTransferred { From = Context.Sender, To = input.To, - Symbol = input.Symbol, + Symbol = tokenInfo.Symbol, Amount = input.Amount, IssueChainId = input.IssueChainId, Memo = input.Memo, @@ -556,28 +604,28 @@ public override Empty CrossChainReceiveToken(CrossChainReceiveTokenInput input) var transferSender = transferTransaction.From; var tokenInfo = AssertValidToken(symbol, amount); - var issueChainId = GetIssueChainId(symbol); + var issueChainId = GetIssueChainId(tokenInfo.Symbol); Assert(issueChainId == crossChainTransferInput.IssueChainId, "Incorrect issue chain id."); Assert(targetChainId == Context.ChainId, "Unable to claim cross chain token."); var registeredTokenContractAddress = State.CrossChainTransferWhiteList[input.FromChainId]; AssertCrossChainTransaction(transferTransaction, registeredTokenContractAddress, nameof(CrossChainTransfer)); Context.LogDebug(() => - $"symbol == {symbol}, amount == {amount}, receivingAddress == {receivingAddress}, targetChainId == {targetChainId}"); + $"symbol == {tokenInfo.Symbol}, amount == {amount}, receivingAddress == {receivingAddress}, targetChainId == {targetChainId}"); CrossChainVerify(transferTransactionId, input.ParentChainHeight, input.FromChainId, input.MerklePath); State.VerifiedCrossChainTransferTransaction[transferTransactionId] = true; tokenInfo.Supply = tokenInfo.Supply.Add(amount); Assert(tokenInfo.Supply <= tokenInfo.TotalSupply, "Total supply exceeded"); - State.TokenInfos[symbol] = tokenInfo; - ModifyBalance(receivingAddress, symbol, amount); + SetTokenInfo(tokenInfo); + ModifyBalance(receivingAddress, tokenInfo.Symbol, amount); Context.Fire(new CrossChainReceived { From = transferSender, To = receivingAddress, - Symbol = symbol, + Symbol = tokenInfo.Symbol, Amount = amount, Memo = crossChainTransferInput.Memo, FromChainId = input.FromChainId, @@ -589,4 +637,187 @@ public override Empty CrossChainReceiveToken(CrossChainReceiveTokenInput input) } #endregion + + public override Empty ModifyTokenIssuerAndOwner(ModifyTokenIssuerAndOwnerInput input) + { + Assert(!State.TokenIssuerAndOwnerModificationDisabled.Value, "Set token issuer and owner disabled."); + Assert(!string.IsNullOrWhiteSpace(input.Symbol), "Invalid input symbol."); + Assert(input.Issuer != null && !input.Issuer.Value.IsNullOrEmpty(), "Invalid input issuer."); + Assert(input.Owner != null && !input.Owner.Value.IsNullOrEmpty(), "Invalid input owner."); + + var tokenInfo = GetTokenInfo(input.Symbol); + + Assert(tokenInfo != null, "Token is not found."); + Assert(tokenInfo.Issuer == Context.Sender, "Only token issuer can set token issuer and owner."); + Assert(tokenInfo.Owner == null, "Can only set token which does not have owner."); + + tokenInfo.Issuer = input.Issuer; + tokenInfo.Owner = input.Owner; + + return new Empty(); + } + + public override Empty SetTokenIssuerAndOwnerModificationEnabled(SetTokenIssuerAndOwnerModificationEnabledInput input) + { + AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress); + Assert(input != null, "Invalid input."); + + State.TokenIssuerAndOwnerModificationDisabled.Value = !input.Enabled; + + return new Empty(); + } + + public override BoolValue GetTokenIssuerAndOwnerModificationEnabled(Empty input) + { + return new BoolValue + { + Value = !State.TokenIssuerAndOwnerModificationDisabled.Value + }; + } + + public override Empty SetMaxBatchApproveCount(Int32Value input) + { + Assert(input.Value > 0, "Invalid input."); + AssertSenderAddressWith(GetDefaultParliamentController().OwnerAddress); + State.MaxBatchApproveCount.Value = input.Value; + return new Empty(); + } + + public override Int32Value GetMaxBatchApproveCount(Empty input) + { + return new Int32Value + { + Value = GetMaxBatchApproveCount() + }; + } + + private int GetMaxBatchApproveCount() + { + return State.MaxBatchApproveCount.Value == 0 + ? TokenContractConstants.DefaultMaxBatchApproveCount + : State.MaxBatchApproveCount.Value; + } + + /// + /// For example: + /// Symbol: SGR-1, Alias: SGR + /// Symbol: ABC-233, Alias: ABC + /// + /// + /// + public override Empty SetSymbolAlias(SetSymbolAliasInput input) + { + // Alias setting can only work for NFT Item for now. + // And the setting exists on the TokenInfo of the NFT Collection. + + // Can only happen on Main Chain. + Assert(Context.ChainId == ChainHelper.ConvertBase58ToChainId("AELF"), + "Symbol alias setting only works on MainChain."); + + var collectionSymbol = GetNftCollectionSymbol(input.Symbol, true); + + // For now, token alias can only be set once. + Assert(State.SymbolAliasMap[input.Alias] == null, $"Token alias {input.Alias} already exists."); + + CheckTokenAlias(input.Alias, collectionSymbol); + + var collectionTokenInfo = GetTokenInfo(collectionSymbol); + if (collectionTokenInfo == null) + { + throw new AssertionException($"NFT Collection {collectionSymbol} not found."); + } + + Assert(collectionTokenInfo.Owner == Context.Sender || collectionTokenInfo.Issuer == Context.Sender, + "No permission."); + + collectionTokenInfo.ExternalInfo.Value[TokenContractConstants.TokenAliasExternalInfoKey] + = $"{{\"{input.Symbol}\":\"{input.Alias}\"}}"; + + SetTokenInfo(collectionTokenInfo); + + State.SymbolAliasMap[input.Alias] = input.Symbol; + + Context.LogDebug(() => $"Token alias added: {input.Symbol} -> {input.Alias}"); + + Context.Fire(new SymbolAliasAdded + { + Symbol = input.Symbol, + Alias = input.Alias + }); + + return new Empty(); + } + + private bool SyncSymbolAliasFromTokenInfo(TokenInfo newTokenInfo) + { + var maybePreviousTokenInfo = State.TokenInfos[newTokenInfo.Symbol]?.Clone(); + + if (maybePreviousTokenInfo != null && IsAliasSettingExists(maybePreviousTokenInfo)) + { + return false; + } + + if (IsAliasSettingExists(newTokenInfo)) + { + SetTokenAlias(newTokenInfo); + return true; + } + + return false; + } + + private bool IsAliasSettingExists(TokenInfo tokenInfo) + { + return tokenInfo.ExternalInfo != null && + tokenInfo.ExternalInfo.Value.Count > 0 && + tokenInfo.ExternalInfo.Value.ContainsKey(TokenContractConstants.TokenAliasExternalInfoKey); + } + + /// + /// Extract alias setting from ExternalInfo. + /// + /// + /// (Symbol, Alias) + private KeyValuePair ExtractAliasSetting(TokenInfo tokenInfo) + { + if (!tokenInfo.ExternalInfo.Value.ContainsKey(TokenContractConstants.TokenAliasExternalInfoKey)) + { + return new KeyValuePair(string.Empty, string.Empty); + } + + var tokenAliasSetting = tokenInfo.ExternalInfo.Value[TokenContractConstants.TokenAliasExternalInfoKey]; + tokenAliasSetting = tokenAliasSetting.Trim('{', '}'); + var parts = tokenAliasSetting.Split(':'); + var key = parts[0].Trim().Trim('\"'); + var value = parts[1].Trim().Trim('\"'); + return new KeyValuePair(key, value); + } + + private void SetTokenAlias(TokenInfo tokenInfo) + { + var (symbol, alias) = ExtractAliasSetting(tokenInfo); + State.SymbolAliasMap[alias] = symbol; + + CheckTokenAlias(alias, tokenInfo.Symbol); + + Context.Fire(new SymbolAliasAdded + { + Symbol = symbol, + Alias = alias + }); + } + + private void CheckTokenAlias(string alias, string collectionSymbol) + { + if (collectionSymbol == null) + { + throw new AssertionException("Token alias can only be set for NFT Item."); + } + + // Current Rule: Alias must be the seed name. + var parts = collectionSymbol.Split(TokenContractConstants.NFTSymbolSeparator); + Assert(parts.Length == 2, $"Incorrect collection symbol: {collectionSymbol}."); + Assert(parts.Last() == TokenContractConstants.CollectionSymbolSuffix, "Incorrect collection symbol suffix."); + Assert(alias == parts.First(), $"Alias for an item of {collectionSymbol} cannot be {alias}."); + } } \ No newline at end of file diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Delegation.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Delegation.cs index 1ac302ccef..37bf3219fd 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_Delegation.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_Delegation.cs @@ -191,7 +191,7 @@ public override GetTransactionFeeDelegateesOutput GetTransactionFeeDelegatees( return new GetTransactionFeeDelegateesOutput { - DelegateeAddresses = { allDelegatees.Delegatees.Keys.Select(Address.FromBase58) } + DelegateeAddresses = { allDelegatees.Delegatees.Keys.Select(k => Address.FromBase58(k)) } }; } @@ -413,7 +413,7 @@ public override GetTransactionFeeDelegateeListOutput GetTransactionFeeDelegateeL return new GetTransactionFeeDelegateeListOutput { - DelegateeAddresses = { allDelegatees.Delegatees.Keys.Select(Address.FromBase58) } + DelegateeAddresses = { allDelegatees.Delegatees.Keys.Select(k => Address.FromBase58(k)) } }; } diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Fees.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Fees.cs index 25f853ec11..12743edd91 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_Fees.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_Fees.cs @@ -140,7 +140,7 @@ private UserContractMethodFees GetActualFee(Address contractAddress, string meth //configuration_key:UserContractMethod_contractAddress_methodName var spec = State.ConfigurationContract.GetConfiguration.Call(new StringValue { - Value = $"{TokenContractConstants.UserContractMethodFeeKey}_{contractAddress}_{methodName}" + Value = $"{TokenContractConstants.UserContractMethodFeeKey}_{contractAddress.ToBase58()}_{methodName}" }); var fee = new UserContractMethodFees(); if (!spec.Value.IsNullOrEmpty()) @@ -320,14 +320,14 @@ private void SetOrRefreshTransactionFeeFreeAllowances(Address address) private Dictionary GetBaseFeeDictionary(MethodFees methodFees) { - return methodFees.Fees + return methodFees.Fees.Where(f => !string.IsNullOrEmpty(f.Symbol)) .GroupBy(f => f.Symbol, f => f.BasicFee) .ToDictionary(g => g.Key, g => g.Sum()); } private Dictionary GetUserContractFeeDictionary(UserContractMethodFees fees) { - return fees.Fees + return fees.Fees.Where(f => !string.IsNullOrEmpty(f.Symbol)) .GroupBy(f => f.Symbol, f => f.BasicFee) .ToDictionary(g => g.Key, g => g.Sum()); } @@ -620,7 +620,6 @@ public override Empty SetSymbolsToPayTxSizeFee(SymbolListToPayTxSizeFee input) var isPrimaryTokenExist = false; var symbolList = new List(); var primaryTokenSymbol = GetPrimaryTokenSymbol(new Empty()); - var primaryTokenInfo = State.TokenInfos[primaryTokenSymbol.Value]; Assert(!string.IsNullOrEmpty(primaryTokenSymbol.Value), "primary token does not exist"); foreach (var tokenWeightInfo in input.SymbolsToPayTxSizeFee) { @@ -1153,7 +1152,7 @@ private void TransferTransactionFeesToFeeReceiver(string symbol, long totalAmoun if (totalAmount <= 0) return; - var tokenInfo = State.TokenInfos[symbol]; + var tokenInfo = GetTokenInfo(symbol); if (!tokenInfo.IsBurnable) { return; @@ -1268,7 +1267,7 @@ public override Empty ConfigTransactionFeeFreeAllowances(ConfigTransactionFeeFre private void ValidateToken(string symbol) { Assert(!string.IsNullOrWhiteSpace(symbol), "Invalid input symbol"); - Assert(State.TokenInfos[symbol] != null, $"Symbol {symbol} not exist"); + Assert(GetTokenInfo(symbol) != null, $"Symbol {symbol} not exist"); } public override Empty RemoveTransactionFeeFreeAllowancesConfig(RemoveTransactionFeeFreeAllowancesConfigInput input) @@ -1411,7 +1410,7 @@ private bool IsDelegationEnough(string txSymbol, string baseSymbol, long cost, private void AssertSymbolToPayTxFeeIsValid(string tokenSymbol, out long totalSupply) { - var tokenInfo = State.TokenInfos[tokenSymbol]; + var tokenInfo = GetTokenInfo(tokenSymbol); if (tokenInfo == null) { throw new AssertionException($"Token is not found. {tokenSymbol}"); diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Helper.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Helper.cs index ed210282d0..3a78c60cbe 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_Helper.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_Helper.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using AElf.Contracts.Parliament; using AElf.CSharp.Core; using AElf.Sdk.CSharp; @@ -14,33 +15,72 @@ namespace AElf.Contracts.MultiToken; public partial class TokenContract { - private static bool IsValidSymbolChar(char character) + private static bool IsValidSymbol(string symbol) { - return (character >= 'A' && character <= 'Z') || (character >= '0' && character <= '9') || - character == TokenContractConstants.NFTSymbolSeparator; + return Regex.IsMatch(symbol, "^[a-zA-Z0-9]+(-[0-9]+)?$"); } - private bool IsValidItemIdChar(char character) + private bool IsValidItemId(string symbolItemId) { - return character >= '0' && character <= '9'; + return Regex.IsMatch(symbolItemId, "^[0-9]+$"); } - private bool IsValidCreateSymbolChar(char character) + private bool IsValidCreateSymbol(string symbol) { - return character >= 'A' && character <= 'Z'; + return Regex.IsMatch(symbol, "^[a-zA-Z0-9]+$"); } private TokenInfo AssertValidToken(string symbol, long amount) { AssertValidSymbolAndAmount(symbol, amount); - var tokenInfo = State.TokenInfos[symbol]; + var tokenInfo = GetTokenInfo(symbol); Assert(tokenInfo != null && !string.IsNullOrEmpty(tokenInfo.Symbol), $"Token is not found. {symbol}"); return tokenInfo; } + private void AssertValidApproveTokenAndAmount(string symbol, long amount) + { + Assert(amount > 0, "Invalid amount."); + AssertApproveToken(symbol); + } + + private void ValidTokenExists(string symbol) + { + var tokenInfo = State.TokenInfos[symbol]; + Assert(tokenInfo != null && !string.IsNullOrEmpty(tokenInfo.Symbol), + $"Token is not found. {symbol}"); + } + + private void AssertApproveToken(string symbol) + { + Assert(!string.IsNullOrEmpty(symbol), "Symbol can not be null."); + var words = symbol.Split(TokenContractConstants.NFTSymbolSeparator); + var symbolPrefix = words[0]; + var allSymbolIdentifier = GetAllSymbolIdentifier(); + Assert(symbolPrefix.Length > 0 && (IsValidCreateSymbol(symbolPrefix) || symbolPrefix.Equals(allSymbolIdentifier)), "Invalid symbol."); + if (words.Length == 1) + { + if (!symbolPrefix.Equals(allSymbolIdentifier)) + { + ValidTokenExists(symbolPrefix); + } + return; + } + Assert(words.Length == 2, "Invalid symbol length."); + var itemId = words[1]; + Assert(itemId.Length > 0 && (IsValidItemId(itemId) || itemId.Equals(allSymbolIdentifier)), "Invalid NFT Symbol."); + var nftSymbol = itemId.Equals(allSymbolIdentifier) ? GetCollectionSymbol(symbolPrefix) : symbol; + ValidTokenExists(nftSymbol); + } + + private string GetCollectionSymbol(string symbolPrefix) + { + return $"{symbolPrefix}-{TokenContractConstants.CollectionSymbolSuffix}"; + } + private void AssertValidSymbolAndAmount(string symbol, long amount) { - Assert(!string.IsNullOrEmpty(symbol) && symbol.All(IsValidSymbolChar), + Assert(!string.IsNullOrEmpty(symbol) && IsValidSymbol(symbol), "Invalid symbol."); Assert(amount > 0, "Invalid amount."); } @@ -122,13 +162,12 @@ private List GetSymbolListSortedByExpirationTime(TransactionFeeFreeAllow fromAddress][t]).Seconds).ToList(); } - private long GetBalance(Address address, string symbol) { AssertValidInputAddress(address); - Assert(!string.IsNullOrWhiteSpace(symbol), "Invalid symbol."); - - return State.Balances[address][symbol]; + var actualSymbol = GetActualTokenSymbol(symbol); + Assert(!string.IsNullOrWhiteSpace(actualSymbol), "Invalid symbol."); + return State.Balances[address][actualSymbol]; } // private MethodFeeFreeAllowance GetFreeFeeAllowance(MethodFeeFreeAllowances freeAllowances, string symbol) @@ -183,14 +222,14 @@ private void AssertCrossChainTransaction(Transaction originalTransaction, Addres private void RegisterTokenInfo(TokenInfo tokenInfo) { - CheckTokenExists(tokenInfo.Symbol); - Assert(!string.IsNullOrEmpty(tokenInfo.Symbol) && tokenInfo.Symbol.All(IsValidSymbolChar), + Assert(!string.IsNullOrEmpty(tokenInfo.Symbol) && IsValidSymbol(tokenInfo.Symbol), "Invalid symbol."); Assert(!string.IsNullOrEmpty(tokenInfo.TokenName), "Token name can neither be null nor empty."); Assert(tokenInfo.TotalSupply > 0, "Invalid total supply."); Assert(tokenInfo.Issuer != null, "Invalid issuer address."); Assert(tokenInfo.Owner != null, "Invalid owner address."); State.TokenInfos[tokenInfo.Symbol] = tokenInfo; + State.InsensitiveTokenExisting[tokenInfo.Symbol.ToUpper()] = true; } private void CrossChainVerify(Hash transactionId, long parentChainHeight, int chainId, MerklePath merklePath) @@ -225,7 +264,7 @@ private AuthorityInfo GetCrossChainTokenContractRegistrationController() private int GetIssueChainId(string symbol) { - var tokenInfo = State.TokenInfos[symbol]; + var tokenInfo = GetTokenInfo(symbol); return tokenInfo.IssueChainId; } @@ -255,8 +294,11 @@ private void CheckTokenAndCollectionExists(string symbol) private void CheckTokenExists(string symbol) { var empty = new TokenInfo(); - var existing = State.TokenInfos[symbol]; + // check old token + var existing = GetTokenInfo(symbol); Assert(existing == null || existing.Equals(empty), "Token already exists."); + // check new token + Assert(!State.InsensitiveTokenExisting[symbol.ToUpper()], "Token already exists."); } private void CheckSymbolLength(string symbol, SymbolType symbolType) @@ -278,7 +320,7 @@ private void CheckCrossChainTokenContractRegistrationControllerAuthority() private void DealWithExternalInfoDuringLocking(TransferFromInput input) { - var tokenInfo = State.TokenInfos[input.Symbol]; + var tokenInfo = GetTokenInfo(input.Symbol); if (tokenInfo.ExternalInfo == null) return; if (tokenInfo.ExternalInfo.Value.ContainsKey(TokenContractConstants.LockCallbackExternalInfoKey)) { @@ -293,7 +335,7 @@ private void DealWithExternalInfoDuringLocking(TransferFromInput input) private void DealWithExternalInfoDuringTransfer(TransferFromInput input) { - var tokenInfo = State.TokenInfos[input.Symbol]; + var tokenInfo = GetTokenInfo(input.Symbol); if (tokenInfo.ExternalInfo == null) return; if (tokenInfo.ExternalInfo.Value.ContainsKey(TokenContractConstants.TransferCallbackExternalInfoKey)) { @@ -308,7 +350,7 @@ private void DealWithExternalInfoDuringTransfer(TransferFromInput input) private void DealWithExternalInfoDuringUnlock(TransferFromInput input) { - var tokenInfo = State.TokenInfos[input.Symbol]; + var tokenInfo = GetTokenInfo(input.Symbol); if (tokenInfo.ExternalInfo == null) return; if (tokenInfo.ExternalInfo.Value.ContainsKey(TokenContractConstants.UnlockCallbackExternalInfoKey)) { @@ -358,4 +400,23 @@ private Address GetVoteContractAddress() return State.VoteContractAddress.Value; } + + private TokenInfo GetTokenInfo(string symbolOrAlias) + { + var tokenInfo = State.TokenInfos[symbolOrAlias]; + if (tokenInfo != null) return tokenInfo; + var actualTokenSymbol = State.SymbolAliasMap[symbolOrAlias]; + if (!string.IsNullOrEmpty(actualTokenSymbol)) + { + tokenInfo = State.TokenInfos[actualTokenSymbol]; + } + + return tokenInfo; + } + + private void SetTokenInfo(TokenInfo tokenInfo) + { + var symbol = tokenInfo.Symbol; + State.TokenInfos[symbol] = tokenInfo; + } } \ No newline at end of file diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_NFTHelper.cs b/contract/AElf.Contracts.MultiToken/TokenContract_NFTHelper.cs index bddfb444bf..ae01062131 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_NFTHelper.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_NFTHelper.cs @@ -4,17 +4,13 @@ namespace AElf.Contracts.MultiToken; public partial class TokenContract { - private SymbolType GetCreateInputSymbolType(string symbol) + private SymbolType GetSymbolType(string symbol) { var words = symbol.Split(TokenContractConstants.NFTSymbolSeparator); - Assert(words[0].Length > 0 && words[0].All(IsValidCreateSymbolChar), "Invalid Symbol input"); + Assert(words[0].Length > 0 && IsValidCreateSymbol(words[0]), "Invalid Symbol input"); if (words.Length == 1) return SymbolType.Token; - Assert(words.Length == 2 && words[1].Length > 0 && words[1].All(IsValidItemIdChar), "Invalid NFT Symbol input"); + Assert(words.Length == 2 && words[1].Length > 0 && IsValidItemId(words[1]), "Invalid NFT Symbol input"); return words[1] == TokenContractConstants.CollectionSymbolSuffix ? SymbolType.NftCollection : SymbolType.Nft; } - private void AssertNFTCreateInput(CreateInput input) - { - Assert(input.Decimals == 0, "NFT's decimals must be 0"); - } } \ No newline at end of file diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs b/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs index 1926727e68..93d54ec7b3 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_NFT_Actions.cs @@ -9,35 +9,46 @@ public partial class TokenContract { private Empty CreateNFTCollection(CreateInput input) { - AssertNFTCreateInput(input); return CreateToken(input, SymbolType.NftCollection); } private Empty CreateNFTInfo(CreateInput input) { - AssertNFTCreateInput(input); var nftCollectionInfo = AssertNftCollectionExist(input.Symbol); input.IssueChainId = input.IssueChainId == 0 ? nftCollectionInfo.IssueChainId : input.IssueChainId; - Assert(input.IssueChainId == nftCollectionInfo.IssueChainId, - "NFT create ChainId must be collection's issue chainId"); - + Assert( + input.IssueChainId == nftCollectionInfo.IssueChainId, + "NFT issue ChainId must be collection's issue chainId"); + if (nftCollectionInfo.ExternalInfo != null && nftCollectionInfo.ExternalInfo.Value.TryGetValue( + TokenContractConstants.NftCreateChainIdExternalInfoKey, + out var nftCreateChainId) && long.TryParse(nftCreateChainId, out var nftCreateChainIdLong)) + { + Assert(nftCreateChainIdLong == Context.ChainId, + "NFT create ChainId must be collection's NFT create chainId"); + } + else + { + Assert(State.SideChainCreator.Value == null, + "Failed to create token if side chain creator already set."); + } + var owner = nftCollectionInfo.Owner ?? nftCollectionInfo.Issuer; Assert(Context.Sender == owner && owner == input.Owner, "NFT owner must be collection's owner"); - if (nftCollectionInfo.Symbol == TokenContractConstants.SeedCollectionSymbol) { + Assert(input.Decimals == 0 && input.TotalSupply == 1, "SEED must be unique."); Assert(input.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedOwnedSymbolExternalInfoKey, out var ownedSymbol), "OwnedSymbol does not exist."); Assert(input.ExternalInfo.Value.TryGetValue(TokenContractConstants.SeedExpireTimeExternalInfoKey, out var expirationTime) && long.TryParse(expirationTime, out var expirationTimeLong) && Context.CurrentBlockTime.Seconds <= expirationTimeLong, "Invalid ownedSymbol."); - var ownedSymbolType = GetCreateInputSymbolType(ownedSymbol); + var ownedSymbolType = GetSymbolType(ownedSymbol); Assert(ownedSymbolType != SymbolType.Nft, "Invalid OwnedSymbol."); CheckSymbolLength(ownedSymbol, ownedSymbolType); CheckTokenAndCollectionExists(ownedSymbol); CheckSymbolSeed(ownedSymbol); - State.SymbolSeedMap[ownedSymbol] = input.Symbol; + State.SymbolSeedMap[ownedSymbol.ToUpper()] = input.Symbol; } return CreateToken(input, SymbolType.Nft); @@ -45,9 +56,9 @@ private Empty CreateNFTInfo(CreateInput input) private void CheckSymbolSeed(string ownedSymbol) { - var oldSymbolSeed = State.SymbolSeedMap[ownedSymbol]; + var oldSymbolSeed = State.SymbolSeedMap[ownedSymbol.ToUpper()]; - Assert(oldSymbolSeed == null || !State.TokenInfos[oldSymbolSeed].ExternalInfo.Value + Assert(oldSymbolSeed == null || !GetTokenInfo(oldSymbolSeed).ExternalInfo.Value .TryGetValue(TokenContractConstants.SeedExpireTimeExternalInfoKey, out var oldSymbolSeedExpireTime) || !long.TryParse(oldSymbolSeedExpireTime, out var symbolSeedExpireTime) @@ -55,14 +66,13 @@ private void CheckSymbolSeed(string ownedSymbol) "OwnedSymbol has been created"); } - private void DoTransferFrom(Address from, Address to, Address spender, string symbol, long amount, string memo) { AssertValidInputAddress(from); AssertValidInputAddress(to); // First check allowance. - var allowance = State.Allowances[from][spender][symbol]; + var allowance = GetAllowance(from, spender, symbol, amount, out var allowanceSymbol); if (allowance < amount) { if (IsInWhiteList(new IsInWhiteListInput { Symbol = symbol, Address = spender }).Value) @@ -81,25 +91,80 @@ private void DoTransferFrom(Address from, Address to, Address spender, string sy DoTransfer(from, to, symbol, amount, memo); DealWithExternalInfoDuringTransfer(new TransferFromInput() { From = from, To = to, Symbol = symbol, Amount = amount, Memo = memo }); - State.Allowances[from][spender][symbol] = allowance.Sub(amount); + State.Allowances[from][spender][allowanceSymbol] = allowance.Sub(amount); } + private long GetAllowance(Address from, Address spender, string sourceSymbol, long amount, + out string allowanceSymbol) + { + allowanceSymbol = sourceSymbol; + var allowance = State.Allowances[from][spender][sourceSymbol]; + if (allowance >= amount) return allowance; + var tokenType = GetSymbolType(sourceSymbol); + if (tokenType == SymbolType.Token) + { + allowance = GetAllSymbolAllowance(from, spender, out allowanceSymbol); + } + else + { + allowance = GetNftCollectionAllSymbolAllowance(from, spender, sourceSymbol, out allowanceSymbol); + if (allowance >= amount) return allowance; + allowance = GetAllSymbolAllowance(from, spender, out allowanceSymbol); + } + + return allowance; + } + + + private long GetAllSymbolAllowance(Address from, Address spender, out string allowanceSymbol) + { + allowanceSymbol = GetAllSymbolIdentifier(); + return State.Allowances[from][spender][allowanceSymbol]; + } + + private long GetNftCollectionAllSymbolAllowance(Address from, Address spender, string sourceSymbol, + out string allowanceSymbol) + { + allowanceSymbol = GetNftCollectionAllSymbolIdentifier(sourceSymbol); + return State.Allowances[from][spender][allowanceSymbol]; + } + + private string GetNftCollectionAllSymbolIdentifier(string sourceSymbol) + { + // "AAA-*" + return $"{sourceSymbol.Split(TokenContractConstants.NFTSymbolSeparator)[0]}-{TokenContractConstants.AllSymbolIdentifier}"; + } + + private string GetAllSymbolIdentifier() + { + // "*" + return TokenContractConstants.AllSymbolIdentifier.ToString(); + } - private string GetNftCollectionSymbol(string inputSymbol) + /// + /// ELF -> null + /// NFT-1 -> NFT-0 + /// If isAllowCollection == true: NFT-0 -> NFT-0 + /// If isAllowCollection == false: NFT-0 -> null + /// + /// + /// + /// Return null if inputSymbol is not NFT. + private string GetNftCollectionSymbol(string inputSymbol, bool isAllowCollection = false) { var symbol = inputSymbol; var words = symbol.Split(TokenContractConstants.NFTSymbolSeparator); const int tokenSymbolLength = 1; if (words.Length == tokenSymbolLength) return null; - Assert(words.Length == 2 && words[1].All(IsValidItemIdChar), "Invalid NFT Symbol Input"); - return symbol == $"{words[0]}-0" ? null : $"{words[0]}-0"; + Assert(words.Length == 2 && IsValidItemId(words[1]), "Invalid NFT Symbol Input"); + return symbol == $"{words[0]}-0" ? (isAllowCollection ? $"{words[0]}-0" : null) : $"{words[0]}-0"; } private TokenInfo AssertNftCollectionExist(string symbol) { var collectionSymbol = GetNftCollectionSymbol(symbol); if (collectionSymbol == null) return null; - var collectionInfo = State.TokenInfos[collectionSymbol]; + var collectionInfo = GetTokenInfo(collectionSymbol); Assert(collectionInfo != null, "NFT collection not exist"); return collectionInfo; } diff --git a/contract/AElf.Contracts.MultiToken/TokenContract_Views.cs b/contract/AElf.Contracts.MultiToken/TokenContract_Views.cs index 8366261ebf..01eb2bd7be 100644 --- a/contract/AElf.Contracts.MultiToken/TokenContract_Views.cs +++ b/contract/AElf.Contracts.MultiToken/TokenContract_Views.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using AElf.Sdk.CSharp; using AElf.Types; using Google.Protobuf.WellKnownTypes; @@ -10,12 +11,12 @@ public partial class TokenContract [View] public override TokenInfo GetTokenInfo(GetTokenInfoInput input) { - return State.TokenInfos[input.Symbol]; + return GetTokenInfo(input.Symbol); } public override TokenInfo GetNativeTokenInfo(Empty input) { - return State.TokenInfos[State.NativeTokenSymbol.Value]; + return GetTokenInfo(State.NativeTokenSymbol.Value); } public override TokenInfoList GetResourceTokenInfo(Empty input) @@ -23,13 +24,13 @@ public override TokenInfoList GetResourceTokenInfo(Empty input) var tokenInfoList = new TokenInfoList(); foreach (var symbol in Context.Variables.GetStringArray(TokenContractConstants.PayTxFeeSymbolListName) .Where(symbol => - State.TokenInfos[symbol] != null)) - tokenInfoList.Value.Add(State.TokenInfos[symbol]); + GetTokenInfo(symbol) != null)) + tokenInfoList.Value.Add(GetTokenInfo(symbol)); foreach (var symbol in Context.Variables.GetStringArray(TokenContractConstants.PayRentalSymbolListName) .Where(symbol => - State.TokenInfos[symbol] != null)) - tokenInfoList.Value.Add(State.TokenInfos[symbol]); + GetTokenInfo(symbol) != null)) + tokenInfoList.Value.Add(GetTokenInfo(symbol)); return tokenInfoList; } @@ -37,26 +38,61 @@ public override TokenInfoList GetResourceTokenInfo(Empty input) [View] public override GetBalanceOutput GetBalance(GetBalanceInput input) { + var symbol = GetActualTokenSymbol(input.Symbol); return new GetBalanceOutput { Symbol = input.Symbol, Owner = input.Owner, - Balance = GetBalance(input.Owner, input.Symbol) + Balance = GetBalance(input.Owner, symbol) }; } - + [View] public override GetAllowanceOutput GetAllowance(GetAllowanceInput input) { + var symbol = GetActualTokenSymbol(input.Symbol); return new GetAllowanceOutput + { + Symbol = symbol, + Owner = input.Owner, + Spender = input.Spender, + Allowance = State.Allowances[input.Owner][input.Spender][symbol] + }; + } + + [View] + public override GetAllowanceOutput GetAvailableAllowance(GetAllowanceInput input) + { + var result = new GetAllowanceOutput { Symbol = input.Symbol, Owner = input.Owner, Spender = input.Spender, - Allowance = State.Allowances[input.Owner][input.Spender][input.Symbol] }; + var symbol = input.Symbol; + var allowance = State.Allowances[input.Owner][input.Spender][symbol]; + if (CheckSymbolIdentifier(symbol)) + { + result.Allowance = allowance; + return result; + } + var symbolType = GetSymbolType(symbol); + allowance = Math.Max(allowance, GetAllSymbolAllowance(input.Owner,input.Spender,out _)); + if (symbolType == SymbolType.Nft || symbolType == SymbolType.NftCollection) + { + allowance = Math.Max(allowance, GetNftCollectionAllSymbolAllowance(input.Owner, input.Spender, symbol, out _)); + } + result.Allowance = allowance; + return result; } + private bool CheckSymbolIdentifier(string symbol) + { + var words = symbol.Split(TokenContractConstants.NFTSymbolSeparator); + var allSymbolIdentifier = GetAllSymbolIdentifier(); + return words[0].Equals(allSymbolIdentifier) || (words.Length > 1 && words[1].Equals(allSymbolIdentifier)); + } + public override BoolValue IsInWhiteList(IsInWhiteListInput input) { return new BoolValue { Value = State.LockWhiteLists[input.Symbol][input.Address] }; @@ -199,7 +235,6 @@ public override BoolValue IsTokenAvailableForMethodFee(StringValue input) }; } - public override StringList GetReservedExternalInfoKeyList(Empty input) { return new StringList @@ -216,7 +251,7 @@ public override StringList GetReservedExternalInfoKeyList(Empty input) private bool IsTokenAvailableForMethodFee(string symbol) { - var tokenInfo = State.TokenInfos[symbol]; + var tokenInfo = GetTokenInfo(symbol); if (tokenInfo == null) throw new AssertionException("Token is not found."); return tokenInfo.IsBurnable; } @@ -228,4 +263,33 @@ private bool IsAddressInCreateWhiteList(Address address) address == Context.GetContractAddressByName(SmartContractConstants.EconomicContractSystemName) || address == Context.GetContractAddressByName(SmartContractConstants.CrossChainContractSystemName); } + + public override StringValue GetTokenAlias(StringValue input) + { + var collectionSymbol = GetNftCollectionSymbol(input.Value, true); + var tokenInfo = GetTokenInfo(collectionSymbol); + var (_, alias) = ExtractAliasSetting(tokenInfo); + return new StringValue + { + Value = alias + }; + } + + public override StringValue GetSymbolByAlias(StringValue input) + { + return new StringValue + { + Value = GetActualTokenSymbol(input.Value) + }; + } + + private string GetActualTokenSymbol(string aliasOrSymbol) + { + if (State.TokenInfos[aliasOrSymbol] == null) + { + return State.SymbolAliasMap[aliasOrSymbol] ?? aliasOrSymbol; + } + + return aliasOrSymbol; + } } \ No newline at end of file diff --git a/contract/AElf.Contracts.NFT/AElf.Contracts.NFT.csproj b/contract/AElf.Contracts.NFT/AElf.Contracts.NFT.csproj index 9b9bf5e782..dbf4344ac9 100644 --- a/contract/AElf.Contracts.NFT/AElf.Contracts.NFT.csproj +++ b/contract/AElf.Contracts.NFT/AElf.Contracts.NFT.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.NFT true NFT Contract is a contract that implements Non-Fungible-Token functionality like creation, issuance and diff --git a/contract/AElf.Contracts.Parliament/AElf.Contracts.Parliament.csproj b/contract/AElf.Contracts.Parliament/AElf.Contracts.Parliament.csproj index aa4fe7db45..6aafafffcc 100644 --- a/contract/AElf.Contracts.Parliament/AElf.Contracts.Parliament.csproj +++ b/contract/AElf.Contracts.Parliament/AElf.Contracts.Parliament.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Parliament true Parliament is a contract that enables the creation of organizations and approvals. The created diff --git a/contract/AElf.Contracts.Parliament/Parliament.cs b/contract/AElf.Contracts.Parliament/Parliament.cs index 98ae606896..7e52c07d2d 100644 --- a/contract/AElf.Contracts.Parliament/Parliament.cs +++ b/contract/AElf.Contracts.Parliament/Parliament.cs @@ -241,7 +241,9 @@ public override ProposalOutput GetProposal(Hash proposalId) ToBeReleased = Validate(proposal) && IsReleaseThresholdReached(proposal, organization), ApprovalCount = proposal.Approvals.Count, RejectionCount = proposal.Rejections.Count, - AbstentionCount = proposal.Abstentions.Count + AbstentionCount = proposal.Abstentions.Count, + Title = proposal.Title, + Description = proposal.Description }; } diff --git a/contract/AElf.Contracts.Parliament/ParliamentConstants.cs b/contract/AElf.Contracts.Parliament/ParliamentConstants.cs new file mode 100644 index 0000000000..a1646221e8 --- /dev/null +++ b/contract/AElf.Contracts.Parliament/ParliamentConstants.cs @@ -0,0 +1,8 @@ +namespace AElf.Contracts.Parliament; + +public static class ParliamentConstants +{ + public const int MaxLengthForTitle = 255; + public const int MaxLengthForDescription = 10200; + public const int MaxLengthForProposalDescriptionUrl = 255; +} \ No newline at end of file diff --git a/contract/AElf.Contracts.Parliament/Parliament_Helper.cs b/contract/AElf.Contracts.Parliament/Parliament_Helper.cs index 7e1a763d2b..b1317eceb2 100644 --- a/contract/AElf.Contracts.Parliament/Parliament_Helper.cs +++ b/contract/AElf.Contracts.Parliament/Parliament_Helper.cs @@ -224,6 +224,7 @@ private Hash GenerateProposalId(CreateProposalInput input) private Hash CreateNewProposal(CreateProposalInput input) { + CheckCreateProposalInput(input); var proposalId = GenerateProposalId(input); var proposal = new ProposalInfo { @@ -234,15 +235,33 @@ private Hash CreateNewProposal(CreateProposalInput input) OrganizationAddress = input.OrganizationAddress, ProposalId = proposalId, Proposer = Context.Sender, - ProposalDescriptionUrl = input.ProposalDescriptionUrl + ProposalDescriptionUrl = input.ProposalDescriptionUrl, + Title = input.Title, + Description = input.Description }; Assert(Validate(proposal), "Invalid proposal."); Assert(State.Proposals[proposalId] == null, "Proposal already exists."); State.Proposals[proposalId] = proposal; Context.Fire(new ProposalCreated - { ProposalId = proposalId, OrganizationAddress = input.OrganizationAddress }); + { + ProposalId = proposalId, + OrganizationAddress = input.OrganizationAddress, + Title = input.Title, + Description = input.Description + }); return proposalId; } + + private void CheckCreateProposalInput(CreateProposalInput input) + { + // Check the length of title + Assert(input.Title.Length <= ParliamentConstants.MaxLengthForTitle, "Title is too long."); + // Check the length of description + Assert(input.Description.Length <= ParliamentConstants.MaxLengthForDescription, "Description is too long."); + // Check the length of description url + Assert(input.ProposalDescriptionUrl.Length <= ParliamentConstants.MaxLengthForProposalDescriptionUrl, + "Description url is too long."); + } private Address CreateNewOrganization(CreateOrganizationInput input) { diff --git a/contract/AElf.Contracts.Profit/AElf.Contracts.Profit.csproj b/contract/AElf.Contracts.Profit/AElf.Contracts.Profit.csproj index 37a6090cc3..ed7f7096bd 100644 --- a/contract/AElf.Contracts.Profit/AElf.Contracts.Profit.csproj +++ b/contract/AElf.Contracts.Profit/AElf.Contracts.Profit.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Profit true Profit is a contract that enables the creation of schemes for profit distribution. diff --git a/contract/AElf.Contracts.Profit/ProfitContract.cs b/contract/AElf.Contracts.Profit/ProfitContract.cs index c3c09b3aba..a1f43d1af4 100644 --- a/contract/AElf.Contracts.Profit/ProfitContract.cs +++ b/contract/AElf.Contracts.Profit/ProfitContract.cs @@ -769,18 +769,19 @@ public override Empty ClaimProfits(ClaimProfitsInput input) Context.LogDebug(() => $"Profitable details: {profitableDetails.Aggregate("\n", (profit1, profit2) => profit1.ToString() + "\n" + profit2)}"); + var profitableDetailCount = + Math.Min(ProfitContractConstants.ProfitReceivingLimitForEachTime, profitableDetails.Count); + var maxProfitReceivingPeriodCount = GetMaximumPeriodCountForProfitableDetail(profitableDetailCount); // Only can get profit from last profit period to actual last period (profit.CurrentPeriod - 1), // because current period not released yet. - for (var i = 0; - i < Math.Min(ProfitContractConstants.ProfitReceivingLimitForEachTime, profitableDetails.Count); - i++) + for (var i = 0; i < profitableDetailCount; i++) { var profitDetail = profitableDetails[i]; if (profitDetail.LastProfitPeriod == 0) // This detail never performed profit before. profitDetail.LastProfitPeriod = profitDetail.StartPeriod; - ProfitAllPeriods(scheme, profitDetail, beneficiary); + ProfitAllPeriods(scheme, profitDetail, beneficiary, maxProfitReceivingPeriodCount); } var profitDetailsToRemove = profitableDetails @@ -807,7 +808,41 @@ public override Empty ClaimProfits(ClaimProfitsInput input) return new Empty(); } - private Dictionary ProfitAllPeriods(Scheme scheme, ProfitDetail profitDetail, Address beneficiary, + /// + /// This method calculates the maximum period count for a profitable detail + /// based on the number of profitable details and the maximum profit receiving period + /// For example: + /// If the number of profitable detail is 10 and the maximum profit receiving period is 100, + /// the maximum period count for a profitable detail will be 10. + /// If the number of profitable detail is 10 and the maximum profit receiving period is 5, + /// the maximum period count for a profitable detail will be 1. + /// + /// The number of profitable details + /// + private int GetMaximumPeriodCountForProfitableDetail(int profitableDetailCount) + { + // Get the maximum profit receiving period count + var maxPeriodCount = GetMaximumProfitReceivingPeriodCount(); + // Check if the maximum period count is greater than the profitable detail count + // and if the profitable detail count is greater than 0 + return maxPeriodCount > profitableDetailCount && profitableDetailCount > 0 + // Divide the maximum period count by the profitable detail count + ? maxPeriodCount.Div(profitableDetailCount) + // If the conditions are not met, return 1 as the maximum period count + : 1; + } + + public override Empty SetMaximumProfitReceivingPeriodCount(Int32Value input) + { + ValidateContractState(State.ParliamentContract, SmartContractConstants.ParliamentContractSystemName); + Assert(Context.Sender == State.ParliamentContract.GetDefaultOrganizationAddress.Call(new Empty()), + "No permission."); + Assert(input.Value > 0, "Invalid maximum profit receiving period count."); + State.MaximumProfitReceivingPeriodCount.Value = input.Value; + return new Empty(); + } + + private Dictionary ProfitAllPeriods(Scheme scheme, ProfitDetail profitDetail, Address beneficiary, long maxProfitReceivingPeriodCount, bool isView = false, string targetSymbol = null) { var profitsMap = new Dictionary(); @@ -818,13 +853,11 @@ private Dictionary ProfitAllPeriods(Scheme scheme, ProfitDetail pr foreach (var symbol in symbols) { var totalAmount = 0L; - for (var period = profitDetail.LastProfitPeriod; - period <= (profitDetail.EndPeriod == long.MaxValue - ? Math.Min(scheme.CurrentPeriod - 1, - profitDetail.LastProfitPeriod.Add(ProfitContractConstants - .MaximumProfitReceivingPeriodCountOfOneTime)) - : Math.Min(scheme.CurrentPeriod - 1, profitDetail.EndPeriod)); - period++) + var targetPeriod = Math.Min(scheme.CurrentPeriod - 1, profitDetail.EndPeriod); + var maxProfitPeriod = profitDetail.EndPeriod == long.MaxValue + ? Math.Min(scheme.CurrentPeriod - 1, profitDetail.LastProfitPeriod.Add(maxProfitReceivingPeriodCount)) + : Math.Min(targetPeriod, profitDetail.LastProfitPeriod.Add(maxProfitReceivingPeriodCount)); + for (var period = profitDetail.LastProfitPeriod; period <= maxProfitPeriod; period++) { var periodToPrint = period; var detailToPrint = profitDetail; @@ -885,6 +918,15 @@ private Dictionary ProfitAllPeriods(Scheme scheme, ProfitDetail pr return profitsMap; } + + private int GetMaximumProfitReceivingPeriodCount() + { + var maxPeriodCount = State.MaximumProfitReceivingPeriodCount.Value; + maxPeriodCount = maxPeriodCount == 0 + ? ProfitContractConstants.DefaultMaximumProfitReceivingPeriodCountOfOneTime + : maxPeriodCount; + return maxPeriodCount; + } private void ValidateContractState(ContractReferenceState state, string contractSystemName) { diff --git a/contract/AElf.Contracts.Profit/ProfitContractConstants.cs b/contract/AElf.Contracts.Profit/ProfitContractConstants.cs index 59b80b971f..0aaf080aa5 100644 --- a/contract/AElf.Contracts.Profit/ProfitContractConstants.cs +++ b/contract/AElf.Contracts.Profit/ProfitContractConstants.cs @@ -6,5 +6,5 @@ public class ProfitContractConstants public const int DefaultProfitReceivingDuePeriodCount = 10; public const int MaximumProfitReceivingDuePeriodCount = 1024; public const int TokenAmountLimit = 5; - public const int MaximumProfitReceivingPeriodCountOfOneTime = 100; + public const int DefaultMaximumProfitReceivingPeriodCountOfOneTime = 100; } \ No newline at end of file diff --git a/contract/AElf.Contracts.Profit/ProfitContractState.cs b/contract/AElf.Contracts.Profit/ProfitContractState.cs index 7a525e3ff6..b0046830e0 100644 --- a/contract/AElf.Contracts.Profit/ProfitContractState.cs +++ b/contract/AElf.Contracts.Profit/ProfitContractState.cs @@ -17,4 +17,6 @@ public partial class ProfitContractState : ContractState public MappedState TransactionFees { get; set; } public SingletonState MethodFeeController { get; set; } + + public SingletonState MaximumProfitReceivingPeriodCount { get; set; } } \ No newline at end of file diff --git a/contract/AElf.Contracts.Profit/ViewMethods.cs b/contract/AElf.Contracts.Profit/ViewMethods.cs index 31d8c0d4d6..190204c3c5 100644 --- a/contract/AElf.Contracts.Profit/ViewMethods.cs +++ b/contract/AElf.Contracts.Profit/ViewMethods.cs @@ -61,49 +61,53 @@ private Hash GeneratePeriodVirtualAddressFromHash(Hash schemeId, long period) public override Int64Value GetProfitAmount(GetProfitAmountInput input) { - var profitItem = State.SchemeInfos[input.SchemeId]; - Assert(profitItem != null, "Scheme not found."); - var beneficiary = input.Beneficiary ?? Context.Sender; - var profitDetails = State.ProfitDetailsMap[input.SchemeId][beneficiary]; + var allProfitsMapResult = GetAllProfitsMap(input.SchemeId, input.Beneficiary, input.Symbol); - if (profitDetails == null) return new Int64Value { Value = 0 }; - - var profitVirtualAddress = Context.ConvertVirtualAddressToContractAddress(input.SchemeId); + return new Int64Value + { + Value = allProfitsMapResult.AllProfitsMap.TryGetValue(input.Symbol, out var value) ? value : 0 + }; + } - // ReSharper disable once PossibleNullReferenceException - var availableDetails = profitDetails.Details.Where(d => - d.LastProfitPeriod < profitItem.CurrentPeriod && (d.LastProfitPeriod == 0 - ? d.EndPeriod >= d.StartPeriod - : d.EndPeriod >= d.LastProfitPeriod) - ).ToList(); + public override GetAllProfitAmountOutput GetAllProfitAmount(GetAllProfitAmountInput input) + { + var allProfitsMapResult = GetAllProfitsMap(input.SchemeId, input.Beneficiary, input.Symbol); + return new GetAllProfitAmountOutput + { + AllProfitAmount = allProfitsMapResult.AllProfitsMap.TryGetValue(input.Symbol, out var allProfitAmount) + ? allProfitAmount + : 0, + OneTimeClaimableProfitAmount = + allProfitsMapResult.OneTimeClaimableProfitsMap.TryGetValue(input.Symbol, + out var oneTimeClaimableProfitAmount) + ? oneTimeClaimableProfitAmount + : 0 + }; + } - var amount = 0L; + public override ReceivedProfitsMap GetProfitsMap(ClaimProfitsInput input) + { + var allProfitsMapResult = GetAllProfitsMap(input.SchemeId, input.Beneficiary); - for (var i = 0; - i < Math.Min(ProfitContractConstants.ProfitReceivingLimitForEachTime, availableDetails.Count); - i++) + return new ReceivedProfitsMap { - var profitDetail = availableDetails[i]; - if (profitDetail.LastProfitPeriod == 0) profitDetail.LastProfitPeriod = profitDetail.StartPeriod; - - var profitsDict = ProfitAllPeriods(profitItem, profitDetail, beneficiary, true, - input.Symbol); - amount = amount.Add(profitsDict[input.Symbol]); - } + Value = { allProfitsMapResult.AllProfitsMap } + }; + } - return new Int64Value { Value = amount }; + public override GetAllProfitsMapOutput GetAllProfitsMap(GetAllProfitsMapInput input) + { + return GetAllProfitsMap(input.SchemeId, input.Beneficiary); } - public override ReceivedProfitsMap GetProfitsMap(ClaimProfitsInput input) + private GetAllProfitsMapOutput GetAllProfitsMap(Hash schemeId, Address beneficiary, string symbol = null) { - var scheme = State.SchemeInfos[input.SchemeId]; + var scheme = State.SchemeInfos[schemeId]; Assert(scheme != null, "Scheme not found."); - var beneficiary = input.Beneficiary ?? Context.Sender; - var profitDetails = State.ProfitDetailsMap[input.SchemeId][beneficiary]; - - if (profitDetails == null) return new ReceivedProfitsMap(); + beneficiary = beneficiary ?? Context.Sender; + var profitDetails = State.ProfitDetailsMap[schemeId][beneficiary]; - var profitVirtualAddress = Context.ConvertVirtualAddressToContractAddress(input.SchemeId); + if (profitDetails == null) return new GetAllProfitsMapOutput(); // ReSharper disable once PossibleNullReferenceException var availableDetails = profitDetails.Details.Where(d => @@ -111,26 +115,46 @@ public override ReceivedProfitsMap GetProfitsMap(ClaimProfitsInput input) ? d.EndPeriod >= d.StartPeriod : d.EndPeriod >= d.LastProfitPeriod) ).ToList(); - - var profitsDict = new Dictionary(); - for (var i = 0; - i < Math.Min(ProfitContractConstants.ProfitReceivingLimitForEachTime, availableDetails.Count); - i++) + + var profitableDetailCount = + Math.Min(ProfitContractConstants.ProfitReceivingLimitForEachTime, availableDetails.Count); + var maxProfitReceivingPeriodCount = GetMaximumPeriodCountForProfitableDetail(profitableDetailCount); + + var allProfitsDict = new Dictionary(); + var claimableProfitsDict = new Dictionary(); + for (var i = 0; i < availableDetails.Count; i++) { var profitDetail = availableDetails[i]; if (profitDetail.LastProfitPeriod == 0) profitDetail.LastProfitPeriod = profitDetail.StartPeriod; - - var profitsDictForEachProfitDetail = ProfitAllPeriods(scheme, profitDetail, beneficiary, true); - foreach (var kv in profitsDictForEachProfitDetail) - if (profitsDict.ContainsKey(kv.Key)) - profitsDict[kv.Key] = profitsDict[kv.Key].Add(kv.Value); - else - profitsDict[kv.Key] = kv.Value; + + var totalProfitsDictForEachProfitDetail = ProfitAllPeriods(scheme, profitDetail, beneficiary, profitDetail.EndPeriod.Sub(profitDetail.LastProfitPeriod),true, symbol); + AddProfitToDict(allProfitsDict, totalProfitsDictForEachProfitDetail); + if(i >= profitableDetailCount) continue; + var claimableProfitsDictForEachProfitDetail = ProfitAllPeriods(scheme, profitDetail, beneficiary, maxProfitReceivingPeriodCount,true, symbol); + AddProfitToDict(claimableProfitsDict, claimableProfitsDictForEachProfitDetail); } - return new ReceivedProfitsMap + return new GetAllProfitsMapOutput + { + AllProfitsMap = { allProfitsDict }, + OneTimeClaimableProfitsMap = { claimableProfitsDict } + }; + } + + private void AddProfitToDict(Dictionary profitsDict, Dictionary profitsToAdd) + { + foreach (var kv in profitsToAdd) + if (profitsDict.ContainsKey(kv.Key)) + profitsDict[kv.Key] = profitsDict[kv.Key].Add(kv.Value); + else + profitsDict[kv.Key] = kv.Value; + } + + public override Int32Value GetMaximumProfitReceivingPeriodCount(Empty input) + { + return new Int32Value { - Value = { profitsDict } + Value = GetMaximumProfitReceivingPeriodCount() }; } } \ No newline at end of file diff --git a/contract/AElf.Contracts.Referendum/AElf.Contracts.Referendum.csproj b/contract/AElf.Contracts.Referendum/AElf.Contracts.Referendum.csproj index a59a11dedb..11725e3094 100644 --- a/contract/AElf.Contracts.Referendum/AElf.Contracts.Referendum.csproj +++ b/contract/AElf.Contracts.Referendum/AElf.Contracts.Referendum.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Referendum true Referendum is a contract that enables the creation of organizations and approvals. The created diff --git a/contract/AElf.Contracts.Referendum/Referendum.cs b/contract/AElf.Contracts.Referendum/Referendum.cs index f6112e2827..b2d63bf78f 100644 --- a/contract/AElf.Contracts.Referendum/Referendum.cs +++ b/contract/AElf.Contracts.Referendum/Referendum.cs @@ -202,7 +202,9 @@ public override ProposalOutput GetProposal(Hash proposalId) ToBeReleased = readyToRelease, ApprovalCount = proposal.ApprovalCount, RejectionCount = proposal.RejectionCount, - AbstentionCount = proposal.AbstentionCount + AbstentionCount = proposal.AbstentionCount, + Title = proposal.Title, + Description = proposal.Description }; } diff --git a/contract/AElf.Contracts.Referendum/ReferendumConstants.cs b/contract/AElf.Contracts.Referendum/ReferendumConstants.cs new file mode 100644 index 0000000000..89eded59d7 --- /dev/null +++ b/contract/AElf.Contracts.Referendum/ReferendumConstants.cs @@ -0,0 +1,8 @@ +namespace AElf.Contracts.Referendum; + +public static class ReferendumConstants +{ + public const int MaxLengthForTitle = 255; + public const int MaxLengthForDescription = 10200; + public const int MaxLengthForProposalDescriptionUrl = 255; +} \ No newline at end of file diff --git a/contract/AElf.Contracts.Referendum/Referendum_Helper.cs b/contract/AElf.Contracts.Referendum/Referendum_Helper.cs index 02b00d07c1..9b6e4343d9 100644 --- a/contract/AElf.Contracts.Referendum/Referendum_Helper.cs +++ b/contract/AElf.Contracts.Referendum/Referendum_Helper.cs @@ -158,6 +158,7 @@ private Hash GenerateProposalId(CreateProposalInput input) private Hash CreateNewProposal(CreateProposalInput input) { + CheckCreateProposalInput(input); var proposalId = GenerateProposalId(input); Assert(State.Proposals[proposalId] == null, "Proposal already exists."); var proposal = new ProposalInfo @@ -168,14 +169,33 @@ private Hash CreateNewProposal(CreateProposalInput input) Params = input.Params, OrganizationAddress = input.OrganizationAddress, Proposer = Context.Sender, - ProposalDescriptionUrl = input.ProposalDescriptionUrl + ProposalDescriptionUrl = input.ProposalDescriptionUrl, + Title = input.Title, + Description = input.Description }; Assert(Validate(proposal), "Invalid proposal."); State.Proposals[proposalId] = proposal; - Context.Fire(new ProposalCreated { ProposalId = proposalId, OrganizationAddress = input.OrganizationAddress }); + Context.Fire(new ProposalCreated + { + ProposalId = proposalId, + OrganizationAddress = input.OrganizationAddress, + Title = input.Title, + Description = input.Description + }); return proposalId; } + + private void CheckCreateProposalInput(CreateProposalInput input) + { + // Check the length of title + Assert(input.Title.Length <= ReferendumConstants.MaxLengthForTitle, "Title is too long."); + // Check the length of description + Assert(input.Description.Length <= ReferendumConstants.MaxLengthForDescription, "Description is too long."); + // Check the length of description url + Assert(input.ProposalDescriptionUrl.Length <= ReferendumConstants.MaxLengthForProposalDescriptionUrl, + "Description url is too long."); + } private void AssertIsAuthorizedProposer(Address organizationAddress, Address proposer) { diff --git a/contract/AElf.Contracts.TokenConverter/AElf.Contracts.TokenConverter.csproj b/contract/AElf.Contracts.TokenConverter/AElf.Contracts.TokenConverter.csproj index 073abc3ec4..1593aa77ec 100644 --- a/contract/AElf.Contracts.TokenConverter/AElf.Contracts.TokenConverter.csproj +++ b/contract/AElf.Contracts.TokenConverter/AElf.Contracts.TokenConverter.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 AElf.Contracts.TokenConverter true TokenConverter is a contract that enables buying and selling tokens based on connector diff --git a/contract/AElf.Contracts.TokenConverter/TokenConverterContract.cs b/contract/AElf.Contracts.TokenConverter/TokenConverterContract.cs index 1a7aaf80d2..267d3ad622 100644 --- a/contract/AElf.Contracts.TokenConverter/TokenConverterContract.cs +++ b/contract/AElf.Contracts.TokenConverter/TokenConverterContract.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Linq; +using System.Text.RegularExpressions; using AElf.Contracts.MultiToken; using AElf.CSharp.Core; using AElf.Sdk.CSharp; @@ -12,6 +13,9 @@ namespace AElf.Contracts.TokenConverter; public partial class TokenConverterContract : TokenConverterContractImplContainer.TokenConverterContractImplBase { private const string NtTokenPrefix = "nt"; + private const string NewNtTokenPrefix = "(NT)"; + public const string PayTxFeeSymbolListName = "SymbolListToPayTxFee"; + public const string PayRentalSymbolListName = "SymbolListToPayRental"; #region Actions @@ -77,7 +81,7 @@ public override Empty AddPairConnector(PairConnectorParam input) AssertPerformedByConnectorController(); Assert(!string.IsNullOrEmpty(input.ResourceConnectorSymbol), "resource token symbol should not be empty"); - var nativeConnectorSymbol = NtTokenPrefix.Append(input.ResourceConnectorSymbol); + var nativeConnectorSymbol = NewNtTokenPrefix.Append(input.ResourceConnectorSymbol); Assert(State.Connectors[input.ResourceConnectorSymbol] == null, "resource token symbol has existed"); var resourceConnector = new Connector @@ -304,6 +308,39 @@ public override Empty ChangeConnectorController(AuthorityInfo input) return new Empty(); } + public override Empty MigrateConnectorTokens(Empty input) + { + foreach (var resourceTokenSymbol in Context.Variables.GetStringArray(PayTxFeeSymbolListName) + .Union(Context.Variables.GetStringArray(PayRentalSymbolListName))) + { + var newConnectorTokenSymbol = NewNtTokenPrefix.Append(resourceTokenSymbol); + + if (State.Connectors[resourceTokenSymbol] == null) + { + continue; + } + + var oldConnectorTokenSymbol = State.Connectors[resourceTokenSymbol].RelatedSymbol; + + Assert(!oldConnectorTokenSymbol.StartsWith(NewNtTokenPrefix), "Already migrated."); + + // Migrate + + State.Connectors[resourceTokenSymbol].RelatedSymbol = newConnectorTokenSymbol; + + if (State.Connectors[oldConnectorTokenSymbol] != null) + { + var connector = State.Connectors[oldConnectorTokenSymbol]; + connector.Symbol = newConnectorTokenSymbol; + State.Connectors[newConnectorTokenSymbol] = connector; + } + + State.DepositBalance[newConnectorTokenSymbol] = State.DepositBalance[oldConnectorTokenSymbol]; + } + + return new Empty(); + } + #endregion Actions #region Helpers @@ -321,8 +358,7 @@ private static bool IsBetweenZeroAndOne(decimal number) private static bool IsValidSymbol(string symbol) { - return symbol.Length > 0 && - symbol.All(c => c >= 'A' && c <= 'Z'); + return Regex.IsMatch(symbol, "^[a-zA-Z0-9]+$"); } private static bool IsValidBaseSymbol(string symbol) diff --git a/contract/AElf.Contracts.TokenHolder/AElf.Contracts.TokenHolder.csproj b/contract/AElf.Contracts.TokenHolder/AElf.Contracts.TokenHolder.csproj index 1d8fbf296f..69a8e89213 100644 --- a/contract/AElf.Contracts.TokenHolder/AElf.Contracts.TokenHolder.csproj +++ b/contract/AElf.Contracts.TokenHolder/AElf.Contracts.TokenHolder.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 AElf.Contracts.TokenHolder true TokenHolder is a contract that assists dApp developers to manage profit schemes for token diff --git a/contract/AElf.Contracts.Treasury/AElf.Contracts.Treasury.csproj b/contract/AElf.Contracts.Treasury/AElf.Contracts.Treasury.csproj index e80a82b65b..47dff10f6b 100644 --- a/contract/AElf.Contracts.Treasury/AElf.Contracts.Treasury.csproj +++ b/contract/AElf.Contracts.Treasury/AElf.Contracts.Treasury.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Treasury true Treasury is a contract used to manage the finances of the system (dividend pool for diff --git a/contract/AElf.Contracts.Vote/AElf.Contracts.Vote.csproj b/contract/AElf.Contracts.Vote/AElf.Contracts.Vote.csproj index 4efe86b949..b199e31b19 100644 --- a/contract/AElf.Contracts.Vote/AElf.Contracts.Vote.csproj +++ b/contract/AElf.Contracts.Vote/AElf.Contracts.Vote.csproj @@ -2,7 +2,7 @@ - net6.0 + net8.0 AElf.Contracts.Vote true Vote is a contract used for voting. diff --git a/contract/ZkTreeVerifier/PairingLib.cs b/contract/ZkTreeVerifier/PairingLib.cs new file mode 100644 index 0000000000..5b1f9eda71 --- /dev/null +++ b/contract/ZkTreeVerifier/PairingLib.cs @@ -0,0 +1,199 @@ +using System.Collections.Generic; +using System.Linq; +using AElf.CSharp.Core; +using AElf.Sdk.CSharp; +using AElf.Types; + +// ReSharper disable MethodNameNotMeaningful +// ReSharper disable TooManyArguments + +namespace AElf.Contracts.ZkTreeVerifier; + +public class Proof +{ + public G1Point A { get; set; } + public G2Point B { get; set; } + public G1Point C { get; set; } +} + +public class G1Point +{ + public BigIntValue X { get; set; } + public BigIntValue Y { get; set; } +} + +public class G2Point +{ + public Fp2 X { get; set; } + public Fp2 Y { get; set; } +} + +public class Fp2 +{ + public BigIntValue A { get; set; } + public BigIntValue B { get; set; } +} + +public static class PairingLib +{ + internal static bool IsZero(this BigIntValue v) + { + return v == BigIntValue.Zero; + } + + internal static BigIntValue ToBigIntValue(this string v) + { + return v; + } + + internal static G1Point P1() + { + return new G1Point() + { + X = "1", + Y = "2" + }; + } + + internal static G2Point P2() + { + return new G2Point() + { + X = new Fp2() + { + A = "11559732032986387107991004021392285783925812861821192530917403151452391805634", + B = "10857046999023057135944570762232829481370756359578518086990519993285655852781" + }, + Y = new Fp2() + { + A = "4082367875863433681332203403145435568316851327593401208105741076214120093531", + B = "8495653923123431417604973247489272438418190587263600148770280649306958101930" + } + }; + } + + internal static G1Point Negate(this CSharpSmartContractContext ctx, G1Point p) + { + BigIntValue q = "21888242871839275222246405745257275088696311157297823662689037894645226208583"; + if (p.X.IsZero() && p.Y.IsZero()) + { + return new G1Point() + { + X = "0", + Y = "0" + }; + } + + return new G1Point() + { + X = p.X, + Y = q - p.Y.ModPow(1, q) + }; + } + + internal static G1Point Addition(this CSharpSmartContractContext ctx, G1Point p1, G1Point p2) + { + var (x, y) = ctx.Bn254G1Add( + p1.X.ToBytes32(), + p1.Y.ToBytes32(), + p2.X.ToBytes32(), + p2.Y.ToBytes32() + ); + return new G1Point() + { + X = BigIntValue.FromBigEndianBytes(x), + Y = BigIntValue.FromBigEndianBytes(y) + }; + } + + internal static G1Point ScalarMul(this CSharpSmartContractContext ctx, G1Point p, BigIntValue scalar) + { + var (x, y) = ctx.Bn254G1Mul( + p.X.ToBytes32(), + p.Y.ToBytes32(), + scalar.ToBytes32() + ); + return new G1Point() + { + X = BigIntValue.FromBigEndianBytes(x), + Y = BigIntValue.FromBigEndianBytes(y) + }; + } + + internal static bool Pairing(this CSharpSmartContractContext ctx, List p1, List p2) + { + if (p1.Count != p2.Count) + { + throw new AssertionException("pairing-lengths-failed"); + } + + var success = ctx.Bn254Pairing(p1.Zip(p2).Select(p => + ( + p.First.X.ToBytes32(), p.First.Y.ToBytes32(), + p.Second.X.A.ToBytes32(), p.Second.X.B.ToBytes32(), + p.Second.Y.A.ToBytes32(), p.Second.Y.B.ToBytes32() + ) + ).ToArray()); + + if (!success) + { + throw new AssertionException("pairing-check-failed"); + } + + return true; + } + + internal static bool PairingProd2(this CSharpSmartContractContext ctx, + G1Point a1, G2Point a2, + G1Point b1, G2Point b2) + { + return ctx.Pairing(new List() + { + a1, b1 + }, new List() + { + a2, b2 + }); + } + + internal static bool PairingProd3(this CSharpSmartContractContext ctx, + G1Point a1, G2Point a2, + G1Point b1, G2Point b2, + G1Point c1, G2Point c2) + { + return ctx.Pairing(new List() + { + a1, b1, c1 + }, new List() + { + a2, b2, c2 + }); + } + + internal static bool PairingProd4(this CSharpSmartContractContext ctx, + G1Point a1, G2Point a2, + G1Point b1, G2Point b2, + G1Point c1, G2Point c2, + G1Point d1, G2Point d2) + { + return ctx.Pairing(new List() + { + a1, b1, c1, d1 + }, new List() + { + a2, b2, c2, d2 + }); + } + + public static byte[] ToBytes32(this BigIntValue value) + { + var bytes = value.ToBigEndianBytes(); + var newArray = new byte[32]; + for (int i = 0; i < bytes.Length; i++) + { + newArray[31 - i] = bytes[bytes.Length - 1 - i]; + } + + return newArray; + } +} \ No newline at end of file diff --git a/contract/ZkTreeVerifier/ZkTreeVerifier.csproj b/contract/ZkTreeVerifier/ZkTreeVerifier.csproj new file mode 100644 index 0000000000..32866adb83 --- /dev/null +++ b/contract/ZkTreeVerifier/ZkTreeVerifier.csproj @@ -0,0 +1,51 @@ + + + + + + net8.0 + ZkTreeVerifier + true + An on-chain verifier for Zk-Tree proof. + AElf.Contracts.ZkTreeVerifier + + + + true + + + + true + + + + + Protobuf\Proto\authority_info.proto + + + + + + Protobuf\Proto\reference\acs0.proto + + + Protobuf\Proto\reference\parliament_contract.proto + + + Protobuf\Proto\reference\token_contract.proto + + + + + Protobuf\Proto\acs1.proto + + + Protobuf\Proto\acs3.proto + + + + + Protobuf\Proto\zk_tree_verifier_contract.proto + + + diff --git a/contract/ZkTreeVerifier/ZkWasmVerifier.cs b/contract/ZkTreeVerifier/ZkWasmVerifier.cs new file mode 100644 index 0000000000..edaf11df2d --- /dev/null +++ b/contract/ZkTreeVerifier/ZkWasmVerifier.cs @@ -0,0 +1,122 @@ +using System.Collections.Generic; +using System.Linq; +using AElf.Types; +using Google.Protobuf.WellKnownTypes; + +namespace AElf.Contracts.ZkTreeVerifier +{ + class VerifyingKey + { + public G1Point alfa1; + public G2Point beta2; + public G2Point gamma2; + public G2Point delta2; + public List IC; + } + + public class ZkTreeVerifier : ZkTreeVerifierContainer.ZkTreeVerifierBase + { + public override BoolValue VerifyProof(VerifyProofInput input) + { + var proof = new Proof() + { + A = new G1Point() + { + X = input.Proof.A.X, + Y = input.Proof.A.Y, + }, + B = new G2Point() + { + X = new Fp2() + { + A = input.Proof.B.X.First, + B = input.Proof.B.X.Second, + }, + Y = new Fp2() + { + A = input.Proof.B.Y.First, + B = input.Proof.B.Y.Second, + } + }, + C = new G1Point() + { + X = input.Proof.C.X, + Y = input.Proof.C.Y, + } + }; + var inputValues = input.Input.Select(x => x.ToBigIntValue()).ToArray(); + + + var verified = Verify(inputValues, proof); + return new BoolValue { Value = verified }; + } + + #region Private Methods + + private bool Verify(BigIntValue[] input, Proof proof) + { + var snarkScalarField = "21888242871839275222246405745257275088548364400416034343698204186575808495617" + .ToBigIntValue(); + var vk = VerifyingKey(); + Assert(input.Length + 1 == vk.IC.Count, "verifier-bad-input"); + // Compute the linear combination vk_x + var vkX = new G1Point + { + X = "0", + Y = "0" + }; + for (var i = 0; i < input.Length; i++) + { + Assert(input[i] < snarkScalarField, "verifier-gte-snark-scalar-field"); + vkX = Context.Addition(vkX, Context.ScalarMul(vk.IC[i + 1], input[i])); + } + + vkX = Context.Addition(vkX, vk.IC[0]); + return Context.PairingProd4( + Context.Negate(proof.A), proof.B, + vk.alfa1, vk.beta2, + vkX, vk.gamma2, + proof.C, vk.delta2 + ); + } + + private VerifyingKey VerifyingKey() + { + Fp2 MakeFp2(string x, string y) => new Fp2() { A = x, B = y }; + G1Point MakeG1(string x, string y) => new G1Point() { X = x, Y = y }; + + G2Point MakeG2(string x1, string x2, string y1, string y2) => + new G2Point() { X = MakeFp2(x1, x2), Y = MakeFp2(y1, y2), }; + + return new VerifyingKey + { + alfa1 = MakeG1( + "20491192805390485299153009773594534940189261866228447918068658471970481763042", + "9383485363053290200918347156157836566562967994039712273449902621266178545958"), + beta2 = MakeG2("4252822878758300859123897981450591353533073413197771768651442665752259397132", + "6375614351688725206403948262868962793625744043794305715222011528459656738731", + "21847035105528745403288232691147584728191162732299865338377159692350059136679", + "10505242626370262277552901082094356697409835680220590971873171140371331206856"), + gamma2 = MakeG2("11559732032986387107991004021392285783925812861821192530917403151452391805634", + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "4082367875863433681332203403145435568316851327593401208105741076214120093531", + "8495653923123431417604973247489272438418190587263600148770280649306958101930"), + delta2 = MakeG2("11559732032986387107991004021392285783925812861821192530917403151452391805634", + "10857046999023057135944570762232829481370756359578518086990519993285655852781", + "4082367875863433681332203403145435568316851327593401208105741076214120093531", + "8495653923123431417604973247489272438418190587263600148770280649306958101930"), + IC = new List() + { + MakeG1("907082046166848403662755682318758048763333219052759262226888852664247719678", + "13772868673976322661276556815121724196712611456125880819435532265591384929117"), + MakeG1("14808146059947600581045955083782207443549812856960403909774034802573047162050", + "1086338950447616826289662789021021878021771857362357242781351280816191633621"), + MakeG1("4409293795953421913352017523563336444457550942519899190266670184661945314920", + "13002239337001261969473038829996565475753673331173499940341032884807981931927") + } + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/contract/ZkTreeVerifier/ZkWasmVerifierState.cs b/contract/ZkTreeVerifier/ZkWasmVerifierState.cs new file mode 100644 index 0000000000..4ffbbf0531 --- /dev/null +++ b/contract/ZkTreeVerifier/ZkWasmVerifierState.cs @@ -0,0 +1,9 @@ +using AElf.Sdk.CSharp.State; + +namespace AElf.Contracts.ZkTreeVerifier +{ + // The state class is access the blockchain state + public class ZkTreeVerifierState : ContractState + { + } +} \ No newline at end of file diff --git a/contract/ZkWasmGame/ZkWasmGame.csproj b/contract/ZkWasmGame/ZkWasmGame.csproj new file mode 100644 index 0000000000..8638a898e4 --- /dev/null +++ b/contract/ZkWasmGame/ZkWasmGame.csproj @@ -0,0 +1,55 @@ + + + + + + net8.0 + ZkWasmGame + true + An on-chain Game contract working with Zk-Wasm. + AElf.Contracts.ZkWasmGame + + + + true + + + + true + + + + + Protobuf\Proto\authority_info.proto + + + + + + Protobuf\Proto\reference\acs0.proto + + + Protobuf\Proto\reference\parliament_contract.proto + + + Protobuf\Proto\reference\token_contract.proto + + + + + Protobuf\Proto\acs1.proto + + + Protobuf\Proto\acs3.proto + + + + + Protobuf\Proto\zk_wasm_verifier_contract.proto + + + Protobuf\Proto\zk_wasm_game_contract.proto + + + + diff --git a/contract/ZkWasmGame/ZkWasmGameContract.cs b/contract/ZkWasmGame/ZkWasmGameContract.cs new file mode 100644 index 0000000000..e5a16a4179 --- /dev/null +++ b/contract/ZkWasmGame/ZkWasmGameContract.cs @@ -0,0 +1,79 @@ +using System.Linq; +using AElf.Contracts.ZkWasmVerifier; +using AElf.Types; +using Google.Protobuf.Collections; +using Google.Protobuf.WellKnownTypes; + +namespace AElf.Contracts.ZkWasmGame; + +public class ZkWasmGameContract : ZkWasmGameContainer.ZkWasmGameBase +{ + public override Empty SubmitGame(SubmitGameInput input) + { + Assert(State.Verifier.Value != null, "Verifier not set."); + State.Verifier.Verify.Send(MapInput(input)); + Settle(input.TargetInstance); + return new Empty(); + } + + public override Empty SetVerifier(Address input) + { + State.Verifier.Value = input; + return new Empty(); + } + + public override Address GetVerifier(Empty input) + { + return State.Verifier.Value; + } + + public override GameState GetGameState(Empty input) + { + return State.GameState.Value; + } + + #region Private Methods + + private VerifyInput MapInput(SubmitGameInput input) + { + var inputToVerifier = new VerifyInput(); + inputToVerifier.Proof.AddRange(input.Proof); + inputToVerifier.Aux.AddRange(input.Aux); + inputToVerifier.VerifyInstance.AddRange(input.VerifyInstance); + inputToVerifier.TargetInstance.AddRange(input.TargetInstance.Select(arr => + { + var newArr = new VerifyInput.Types.StringArray(); + newArr.Value.AddRange(arr.Value); + return newArr; + })); + return inputToVerifier; + } + + private void Settle(RepeatedField instances) + { + var instance = instances.FirstOrDefault(); + if (instance == null) + { + return; + } + + var startState = new GameState() + { + TotalSteps = instance.Value[0], + CurrentPosition = instance.Value[1] + }; + var endState = new GameState() + { + TotalSteps = instance.Value[2], + CurrentPosition = instance.Value[3] + }; + Assert(startState.Equals(State.GameState.Value ?? new GameState() + { + TotalSteps = "0", + CurrentPosition = "0", + }), "Invalid start state."); + State.GameState.Value = endState; + } + + #endregion +} \ No newline at end of file diff --git a/contract/ZkWasmGame/ZkWasmGameState.cs b/contract/ZkWasmGame/ZkWasmGameState.cs new file mode 100644 index 0000000000..5be9156537 --- /dev/null +++ b/contract/ZkWasmGame/ZkWasmGameState.cs @@ -0,0 +1,10 @@ +using AElf.Contracts.ZkWasmVerifier; +using AElf.Sdk.CSharp.State; + +namespace AElf.Contracts.ZkWasmGame; + +public class ZkWasmGameState : ContractState +{ + public SingletonState GameState { get; set; } + internal ZkWasmVerifierContainer.ZkWasmVerifierReferenceState Verifier { get; set; } +} \ No newline at end of file diff --git a/contract/ZkWasmVerifier/AggregatorConfig.cs b/contract/ZkWasmVerifier/AggregatorConfig.cs index 1b6b64ce53..3004410484 100644 --- a/contract/ZkWasmVerifier/AggregatorConfig.cs +++ b/contract/ZkWasmVerifier/AggregatorConfig.cs @@ -1,13 +1,14 @@ using System.Linq; -using Bn254.Net; -using Nethereum.Util; +using AElf.CSharp.Core; +using AElf.Sdk.CSharp; +using AElf.Types; namespace ZkWasmVerifier; public static class AggregatorConfig { - - public static void FillVerifyCircuitsG2(UInt256[] s) { + public static void FillVerifyCircuitsG2(BigIntValue[] s) + { s[2] = "10912121346736960153119032326674308622836895172287017181004332853287395747540"; s[3] = "1141242303575873671169773919745529817497021056319105990006251901769180589131"; s[4] = "13736722489223410979012950988289654946078517441362861355057236908979399480985"; @@ -18,14 +19,15 @@ public static void FillVerifyCircuitsG2(UInt256[] s) { s[10] = "17805874995975841540914202342111839520379459829704422454583296818431106115052"; s[11] = "13392588948715843804641432497768002650278120570034223513918757245338268106653"; } - public static void GetChallenges(UInt256[] transcript, UInt256[] buf) + + public static void GetChallenges(this CSharpSmartContractContext ctx, BigIntValue[] transcript, BigIntValue[] buf) { - GetChallengesShplonk(transcript, buf); + ctx.GetChallengesShplonk(transcript, buf); } - public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) + public static void GetChallengesShplonk(this CSharpSmartContractContext ctx, BigIntValue[] transcript, BigIntValue[] buf) { - UInt256[] absorbing = new UInt256[112]; + BigIntValue[] absorbing = new BigIntValue[112]; absorbing[0] = "8987513744584090369347489657311893833926946877426413758008060670913747976065"; absorbing[1] = buf[0]; absorbing[2] = buf[1]; @@ -39,7 +41,7 @@ public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) } // theta - buf[2] = SqeezeChallenge(absorbing, pos); + buf[2] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; for (var i = 0; i < 4; i++) @@ -50,14 +52,14 @@ public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) } // beta - buf[3] = SqeezeChallenge(absorbing, pos); + buf[3] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; // gamma - buf[4] = SqeezeChallenge(absorbing, pos); + buf[4] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; - for (int i = 0; i < 7; i++) + for (var i = 0; i < 7; i++) { AggregatorLib.CheckOnCurve(transcript[transcriptPos], transcript[transcriptPos + 1]); absorbing[pos++] = transcript[transcriptPos++]; @@ -65,10 +67,10 @@ public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) } // y - buf[5] = SqeezeChallenge(absorbing, pos); + buf[5] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { AggregatorLib.CheckOnCurve(transcript[transcriptPos], transcript[transcriptPos + 1]); absorbing[pos++] = transcript[transcriptPos++]; @@ -76,7 +78,7 @@ public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) } // x - buf[6] = SqeezeChallenge(absorbing, pos); + buf[6] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; for (var i = 0; i < 56; i++) @@ -85,40 +87,40 @@ public static void GetChallengesShplonk(UInt256[] transcript, UInt256[] buf) } // y - buf[7] = SqeezeChallenge(absorbing, pos); + buf[7] = ctx.SqeezeChallenge(absorbing, pos); pos = 1; // v - buf[8] = SqeezeChallenge(absorbing, pos); + buf[8] = ctx.SqeezeChallenge(absorbing, pos); AggregatorLib.CheckOnCurve(transcript[transcriptPos], transcript[transcriptPos + 1]); absorbing[pos++] = transcript[transcriptPos++]; absorbing[pos++] = transcript[transcriptPos++]; // u - buf[9] = SqeezeChallenge(absorbing, pos); + buf[9] = ctx.SqeezeChallenge(absorbing, pos); AggregatorLib.CheckOnCurve(transcript[transcriptPos], transcript[transcriptPos + 1]); } - public static void CalcVerifyCircuitLagrange(UInt256[] buf) + public static void CalcVerifyCircuitLagrange(this CSharpSmartContractContext ctx, BigIntValue[] buf) { buf[0] = "2735708597799451452160332461848350692128893288992167946537450125562183732533"; buf[1] = "16512170175385812892195391099574916023024416995263347775961451770318731872745"; - AggregatorLib.Msm(buf, 0, 1); + ctx.Msm(buf, 0, 1); } - public static UInt256 Hash(UInt256[] absorbing, UInt256 length) + public static BigIntValue Hash(this CSharpSmartContractContext ctx, BigIntValue[] absorbing, int length) { - var bytes = absorbing.Take(length).SelectMany(x => x.ToBigEndianBytes()).Concat(new byte[1]).ToArray(); - var hash = Sha3Keccack.Current.CalculateHash(bytes); - return hash.ToUInt256(); + var bytes = absorbing.Take(length).SelectMany(x => x.ToBytes32()).Concat(new byte[1]).ToArray(); + var hash = ctx.Keccak256(bytes); + return BigIntValue.FromBigEndianBytes(hash); } - public static UInt256 SqeezeChallenge(UInt256[] absorbing, UInt256 length) + public static BigIntValue SqeezeChallenge(this CSharpSmartContractContext ctx, BigIntValue[] absorbing, int length) { absorbing[length] = 0; - var hash = Hash(absorbing, length); + var hash = ctx.Hash(absorbing, length); absorbing[0] = hash; - return hash % AggregatorLib.QMod; + return hash.ModPow(1, AggregatorLib.QMod); } } \ No newline at end of file diff --git a/contract/ZkWasmVerifier/AggregatorLib.cs b/contract/ZkWasmVerifier/AggregatorLib.cs index aa5f3a40e4..fd89a11b8d 100644 --- a/contract/ZkWasmVerifier/AggregatorLib.cs +++ b/contract/ZkWasmVerifier/AggregatorLib.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; +using AElf.CSharp.Core; using AElf.Sdk.CSharp; -using Bn254.Net; -using Nethereum.Util; +using AElf.Types; namespace ZkWasmVerifier; @@ -14,40 +13,47 @@ public NotOnCurveException(string message) : base(message) } } -public class AggregatorLib +public static class AggregatorLib { - private const string PMod = - "21888242871839275222246405745257275088696311157297823662689037894645226208583"; - public const string QMod = - "21888242871839275222246405745257275088548364400416034343698204186575808495617"; + private static BigIntValue PMod => new BigIntValue + { + Value = + "21888242871839275222246405745257275088696311157297823662689037894645226208583" + }; - public static UInt256 HashInstances(UInt256[] absorbing) + public static BigIntValue QMod => new BigIntValue { - var hash = Sha3Keccack.Current.CalculateHash(absorbing.SelectMany(x => x.ToBigEndianBytes()).ToArray()); - return hash.ToUInt256() % QMod; - } + Value = "21888242871839275222246405745257275088548364400416034343698204186575808495617" + }; + + // public static BigIntValue HashInstances(BigIntValue[] absorbing) + // { + // var hash = Sha3Keccack.Current.CalculateHash(absorbing.SelectMany(x => x.ToBytes32()).ToArray()); + // return hash.ToBigIntValue() % QMod; + // } - public static void CheckOnCurve(UInt256 x, UInt256 y) + public static void CheckOnCurve(BigIntValue x, BigIntValue y) { // y^2 = x^3 + 3 if (x.IsZero()) return; if (y.IsZero()) return; - UInt256 l = y * y % PMod; - UInt256 r = x * x % PMod; - r = r * x % PMod; - r = (r + 3) % PMod; + BigIntValue l = (y * y).ModPow(1, PMod); + BigIntValue r = (x * x).ModPow(1, PMod); + r = (r * x).ModPow(1, PMod); + r = (r + 3).ModPow(1, PMod); if (l != r) { throw new NotOnCurveException("Not on curve"); } } - private static (bool, UInt256 x, UInt256 y) TryMul(UInt256 x1, UInt256 y1, UInt256 s) + private static (bool, BigIntValue x, BigIntValue y) TryMul(this CSharpSmartContractContext ctx, BigIntValue x1, + BigIntValue y1, BigIntValue s) { try { - var (x, y) = Bn254.Net.Bn254.Mul(x1, y1, s); - return (true, x, y); + var (x, y) = ctx.Bn254G1Mul(x1.ToBytes32(), y1.ToBytes32(), s.ToBytes32()); + return (true, BigIntValue.FromBigEndianBytes(x), BigIntValue.FromBigEndianBytes(y)); } catch (Exception e) { @@ -55,12 +61,15 @@ private static (bool, UInt256 x, UInt256 y) TryMul(UInt256 x1, UInt256 y1, UInt2 } } - private static (bool, UInt256 x, UInt256 y) TryAdd(UInt256 x1, UInt256 y1, UInt256 x2, UInt256 y2) + private static (bool, BigIntValue x, BigIntValue y) TryAdd(this CSharpSmartContractContext ctx, BigIntValue x1, + BigIntValue y1, BigIntValue x2, + BigIntValue y2) { try { - var (x, y) = Bn254.Net.Bn254.Add(x1, y1, x2, y2); - return (true, x, y); + var (x, y) = ctx.Bn254G1Add(x1.ToBytes32(), y1.ToBytes32(), x2.ToBytes32(), + y2.ToBytes32()); + return (true, BigIntValue.FromBigEndianBytes(x), BigIntValue.FromBigEndianBytes(y)); } catch (Exception e) { @@ -68,9 +77,9 @@ private static (bool, UInt256 x, UInt256 y) TryAdd(UInt256 x1, UInt256 y1, UInt2 } } - public static bool Pairing(UInt256[] input) + public static bool Pairing(this CSharpSmartContractContext ctx, BigIntValue[] input) { - var elements = new List<(UInt256, UInt256, UInt256, UInt256, UInt256, UInt256)>(); + var elements = new List<(byte[], byte[], byte[], byte[], byte[], byte[])>(); for (var i = 0; 6 * i < input.Length; i++) { var (x1, y1, x2, y2, x3, y3) = ( @@ -78,13 +87,14 @@ public static bool Pairing(UInt256[] input) input[6 * i + 2], input[6 * i + 3], input[6 * i + 4], input[6 * i + 5] ); - elements.Add((x1, y1, x2, y2, x3, y3)); + elements.Add((x1.ToBytes32(), y1.ToBytes32(), x2.ToBytes32(), y2.ToBytes32(), + x3.ToBytes32(), y3.ToBytes32())); } - return Bn254.Net.Bn254.Pairing(elements.ToArray()); + return ctx.Bn254Pairing(elements.ToArray()); } - public static void Msm(UInt256[] input, UInt256 offset, UInt256 count) + public static void Msm(this CSharpSmartContractContext ctx, BigIntValue[] input, int offset, int count) { if (count == 0) { @@ -96,7 +106,7 @@ public static void Msm(UInt256[] input, UInt256 offset, UInt256 count) var ret = false; var start = offset + count * 3 - 3; { - var (ret0, x, y) = TryMul(input[start], input[start + 1], input[start + 2]); + var (ret0, x, y) = ctx.TryMul(input[start], input[start + 1], input[start + 2]); ret = ret0; input[start] = x; input[start + 1] = y; @@ -107,13 +117,13 @@ public static void Msm(UInt256[] input, UInt256 offset, UInt256 count) { start -= 3; { - var (ret0, x, y) = TryMul(input[start], input[start + 1], input[start + 2]); + var (ret0, x, y) = ctx.TryMul(input[start], input[start + 1], input[start + 2]); ret = ret0; input[start + 1] = x; input[start + 2] = y; } { - var (ret0, x, y) = TryAdd(input[start + 1], input[start + 2], input[start + 3], input[start + 4]); + var (ret0, x, y) = ctx.TryAdd(input[start + 1], input[start + 2], input[start + 3], input[start + 4]); ret = ret0; input[start] = x; input[start + 1] = y; @@ -121,29 +131,29 @@ public static void Msm(UInt256[] input, UInt256 offset, UInt256 count) } } - public static void EccMul(UInt256[] input, UInt256 offset) + public static void EccMul(this CSharpSmartContractContext ctx, BigIntValue[] input, int offset) { - if (input[offset + 2] == 1) + if (input[offset + 2].Value == "1") { return; } - Msm(input, offset, 1); + ctx.Msm(input, offset, 1); } - public static void EccMulAdd(UInt256[] input, UInt256 offset) + public static void EccMulAdd(this CSharpSmartContractContext ctx, BigIntValue[] input, int offset) { var ret = false; var p1 = offset; var p2 = p1 + 2; { - var (ret0, x, y) = TryMul(input[p2], input[p2 + 1], input[p2 + 2]); + var (ret0, x, y) = ctx.TryMul(input[p2], input[p2 + 1], input[p2 + 2]); ret = ret0; input[p2] = x; input[p2 + 1] = y; } { - var (ret0, x, y) = TryAdd(input[p1], input[p1 + 1], input[p1 + 2], input[p1 + 3]); + var (ret0, x, y) = ctx.TryAdd(input[p1], input[p1 + 1], input[p1 + 2], input[p1 + 3]); ret = ret0; input[p1] = x; input[p1 + 1] = y; @@ -183,15 +193,14 @@ public static void EccMulAdd(UInt256[] input, UInt256 offset) // require(ret); // } - public static UInt256 FrPow(UInt256 a, UInt256 power) + public static BigIntValue FrPow(BigIntValue a, BigIntValue power) { - var result = Bn254.Net.Bn254.ModExp(a.ToBigEndianBytes(), power.ToBigEndianBytes(), QMod.DecToUInt256().ToBigEndianBytes()); - return new UInt256(result); + return SafeMath.ModPow(a, power, QMod); } - public static UInt256 FrDiv(UInt256 a, UInt256 b, UInt256 aux) + public static BigIntValue FrDiv(BigIntValue a, BigIntValue b, BigIntValue aux) { - var r = b * aux % QMod.DecToUInt256(); + var r = (b * aux).ModPow(1, QMod); if (a != r) { throw new AssertionException("div fail"); @@ -202,7 +211,7 @@ public static UInt256 FrDiv(UInt256 a, UInt256 b, UInt256 aux) throw new AssertionException("div zero"); } - return aux % QMod.DecToUInt256(); + return aux.ModPow(1, QMod); } // function fr_div(uint256 a, uint256 b, uint256 aux) internal pure returns (uint256) { diff --git a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep1.cs b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep1.cs index f24923ae04..e0dd0906b9 100644 --- a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep1.cs +++ b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep1.cs @@ -1,113 +1,115 @@ -using Bn254.Net; +using AElf.CSharp.Core; +using AElf.Types; +using ZkWasmVerifier; -namespace ZkWasmVerifier; +namespace AElf.Contracts.ZkWasmVerifier; -public class AggregatorVerifierCoreStep1 : IAggregatorVerifierCoreStep +public partial class ZkWasmVerifier { - public UInt256[] VerifyProof(UInt256[] transcript, UInt256[] aux, UInt256[] buf) + private BigIntValue[] VerifyProofStep1(BigIntValue[] transcript, BigIntValue[] aux, BigIntValue[] buf) { // @formatter:off - var mulmod = (UInt256 a, UInt256 b, UInt256 m) => (a * b) % m; - var addmod = (UInt256 a, UInt256 b, UInt256 m) => (a + b) % m; + var mulmod = (BigIntValue a, BigIntValue b, BigIntValue m) => a.Mul(b).ModPow(1,m); + var addmod = (BigIntValue a, BigIntValue b, BigIntValue m) => a.Add(b).ModPow(1,m); (buf[10], buf[11]) = (transcript[102], transcript[103]); buf[12] = 1; - AggregatorLib.EccMul(buf, 10); - buf[17] = mulmod("21710372849001950800533397158415938114909991150039389063546734567764856596059", buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[18] = AggregatorLib.FrDiv(1, addmod(buf[17], AggregatorLib.QMod.DecToUInt256() - buf[6], AggregatorLib.QMod.DecToUInt256()), aux[0]); - buf[19] = mulmod("8374374965308410102411073611984011876711565317741801500439755773472076597347", buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[20] = AggregatorLib.FrDiv(1, addmod(buf[17], AggregatorLib.QMod.DecToUInt256() - buf[19], AggregatorLib.QMod.DecToUInt256()), aux[1]); - buf[21] = mulmod(buf[18], buf[20], AggregatorLib.QMod.DecToUInt256()); - buf[22] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - buf[17], AggregatorLib.QMod.DecToUInt256()), aux[2]); - buf[23] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - buf[19], AggregatorLib.QMod.DecToUInt256()), aux[3]); - buf[24] = mulmod(buf[22], buf[23], AggregatorLib.QMod.DecToUInt256()); - buf[25] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod.DecToUInt256() - buf[17], AggregatorLib.QMod.DecToUInt256()), aux[4]); - buf[26] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod.DecToUInt256() - buf[6], AggregatorLib.QMod.DecToUInt256()), aux[5]); - buf[27] = mulmod(buf[25], buf[26], AggregatorLib.QMod.DecToUInt256()); - buf[28] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[18], buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[20], buf[19], AggregatorLib.QMod.DecToUInt256()); - buf[18] = addmod(mulmod(buf[28], buf[20], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[18], buf[29], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[20] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[22], buf[17], AggregatorLib.QMod.DecToUInt256()); - buf[30] = mulmod(buf[23], buf[19], AggregatorLib.QMod.DecToUInt256()); - buf[22] = addmod(mulmod(buf[20], buf[23], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[22], buf[30], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[25], buf[17], AggregatorLib.QMod.DecToUInt256()); - buf[32] = mulmod(buf[26], buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[25] = addmod(mulmod(buf[31], buf[26], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[25], buf[32], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[33] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[81], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[24], transcript[79], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[27], transcript[80], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[18], transcript[81], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[22], transcript[79], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[25], transcript[80], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[28] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[28], buf[29], AggregatorLib.QMod.DecToUInt256()); - buf[20] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[20], buf[30], AggregatorLib.QMod.DecToUInt256()); - buf[29] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[31], buf[32], AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(buf[7], addmod(mulmod(buf[33], buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[28], transcript[81], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[20], transcript[79], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[80], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[33] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[84], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[24], transcript[82], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[27], transcript[83], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[18], transcript[84], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[22], transcript[82], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[25], transcript[83], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(buf[31], addmod(mulmod(buf[33], buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[28], transcript[84], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[20], transcript[82], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[83], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[18] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[87], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[24], transcript[85], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[27], transcript[86], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[18], transcript[87], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[22], transcript[85], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[25], transcript[86], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[18] = addmod(mulmod(buf[7], buf[31], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[18], buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[28], transcript[87], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[20], transcript[85], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[86], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[20] = mulmod("9741553891420464328295280489650144566903017206473301385034033384879943874347", buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[21] = AggregatorLib.FrDiv(1, addmod(buf[20], AggregatorLib.QMod.DecToUInt256() - buf[6], AggregatorLib.QMod.DecToUInt256()), aux[6]); - buf[22] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - buf[20], AggregatorLib.QMod.DecToUInt256()), aux[7]); - buf[24] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[21], buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[25] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[22], buf[20], AggregatorLib.QMod.DecToUInt256()); - buf[27] = mulmod(buf[7], addmod(mulmod(addmod(mulmod(buf[21], transcript[93], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[22], transcript[92], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[24], transcript[93], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[25], transcript[92], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[21] = addmod(buf[27], addmod(mulmod(addmod(mulmod(buf[21], transcript[98], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[22], transcript[97], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[24], transcript[98], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[25], transcript[97], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[17] = addmod(buf[9], AggregatorLib.QMod.DecToUInt256() - buf[17], AggregatorLib.QMod.DecToUInt256()); - buf[22] = addmod(buf[9], AggregatorLib.QMod.DecToUInt256() - buf[19], AggregatorLib.QMod.DecToUInt256()); - buf[24] = mulmod("11211301017135681023579411905410872569206244553457844956874280139879520583390", buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[25] = addmod(buf[9], AggregatorLib.QMod.DecToUInt256() - buf[24], AggregatorLib.QMod.DecToUInt256()); - buf[20] = addmod(buf[9], AggregatorLib.QMod.DecToUInt256() - buf[20], AggregatorLib.QMod.DecToUInt256()); - buf[27] = AggregatorLib.FrDiv(1, mulmod(buf[20], buf[25], AggregatorLib.QMod.DecToUInt256()), aux[8]); - buf[28] = mulmod(mulmod(mulmod(buf[17], buf[22], AggregatorLib.QMod.DecToUInt256()), buf[25], AggregatorLib.QMod.DecToUInt256()), buf[27], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], transcript[44], AggregatorLib.QMod.DecToUInt256()), transcript[45], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[46], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[47], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[48], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[51], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod.DecToUInt256()), transcript[94], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[99], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[58], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[59], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[60], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod.DecToUInt256()), transcript[61], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[62], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[63], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[64], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[65], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod.DecToUInt256()), transcript[66], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[67], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[68], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[69], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[70], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod.DecToUInt256()), transcript[72], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[73], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[74], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[75], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[76], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod.DecToUInt256()), transcript[77], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[78], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(addmod(addmod(addmod(transcript[58], mulmod(transcript[50], transcript[59], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(transcript[45], transcript[60], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(transcript[46], transcript[61], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(transcript[47], transcript[62], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(addmod(addmod(addmod(buf[31], mulmod(transcript[48], transcript[63], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(transcript[49], transcript[64], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(mulmod(transcript[45], transcript[46], AggregatorLib.QMod.DecToUInt256()), transcript[65], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(mulmod(transcript[47], transcript[48], AggregatorLib.QMod.DecToUInt256()), transcript[66], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[33] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495615", AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495614", AggregatorLib.QMod.DecToUInt256()); - buf[35] = mulmod(mulmod(mulmod(addmod(transcript[51], AggregatorLib.QMod.DecToUInt256() - transcript[52], AggregatorLib.QMod.DecToUInt256()), transcript[70], AggregatorLib.QMod.DecToUInt256()), buf[33], AggregatorLib.QMod.DecToUInt256()), buf[34], AggregatorLib.QMod.DecToUInt256()); - buf[36] = addmod(addmod(transcript[51], AggregatorLib.QMod.DecToUInt256() - transcript[53], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[54], 262144, AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[37] = mulmod(addmod(addmod(buf[36], AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[52], "68719476736", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[55], "18014398509481984", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[70], AggregatorLib.QMod.DecToUInt256()); - buf[38] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495616", AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod.DecToUInt256()), buf[35], AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(mulmod(buf[37], buf[38], AggregatorLib.QMod.DecToUInt256()), buf[34], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(addmod(addmod(buf[36], AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[56], "68719476736", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[52], "18014398509481984", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[55], "4722366482869645213696", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[34] = mulmod(mulmod(addmod(buf[34], AggregatorLib.QMod.DecToUInt256() - mulmod(transcript[57], "1237940039285380274899124224", AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[70], AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()); + Context.EccMul(buf, 10); + buf[17] = mulmod("21710372849001950800533397158415938114909991150039389063546734567764856596059", buf[6], AggregatorLib.QMod); + buf[18] = AggregatorLib.FrDiv(1, addmod(buf[17], AggregatorLib.QMod - buf[6], AggregatorLib.QMod), aux[0]); + buf[19] = mulmod("8374374965308410102411073611984011876711565317741801500439755773472076597347", buf[6], AggregatorLib.QMod); + buf[20] = AggregatorLib.FrDiv(1, addmod(buf[17], AggregatorLib.QMod - buf[19], AggregatorLib.QMod), aux[1]); + buf[21] = mulmod(buf[18], buf[20], AggregatorLib.QMod); + buf[22] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod - buf[17], AggregatorLib.QMod), aux[2]); + buf[23] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod - buf[19], AggregatorLib.QMod), aux[3]); + buf[24] = mulmod(buf[22], buf[23], AggregatorLib.QMod); + buf[25] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod - buf[17], AggregatorLib.QMod), aux[4]); + buf[26] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod - buf[6], AggregatorLib.QMod), aux[5]); + buf[27] = mulmod(buf[25], buf[26], AggregatorLib.QMod); + buf[28] = AggregatorLib.QMod - mulmod(buf[18], buf[6], AggregatorLib.QMod); + buf[29] = mulmod(buf[20], buf[19], AggregatorLib.QMod); + buf[18] = addmod(mulmod(buf[28], buf[20], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[18], buf[29], AggregatorLib.QMod), AggregatorLib.QMod); + buf[20] = AggregatorLib.QMod - mulmod(buf[22], buf[17], AggregatorLib.QMod); + buf[30] = mulmod(buf[23], buf[19], AggregatorLib.QMod); + buf[22] = addmod(mulmod(buf[20], buf[23], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[22], buf[30], AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = AggregatorLib.QMod - mulmod(buf[25], buf[17], AggregatorLib.QMod); + buf[32] = mulmod(buf[26], buf[6], AggregatorLib.QMod); + buf[25] = addmod(mulmod(buf[31], buf[26], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[25], buf[32], AggregatorLib.QMod), AggregatorLib.QMod); + buf[33] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[81], AggregatorLib.QMod), mulmod(buf[24], transcript[79], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[27], transcript[80], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[18], transcript[81], AggregatorLib.QMod), mulmod(buf[22], transcript[79], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[25], transcript[80], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[28] = AggregatorLib.QMod - mulmod(buf[28], buf[29], AggregatorLib.QMod); + buf[20] = AggregatorLib.QMod - mulmod(buf[20], buf[30], AggregatorLib.QMod); + buf[29] = AggregatorLib.QMod - mulmod(buf[31], buf[32], AggregatorLib.QMod); + buf[31] = mulmod(buf[7], addmod(mulmod(buf[33], buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[28], transcript[81], AggregatorLib.QMod), mulmod(buf[20], transcript[79], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[29], transcript[80], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[33] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[84], AggregatorLib.QMod), mulmod(buf[24], transcript[82], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[27], transcript[83], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[18], transcript[84], AggregatorLib.QMod), mulmod(buf[22], transcript[82], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[25], transcript[83], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = addmod(buf[31], addmod(mulmod(buf[33], buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[28], transcript[84], AggregatorLib.QMod), mulmod(buf[20], transcript[82], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[29], transcript[83], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[18] = addmod(mulmod(addmod(addmod(mulmod(buf[21], transcript[87], AggregatorLib.QMod), mulmod(buf[24], transcript[85], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[27], transcript[86], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[18], transcript[87], AggregatorLib.QMod), mulmod(buf[22], transcript[85], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[25], transcript[86], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[18] = addmod(mulmod(buf[7], buf[31], AggregatorLib.QMod), addmod(mulmod(buf[18], buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[28], transcript[87], AggregatorLib.QMod), mulmod(buf[20], transcript[85], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[29], transcript[86], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[20] = mulmod("9741553891420464328295280489650144566903017206473301385034033384879943874347", buf[6], AggregatorLib.QMod); + buf[21] = AggregatorLib.FrDiv(1, addmod(buf[20], AggregatorLib.QMod - buf[6], AggregatorLib.QMod), aux[6]); + buf[22] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod - buf[20], AggregatorLib.QMod), aux[7]); + buf[24] = AggregatorLib.QMod - mulmod(buf[21], buf[6], AggregatorLib.QMod); + buf[25] = AggregatorLib.QMod - mulmod(buf[22], buf[20], AggregatorLib.QMod); + buf[27] = mulmod(buf[7], addmod(mulmod(addmod(mulmod(buf[21], transcript[93], AggregatorLib.QMod), mulmod(buf[22], transcript[92], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[24], transcript[93], AggregatorLib.QMod), mulmod(buf[25], transcript[92], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[21] = addmod(buf[27], addmod(mulmod(addmod(mulmod(buf[21], transcript[98], AggregatorLib.QMod), mulmod(buf[22], transcript[97], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[24], transcript[98], AggregatorLib.QMod), mulmod(buf[25], transcript[97], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[17] = addmod(buf[9], AggregatorLib.QMod - buf[17], AggregatorLib.QMod); + buf[22] = addmod(buf[9], AggregatorLib.QMod - buf[19], AggregatorLib.QMod); + buf[24] = mulmod("11211301017135681023579411905410872569206244553457844956874280139879520583390", buf[6], AggregatorLib.QMod); + buf[25] = addmod(buf[9], AggregatorLib.QMod - buf[24], AggregatorLib.QMod); + buf[20] = addmod(buf[9], AggregatorLib.QMod - buf[20], AggregatorLib.QMod); + buf[27] = AggregatorLib.FrDiv(1, mulmod(buf[20], buf[25], AggregatorLib.QMod), aux[8]); + buf[28] = mulmod(mulmod(mulmod(buf[17], buf[22], AggregatorLib.QMod), buf[25], AggregatorLib.QMod), buf[27], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], transcript[44], AggregatorLib.QMod), transcript[45], AggregatorLib.QMod), AggregatorLib.QMod), transcript[46], AggregatorLib.QMod), AggregatorLib.QMod); + buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[47], AggregatorLib.QMod), AggregatorLib.QMod), transcript[48], AggregatorLib.QMod), AggregatorLib.QMod), transcript[51], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod), transcript[94], AggregatorLib.QMod), AggregatorLib.QMod), transcript[99], AggregatorLib.QMod), AggregatorLib.QMod); + buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[58], AggregatorLib.QMod), AggregatorLib.QMod), transcript[59], AggregatorLib.QMod), AggregatorLib.QMod), transcript[60], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod), transcript[61], AggregatorLib.QMod), AggregatorLib.QMod), transcript[62], AggregatorLib.QMod), AggregatorLib.QMod); + buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[63], AggregatorLib.QMod), AggregatorLib.QMod), transcript[64], AggregatorLib.QMod), AggregatorLib.QMod), transcript[65], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod), transcript[66], AggregatorLib.QMod), AggregatorLib.QMod), transcript[67], AggregatorLib.QMod), AggregatorLib.QMod); + buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[68], AggregatorLib.QMod), AggregatorLib.QMod), transcript[69], AggregatorLib.QMod), AggregatorLib.QMod), transcript[70], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod), transcript[72], AggregatorLib.QMod), AggregatorLib.QMod), transcript[73], AggregatorLib.QMod), AggregatorLib.QMod); + buf[29] = addmod(mulmod(buf[7], addmod(mulmod(buf[7], addmod(buf[29], transcript[74], AggregatorLib.QMod), AggregatorLib.QMod), transcript[75], AggregatorLib.QMod), AggregatorLib.QMod), transcript[76], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[7], addmod(mulmod(buf[7], buf[29], AggregatorLib.QMod), transcript[77], AggregatorLib.QMod), AggregatorLib.QMod), transcript[78], AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = addmod(addmod(addmod(addmod(transcript[58], mulmod(transcript[50], transcript[59], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(transcript[45], transcript[60], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(transcript[46], transcript[61], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(transcript[47], transcript[62], AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = addmod(addmod(addmod(addmod(buf[31], mulmod(transcript[48], transcript[63], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(transcript[49], transcript[64], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(mulmod(transcript[45], transcript[46], AggregatorLib.QMod), transcript[65], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(mulmod(transcript[47], transcript[48], AggregatorLib.QMod), transcript[66], AggregatorLib.QMod), AggregatorLib.QMod); + buf[33] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495615", AggregatorLib.QMod); + buf[34] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495614", AggregatorLib.QMod); + buf[35] = mulmod(mulmod(mulmod(addmod(transcript[51], AggregatorLib.QMod - transcript[52], AggregatorLib.QMod), transcript[70], AggregatorLib.QMod), buf[33], AggregatorLib.QMod), buf[34], AggregatorLib.QMod); + buf[36] = addmod(addmod(transcript[51], AggregatorLib.QMod - transcript[53], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(transcript[54], 262144, AggregatorLib.QMod), AggregatorLib.QMod); + buf[37] = mulmod(addmod(addmod(buf[36], AggregatorLib.QMod - mulmod(transcript[52], "68719476736", AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(transcript[55], "18014398509481984", AggregatorLib.QMod), AggregatorLib.QMod), transcript[70], AggregatorLib.QMod); + buf[38] = addmod(transcript[70], "21888242871839275222246405745257275088548364400416034343698204186575808495616", AggregatorLib.QMod); + buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod), buf[35], AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(mulmod(buf[37], buf[38], AggregatorLib.QMod), buf[34], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[34] = addmod(addmod(addmod(buf[36], AggregatorLib.QMod - mulmod(transcript[56], "68719476736", AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(transcript[52], "18014398509481984", AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(transcript[55], "4722366482869645213696", AggregatorLib.QMod), AggregatorLib.QMod); + buf[34] = mulmod(mulmod(addmod(buf[34], AggregatorLib.QMod - mulmod(transcript[57], "1237940039285380274899124224", AggregatorLib.QMod), AggregatorLib.QMod), transcript[70], AggregatorLib.QMod), buf[38], AggregatorLib.QMod); buf[35] = AggregatorLib.FrPow(buf[6], 8388608); - buf[36] = addmod(buf[35], AggregatorLib.QMod.DecToUInt256() - 1, AggregatorLib.QMod.DecToUInt256()); - buf[37] = AggregatorLib.FrDiv(mulmod("21888240262557392955334514970720457388010314637169927192662615958087340972065", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - 1, AggregatorLib.QMod.DecToUInt256()), aux[9]); - buf[31] = mulmod(addmod(mulmod(addmod(buf[31], mulmod(buf[34], buf[33], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[37], addmod(1, AggregatorLib.QMod.DecToUInt256() - transcript[79], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[33] = AggregatorLib.FrDiv(mulmod("4976187549286291281196346419790865785215437125361463174887299780224677482739", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "21710372849001950800533397158415938114909991150039389063546734567764856596059", AggregatorLib.QMod.DecToUInt256()), aux[10]); - buf[31] = mulmod(addmod(buf[31], mulmod(buf[33], addmod(mulmod(transcript[88], transcript[88], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - transcript[88], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(mulmod(addmod(buf[31], mulmod(addmod(transcript[82], AggregatorLib.QMod.DecToUInt256() - transcript[81], AggregatorLib.QMod.DecToUInt256()), buf[37], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(transcript[85], AggregatorLib.QMod.DecToUInt256() - transcript[84], AggregatorLib.QMod.DecToUInt256()), buf[37], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(transcript[46], buf[4], AggregatorLib.QMod.DecToUInt256()); - buf[38] = addmod(transcript[45], buf[4], AggregatorLib.QMod.DecToUInt256()); - buf[39] = mulmod(buf[3], buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[73], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[38], mulmod(buf[3], transcript[72], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[80], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(addmod(buf[34], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[39], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[38], buf[39], AggregatorLib.QMod.DecToUInt256()), transcript[79], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[38] = addmod(addmod(addmod(AggregatorLib.FrDiv(mulmod("17545179510056424625657753961500172777187948487824275719647175633757629801999", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "1887003188133998471169152042388914354640772748308168868301418279904560637395", AggregatorLib.QMod.DecToUInt256()), aux[11]), AggregatorLib.FrDiv(mulmod("12181902470161097505840471953356915228510866946798053228669051859673065660797", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "2785514556381676080176937710880804108647911392478702105860685610379369825016", AggregatorLib.QMod.DecToUInt256()), aux[12]), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.FrDiv(mulmod("3094683119308499972127188652296432785995218440930254516456812473854441617488", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "14655294445420895451632927078981340937842238432098198055057679026789553137428", AggregatorLib.QMod.DecToUInt256()), aux[13]), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.FrDiv(mulmod("17403859010271654340651602860211012227656903909453797585120745724534928821531", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "8734126352828345679573237859165904705806588461301144420590422589042130041188", AggregatorLib.QMod.DecToUInt256()), aux[14]), AggregatorLib.QMod.DecToUInt256()); - buf[38] = addmod(1, AggregatorLib.QMod.DecToUInt256() - addmod(buf[33], addmod(buf[38], AggregatorLib.FrDiv(mulmod("7444483286096152693477325065105185543054922671492455540957072536952082259082", buf[36], AggregatorLib.QMod.DecToUInt256()), addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - "9741553891420464328295280489650144566903017206473301385034033384879943874347", AggregatorLib.QMod.DecToUInt256()), aux[15]), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(transcript[88], AggregatorLib.QMod.DecToUInt256() - transcript[87], AggregatorLib.QMod.DecToUInt256()), buf[37], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[34], buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(transcript[48], buf[4], AggregatorLib.QMod.DecToUInt256()); - buf[40] = addmod(transcript[47], buf[4], AggregatorLib.QMod.DecToUInt256()); + buf[36] = addmod(buf[35], AggregatorLib.QMod - BigIntValue.One, AggregatorLib.QMod); + buf[37] = AggregatorLib.FrDiv(mulmod("21888240262557392955334514970720457388010314637169927192662615958087340972065", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - BigIntValue.One, AggregatorLib.QMod), aux[9]); + buf[31] = mulmod(addmod(mulmod(addmod(buf[31], mulmod(buf[34], buf[33], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[37], addmod(1, AggregatorLib.QMod - transcript[79], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[33] = AggregatorLib.FrDiv(mulmod("4976187549286291281196346419790865785215437125361463174887299780224677482739", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "21710372849001950800533397158415938114909991150039389063546734567764856596059", AggregatorLib.QMod), aux[10]); + buf[31] = mulmod(addmod(buf[31], mulmod(buf[33], addmod(mulmod(transcript[88], transcript[88], AggregatorLib.QMod), AggregatorLib.QMod - transcript[88], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[31] = addmod(mulmod(addmod(buf[31], mulmod(addmod(transcript[82], AggregatorLib.QMod - transcript[81], AggregatorLib.QMod), buf[37], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(addmod(transcript[85], AggregatorLib.QMod - transcript[84], AggregatorLib.QMod), buf[37], AggregatorLib.QMod), AggregatorLib.QMod); + buf[34] = addmod(transcript[46], buf[4], AggregatorLib.QMod); + buf[38] = addmod(transcript[45], buf[4], AggregatorLib.QMod); + buf[39] = mulmod(buf[3], buf[6], AggregatorLib.QMod); + buf[34] = addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[73], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[38], mulmod(buf[3], transcript[72], AggregatorLib.QMod), AggregatorLib.QMod), transcript[80], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(addmod(buf[34], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[39], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[38], buf[39], AggregatorLib.QMod), transcript[79], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[38] = addmod(addmod(addmod(AggregatorLib.FrDiv(mulmod("17545179510056424625657753961500172777187948487824275719647175633757629801999", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "1887003188133998471169152042388914354640772748308168868301418279904560637395", AggregatorLib.QMod), aux[11]), AggregatorLib.FrDiv(mulmod("12181902470161097505840471953356915228510866946798053228669051859673065660797", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "2785514556381676080176937710880804108647911392478702105860685610379369825016", AggregatorLib.QMod), aux[12]), AggregatorLib.QMod), AggregatorLib.FrDiv(mulmod("3094683119308499972127188652296432785995218440930254516456812473854441617488", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "14655294445420895451632927078981340937842238432098198055057679026789553137428", AggregatorLib.QMod), aux[13]), AggregatorLib.QMod), AggregatorLib.FrDiv(mulmod("17403859010271654340651602860211012227656903909453797585120745724534928821531", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "8734126352828345679573237859165904705806588461301144420590422589042130041188", AggregatorLib.QMod), aux[14]), AggregatorLib.QMod); + buf[38] = addmod(1, AggregatorLib.QMod - addmod(buf[33], addmod(buf[38], AggregatorLib.FrDiv(mulmod("7444483286096152693477325065105185543054922671492455540957072536952082259082", buf[36], AggregatorLib.QMod), addmod(buf[6], AggregatorLib.QMod - "9741553891420464328295280489650144566903017206473301385034033384879943874347", AggregatorLib.QMod), aux[15]), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod), mulmod(addmod(transcript[88], AggregatorLib.QMod - transcript[87], AggregatorLib.QMod), buf[37], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[34], buf[38], AggregatorLib.QMod), AggregatorLib.QMod); + buf[34] = addmod(transcript[48], buf[4], AggregatorLib.QMod); + buf[40] = addmod(transcript[47], buf[4], AggregatorLib.QMod); buf[41] = AggregatorLib.FrPow("4131629893567559867359510883348571134090853742863529169391034518566172092834", 2); - buf[41] = mulmod(buf[39], buf[41], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[75], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[40], mulmod(buf[3], transcript[74], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[83], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(addmod(buf[34], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[41], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[40], buf[41], AggregatorLib.QMod.DecToUInt256()), transcript[82], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[40] = addmod(transcript[51], buf[4], AggregatorLib.QMod.DecToUInt256()); - buf[41] = addmod(transcript[49], buf[4], AggregatorLib.QMod.DecToUInt256()); + buf[41] = mulmod(buf[39], buf[41], AggregatorLib.QMod); + buf[34] = addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[75], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[40], mulmod(buf[3], transcript[74], AggregatorLib.QMod), AggregatorLib.QMod), transcript[83], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(addmod(buf[34], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[41], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[40], buf[41], AggregatorLib.QMod), transcript[82], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[40] = addmod(transcript[51], buf[4], AggregatorLib.QMod); + buf[41] = addmod(transcript[49], buf[4], AggregatorLib.QMod); buf[42] = AggregatorLib.FrPow("4131629893567559867359510883348571134090853742863529169391034518566172092834", 4); - buf[42] = mulmod(buf[39], buf[42], AggregatorLib.QMod.DecToUInt256()); - buf[40] = addmod(mulmod(addmod(buf[40], mulmod(buf[3], transcript[77], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[41], mulmod(buf[3], transcript[76], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[86], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(addmod(buf[40], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[42], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(buf[41], buf[42], AggregatorLib.QMod.DecToUInt256()), transcript[85], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[34], buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[40], buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(transcript[44], buf[4], AggregatorLib.QMod.DecToUInt256()); + buf[42] = mulmod(buf[39], buf[42], AggregatorLib.QMod); + buf[40] = addmod(mulmod(addmod(buf[40], mulmod(buf[3], transcript[77], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[41], mulmod(buf[3], transcript[76], AggregatorLib.QMod), AggregatorLib.QMod), transcript[86], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - mulmod(addmod(buf[40], mulmod("4131629893567559867359510883348571134090853742863529169391034518566172092834", buf[42], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(buf[41], buf[42], AggregatorLib.QMod), transcript[85], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod), mulmod(buf[34], buf[38], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[40], buf[38], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[34] = addmod(transcript[44], buf[4], AggregatorLib.QMod); buf[40] = AggregatorLib.FrPow("4131629893567559867359510883348571134090853742863529169391034518566172092834", 6); - buf[34] = mulmod(addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[78], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[89], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(addmod(buf[34], mulmod(buf[39], buf[40], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[88], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(mulmod(addmod(mulmod(addmod(buf[31], buf[34], AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[37], addmod(1, AggregatorLib.QMod.DecToUInt256() - transcript[90], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[33], addmod(mulmod(transcript[90], transcript[90], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - transcript[90], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(addmod(mulmod(transcript[68], buf[2], AggregatorLib.QMod.DecToUInt256()), transcript[69], AggregatorLib.QMod.DecToUInt256()), buf[4], AggregatorLib.QMod.DecToUInt256()); - buf[39] = mulmod(mulmod(transcript[90], addmod(addmod(mulmod(transcript[67], buf[2], AggregatorLib.QMod.DecToUInt256()), transcript[52], AggregatorLib.QMod.DecToUInt256()), buf[3], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[34], AggregatorLib.QMod.DecToUInt256()); + buf[34] = mulmod(addmod(mulmod(addmod(buf[34], mulmod(buf[3], transcript[78], AggregatorLib.QMod), AggregatorLib.QMod), transcript[89], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(addmod(buf[34], mulmod(buf[39], buf[40], AggregatorLib.QMod), AggregatorLib.QMod), transcript[88], AggregatorLib.QMod), AggregatorLib.QMod), buf[38], AggregatorLib.QMod); + buf[31] = addmod(mulmod(addmod(mulmod(addmod(buf[31], buf[34], AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[37], addmod(1, AggregatorLib.QMod - transcript[90], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[33], addmod(mulmod(transcript[90], transcript[90], AggregatorLib.QMod), AggregatorLib.QMod - transcript[90], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[34] = addmod(addmod(mulmod(transcript[68], buf[2], AggregatorLib.QMod), transcript[69], AggregatorLib.QMod), buf[4], AggregatorLib.QMod); + buf[39] = mulmod(mulmod(transcript[90], addmod(addmod(mulmod(transcript[67], buf[2], AggregatorLib.QMod), transcript[52], AggregatorLib.QMod), buf[3], AggregatorLib.QMod), AggregatorLib.QMod), buf[34], AggregatorLib.QMod); // @formatter:on return buf; } diff --git a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep2.cs b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep2.cs index 5c3944d8d2..7abd818699 100644 --- a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep2.cs +++ b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep2.cs @@ -1,149 +1,150 @@ -using Bn254.Net; +using AElf.Types; +using ZkWasmVerifier; -namespace ZkWasmVerifier; +namespace AElf.Contracts.ZkWasmVerifier; -public class AggregatorVerifierCoreStep2 : IAggregatorVerifierCoreStep +public partial class ZkWasmVerifier { - public UInt256[] VerifyProof(UInt256[] transcript, UInt256[] aux, UInt256[] buf) + public BigIntValue[] VerifyProofStep2(BigIntValue[] transcript, BigIntValue[] aux, BigIntValue[] buf) { // @formatter:off - var mulmod = (UInt256 a, UInt256 b, UInt256 m) => (a * b) % m; - var addmod = (UInt256 a, UInt256 b, UInt256 m) => (a + b) % m; - buf[39] = mulmod(addmod(mulmod(mulmod(transcript[91], addmod(transcript[92], buf[3], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), addmod(transcript[94], buf[4], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - buf[39], AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()); - buf[40] = addmod(transcript[92], AggregatorLib.QMod.DecToUInt256() - transcript[94], AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod.DecToUInt256()), buf[39], AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[37], buf[40], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(addmod(buf[31], mulmod(mulmod(buf[40], addmod(transcript[92], AggregatorLib.QMod.DecToUInt256() - transcript[93], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[31] = addmod(mulmod(addmod(buf[31], mulmod(buf[37], addmod(1, AggregatorLib.QMod.DecToUInt256() - transcript[95], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[33], addmod(mulmod(transcript[95], transcript[95], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - transcript[95], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[33] = mulmod(mulmod(transcript[95], addmod(addmod(mulmod(18, buf[2], AggregatorLib.QMod.DecToUInt256()), transcript[53], AggregatorLib.QMod.DecToUInt256()), buf[3], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[34], AggregatorLib.QMod.DecToUInt256()); - buf[33] = mulmod(addmod(mulmod(mulmod(transcript[96], addmod(transcript[97], buf[3], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), addmod(transcript[99], buf[4], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - buf[33], AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(transcript[97], AggregatorLib.QMod.DecToUInt256() - transcript[99], AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod.DecToUInt256()), buf[33], AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[37], buf[34], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[5], AggregatorLib.QMod.DecToUInt256()); - buf[31] = AggregatorLib.FrDiv(addmod(buf[31], mulmod(mulmod(buf[34], addmod(transcript[97], AggregatorLib.QMod.DecToUInt256() - transcript[98], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[36], aux[16]); - buf[20] = mulmod(buf[17], buf[20], AggregatorLib.QMod.DecToUInt256()); - buf[33] = mulmod(mulmod(mulmod(buf[20], buf[22], AggregatorLib.QMod.DecToUInt256()), buf[25], AggregatorLib.QMod.DecToUInt256()), buf[27], AggregatorLib.QMod.DecToUInt256()); - buf[18] = addmod(mulmod(buf[8], addmod(mulmod(buf[8], buf[18], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[21], buf[28], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(addmod(mulmod(buf[7], addmod(buf[29], buf[31], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), transcript[71], AggregatorLib.QMod.DecToUInt256()), buf[33], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[21] = AggregatorLib.QMod.DecToUInt256() - buf[30]; - buf[29] = AggregatorLib.QMod.DecToUInt256() - buf[32]; - buf[30] = mulmod(buf[7], addmod(mulmod(addmod(mulmod(buf[23], transcript[49], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[50], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[21], transcript[49], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[50], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[30] = addmod(buf[30], addmod(mulmod(addmod(mulmod(buf[23], transcript[88], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[89], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[21], transcript[88], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[89], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[30] = addmod(mulmod(buf[7], buf[30], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(addmod(mulmod(buf[23], transcript[90], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[91], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[21], transcript[90], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[91], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[30] = addmod(mulmod(buf[7], buf[30], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(addmod(mulmod(buf[23], transcript[95], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[96], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(mulmod(buf[21], transcript[95], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[29], transcript[96], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[25] = mulmod(mulmod(buf[20], buf[25], AggregatorLib.QMod.DecToUInt256()), buf[27], AggregatorLib.QMod.DecToUInt256()); - buf[31] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod.DecToUInt256() - buf[24], AggregatorLib.QMod.DecToUInt256()), aux[17]); - buf[32] = mulmod(buf[23], buf[31], AggregatorLib.QMod.DecToUInt256()); - buf[34] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod.DecToUInt256() - buf[24], AggregatorLib.QMod.DecToUInt256()), aux[18]); - buf[36] = mulmod(buf[26], buf[34], AggregatorLib.QMod.DecToUInt256()); - buf[37] = AggregatorLib.FrDiv(1, addmod(buf[24], AggregatorLib.QMod.DecToUInt256() - buf[6], AggregatorLib.QMod.DecToUInt256()), aux[19]); - buf[38] = AggregatorLib.FrDiv(1, addmod(buf[24], AggregatorLib.QMod.DecToUInt256() - buf[19], AggregatorLib.QMod.DecToUInt256()), aux[20]); - buf[39] = mulmod(buf[37], buf[38], AggregatorLib.QMod.DecToUInt256()); - buf[40] = mulmod(buf[31], buf[24], AggregatorLib.QMod.DecToUInt256()); - buf[23] = addmod(mulmod(buf[21], buf[31], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[23], buf[40], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[24] = mulmod(buf[34], buf[24], AggregatorLib.QMod.DecToUInt256()); - buf[26] = addmod(mulmod(buf[29], buf[34], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[26], buf[24], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[31] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[37], buf[6], AggregatorLib.QMod.DecToUInt256()); - buf[19] = mulmod(buf[38], buf[19], AggregatorLib.QMod.DecToUInt256()); - buf[34] = addmod(mulmod(buf[31], buf[38], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256() - mulmod(buf[37], buf[19], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[37] = addmod(mulmod(addmod(addmod(mulmod(buf[32], transcript[52], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[36], transcript[55], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[39], transcript[57], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[23], transcript[52], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[55], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[34], transcript[57], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[21] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[21], buf[40], AggregatorLib.QMod.DecToUInt256()); - buf[24] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[29], buf[24], AggregatorLib.QMod.DecToUInt256()); - buf[19] = AggregatorLib.QMod.DecToUInt256() - mulmod(buf[31], buf[19], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[7], addmod(mulmod(buf[37], buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[21], transcript[52], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[24], transcript[55], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[19], transcript[57], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[23] = addmod(mulmod(addmod(addmod(mulmod(buf[32], transcript[53], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[36], transcript[54], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[39], transcript[56], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[23], transcript[53], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[26], transcript[54], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[34], transcript[56], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[19] = addmod(buf[29], addmod(mulmod(buf[23], buf[9], AggregatorLib.QMod.DecToUInt256()), addmod(addmod(mulmod(buf[21], transcript[53], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[24], transcript[54], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[19], transcript[56], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - buf[20] = mulmod(buf[20], buf[27], AggregatorLib.QMod.DecToUInt256()); - buf[18] = addmod(mulmod(buf[8], addmod(mulmod(buf[8], buf[18], AggregatorLib.QMod.DecToUInt256()), mulmod(buf[30], buf[25], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), mulmod(buf[19], buf[20], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); + var mulmod = (BigIntValue a, BigIntValue b, BigIntValue m) => (a * b) % m; + var addmod = (BigIntValue a, BigIntValue b, BigIntValue m) => (a + b) % m; + buf[39] = mulmod(addmod(mulmod(mulmod(transcript[91], addmod(transcript[92], buf[3], AggregatorLib.QMod), AggregatorLib.QMod), addmod(transcript[94], buf[4], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - buf[39], AggregatorLib.QMod), buf[38], AggregatorLib.QMod); + buf[40] = addmod(transcript[92], AggregatorLib.QMod - transcript[94], AggregatorLib.QMod); + buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod), buf[39], AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[37], buf[40], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[31] = mulmod(addmod(buf[31], mulmod(mulmod(buf[40], addmod(transcript[92], AggregatorLib.QMod - transcript[93], AggregatorLib.QMod), AggregatorLib.QMod), buf[38], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[31] = addmod(mulmod(addmod(buf[31], mulmod(buf[37], addmod(1, AggregatorLib.QMod - transcript[95], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[33], addmod(mulmod(transcript[95], transcript[95], AggregatorLib.QMod), AggregatorLib.QMod - transcript[95], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[33] = mulmod(mulmod(transcript[95], addmod(addmod(mulmod(18, buf[2], AggregatorLib.QMod), transcript[53], AggregatorLib.QMod), buf[3], AggregatorLib.QMod), AggregatorLib.QMod), buf[34], AggregatorLib.QMod); + buf[33] = mulmod(addmod(mulmod(mulmod(transcript[96], addmod(transcript[97], buf[3], AggregatorLib.QMod), AggregatorLib.QMod), addmod(transcript[99], buf[4], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod - buf[33], AggregatorLib.QMod), buf[38], AggregatorLib.QMod); + buf[34] = addmod(transcript[97], AggregatorLib.QMod - transcript[99], AggregatorLib.QMod); + buf[31] = mulmod(addmod(mulmod(addmod(mulmod(buf[31], buf[5], AggregatorLib.QMod), buf[33], AggregatorLib.QMod), buf[5], AggregatorLib.QMod), mulmod(buf[37], buf[34], AggregatorLib.QMod), AggregatorLib.QMod), buf[5], AggregatorLib.QMod); + buf[31] = AggregatorLib.FrDiv(addmod(buf[31], mulmod(mulmod(buf[34], addmod(transcript[97], AggregatorLib.QMod - transcript[98], AggregatorLib.QMod), AggregatorLib.QMod), buf[38], AggregatorLib.QMod), AggregatorLib.QMod), buf[36], aux[16]); + buf[20] = mulmod(buf[17], buf[20], AggregatorLib.QMod); + buf[33] = mulmod(mulmod(mulmod(buf[20], buf[22], AggregatorLib.QMod), buf[25], AggregatorLib.QMod), buf[27], AggregatorLib.QMod); + buf[18] = addmod(mulmod(buf[8], addmod(mulmod(buf[8], buf[18], AggregatorLib.QMod), mulmod(buf[21], buf[28], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), mulmod(addmod(mulmod(buf[7], addmod(buf[29], buf[31], AggregatorLib.QMod), AggregatorLib.QMod), transcript[71], AggregatorLib.QMod), buf[33], AggregatorLib.QMod), AggregatorLib.QMod); + buf[21] = AggregatorLib.QMod - buf[30]; + buf[29] = AggregatorLib.QMod - buf[32]; + buf[30] = mulmod(buf[7], addmod(mulmod(addmod(mulmod(buf[23], transcript[49], AggregatorLib.QMod), mulmod(buf[26], transcript[50], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[21], transcript[49], AggregatorLib.QMod), mulmod(buf[29], transcript[50], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[30] = addmod(buf[30], addmod(mulmod(addmod(mulmod(buf[23], transcript[88], AggregatorLib.QMod), mulmod(buf[26], transcript[89], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[21], transcript[88], AggregatorLib.QMod), mulmod(buf[29], transcript[89], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[30] = addmod(mulmod(buf[7], buf[30], AggregatorLib.QMod), addmod(mulmod(addmod(mulmod(buf[23], transcript[90], AggregatorLib.QMod), mulmod(buf[26], transcript[91], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[21], transcript[90], AggregatorLib.QMod), mulmod(buf[29], transcript[91], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[30] = addmod(mulmod(buf[7], buf[30], AggregatorLib.QMod), addmod(mulmod(addmod(mulmod(buf[23], transcript[95], AggregatorLib.QMod), mulmod(buf[26], transcript[96], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(mulmod(buf[21], transcript[95], AggregatorLib.QMod), mulmod(buf[29], transcript[96], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[25] = mulmod(mulmod(buf[20], buf[25], AggregatorLib.QMod), buf[27], AggregatorLib.QMod); + buf[31] = AggregatorLib.FrDiv(1, addmod(buf[6], AggregatorLib.QMod - buf[24], AggregatorLib.QMod), aux[17]); + buf[32] = mulmod(buf[23], buf[31], AggregatorLib.QMod); + buf[34] = AggregatorLib.FrDiv(1, addmod(buf[19], AggregatorLib.QMod - buf[24], AggregatorLib.QMod), aux[18]); + buf[36] = mulmod(buf[26], buf[34], AggregatorLib.QMod); + buf[37] = AggregatorLib.FrDiv(1, addmod(buf[24], AggregatorLib.QMod - buf[6], AggregatorLib.QMod), aux[19]); + buf[38] = AggregatorLib.FrDiv(1, addmod(buf[24], AggregatorLib.QMod - buf[19], AggregatorLib.QMod), aux[20]); + buf[39] = mulmod(buf[37], buf[38], AggregatorLib.QMod); + buf[40] = mulmod(buf[31], buf[24], AggregatorLib.QMod); + buf[23] = addmod(mulmod(buf[21], buf[31], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[23], buf[40], AggregatorLib.QMod), AggregatorLib.QMod); + buf[24] = mulmod(buf[34], buf[24], AggregatorLib.QMod); + buf[26] = addmod(mulmod(buf[29], buf[34], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[26], buf[24], AggregatorLib.QMod), AggregatorLib.QMod); + buf[31] = AggregatorLib.QMod - mulmod(buf[37], buf[6], AggregatorLib.QMod); + buf[19] = mulmod(buf[38], buf[19], AggregatorLib.QMod); + buf[34] = addmod(mulmod(buf[31], buf[38], AggregatorLib.QMod), AggregatorLib.QMod - mulmod(buf[37], buf[19], AggregatorLib.QMod), AggregatorLib.QMod); + buf[37] = addmod(mulmod(addmod(addmod(mulmod(buf[32], transcript[52], AggregatorLib.QMod), mulmod(buf[36], transcript[55], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[39], transcript[57], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[23], transcript[52], AggregatorLib.QMod), mulmod(buf[26], transcript[55], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[34], transcript[57], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[21] = AggregatorLib.QMod - mulmod(buf[21], buf[40], AggregatorLib.QMod); + buf[24] = AggregatorLib.QMod - mulmod(buf[29], buf[24], AggregatorLib.QMod); + buf[19] = AggregatorLib.QMod - mulmod(buf[31], buf[19], AggregatorLib.QMod); + buf[29] = mulmod(buf[7], addmod(mulmod(buf[37], buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[21], transcript[52], AggregatorLib.QMod), mulmod(buf[24], transcript[55], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[19], transcript[57], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[23] = addmod(mulmod(addmod(addmod(mulmod(buf[32], transcript[53], AggregatorLib.QMod), mulmod(buf[36], transcript[54], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[39], transcript[56], AggregatorLib.QMod), AggregatorLib.QMod), buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[23], transcript[53], AggregatorLib.QMod), mulmod(buf[26], transcript[54], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[34], transcript[56], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[19] = addmod(buf[29], addmod(mulmod(buf[23], buf[9], AggregatorLib.QMod), addmod(addmod(mulmod(buf[21], transcript[53], AggregatorLib.QMod), mulmod(buf[24], transcript[54], AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[19], transcript[56], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod); + buf[20] = mulmod(buf[20], buf[27], AggregatorLib.QMod); + buf[18] = addmod(mulmod(buf[8], addmod(mulmod(buf[8], buf[18], AggregatorLib.QMod), mulmod(buf[30], buf[25], AggregatorLib.QMod), AggregatorLib.QMod), AggregatorLib.QMod), mulmod(buf[19], buf[20], AggregatorLib.QMod), AggregatorLib.QMod); (buf[12], buf[13]) = (1, "21888242871839275222246405745257275088696311157297823662689037894645226208581"); buf[14] = buf[18]; - AggregatorLib.EccMul(buf, 12); - buf[19] = mulmod(buf[8], buf[8], AggregatorLib.QMod.DecToUInt256()); - buf[21] = mulmod(buf[19], buf[33], AggregatorLib.QMod.DecToUInt256()); - buf[23] = mulmod(buf[7], buf[7], AggregatorLib.QMod.DecToUInt256()); - buf[24] = mulmod(buf[23], buf[23], AggregatorLib.QMod.DecToUInt256()); - buf[26] = mulmod(buf[24], buf[24], AggregatorLib.QMod.DecToUInt256()); - buf[27] = mulmod(buf[26], buf[26], AggregatorLib.QMod.DecToUInt256()); - buf[29] = mulmod(buf[27], buf[26], AggregatorLib.QMod.DecToUInt256()); - buf[30] = mulmod(buf[29], buf[24], AggregatorLib.QMod.DecToUInt256()); + Context.EccMul(buf, 12); + buf[19] = mulmod(buf[8], buf[8], AggregatorLib.QMod); + buf[21] = mulmod(buf[19], buf[33], AggregatorLib.QMod); + buf[23] = mulmod(buf[7], buf[7], AggregatorLib.QMod); + buf[24] = mulmod(buf[23], buf[23], AggregatorLib.QMod); + buf[26] = mulmod(buf[24], buf[24], AggregatorLib.QMod); + buf[27] = mulmod(buf[26], buf[26], AggregatorLib.QMod); + buf[29] = mulmod(buf[27], buf[26], AggregatorLib.QMod); + buf[30] = mulmod(buf[29], buf[24], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[0], transcript[1]); - buf[16] = mulmod(buf[21], buf[30], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[31] = mulmod(buf[29], buf[23], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[30], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[31] = mulmod(buf[29], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[2], transcript[3]); - buf[16] = mulmod(buf[21], mulmod(buf[31], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[31], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[4], transcript[5]); - buf[16] = mulmod(buf[21], buf[31], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[31], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[6], transcript[7]); - buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[25] = mulmod(buf[8], buf[25], AggregatorLib.QMod.DecToUInt256()); - buf[31] = mulmod(buf[23], buf[7], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[25] = mulmod(buf[8], buf[25], AggregatorLib.QMod); + buf[31] = mulmod(buf[23], buf[7], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[8], transcript[9]); - buf[16] = mulmod(buf[25], buf[31], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[25], buf[31], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[10], transcript[11]); - buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[12], transcript[13]); - buf[16] = mulmod(buf[20], buf[7], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[20], buf[7], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[14], transcript[15]); buf[16] = buf[20]; - AggregatorLib.EccMulAdd(buf, 12); - buf[20] = mulmod(buf[27], buf[23], AggregatorLib.QMod.DecToUInt256()); + Context.EccMulAdd(buf, 12); + buf[20] = mulmod(buf[27], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = ("1207916945929808976270526282053854023692542739230000272873644015185793296368", "333655719733869244917384316784707989805538463000414489296314654544293187643"); - buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("618231491944314346890471681224521967871683178752309602681515366098407374206", "1547106910999542710330303205205471910035673487471512416409330152033984213442"); - buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[20] = mulmod(buf[26], buf[24], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[20] = mulmod(buf[26], buf[24], AggregatorLib.QMod); (buf[14], buf[15]) = ("13752304032751265773388568368690952313346373847818030355565198504575163252857", "15699138031843585527795027222357271693964445904506796528039783746896944572576"); - buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[29] = mulmod(buf[26], buf[23], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[29] = mulmod(buf[26], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = ("2860348938008516295342440148193198092510420690025470368433071928276330127666", "13798530407527146344832081201325939484315000250653330040095163163962642066101"); - buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("14390479789872834578949877445376305228054722011348207550893776286663419046557", "7204047301065162098259616074187017654572163314399050595428908522796007253977"); - buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("1056833256995721181794313947859361700675613255846609013688782956441439749526", "17440597018953292249182049648101858573256400831921081203912808720604993487466"); - buf[16] = mulmod(buf[21], mulmod(buf[27], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[27], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("19207819916323799140539471238781937247533258479342753136419754431371864139220", "16398977035358673033090553616272584516942365359189763094905189335216399893048"); - buf[16] = mulmod(buf[21], buf[27], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[29] = mulmod(buf[20], buf[23], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[27], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[29] = mulmod(buf[20], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = ("18727268301254709837695561754430743811087178758994984866708998369335881794533", "5771006186783366108295805589828141419604675726535405645756208294112833055471"); - buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[29], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("8138420147872156333568125149467446041279298081497883420825913745857062420523", "13762450858016313545220019976563322968787227888972373523931845640799616686811"); - buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[29], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("13185867370215857208233387398040674400951489463742865783616623073151330329078", "3425883033867904231216730370053158898252175086457454738743683903644612966450"); - buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[20] = mulmod(buf[27], buf[24], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[20] = mulmod(buf[27], buf[24], AggregatorLib.QMod); (buf[14], buf[15]) = ("5809572897051189800056996065867944735828542713732596853907077380342000849224", "5770846417600899713009281105485305066210413547630759524415184441167035618969"); - buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("6378528853177786953117877890334142316482148143584178844724641201426346328155", "5124809223360507647814097145822761234530657230711863107799398382998817945911"); - buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("4936480706874911535373942394288673968130019275904758918617335440689668378821", "11933485432519003463128255408773500258400241194032466008744285015256152846462"); - buf[16] = mulmod(buf[21], mulmod(buf[26], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[26], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[100], transcript[101]); - buf[16] = AggregatorLib.QMod.DecToUInt256() - mulmod(mulmod(buf[17], addmod(buf[9], AggregatorLib.QMod.DecToUInt256() - buf[6], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()), buf[22], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = AggregatorLib.QMod - mulmod(mulmod(buf[17], addmod(buf[9], AggregatorLib.QMod - buf[6], AggregatorLib.QMod), AggregatorLib.QMod), buf[22], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[102], transcript[103]); buf[16] = buf[9]; - AggregatorLib.EccMulAdd(buf, 12); - buf[17] = mulmod(buf[21], buf[7], AggregatorLib.QMod.DecToUInt256()); + Context.EccMulAdd(buf, 12); + buf[17] = mulmod(buf[21], buf[7], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[42], transcript[43]); - buf[16] = mulmod(buf[17], mulmod(buf[35], buf[35], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[17], mulmod(buf[35], buf[35], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); // @formatter:on return buf; diff --git a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep3.cs b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep3.cs index 9f5811fabe..35eec0ac49 100644 --- a/contract/ZkWasmVerifier/AggregatorVerifierCoreStep3.cs +++ b/contract/ZkWasmVerifier/AggregatorVerifierCoreStep3.cs @@ -1,83 +1,84 @@ -using Bn254.Net; +using AElf.Types; +using ZkWasmVerifier; -namespace ZkWasmVerifier; +namespace AElf.Contracts.ZkWasmVerifier; -public class AggregatorVerifierCoreStep3 : IAggregatorVerifierCoreStep +public partial class ZkWasmVerifier { - public UInt256[] VerifyProof(UInt256[] transcript, UInt256[] aux, UInt256[] buf) + public BigIntValue[] VerifyProofStep3(BigIntValue[] transcript, BigIntValue[] aux, BigIntValue[] buf) { // @formatter:off - var mulmod = (UInt256 a, UInt256 b, UInt256 m) => (a * b) % m; - var addmod = (UInt256 a, UInt256 b, UInt256 m) => (a + b) % m; + var mulmod = (BigIntValue a, BigIntValue b, BigIntValue m) => (a * b) % m; + var addmod = (BigIntValue a, BigIntValue b, BigIntValue m) => (a + b) % m; (buf[14], buf[15]) = (transcript[40], transcript[41]); - buf[16] = mulmod(buf[17], buf[35], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[17], buf[35], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[38], transcript[39]); buf[16] = buf[17]; - AggregatorLib.EccMulAdd(buf, 12); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (buf[0], buf[1]); - buf[16] = mulmod(buf[21], mulmod(buf[30], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[17] = mulmod(mulmod(buf[19], buf[8], AggregatorLib.QMod.DecToUInt256()), buf[28], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], mulmod(buf[30], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[17] = mulmod(mulmod(buf[19], buf[8], AggregatorLib.QMod), buf[28], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[16], transcript[17]); - buf[16] = mulmod(buf[17], buf[7], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[20] = mulmod(buf[20], buf[23], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[17], buf[7], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[20] = mulmod(buf[20], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[18], transcript[19]); - buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[20], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[32], transcript[33]); - buf[16] = mulmod(buf[25], buf[7], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[25], buf[7], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[20], transcript[21]); buf[16] = buf[17]; - AggregatorLib.EccMulAdd(buf, 12); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[22], transcript[23]); - buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[20], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[34], transcript[35]); buf[16] = buf[25]; - AggregatorLib.EccMulAdd(buf, 12); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("13292207742358048193363903155311282303694990999153147378260744839175179844272", "8069646990961401522004619706042590276391180087782205971002027097172883400355"); - buf[16] = mulmod(buf[21], buf[26], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[17] = mulmod(buf[24], buf[23], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[26], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[17] = mulmod(buf[24], buf[23], AggregatorLib.QMod); (buf[14], buf[15]) = ("16962709593911359056643584098658643393752005484223049643104296353822683710608", "10559423757078030678373057222882755533496505850657344541786773871445981479972"); - buf[16] = mulmod(buf[21], mulmod(buf[17], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[17], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("1289930964916810258948649523842583935162163198616891195090185552481132662306", "9349427207481746847457819049174580746099595602688060645669692066778067157287"); - buf[16] = mulmod(buf[21], buf[17], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[17], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("13027342631838746326863822286082389694409544498995811462671038670568858108891", "5047939170640162610161164136085743909314737380382289915607715473538237141482"); - buf[16] = mulmod(buf[21], mulmod(buf[24], buf[7], AggregatorLib.QMod.DecToUInt256()), AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], mulmod(buf[24], buf[7], AggregatorLib.QMod), AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("4202332094118111758910265968032668730009038512388316357931820855479441638624", "14227708779289885609649995391374967451355616790242748385077714572462384655123"); - buf[16] = mulmod(buf[21], buf[24], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[24], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("9230882410532336358822556144187239116196302704399492952375596356113985875521", "13682064521086611398833038852259806568259918019163169600724810995458152518040"); - buf[16] = mulmod(buf[21], buf[31], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[21], buf[31], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = ("3410909432599015228817777153842470803679052023504007951748169347603737115779", "4278355855479791189030463433364613592289197199970447328585000204791248828073"); - buf[16] = mulmod(buf[21], buf[23], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); - buf[17] = mulmod(buf[19], buf[19], AggregatorLib.QMod.DecToUInt256()); + buf[16] = mulmod(buf[21], buf[23], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); + buf[17] = mulmod(buf[19], buf[19], AggregatorLib.QMod); (buf[14], buf[15]) = (transcript[24], transcript[25]); - buf[16] = mulmod(buf[17], buf[23], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[17], buf[23], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[26], transcript[27]); - buf[16] = mulmod(buf[17], buf[7], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[17], buf[7], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[28], transcript[29]); buf[16] = buf[17]; - AggregatorLib.EccMulAdd(buf, 12); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[30], transcript[31]); - buf[16] = mulmod(buf[25], buf[23], AggregatorLib.QMod.DecToUInt256()); - AggregatorLib.EccMulAdd(buf, 12); + buf[16] = mulmod(buf[25], buf[23], AggregatorLib.QMod); + Context.EccMulAdd(buf, 12); (buf[14], buf[15]) = (transcript[36], transcript[37]); buf[16] = buf[21]; - AggregatorLib.EccMulAdd(buf, 12); + Context.EccMulAdd(buf, 12); - UInt256[] ret = new UInt256[4]; + BigIntValue[] ret = new BigIntValue[4]; ret[0] = buf[10]; ret[1] = buf[11]; ret[2] = buf[12]; diff --git a/contract/ZkWasmVerifier/Extensions.cs b/contract/ZkWasmVerifier/Extensions.cs new file mode 100644 index 0000000000..b29a72b1ad --- /dev/null +++ b/contract/ZkWasmVerifier/Extensions.cs @@ -0,0 +1,23 @@ +using AElf.Types; + +namespace ZkWasmVerifier; + +public static class Extensions +{ + public static bool IsZero(this BigIntValue value) + { + return value.Value == "0"; + } + + public static byte[] ToBytes32(this BigIntValue value) + { + var bytes = value.ToBigEndianBytes(); + var newArray = new byte[32]; + for (int i = 0; i < bytes.Length; i++) + { + newArray[31 - i] = bytes[bytes.Length - 1 - i]; + } + + return newArray; + } +} \ No newline at end of file diff --git a/contract/ZkWasmVerifier/IAggregatorVerifierCoreStep.cs b/contract/ZkWasmVerifier/IAggregatorVerifierCoreStep.cs index 33c20e660d..a4096c6d7b 100644 --- a/contract/ZkWasmVerifier/IAggregatorVerifierCoreStep.cs +++ b/contract/ZkWasmVerifier/IAggregatorVerifierCoreStep.cs @@ -1,8 +1,8 @@ -using Bn254.Net; +using AElf.Types; namespace ZkWasmVerifier; public interface IAggregatorVerifierCoreStep { - UInt256[] VerifyProof(UInt256[] transcript, UInt256[] aux, UInt256[] buf); + BigIntValue[] VerifyProof(BigIntValue[] transcript, BigIntValue[] aux, BigIntValue[] buf); } \ No newline at end of file diff --git a/contract/ZkWasmVerifier/ZkWasmVerifier.cs b/contract/ZkWasmVerifier/ZkWasmVerifier.cs index c2f1b67378..492d19e551 100644 --- a/contract/ZkWasmVerifier/ZkWasmVerifier.cs +++ b/contract/ZkWasmVerifier/ZkWasmVerifier.cs @@ -1,49 +1,42 @@ -using System; using System.Linq; +using AElf.CSharp.Core; using AElf.Sdk.CSharp; -using Bn254.Net; +using AElf.Types; using Google.Protobuf.WellKnownTypes; using ZkWasmVerifier; namespace AElf.Contracts.ZkWasmVerifier { - public class ZkWasmVerifier : ZkWasmVerifierContainer.ZkWasmVerifierBase + public partial class ZkWasmVerifier : ZkWasmVerifierContainer.ZkWasmVerifierBase { public override Empty Verify(VerifyInput input) { - var steps = new Object[] - { - new AggregatorVerifierCoreStep1(), - new AggregatorVerifierCoreStep2(), - new AggregatorVerifierCoreStep3(), - }; - - var proof = input.Proof.Select(x => x.DecToUInt256()).ToArray(); - var aux = input.Aux.Select(x => x.DecToUInt256()).ToArray().ToArray(); - var verifyInstance = input.VerifyInstance.Select(x => x.DecToUInt256()).ToArray(); - var targetInstance = input.TargetInstance.Select(x => x.Value.Select(y => y.DecToUInt256()).ToArray()) + var proof = input.Proof.Select(x => (BigIntValue)x).ToArray(); + var aux = input.Aux.Select(x => (BigIntValue)x).ToArray().ToArray(); + var verifyInstance = input.VerifyInstance.Select(x => (BigIntValue)x).ToArray(); + var targetInstance = input.TargetInstance.Select(x => x.Value.Select(y => (BigIntValue)y).ToArray()) .ToArray(); - var buf = new UInt256[43]; + var buf = new BigIntValue[43]; var forCalulatingKeccakHash = targetInstance.SelectMany(x => x) .Concat(verifyInstance).ToArray(); - buf[2] = AggregatorLib.HashInstances(forCalulatingKeccakHash); + var hash = Context.Keccak256(forCalulatingKeccakHash.SelectMany(x => x.ToBytes32()).ToArray()); + buf[2] = BigIntValue.FromBigEndianBytes(hash).ModPow(1, AggregatorLib.QMod); - UInt256[] verifyCircuitPairingBuf = new UInt256[12]; + BigIntValue[] verifyCircuitPairingBuf = new BigIntValue[12]; { // step 1: calculate verify circuit instance commitment - AggregatorConfig.CalcVerifyCircuitLagrange(buf); + Context.CalcVerifyCircuitLagrange(buf); // step 2: calculate challenge // take transcript[0..102] // calculate challenges and store them in buf[0..10] - AggregatorConfig.GetChallenges(proof, buf); + Context.GetChallenges(proof, buf); // step 3: calculate verify circuit pair - foreach (var step in steps) - { - buf = ((IAggregatorVerifierCoreStep)step).VerifyProof(proof, aux, buf); - } + buf = VerifyProofStep1(proof, aux, buf); + buf = VerifyProofStep2(proof, aux, buf); + buf = VerifyProofStep3(proof, aux, buf); verifyCircuitPairingBuf[0] = buf[0]; verifyCircuitPairingBuf[1] = buf[1]; @@ -61,7 +54,7 @@ public override Empty Verify(VerifyInput input) } var checked_ = false; AggregatorConfig.FillVerifyCircuitsG2(verifyCircuitPairingBuf); - checked_ = AggregatorLib.Pairing(verifyCircuitPairingBuf); + checked_ = Context.Pairing(verifyCircuitPairingBuf); if (!checked_) { throw new AssertionException("pairing check failed"); diff --git a/contract/ZkWasmVerifier/ZkWasmVerifier.csproj b/contract/ZkWasmVerifier/ZkWasmVerifier.csproj index f52605e022..e85e3585e9 100644 --- a/contract/ZkWasmVerifier/ZkWasmVerifier.csproj +++ b/contract/ZkWasmVerifier/ZkWasmVerifier.csproj @@ -3,10 +3,11 @@ - net6.0 + net8.0 ZkWasmVerifier true An on-chain verifier for Zk-Wasm proof. + AElf.Contracts.ZkWasmVerifier @@ -49,9 +50,9 @@ - - - - + + + + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 14baea36ad..1d1b2aca06 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -9,4 +9,3 @@ services: - 8001:8000 volumes: - /opt:/opt - diff --git a/docker/start-cli.sh b/docker/start-cli.sh index e5bcf63182..daaf665766 100755 --- a/docker/start-cli.sh +++ b/docker/start-cli.sh @@ -2,4 +2,3 @@ BIND_VOLUME='-v /opt:/opt' CONFIGURE_PATH='-w /opt/aelf-node' docker run -it --rm $BIND_VOLUME $CONFIGURE_PATH aelf/node - diff --git a/docker/start-node.sh b/docker/start-node.sh index a63b5c9798..b258ddaee4 100755 --- a/docker/start-node.sh +++ b/docker/start-node.sh @@ -2,4 +2,4 @@ PUBLISH_PORT='-p 6800:6800 -p 8000:8000' BIND_VOLUME='-v /opt:/opt' CONfIGURE_PATH='/opt/aelf-node' -docker run -itd $PUBLISH_PORT $BIND_VOLUME -w $CONfIGURE_PATH aelf/node dotnet /app/AElf.Launcher.dll --config.path $CONfIGURE_PATH +docker run -itd $PUBLISH_PORT $BIND_VOLUME -w $CONfIGURE_PATH aelf/node dotnet /app/AElf.Launcher.dll --config.path $CONfIGURE_PATH \ No newline at end of file diff --git a/docs-sphinx/architecture/smart-contract/restrictions/project.md b/docs-sphinx/architecture/smart-contract/restrictions/project.md index a5a2fbe591..93236cb1b6 100644 --- a/docs-sphinx/architecture/smart-contract/restrictions/project.md +++ b/docs-sphinx/architecture/smart-contract/restrictions/project.md @@ -5,7 +5,7 @@ ```xml - net6.0 + net8.0 AElf.Contracts.MyContract true diff --git a/docs-sphinx/index.rst b/docs-sphinx/index.rst index 83e9ac6929..3cff784021 100644 --- a/docs-sphinx/index.rst +++ b/docs-sphinx/index.rst @@ -78,4 +78,4 @@ Welcome to AElf's official documentation! tutorials/cross-chain/running-side-chain tutorials/__run-node - getting-started/smart-contract-development/developing-smart-contracts/index + getting-started/smart-contract-development/developing-smart-contracts/index \ No newline at end of file diff --git a/docs/contract/restrictions/project.md b/docs/contract/restrictions/project.md index 73bd5b3f59..92734ddb9d 100644 --- a/docs/contract/restrictions/project.md +++ b/docs/contract/restrictions/project.md @@ -5,7 +5,7 @@ ```xml - net6.0 + net8.0 AElf.Contracts.MyContract true true diff --git a/docs/main-structure.md b/docs/main-structure.md index ba12f8e728..a079e012fe 100644 --- a/docs/main-structure.md +++ b/docs/main-structure.md @@ -88,4 +88,4 @@ * [Google cloud](resources/cloud/gcp/GCP.md) * [Browser Extension](resources/browser-extension.md) * [Joining AElf's testnet](resources/testnet.md) - * [Running a side chain](tutorials/cross-chain/running-side-chain.md) + * [Running a side chain](tutorials/cross-chain/running-side-chain.md) \ No newline at end of file diff --git a/global.json b/global.json new file mode 100644 index 0000000000..1978c843c7 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "8.0.303" + } +} \ No newline at end of file diff --git a/nuget.config b/nuget.config index 38a5ad4dca..d611874736 100644 --- a/nuget.config +++ b/nuget.config @@ -2,5 +2,6 @@ + \ No newline at end of file diff --git a/protobuf/acs3.proto b/protobuf/acs3.proto index 65ee66e8ac..79b3391202 100644 --- a/protobuf/acs3.proto +++ b/protobuf/acs3.proto @@ -90,6 +90,10 @@ message CreateProposalInput { string proposal_description_url = 6; // The token is for proposal id generation and with this token, proposal id can be calculated before proposing. aelf.Hash token = 7; + // Title of this proposal. + string title = 8; + // Description of this proposal. + string description = 9; } message ProposalOutput { @@ -115,6 +119,10 @@ message ProposalOutput { int64 rejection_count = 10; // Abstention count for this proposal. int64 abstention_count = 11; + // Title of this proposal. + string title = 12; + // Description of this proposal. + string description = 13; } message ProposalReleaseThreshold { @@ -159,7 +167,11 @@ message ProposalCreated{ // The id of the created proposal. aelf.Hash proposal_id = 1; // The organization address of the created proposal. - aelf.Address organization_address=2 [(aelf.is_indexed) = true]; + aelf.Address organization_address = 2 [(aelf.is_indexed) = true]; + // Title of this proposal. + string title = 3; + // Description of this proposal. + string description = 4; } message ProposalReleased{ @@ -168,6 +180,10 @@ message ProposalReleased{ aelf.Hash proposal_id = 1; // The organization address of the released proposal. aelf.Address organization_address=2 [(aelf.is_indexed) = true]; + // Title of this proposal. + string title = 3; + // Description of this proposal. + string description = 4; } message OrganizationCreated{ diff --git a/protobuf/aelf/core.proto b/protobuf/aelf/core.proto index c990aa9df6..e45d7e581d 100644 --- a/protobuf/aelf/core.proto +++ b/protobuf/aelf/core.proto @@ -72,6 +72,15 @@ message TransactionResult { string error = 10; } +message InvalidTransactionResult{ + // The transaction id. + Hash transaction_id = 1; + // The transaction result status. + TransactionResultStatus status = 2; + // Failed execution error message. + string error = 3; +} + message LogEvent { // The contract address. Address address = 1; diff --git a/protobuf/association_contract.proto b/protobuf/association_contract.proto index 2efb8210c6..5b2a78e2b7 100644 --- a/protobuf/association_contract.proto +++ b/protobuf/association_contract.proto @@ -96,6 +96,10 @@ message ProposalInfo { repeated aelf.Address abstentions = 10; // Url is used for proposal describing. string proposal_description_url = 11; + // Title of this proposal. + string title = 12; + // Description of this proposal. + string description = 13; } message OrganizationMemberList { diff --git a/protobuf/basic_contract_zero.proto b/protobuf/basic_contract_zero.proto index 30960f8433..0967cf866d 100644 --- a/protobuf/basic_contract_zero.proto +++ b/protobuf/basic_contract_zero.proto @@ -37,6 +37,9 @@ service BasicContractZero { rpc SetContractProposalExpirationTimePeriod(SetContractProposalExpirationTimePeriodInput) returns(google.protobuf.Empty){ } + + rpc SetCodeCheckProposalExpirationTimePeriod(google.protobuf.Int32Value) returns(google.protobuf.Empty){ + } // Query the ContractDeploymentController authority info. rpc GetContractDeploymentController (google.protobuf.Empty) returns (AuthorityInfo) { @@ -51,6 +54,10 @@ service BasicContractZero { rpc GetContractProposalExpirationTimePeriod(google.protobuf.Empty) returns (google.protobuf.Int32Value){ option (aelf.is_view) = true; } + + rpc GetCodeCheckProposalExpirationTimePeriod(google.protobuf.Empty) returns (google.protobuf.Int32Value){ + option (aelf.is_view) = true; + } } message InitializeInput{ diff --git a/protobuf/parliament_contract.proto b/protobuf/parliament_contract.proto index e5d2ef4422..8d0fca5bef 100644 --- a/protobuf/parliament_contract.proto +++ b/protobuf/parliament_contract.proto @@ -136,6 +136,10 @@ message ProposalInfo { repeated aelf.Address abstentions = 10; // Url is used for proposal describing. string proposal_description_url = 11; + // Title of this proposal. + string title = 12; + // Description of this proposal. + string description = 13; } message InitializeInput{ diff --git a/protobuf/profit_contract.proto b/protobuf/profit_contract.proto index 1326da62ff..aac44f2d6a 100644 --- a/protobuf/profit_contract.proto +++ b/protobuf/profit_contract.proto @@ -63,6 +63,9 @@ service ProfitContract { // Reset the manager of a scheme. rpc ResetManager (ResetManagerInput) returns (google.protobuf.Empty) { } + + rpc SetMaximumProfitReceivingPeriodCount(google.protobuf.Int32Value) returns (google.protobuf.Empty) { + } // Get all schemes managed by the specified manager. rpc GetManagingSchemeIds (GetManagingSchemeIdsInput) returns (CreatedSchemeIds) { @@ -93,11 +96,25 @@ service ProfitContract { rpc GetProfitAmount (GetProfitAmountInput) returns (google.protobuf.Int64Value) { option (aelf.is_view) = true; } + + // Query the amount of profit according to token symbol. + rpc GetAllProfitAmount (GetAllProfitAmountInput) returns (GetAllProfitAmountOutput) { + option (aelf.is_view) = true; + } // Query all profit (up to 10 periods). rpc GetProfitsMap (ClaimProfitsInput) returns (ReceivedProfitsMap) { option (aelf.is_view) = true; } + + // Query all profit. + rpc GetAllProfitsMap (GetAllProfitsMapInput) returns (GetAllProfitsMapOutput) { + option (aelf.is_view) = true; + } + + rpc GetMaximumProfitReceivingPeriodCount(google.protobuf.Empty) returns (google.protobuf.Int32Value) { + option (aelf.is_view) = true; + } } message CreateSchemeInput { @@ -308,11 +325,39 @@ message GetProfitAmountInput { aelf.Address beneficiary = 3; } +message GetAllProfitAmountInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The token symbol. + string symbol = 2; + // The beneficiary's address. + aelf.Address beneficiary = 3; +} + +message GetAllProfitAmountOutput{ + int64 all_profit_amount = 1; + int64 one_time_claimable_profit_amount = 2; +} + message ReceivedProfitsMap { // The collection of profits received, token symbol -> amount. map value = 1; } +message GetAllProfitsMapInput { + // The scheme id. + aelf.Hash scheme_id = 1; + // The address of beneficiary. + aelf.Address beneficiary = 2; +} + +message GetAllProfitsMapOutput { + // The collection of all profits received, token symbol -> amount. + map all_profits_map = 1; + // The collection of claimable profits received, token symbol -> amount. + map one_time_claimable_profits_map = 2; +} + message SchemeCreated { option (aelf.is_event) = true; // The virtual address of the created scheme. diff --git a/protobuf/referendum_contract.proto b/protobuf/referendum_contract.proto index 82af016f13..53bb243b6e 100644 --- a/protobuf/referendum_contract.proto +++ b/protobuf/referendum_contract.proto @@ -101,6 +101,10 @@ message ProposalInfo { int64 abstention_count = 10; // Url is used for proposal describing. string proposal_description_url = 11; + // Title of this proposal. + string title = 12; + // Description of this proposal. + string description = 13; } message CreateOrganizationBySystemContractInput { diff --git a/protobuf/token_contract.proto b/protobuf/token_contract.proto index 5082990a99..9931b680a3 100644 --- a/protobuf/token_contract.proto +++ b/protobuf/token_contract.proto @@ -40,7 +40,10 @@ service TokenContract { // enabling the Spender to call TransferFrom. rpc Approve (ApproveInput) returns (google.protobuf.Empty) { } - + + rpc BatchApprove (BatchApproveInput) returns (google.protobuf.Empty) { + } + // This is the reverse operation for Approve, it will decrease the allowance. rpc UnApprove (UnApproveInput) returns (google.protobuf.Empty) { } @@ -141,6 +144,9 @@ service TokenContract { rpc RemoveTransactionFeeDelegatee (RemoveTransactionFeeDelegateeInput) returns (google.protobuf.Empty){ } + rpc SetSymbolAlias (SetSymbolAliasInput) returns (google.protobuf.Empty){ + } + // Get all delegatees' address of delegator from input rpc GetTransactionFeeDelegatees (GetTransactionFeeDelegateesInput) returns (GetTransactionFeeDelegateesOutput) { option (aelf.is_view) = true; @@ -171,6 +177,11 @@ service TokenContract { option (aelf.is_view) = true; } + // Query the account's available allowance for other addresses + rpc GetAvailableAllowance (GetAllowanceInput) returns (GetAllowanceOutput) { + option (aelf.is_view) = true; + } + // Check whether the token is in the whitelist of an address, // which can be called TransferFrom to transfer the token under the condition of not being credited. rpc IsInWhiteList (IsInWhiteListInput) returns (google.protobuf.BoolValue) { @@ -226,6 +237,14 @@ service TokenContract { rpc GetTransactionFeeDelegationsOfADelegatee(GetTransactionFeeDelegationsOfADelegateeInput) returns(TransactionFeeDelegations){ option (aelf.is_view) = true; } + + rpc GetTokenAlias (google.protobuf.StringValue) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } + + rpc GetSymbolByAlias (google.protobuf.StringValue) returns (google.protobuf.StringValue) { + option (aelf.is_view) = true; + } } message TokenInfo { @@ -354,6 +373,9 @@ message ApproveInput { // The amount of token to approve. int64 amount = 3; } +message BatchApproveInput { + repeated ApproveInput value = 1; +} message UnApproveInput { // The address that allowance will be decreased. @@ -632,19 +654,6 @@ message TotalResourceTokensMap map value = 1; } -message ChangeTokenIssuerInput -{ - // The token symbol. - string symbol = 1; - // The new token issuer for change. - aelf.Address new_token_Issuer = 2; -} - -message ResetExternalInfoInput { - string symbol = 1; - ExternalInfo external_info = 2; -} - message StringList { repeated string value = 1; } @@ -696,6 +705,11 @@ message GetTransactionFeeDelegateesOutput { repeated aelf.Address delegatee_addresses = 1; } +message SetSymbolAliasInput { + string symbol = 1; + string alias = 2; +} + // Events message Transferred { @@ -853,12 +867,6 @@ message CrossChainReceived { aelf.Hash transfer_transaction_id =9; } -message ExternalInfoChanged { - option (aelf.is_event) = true; - string symbol = 1; - ExternalInfo external_info = 2; -} - message TransactionFeeDelegationAdded { option (aelf.is_event) = true; aelf.Address delegator = 1 [(aelf.is_indexed) = true]; @@ -871,4 +879,16 @@ message TransactionFeeDelegationCancelled { aelf.Address delegator = 1 [(aelf.is_indexed) = true]; aelf.Address delegatee = 2 [(aelf.is_indexed) = true]; aelf.Address caller = 3 [(aelf.is_indexed) = true]; +} + +message SymbolAliasAdded { + option (aelf.is_event) = true; + string symbol = 1 [(aelf.is_indexed) = true]; + string alias = 2 [(aelf.is_indexed) = true]; +} + +message SymbolAliasDeleted { + option (aelf.is_event) = true; + string symbol = 1 [(aelf.is_indexed) = true]; + string alias = 2 [(aelf.is_indexed) = true]; } \ No newline at end of file diff --git a/protobuf/token_contract_impl.proto b/protobuf/token_contract_impl.proto index 97acd5b439..5885914e80 100644 --- a/protobuf/token_contract_impl.proto +++ b/protobuf/token_contract_impl.proto @@ -83,6 +83,11 @@ service TokenContractImpl { rpc RemoveTransactionFeeFreeAllowancesConfig (RemoveTransactionFeeFreeAllowancesConfigInput) returns (google.protobuf.Empty) { } + rpc SetMaxBatchApproveCount (google.protobuf.Int32Value) returns (google.protobuf.Empty) { + + } + + // Delegatee sets the delegation and related information of the delegator based on a transaction. rpc SetTransactionFeeDelegateInfos (SetTransactionFeeDelegateInfosInput) returns (google.protobuf.Empty){ } @@ -163,6 +168,20 @@ service TokenContractImpl { rpc GetTransactionFeeDelegateInfo(GetTransactionFeeDelegateInfoInput) returns (token.TransactionFeeDelegations){ option (aelf.is_view) = true; } + + rpc ModifyTokenIssuerAndOwner(ModifyTokenIssuerAndOwnerInput) returns (google.protobuf.Empty) { + } + + rpc SetTokenIssuerAndOwnerModificationEnabled(SetTokenIssuerAndOwnerModificationEnabledInput) returns (google.protobuf.Empty) { + } + + rpc GetTokenIssuerAndOwnerModificationEnabled(google.protobuf.Empty) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } + + rpc GetMaxBatchApproveCount (google.protobuf.Empty) returns (google.protobuf.Int32Value) { + + } } message AdvanceResourceTokenInput { @@ -416,3 +435,13 @@ message TransactionFeeDelegateInfoCancelled { aelf.Address caller = 3 ; DelegateTransactionList delegate_transaction_list = 4; } + +message ModifyTokenIssuerAndOwnerInput { + string symbol = 1; + aelf.Address issuer = 2; + aelf.Address owner = 3; +} + +message SetTokenIssuerAndOwnerModificationEnabledInput{ + bool enabled = 1; +} \ No newline at end of file diff --git a/protobuf/token_converter_contract.proto b/protobuf/token_converter_contract.proto index af6e99c10c..5f92194185 100644 --- a/protobuf/token_converter_contract.proto +++ b/protobuf/token_converter_contract.proto @@ -51,7 +51,10 @@ service TokenConverterContract { // Set the governance authority information for TokenConvert contract. rpc ChangeConnectorController (AuthorityInfo) returns (google.protobuf.Empty) { } - + + rpc MigrateConnectorTokens (google.protobuf.Empty) returns (google.protobuf.Empty) { + } + // Query the pair connector according to token symbol. rpc GetPairConnector (TokenSymbol) returns (PairConnector) { option (aelf.is_view) = true; diff --git a/protobuf/zk_tree_verifier_contract.proto b/protobuf/zk_tree_verifier_contract.proto new file mode 100644 index 0000000000..4bf29295c5 --- /dev/null +++ b/protobuf/zk_tree_verifier_contract.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +import "aelf/options.proto"; +import "google/protobuf/wrappers.proto"; +// The namespace of this class +option csharp_namespace = "AElf.Contracts.ZkTreeVerifier"; + +service ZkTreeVerifier { + // The name of the state class the smart contract is going to use to access blockchain state + option (aelf.csharp_state) = "AElf.Contracts.ZkTreeVerifier.ZkTreeVerifierState"; + + // Views (methods that don't modify contract state) + // Get the value stored from contract state + rpc VerifyProof (VerifyProofInput) returns (google.protobuf.BoolValue) { + option (aelf.is_view) = true; + } +} + +// An event that will be emitted from contract method call +message VerifyProofInput { + message G1Point { + string x = 1; + string y = 2; + } + message Fp2 { + string first = 1; + string second = 2; + } + message G2Point { + Fp2 x = 1; + Fp2 y = 2; + } + message Proof { + G1Point a = 1; + G2Point b = 2; + G1Point c = 3; + } + Proof proof = 1; + repeated string input = 2; +} \ No newline at end of file diff --git a/protobuf/zk_wasm_game_contract.proto b/protobuf/zk_wasm_game_contract.proto new file mode 100644 index 0000000000..f32a77805d --- /dev/null +++ b/protobuf/zk_wasm_game_contract.proto @@ -0,0 +1,44 @@ +syntax = "proto3"; + +import "aelf/core.proto"; +import "aelf/options.proto"; +import "google/protobuf/empty.proto"; +import "google/protobuf/wrappers.proto"; +// The namespace of this class +option csharp_namespace = "AElf.Contracts.ZkWasmGame"; + +service ZkWasmGame { + // The name of the state class the smart contract is going to use to access blockchain state + option (aelf.csharp_state) = "AElf.Contracts.ZkWasmGame.ZkWasmGameState"; + + // Actions (methods that modify contract state) + // Stores the value in contract state + rpc SubmitGame (SubmitGameInput) returns (google.protobuf.Empty) { + } + + rpc SetVerifier (aelf.Address) returns (google.protobuf.Empty) { + } + + // Views + rpc GetVerifier(google.protobuf.Empty) returns (aelf.Address) { + option (aelf.is_view) = true; + } + rpc GetGameState(google.protobuf.Empty) returns (GameState) { + option (aelf.is_view) = true; + } +} + +message GameState { + string total_steps = 1; + string current_position = 2; +} + +message SubmitGameInput { + repeated string proof = 1; + repeated string verifyInstance = 2; + repeated string aux = 3; + repeated StringArray targetInstance = 4; + message StringArray { + repeated string value = 1; + } +} \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh index 83356576d6..f614ac0aaa 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -6,4 +6,4 @@ dotnet build /clp:ErrorsOnly /p:GeneratePackageOnBuild=false -v quiet "AElf.All. if [[ $? -ne 0 ]] ; then echo "Build failed." exit 1 -fi +fi \ No newline at end of file diff --git a/scripts/deploy_docker.sh b/scripts/deploy_docker.sh index 3224bfb7ad..e7a768efdb 100644 --- a/scripts/deploy_docker.sh +++ b/scripts/deploy_docker.sh @@ -13,4 +13,4 @@ docker build -t aelf/node:${TAG} ~/aelf/. docker tag aelf/node:${TAG} aelf/node:latest docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" docker push aelf/node:${TAG} -docker push aelf/node:latest +docker push aelf/node:latest \ No newline at end of file diff --git a/scripts/deploy_myget.sh b/scripts/deploy_myget.sh index 0931a825cf..09b26015ca 100644 --- a/scripts/deploy_myget.sh +++ b/scripts/deploy_myget.sh @@ -31,4 +31,4 @@ do fi done cd ../ -done +done \ No newline at end of file diff --git a/scripts/deploy_myget_daily.sh b/scripts/deploy_myget_daily.sh index 4843b3f7ab..b6916f79b2 100644 --- a/scripts/deploy_myget_daily.sh +++ b/scripts/deploy_myget_daily.sh @@ -34,4 +34,4 @@ do fi done cd ../ -done +done \ No newline at end of file diff --git a/scripts/deploy_nuget.sh b/scripts/deploy_nuget.sh index 0fdc981c3e..ef9f49c37d 100644 --- a/scripts/deploy_nuget.sh +++ b/scripts/deploy_nuget.sh @@ -31,4 +31,4 @@ do fi done cd ../ -done +done \ No newline at end of file diff --git a/scripts/download_binary.bat b/scripts/download_binary.bat index 02382a3bb9..7ec3dc18ca 100644 --- a/scripts/download_binary.bat +++ b/scripts/download_binary.bat @@ -13,4 +13,4 @@ if not exist "%scriptdir%contract_csharp_plugin.exe" ( ) echo "unzip file: %file%" unzip %scriptdir%%filename% -d %scriptdir% -) +) \ No newline at end of file diff --git a/scripts/download_binary.sh b/scripts/download_binary.sh index 49b8fdbe77..0234693718 100644 --- a/scripts/download_binary.sh +++ b/scripts/download_binary.sh @@ -30,4 +30,4 @@ if [[ ! -f ${plugin} ]]; then # Unzip unzip -o ${filename} -d "${scriptdir}" -fi +fi \ No newline at end of file diff --git a/scripts/generate_contract_base.bat b/scripts/generate_contract_base.bat index 57ca166469..ed022fa2c9 100644 --- a/scripts/generate_contract_base.bat +++ b/scripts/generate_contract_base.bat @@ -8,4 +8,4 @@ protoc --proto_path=../../protobuf ^ --contract_opt=%2,nocontract ^ --contract_out=./Protobuf/Generated ^ --plugin=protoc-gen-contract="%scriptdir%contract_csharp_plugin.exe" ^ -%1 +%1 \ No newline at end of file diff --git a/scripts/generate_contract_base.sh b/scripts/generate_contract_base.sh index 28a1550d3e..6d35a165aa 100755 --- a/scripts/generate_contract_base.sh +++ b/scripts/generate_contract_base.sh @@ -13,4 +13,4 @@ protoc --proto_path=${solutiondir}/protobuf \ --contract_opt="$2",nocontract \ --contract_out=./Protobuf/Generated \ --plugin=protoc-gen-contract=${plugin} \ -$1 +$1 \ No newline at end of file diff --git a/scripts/generate_contract_code.bat b/scripts/generate_contract_code.bat index 3b95aad75b..ccd91e4ede 100644 --- a/scripts/generate_contract_code.bat +++ b/scripts/generate_contract_code.bat @@ -7,4 +7,4 @@ protoc --proto_path=../../protobuf ^ --csharp_opt=file_extension=.g.cs ^ --contract_out=./Protobuf/Generated ^ --plugin=protoc-gen-contract="%scriptdir%contract_csharp_plugin.exe" ^ -%* +%* \ No newline at end of file diff --git a/scripts/generate_contract_code.sh b/scripts/generate_contract_code.sh index 60093c9a13..7dec613fc8 100755 --- a/scripts/generate_contract_code.sh +++ b/scripts/generate_contract_code.sh @@ -12,4 +12,4 @@ protoc --proto_path=${solutiondir}/protobuf \ --csharp_opt=file_extension=.g.cs \ --contract_out=./Protobuf/Generated \ --plugin=protoc-gen-contract=${plugin} \ -$@ +$@ \ No newline at end of file diff --git a/scripts/generate_contract_reference.bat b/scripts/generate_contract_reference.bat index 97fee83d02..6c69a31a54 100644 --- a/scripts/generate_contract_reference.bat +++ b/scripts/generate_contract_reference.bat @@ -8,4 +8,4 @@ protoc --proto_path=../../protobuf ^ --contract_opt=reference ^ --contract_out=internal_access:./Protobuf/Generated ^ --plugin=protoc-gen-contract="%scriptdir%contract_csharp_plugin.exe" ^ -%* +%* \ No newline at end of file diff --git a/scripts/generate_contract_reference.sh b/scripts/generate_contract_reference.sh index 47f8027ed1..4fe24547ed 100755 --- a/scripts/generate_contract_reference.sh +++ b/scripts/generate_contract_reference.sh @@ -13,4 +13,4 @@ protoc --proto_path=${solutiondir}/protobuf \ --contract_opt=reference \ --contract_out=internal_access:./Protobuf/Generated \ --plugin=protoc-gen-contract="${plugin}" \ -$@ +$@ \ No newline at end of file diff --git a/scripts/generate_contract_stub.bat b/scripts/generate_contract_stub.bat index 9e1120e8cd..67f8d11149 100644 --- a/scripts/generate_contract_stub.bat +++ b/scripts/generate_contract_stub.bat @@ -9,4 +9,4 @@ protoc --proto_path=../../protobuf ^ --contract_opt=internal_access ^ --contract_out=./Protobuf/Generated ^ --plugin=protoc-gen-contract="%scriptdir%contract_csharp_plugin.exe" ^ -%* +%* \ No newline at end of file diff --git a/scripts/generate_contract_stub.sh b/scripts/generate_contract_stub.sh index ac303fabb7..1e8faa7db1 100755 --- a/scripts/generate_contract_stub.sh +++ b/scripts/generate_contract_stub.sh @@ -18,4 +18,4 @@ protoc --proto_path=${solutiondir}/protobuf \ --contract_opt=internal_access \ --contract_out=${destdir} \ --plugin=protoc-gen-contract="${plugin}" \ -$@ +$@ \ No newline at end of file diff --git a/scripts/generate_event_only.bat b/scripts/generate_event_only.bat index 31dd3e1d16..c4e8fb587d 100644 --- a/scripts/generate_event_only.bat +++ b/scripts/generate_event_only.bat @@ -8,4 +8,4 @@ protoc --proto_path=../../protobuf ^ --contract_opt=nocontract ^ --contract_out=internal_access:./Protobuf/Generated ^ --plugin=protoc-gen-contract="%scriptdir%contract_csharp_plugin.exe" ^ -%* +%* \ No newline at end of file diff --git a/scripts/generate_event_only.sh b/scripts/generate_event_only.sh index db7d22d03f..8bc466768a 100755 --- a/scripts/generate_event_only.sh +++ b/scripts/generate_event_only.sh @@ -13,4 +13,4 @@ protoc --proto_path=${solutiondir}/protobuf \ --contract_opt=nocontract \ --contract_out=internal_access:./Protobuf/Generated \ --plugin=protoc-gen-contract=${plugin} \ -$@ +$@ \ No newline at end of file diff --git a/scripts/install_protobuf.sh b/scripts/install_protobuf.sh index 0d6400db02..e29e5b5427 100644 --- a/scripts/install_protobuf.sh +++ b/scripts/install_protobuf.sh @@ -13,18 +13,18 @@ fi echo "Install protobuf on ${osn}" if [[ ${osn} == "macosx" ]]; then - curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protoc-3.11.4-osx-x86_64.zip - unzip protoc-3.11.4-osx-x86_64.zip -d protoc3 + curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-osx-x86_64.zip + unzip protoc-3.19.4-osx-x86_64.zip -d protoc3 sudo mv protoc3/bin/* /usr/local/bin/ sudo mv protoc3/include/* /usr/local/include sudo chown ${USER} /usr/local/bin/protoc sudo chown -R ${USER} /usr/local/include/google elif [[ ${osn} == "linux" ]]; then # Make sure you grab the latest version - curl -OL https://github.com/google/protobuf/releases/download/v3.11.4/protoc-3.11.4-linux-x86_64.zip + curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip # Unzip - unzip protoc-3.11.4-linux-x86_64.zip -d protoc3 + unzip protoc-3.19.4-linux-x86_64.zip -d protoc3 # Move protoc to /usr/local/bin/ sudo mv protoc3/bin/* /usr/local/bin/ @@ -35,4 +35,4 @@ elif [[ ${osn} == "linux" ]]; then # Optional: change owner sudo chown ${USER} /usr/local/bin/protoc sudo chown -R ${USER} /usr/local/include/google -fi +fi \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh index 7922415954..47b7b1de60 100644 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -20,4 +20,4 @@ for i in *Tests ; do echo "Test Run Successful." -done +done \ No newline at end of file diff --git a/scripts/upload_coverage.sh b/scripts/upload_coverage.sh index 082982d9a3..70326d9daf 100644 --- a/scripts/upload_coverage.sh +++ b/scripts/upload_coverage.sh @@ -2,4 +2,4 @@ curl -s https://codecov.io/bash > codecov chmod +x codecov -./codecov -f "../test/results/coverage.opencover.xml" -t $1 +./codecov -f "../test/results/coverage.opencover.xml" -t $1 \ No newline at end of file diff --git a/src/AElf.Blockchains.BasicBaseChain/AElf.Blockchains.BasicBaseChain.csproj b/src/AElf.Blockchains.BasicBaseChain/AElf.Blockchains.BasicBaseChain.csproj index e32d4beb7d..0171e4a76b 100644 --- a/src/AElf.Blockchains.BasicBaseChain/AElf.Blockchains.BasicBaseChain.csproj +++ b/src/AElf.Blockchains.BasicBaseChain/AElf.Blockchains.BasicBaseChain.csproj @@ -1,29 +1,29 @@ - - + + - net6.0 + net8.0 AElf.Blockchains.BasicBaseChain true Base AElf Module for different chain types. - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/AElf.Blockchains.BasicBaseChain/GenesisSmartContractDtoProviderBase.cs b/src/AElf.Blockchains.BasicBaseChain/GenesisSmartContractDtoProviderBase.cs index 844998a236..d056ecd523 100644 --- a/src/AElf.Blockchains.BasicBaseChain/GenesisSmartContractDtoProviderBase.cs +++ b/src/AElf.Blockchains.BasicBaseChain/GenesisSmartContractDtoProviderBase.cs @@ -25,11 +25,13 @@ public virtual IEnumerable GetGenesisSmartContractDtos( { var contractCodes = GetContractCodes(); var deploymentList = ContractDeploymentListProvider.GetDeployContractNameList(); - return ContractInitializationProviders - .Where(p => deploymentList.Contains(p.SystemSmartContractName)) - .OrderBy(p => deploymentList.IndexOf(p.SystemSmartContractName)) - .Select(p => + return ContractInitializationProviders + .GroupBy(p => p.SystemSmartContractName) + .Where(g => deploymentList.Contains(g.Key)) + .OrderBy(g => deploymentList.IndexOf(g.Key)) + .Select(g => { + var p = g.Last(); var code = contractCodes[p.ContractCodeName]; var methodList = p.GetInitializeMethodList(code); var genesisSmartContractDto = new GenesisSmartContractDto diff --git a/src/AElf.Blockchains.MainChain/AElf.Blockchains.MainChain.csproj b/src/AElf.Blockchains.MainChain/AElf.Blockchains.MainChain.csproj index 4765c5a414..c99ca2bf21 100644 --- a/src/AElf.Blockchains.MainChain/AElf.Blockchains.MainChain.csproj +++ b/src/AElf.Blockchains.MainChain/AElf.Blockchains.MainChain.csproj @@ -1,15 +1,15 @@  - net6.0 + net8.0 0436 Main module for a mainchain node. - - - + + + diff --git a/src/AElf.Blockchains.MainChain/MainChainGenesisSmartContractDtoProvider.cs b/src/AElf.Blockchains.MainChain/MainChainGenesisSmartContractDtoProvider.cs index 78826cdd23..460f4759f2 100644 --- a/src/AElf.Blockchains.MainChain/MainChainGenesisSmartContractDtoProvider.cs +++ b/src/AElf.Blockchains.MainChain/MainChainGenesisSmartContractDtoProvider.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; +using System.Linq; using AElf.Blockchains.BasicBaseChain; using AElf.ContractDeployer; +using AElf.Kernel.Plugin.Application; using AElf.Kernel.SmartContract; using AElf.Kernel.SmartContract.Application; using Microsoft.Extensions.Options; @@ -12,19 +14,23 @@ namespace AElf.Blockchains.MainChain; /// public class MainChainGenesisSmartContractDtoProvider : GenesisSmartContractDtoProviderBase { + private readonly IEnumerable _pluginContractProviders; private readonly ContractOptions _contractOptions; public MainChainGenesisSmartContractDtoProvider(IContractDeploymentListProvider contractDeploymentListProvider, IEnumerable contractInitializationProviders, + IEnumerable pluginContractProviders, IOptionsSnapshot contractOptions) : base(contractDeploymentListProvider, contractInitializationProviders) { + _pluginContractProviders = pluginContractProviders; _contractOptions = contractOptions.Value; } protected override IReadOnlyDictionary GetContractCodes() { - return ContractsDeployer.GetContractCodes(_contractOptions - .GenesisContractDir); + return ContractsDeployer.GetContractCodes( + _contractOptions.GenesisContractDir, + pluginContractNames: _pluginContractProviders.Select(p => p.GetContractName()).ToList()); } } \ No newline at end of file diff --git a/src/AElf.Blockchains.SideChain/AElf.Blockchains.SideChain.csproj b/src/AElf.Blockchains.SideChain/AElf.Blockchains.SideChain.csproj index f32797732a..9364aac96b 100644 --- a/src/AElf.Blockchains.SideChain/AElf.Blockchains.SideChain.csproj +++ b/src/AElf.Blockchains.SideChain/AElf.Blockchains.SideChain.csproj @@ -1,15 +1,15 @@  - net6.0 + net8.0 Main module for a sidechain node. 1701;1702 - - + + @@ -105,6 +105,6 @@ - + diff --git a/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj b/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj index 08ec4b91b2..dc5501294c 100644 --- a/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj +++ b/src/AElf.CSharp.CodeOps/AElf.CSharp.CodeOps.csproj @@ -1,17 +1,17 @@ - + - net6.0 + net8.0 true Smart contract code operations like auditing, patching and validating. - - + - + + diff --git a/src/AElf.CSharp.CodeOps/CSharpContractAuditor.cs b/src/AElf.CSharp.CodeOps/CSharpContractAuditor.cs index 58c015f563..b7999fb6d1 100644 --- a/src/AElf.CSharp.CodeOps/CSharpContractAuditor.cs +++ b/src/AElf.CSharp.CodeOps/CSharpContractAuditor.cs @@ -1,8 +1,10 @@ +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; +using System.Threading.Tasks; using AElf.CSharp.CodeOps.Policies; using AElf.CSharp.CodeOps.Validators; using AElf.CSharp.CodeOps.Validators.Assembly; @@ -11,77 +13,112 @@ using Microsoft.Extensions.Options; using Mono.Cecil; - -namespace AElf.CSharp.CodeOps; - -public class CSharpContractAuditor : IContractAuditor +namespace AElf.CSharp.CodeOps { - private readonly IAcsValidator _acsValidator; - - public int Category { get; } = 0; - - public IOptionsMonitor CodeOpsOptionsMonitor { get; set; } - - private readonly IPolicy _policy; - - public CSharpContractAuditor(IPolicy policy, IAcsValidator acsValidator) + public class CSharpContractAuditor : IContractAuditor { - _policy = policy; - _acsValidator = acsValidator; - } + private readonly IAcsValidator _acsValidator; + private readonly IPolicy _policy; - public void Audit(byte[] code, RequiredAcs requiredAcs, bool isSystemContract) - { - var findings = new List(); - var asm = Assembly.Load(code); - var modDef = ModuleDefinition.ReadModule(new MemoryStream(code)); - var cts = new CancellationTokenSource(CodeOpsOptionsMonitor?.CurrentValue.AuditTimeoutDuration ?? - Constants.DefaultAuditTimeoutDuration); - // Run module validators - findings.AddRange(Validate(modDef, cts.Token, isSystemContract)); - - // Run assembly validators (run after module validators since we invoke BindService method below) - findings.AddRange(Validate(asm, cts.Token, isSystemContract)); - - // Run method validators - foreach (var type in modDef.Types) + public int Category { get; } = 0; + public IOptionsMonitor CodeOpsOptionsMonitor { get; set; } + + public CSharpContractAuditor(IPolicy policy, IAcsValidator acsValidator) { - findings.AddRange(ValidateMethodsInType(type, cts.Token, isSystemContract)); + _policy = policy; + _acsValidator = acsValidator; } - // Perform ACS validation - if (requiredAcs != null) - findings.AddRange(_acsValidator.Validate(asm, requiredAcs)); - - if (findings.Count > 0) + public void Audit(byte[] code, RequiredAcs requiredAcs, bool isSystemContract) { - throw new CSharpCodeCheckException( - $"Contract code did not pass audit. Audit failed for contract: {modDef.Assembly.MainModule.Name}\n" + - string.Join("\n", findings), findings); + var findings = new ConcurrentBag(); + var asm = Assembly.Load(code); + var modDef = ModuleDefinition.ReadModule(new MemoryStream(code)); + var cts = new CancellationTokenSource(CodeOpsOptionsMonitor?.CurrentValue.AuditTimeoutDuration ?? + Constants.DefaultAuditTimeoutDuration); + + // Run module validators + var moduleFindings = Validate(modDef, cts.Token, isSystemContract); + foreach (var finding in moduleFindings) + { + findings.Add(finding); + } + + // Run assembly validators + var assemblyFindings = Validate(asm, cts.Token, isSystemContract); + foreach (var finding in assemblyFindings) + { + findings.Add(finding); + } + + // Run method validators + foreach (var type in modDef.Types) + { + var methodFindings = ValidateMethodsInType(type, cts.Token, isSystemContract); + foreach (var finding in methodFindings) + { + findings.Add(finding); + } + } + + + // Perform ACS validation + if (requiredAcs != null) + { + var acsFindings = _acsValidator.Validate(asm, requiredAcs); + foreach (var finding in acsFindings) + { + findings.Add(finding); + } + } + + if (findings.Count > 0) + { + throw new CSharpCodeCheckException( + $"Contract code did not pass audit. Audit failed for contract: {modDef.Assembly.MainModule.Name}\n" + + string.Join("\n", findings), findings.ToList()); + } } - } - - private IEnumerable Validate(T t, CancellationToken ct, bool isSystemContract) - { - var validators = _policy.GetValidators().Where(v => !v.SystemContactIgnored || !isSystemContract); - return validators.SelectMany(v => v.Validate(t, ct)); - } - - private IEnumerable ValidateMethodsInType(TypeDefinition type, - CancellationToken ct, bool isSystemContract) - { - var findings = new List(); - foreach (var method in type.Methods) + private IEnumerable Validate(T t, CancellationToken ct, bool isSystemContract) { - findings.AddRange(Validate(method, ct, isSystemContract)); + var validators = _policy.GetValidators().AsParallel() + .Where(v => !v.SystemContactIgnored || !isSystemContract); + + var results = new ConcurrentBag(); + foreach (var v in validators) + { + foreach (var result in v.Validate(t, ct)) + { + results.Add(result); + } + } + + return results; } - foreach (var nestedType in type.NestedTypes) + private IEnumerable ValidateMethodsInType(TypeDefinition type, + CancellationToken ct, bool isSystemContract) { - findings.AddRange(ValidateMethodsInType(nestedType, ct, isSystemContract)); + var findings = new ConcurrentBag(); + + Parallel.ForEach(type.Methods, method => + { + foreach (var finding in Validate(method, ct, isSystemContract)) + { + findings.Add(finding); + } + }); + + Parallel.ForEach(type.NestedTypes, nestedType => + { + foreach (var finding in ValidateMethodsInType(nestedType, ct, isSystemContract)) + { + findings.Add(finding); + } + }); + + return findings; } - - return findings; } -} \ No newline at end of file +} diff --git a/src/AElf.CSharp.CodeOps/Patchers/Module/ResetFieldsMethodInjector.cs b/src/AElf.CSharp.CodeOps/Patchers/Module/ResetFieldsMethodInjector.cs index f17c0930cb..9e6d4f60a8 100644 --- a/src/AElf.CSharp.CodeOps/Patchers/Module/ResetFieldsMethodInjector.cs +++ b/src/AElf.CSharp.CodeOps/Patchers/Module/ResetFieldsMethodInjector.cs @@ -188,7 +188,7 @@ public partial class ResetFieldsMethodInjector static ResetFieldsMethodInjector() { - var systemRuntime = Basic.Reference.Assemblies.Net60.Resources.SystemRuntime; + var systemRuntime = Basic.Reference.Assemblies.Net80.Resources.SystemRuntime; using var stream = new MemoryStream(systemRuntime); diff --git a/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs b/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs index 1eacd14c55..08fced5f36 100644 --- a/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs +++ b/src/AElf.CSharp.CodeOps/Validators/Method/ArrayValidator.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading; using AElf.CSharp.Core; -using Bn254.Net; +using AElf.Types; using Mono.Cecil; using Mono.Cecil.Cil; using Volo.Abp.DependencyInjection; @@ -22,11 +22,10 @@ public class ArrayValidator : IValidator, ITransientDependency .LimitByTotalSize(typeof(UInt16), sizeof(UInt16)) .LimitByTotalSize(typeof(UInt32), sizeof(UInt32)) .LimitByTotalSize(typeof(UInt64), sizeof(UInt64)) - .LimitByTotalSize(typeof(UInt256), 32) .LimitByTotalSize(typeof(decimal), sizeof(decimal)) .LimitByTotalSize(typeof(char), sizeof(char)) .LimitByTotalSize(typeof(String), 128) // Need to limit the size of strings by disallowing String.Concat - + .LimitByTotalSize(typeof(BigIntValue), 128) // It isn't possible to estimate runtime sizes for below, so limit by count .LimitByCount(typeof(Type), 5) .LimitByCount(typeof(Object), 5) // Support object in Linq queries diff --git a/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs b/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs index 2aec233dc9..d3572cb648 100644 --- a/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs +++ b/src/AElf.CSharp.CodeOps/Validators/Whitelist/IWhitelistProvider.cs @@ -4,13 +4,14 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Text; +using System.Text.RegularExpressions; using AElf.Cryptography.SecretSharing; using AElf.CSharp.Core; using AElf.Kernel.SmartContract; using AElf.Types; -using Nethereum.Util; using Volo.Abp.DependencyInjection; + namespace AElf.CSharp.CodeOps.Validators.Whitelist; public interface IWhitelistProvider @@ -38,6 +39,7 @@ private void WhitelistAssemblies(Whitelist whitelist) .Assembly(System.Reflection.Assembly.Load("System.Runtime.Extensions"), Trust.Partial) .Assembly(System.Reflection.Assembly.Load("System.Private.CoreLib"), Trust.Partial) .Assembly(System.Reflection.Assembly.Load("System.ObjectModel"), Trust.Partial) + .Assembly(System.Reflection.Assembly.Load("System.Text.RegularExpressions"), Trust.Partial) .Assembly(System.Reflection.Assembly.Load("System.Linq"), Trust.Full) .Assembly(System.Reflection.Assembly.Load("System.Linq.Expressions"), Trust.Full) .Assembly(System.Reflection.Assembly.Load("System.Collections"), Trust.Full) @@ -48,8 +50,6 @@ private void WhitelistAssemblies(Whitelist whitelist) .Assembly(typeof(IMethod).Assembly, Trust.Full) // AElf.CSharp.Core .Assembly(typeof(SecretSharingHelper).Assembly, Trust.Partial) // AElf.Cryptography .Assembly(typeof(ISmartContractBridgeContext).Assembly, Trust.Full) // AElf.Kernel.SmartContract.Shared - .Assembly(typeof(Bn254.Net.Bn254).Assembly, Trust.Full) // Bn254.Net - .Assembly(typeof(Sha3Keccack).Assembly, Trust.Full) // Nethereum.Web3 ; } @@ -158,6 +158,17 @@ private void WhitelistOthers(Whitelist whitelist) .Member(nameof(Encoding.UTF8), Permission.Allowed) .Member(nameof(Encoding.UTF8.GetByteCount), Permission.Allowed))) .Namespace("System.Numerics", Permission.Allowed) + .Namespace("System.Text.RegularExpressions", Permission.Denied, type => type + .Type(nameof(Regex), Permission.Denied, member => member + .Member(nameof(Regex.IsMatch), Permission.Allowed) + .Member(nameof(Regex.Match), Permission.Allowed) + .Member(nameof(Regex.Matches), Permission.Allowed) + .Member(nameof(Regex.Replace), Permission.Allowed) + .Member(nameof(Regex.Split), Permission.Allowed) + ) + .Type(nameof(MatchCollection), Permission.Allowed) + .Type(nameof(Match), Permission.Allowed) + ) ; } diff --git a/src/AElf.CSharp.Core/AElf.CSharp.Core.csproj b/src/AElf.CSharp.Core/AElf.CSharp.Core.csproj index 4fa8489d88..77199b6659 100644 --- a/src/AElf.CSharp.Core/AElf.CSharp.Core.csproj +++ b/src/AElf.CSharp.Core/AElf.CSharp.Core.csproj @@ -1,15 +1,15 @@ - - + + - net6.0 + net8.0 AElf.CSharp.Core true Base definitions for C# smart contracts. - + - + \ No newline at end of file diff --git a/src/AElf.Cluster/AElf.Cluster.csproj b/src/AElf.Cluster/AElf.Cluster.csproj index 28d99c4579..53bcaa6eb2 100644 --- a/src/AElf.Cluster/AElf.Cluster.csproj +++ b/src/AElf.Cluster/AElf.Cluster.csproj @@ -1,18 +1,18 @@  - net6.0 + net8.0 - + - - - + + + diff --git a/src/AElf.ContractDeployer/AElf.ContractDeployer.csproj b/src/AElf.ContractDeployer/AElf.ContractDeployer.csproj index 0d99f17fc2..8f34424e0a 100644 --- a/src/AElf.ContractDeployer/AElf.ContractDeployer.csproj +++ b/src/AElf.ContractDeployer/AElf.ContractDeployer.csproj @@ -1,10 +1,10 @@ - - + + AElf.ContractDeployer true - net6.0 + net8.0 Exe Smart contract deployer. AElf.ContractDeployer @@ -13,22 +13,22 @@ TRACE;UNIT_TEST - + - - - + + + - + - + - - + + diff --git a/src/AElf.ContractDeployer/ContractsDeployer.cs b/src/AElf.ContractDeployer/ContractsDeployer.cs index 6c2aec9dd0..a79e0e5121 100644 --- a/src/AElf.ContractDeployer/ContractsDeployer.cs +++ b/src/AElf.ContractDeployer/ContractsDeployer.cs @@ -8,9 +8,14 @@ namespace AElf.ContractDeployer; public static class ContractsDeployer { public static IReadOnlyDictionary GetContractCodes(string contractDir = null, - bool isPatched = false) + bool isPatched = false, List pluginContractNames = null) { var contractNames = GetContractNames(typeof(T).Assembly).ToList(); + if (pluginContractNames is { Count: > 0 }) + { + contractNames.AddRange(pluginContractNames); + } + if (contractNames.Count == 0) throw new NoContractDllFoundInManifestException(); return contractNames.Select(n => (n, GetCode(n, contractDir, isPatched))) diff --git a/src/AElf.ContractDeployer/Program.cs b/src/AElf.ContractDeployer/Program.cs index f9230328a2..2f39589da5 100644 --- a/src/AElf.ContractDeployer/Program.cs +++ b/src/AElf.ContractDeployer/Program.cs @@ -43,7 +43,7 @@ private static void Run(Options o) saveAsPath = o.ContractDllPath + ".patched"; Console.WriteLine($"[CONTRACT-PATCHER] Saving as {saveAsPath}"); } - + using var application = AbpApplicationFactory.Create(); application.Initialize(); var contractPatcher = application.ServiceProvider.GetRequiredService(); @@ -61,6 +61,10 @@ private static void Run(Options o) // Print error in parsable format so that it can be shown in IDE Console.WriteLine($"error: {finding}"); } + catch (Exception e) + { + Console.WriteLine("Audit exception: ",e); + } File.WriteAllBytes(saveAsPath, patchedCode); } diff --git a/src/AElf.ContractTestBase/AElf.ContractTestBase.csproj b/src/AElf.ContractTestBase/AElf.ContractTestBase.csproj index cb38e8bf85..6fe993cbeb 100644 --- a/src/AElf.ContractTestBase/AElf.ContractTestBase.csproj +++ b/src/AElf.ContractTestBase/AElf.ContractTestBase.csproj @@ -1,23 +1,23 @@ - - + + - net6.0 + net8.0 AElf.ContractTestBase true Contract test base. - - - - - - - - - - + + + + + + + + + + false Contract @@ -56,10 +56,10 @@ - - - - - + + + + + diff --git a/src/AElf.ContractTestKit.AEDPoSExtension/AEDPoSExtensionTestBase.cs b/src/AElf.ContractTestKit.AEDPoSExtension/AEDPoSExtensionTestBase.cs index 23b387d996..0f123194e4 100644 --- a/src/AElf.ContractTestKit.AEDPoSExtension/AEDPoSExtensionTestBase.cs +++ b/src/AElf.ContractTestKit.AEDPoSExtension/AEDPoSExtensionTestBase.cs @@ -4,6 +4,7 @@ using AElf.EconomicSystem; using AElf.GovernmentSystem; using AElf.Kernel.Blockchain.Application; +using AElf.Kernel.Configuration; using AElf.Kernel.Consensus; using AElf.Kernel.Proposal; using AElf.Kernel.Token; @@ -30,7 +31,8 @@ public class AEDPoSExtensionTestBase : ContractTestBase ContractAddresses; diff --git a/src/AElf.ContractTestKit.AEDPoSExtension/AElf.ContractTestKit.AEDPoSExtension.csproj b/src/AElf.ContractTestKit.AEDPoSExtension/AElf.ContractTestKit.AEDPoSExtension.csproj index 8230cdb5e4..4fceae4d77 100644 --- a/src/AElf.ContractTestKit.AEDPoSExtension/AElf.ContractTestKit.AEDPoSExtension.csproj +++ b/src/AElf.ContractTestKit.AEDPoSExtension/AElf.ContractTestKit.AEDPoSExtension.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.ContractTestKit.AEDPoSExtension true Contract testing kit using AEDPoS Consensus. diff --git a/src/AElf.ContractTestKit.AEDPoSExtension/UnitTestPlainTransactionExecutingService.cs b/src/AElf.ContractTestKit.AEDPoSExtension/UnitTestPlainTransactionExecutingService.cs index ca7ce8e3f6..37f1b50c43 100644 --- a/src/AElf.ContractTestKit.AEDPoSExtension/UnitTestPlainTransactionExecutingService.cs +++ b/src/AElf.ContractTestKit.AEDPoSExtension/UnitTestPlainTransactionExecutingService.cs @@ -2,6 +2,7 @@ using System.Threading; using System.Threading.Tasks; using AElf.Kernel; +using AElf.Kernel.FeatureDisable.Core; using AElf.Kernel.SmartContract; using AElf.Kernel.SmartContract.Application; using AElf.Kernel.SmartContractExecution.Events; @@ -12,8 +13,8 @@ public class UnitTestPlainTransactionExecutingService : PlainTransactionExecutin { public UnitTestPlainTransactionExecutingService(ISmartContractExecutiveService smartContractExecutiveService, IEnumerable postPlugins, IEnumerable prePlugins, - ITransactionContextFactory transactionContextFactory) : base( - smartContractExecutiveService, postPlugins, prePlugins, transactionContextFactory) + ITransactionContextFactory transactionContextFactory, IFeatureDisableService featureDisableService) : base( + smartContractExecutiveService, postPlugins, prePlugins, transactionContextFactory, featureDisableService) { } diff --git a/src/AElf.ContractTestKit/AElf.ContractTestKit.csproj b/src/AElf.ContractTestKit/AElf.ContractTestKit.csproj index 928732975c..c694129b0d 100644 --- a/src/AElf.ContractTestKit/AElf.ContractTestKit.csproj +++ b/src/AElf.ContractTestKit/AElf.ContractTestKit.csproj @@ -1,7 +1,7 @@ - - + + - net6.0 + net8.0 AElf.ContractTestKit true Contract testing kit. @@ -13,15 +13,15 @@ - - - - - - - - - + + + + + + + + + @@ -49,10 +49,10 @@ - - - - - + + + + + \ No newline at end of file diff --git a/src/AElf.Core/AElf.Core.csproj b/src/AElf.Core/AElf.Core.csproj index 01ffb3ff04..ffab63014d 100644 --- a/src/AElf.Core/AElf.Core.csproj +++ b/src/AElf.Core/AElf.Core.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf AElf.Core true @@ -10,10 +10,10 @@ - - - - + + + + diff --git a/src/AElf.CrossChain.Core/AElf.CrossChain.Core.csproj b/src/AElf.CrossChain.Core/AElf.CrossChain.Core.csproj index 310eb85cdb..9c1e1e9711 100644 --- a/src/AElf.CrossChain.Core/AElf.CrossChain.Core.csproj +++ b/src/AElf.CrossChain.Core/AElf.CrossChain.Core.csproj @@ -1,7 +1,7 @@ - - + + - net6.0 + net8.0 AElf.CrossChain.Core true AElf.CrossChain @@ -13,8 +13,8 @@ - - + + diff --git a/src/AElf.CrossChain.Grpc/AElf.CrossChain.Grpc.csproj b/src/AElf.CrossChain.Grpc/AElf.CrossChain.Grpc.csproj index 2c679e0a27..8b6b48b8de 100644 --- a/src/AElf.CrossChain.Grpc/AElf.CrossChain.Grpc.csproj +++ b/src/AElf.CrossChain.Grpc/AElf.CrossChain.Grpc.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.CrossChain.Grpc true Grpc implementation of cross-chain communication functionality. diff --git a/src/AElf.CrossChain/AElf.CrossChain.csproj b/src/AElf.CrossChain/AElf.CrossChain.csproj index 05c4170990..e7f854420b 100644 --- a/src/AElf.CrossChain/AElf.CrossChain.csproj +++ b/src/AElf.CrossChain/AElf.CrossChain.csproj @@ -1,14 +1,14 @@ - + - net6.0 + net8.0 AElf.CrossChain true Main functionality for crosschain operations. - + diff --git a/src/AElf.Cryptography/AElf.Cryptography.csproj b/src/AElf.Cryptography/AElf.Cryptography.csproj index 91995f617e..1f5c07064d 100644 --- a/src/AElf.Cryptography/AElf.Cryptography.csproj +++ b/src/AElf.Cryptography/AElf.Cryptography.csproj @@ -1,7 +1,7 @@ - + - netstandard2.1;net6.0 + netstandard2.1;net8.0 AElf.Cryptography true Cryptographic primitives used in AElf. @@ -10,7 +10,6 @@ - diff --git a/src/AElf.Cryptography/CryptoHelper.cs b/src/AElf.Cryptography/CryptoHelper.cs index 56a1c1b73c..ea44d70a9a 100644 --- a/src/AElf.Cryptography/CryptoHelper.cs +++ b/src/AElf.Cryptography/CryptoHelper.cs @@ -6,8 +6,15 @@ using AElf.Cryptography.ECDSA; using AElf.Cryptography.ECVRF; using AElf.Cryptography.Exceptions; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; +using Org.BouncyCastle.Crypto.Modes; +using Org.BouncyCastle.Crypto.Paddings; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; using Secp256k1Net; -using Virgil.Crypto; using ECParameters = AElf.Cryptography.ECDSA.ECParameters; namespace AElf.Cryptography @@ -17,8 +24,7 @@ public static class CryptoHelper { private static readonly Secp256k1 Secp256K1 = new Secp256k1(); - // ReaderWriterLock for thread-safe with Secp256k1 APIs - private static readonly ReaderWriterLock Lock = new ReaderWriterLock(); + private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim(); private static readonly Vrf Vrf = new Vrf(new VrfConfig(0xfe, ECParameters.Curve)); @@ -36,7 +42,7 @@ public static ECKeyPair FromPrivateKey(byte[] privateKey) try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); var secp256K1PubKey = new byte[64]; if (!Secp256K1.PublicKeyCreate(secp256K1PubKey, privateKey)) @@ -48,7 +54,7 @@ public static ECKeyPair FromPrivateKey(byte[] privateKey) } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } @@ -56,7 +62,7 @@ public static ECKeyPair GenerateKeyPair() { try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); var privateKey = new byte[32]; var secp256K1PubKey = new byte[64]; @@ -76,7 +82,7 @@ public static ECKeyPair GenerateKeyPair() } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } @@ -84,7 +90,7 @@ public static byte[] SignWithPrivateKey(byte[] privateKey, byte[] hash) { try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); var recSig = new byte[65]; var compactSig = new byte[65]; if (!Secp256K1.SignRecoverable(recSig, hash, privateKey)) @@ -96,7 +102,7 @@ public static byte[] SignWithPrivateKey(byte[] privateKey, byte[] hash) } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } @@ -111,7 +117,7 @@ public static bool RecoverPublicKey(byte[] signature, byte[] hash, out byte[] pu pubkey = null; try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); // Recover id should be greater than or equal to 0 and less than 4 if (signature.Length != Secp256k1.SERIALIZED_UNCOMPRESSED_PUBKEY_LENGTH || signature.Last() >= 4) return false; @@ -129,55 +135,72 @@ public static bool RecoverPublicKey(byte[] signature, byte[] hash, out byte[] pu } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } public static byte[] EncryptMessage(byte[] senderPrivateKey, byte[] receiverPublicKey, byte[] plainText) { - var crypto = new VirgilCrypto(KeyPairType.EC_SECP256K1); - var ecdhKey = Ecdh(senderPrivateKey, receiverPublicKey); - var newKeyPair = crypto.GenerateKeys(KeyPairType.EC_SECP256K1, ecdhKey); - return crypto.Encrypt(plainText, newKeyPair.PublicKey); + var keyBytes = GetSharedSecret(senderPrivateKey, receiverPublicKey); + + var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine())); + cipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), new byte[16])); + + var cipherText = new byte[cipher.GetOutputSize(plainText.Length)]; + var len = cipher.ProcessBytes(plainText, 0, plainText.Length, cipherText, 0); + cipher.DoFinal(cipherText, len); + + return cipherText; } public static byte[] DecryptMessage(byte[] senderPublicKey, byte[] receiverPrivateKey, byte[] cipherText) { - var crypto = new VirgilCrypto(KeyPairType.EC_SECP256K1); - var ecdhKey = Ecdh(receiverPrivateKey, senderPublicKey); - var newKeyPair = crypto.GenerateKeys(KeyPairType.EC_SECP256K1, ecdhKey); - return crypto.Decrypt(cipherText, newKeyPair.PrivateKey); + var keyBytes = GetSharedSecret(receiverPrivateKey, senderPublicKey); + + var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine())); + cipher.Init(false, new ParametersWithIV(new KeyParameter(keyBytes), new byte[16])); + + var temp = new byte[cipher.GetOutputSize(cipherText.Length)]; + var len = cipher.ProcessBytes(cipherText, 0, cipherText.Length, temp, 0); + len += cipher.DoFinal(temp, len); + + // Remove padding + var plainText = new byte[len]; + Array.Copy(temp, 0, plainText, 0, len); + + return plainText; } - public static byte[] Ecdh(byte[] privateKey, byte[] publicKey) + private static byte[] GetSharedSecret(byte[] privateKey, byte[] publicKey) { - try - { - Lock.AcquireWriterLock(Timeout.Infinite); - var usablePublicKey = new byte[Secp256k1.SERIALIZED_UNCOMPRESSED_PUBKEY_LENGTH]; - if (!Secp256K1.PublicKeyParse(usablePublicKey, publicKey)) - throw new PublicKeyOperationException("Parse public key failed."); - var ecdhKey = new byte[Secp256k1.SERIALIZED_COMPRESSED_PUBKEY_LENGTH]; - if (!Secp256K1.Ecdh(ecdhKey, usablePublicKey, privateKey)) - throw new EcdhOperationException("Compute EC Diffie- secret failed."); - return ecdhKey; - } - finally - { - Lock.ReleaseWriterLock(); - } + var curve = ECParameters.Curve; + var domainParams = ECParameters.DomainParams; + var privateKeyParams = new ECPrivateKeyParameters(new BigInteger(1, privateKey), domainParams); + var publicKeyParams = new ECPublicKeyParameters(curve.Curve.DecodePoint(publicKey), domainParams); + + var agreement = AgreementUtilities.GetBasicAgreement("ECDH"); + agreement.Init(privateKeyParams); + var secret = agreement.CalculateAgreement(publicKeyParams); + + var kdf = new Kdf2BytesGenerator(new Sha256Digest()); + kdf.Init(new KdfParameters(secret.ToByteArray(), null)); + + var keyBytes = new byte[32]; + kdf.GenerateBytes(keyBytes, 0, keyBytes.Length); + + return keyBytes; } public static byte[] ECVrfProve(ECKeyPair keyPair, byte[] alpha) { try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); return Vrf.Prove(keyPair, alpha); } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } @@ -185,12 +208,12 @@ public static byte[] ECVrfVerify(byte[] publicKey, byte[] alpha, byte[] pi) { try { - Lock.AcquireWriterLock(Timeout.Infinite); + Lock.EnterWriteLock(); return Vrf.Verify(publicKey, alpha, pi); } finally { - Lock.ReleaseWriterLock(); + Lock.ExitWriteLock(); } } } diff --git a/src/AElf.Database/AElf.Database.csproj b/src/AElf.Database/AElf.Database.csproj index bce730bb49..b404d7ac4c 100644 --- a/src/AElf.Database/AElf.Database.csproj +++ b/src/AElf.Database/AElf.Database.csproj @@ -1,15 +1,15 @@ - - + + - net6.0 + net8.0 AElf.Database true Types and definitions of the data access layer. - + - + \ No newline at end of file diff --git a/src/AElf.EconomicSystem/AElf.EconomicSystem.csproj b/src/AElf.EconomicSystem/AElf.EconomicSystem.csproj index 2ddb7d08d9..70fc3b1dbb 100644 --- a/src/AElf.EconomicSystem/AElf.EconomicSystem.csproj +++ b/src/AElf.EconomicSystem/AElf.EconomicSystem.csproj @@ -1,16 +1,16 @@ - - + + - net6.0 + net8.0 AElf.EconomicSystem true Projects for AElf Economic System contracts releated stuff. - - - + + + diff --git a/src/AElf.GovernmentSystem/AElf.GovernmentSystem.csproj b/src/AElf.GovernmentSystem/AElf.GovernmentSystem.csproj index 4122562536..18435fde09 100644 --- a/src/AElf.GovernmentSystem/AElf.GovernmentSystem.csproj +++ b/src/AElf.GovernmentSystem/AElf.GovernmentSystem.csproj @@ -1,17 +1,17 @@ - - + + - net6.0 + net8.0 AElf.GovernmentSystem true Projects for AElf Government System contracts releated stuff. - - - - + + + + diff --git a/src/AElf.Kernel.ChainController/AElf.Kernel.ChainController.csproj b/src/AElf.Kernel.ChainController/AElf.Kernel.ChainController.csproj index 812b5b0050..a1df9b57b3 100644 --- a/src/AElf.Kernel.ChainController/AElf.Kernel.ChainController.csproj +++ b/src/AElf.Kernel.ChainController/AElf.Kernel.ChainController.csproj @@ -1,12 +1,12 @@ - - + + - net6.0 + net8.0 AElf.Kernel.ChainController true Module that contains chain creation functionality. - + \ No newline at end of file diff --git a/src/AElf.Kernel.CodeCheck/AElf.Kernel.CodeCheck.csproj b/src/AElf.Kernel.CodeCheck/AElf.Kernel.CodeCheck.csproj index 211cd26f0a..a8e9025c77 100644 --- a/src/AElf.Kernel.CodeCheck/AElf.Kernel.CodeCheck.csproj +++ b/src/AElf.Kernel.CodeCheck/AElf.Kernel.CodeCheck.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 latest AElf.Kernel.CodeCheck true diff --git a/src/AElf.Kernel.CodeCheck/Application/CodeCheckJob.cs b/src/AElf.Kernel.CodeCheck/Application/CodeCheckJob.cs index 7898215da7..d6e268718e 100644 --- a/src/AElf.Kernel.CodeCheck/Application/CodeCheckJob.cs +++ b/src/AElf.Kernel.CodeCheck/Application/CodeCheckJob.cs @@ -11,4 +11,12 @@ public class CodeCheckJob public Hash CodeCheckProposalId { get; set; } public Hash ProposedContractInputHash { get; set; } public long BucketIndex { get; set; } + + public override string ToString() + { + return $"BlockHash: {BlockHash}, BlockHeight: {BlockHeight}, ContractCategory: {ContractCategory}, " + + $"IsSystemContract: {IsSystemContract}, IsUserContract: {IsUserContract}, " + + $"CodeCheckProposalId: {CodeCheckProposalId}, ProposedContractInputHash: {ProposedContractInputHash}, " + + $"BucketIndex: {BucketIndex}"; + } } \ No newline at end of file diff --git a/src/AElf.Kernel.CodeCheck/Application/CodeCheckJobProcessor.cs b/src/AElf.Kernel.CodeCheck/Application/CodeCheckJobProcessor.cs index 99c53b9c35..bcb74dfd14 100644 --- a/src/AElf.Kernel.CodeCheck/Application/CodeCheckJobProcessor.cs +++ b/src/AElf.Kernel.CodeCheck/Application/CodeCheckJobProcessor.cs @@ -16,14 +16,14 @@ public interface ICodeCheckJobProcessor public class CodeCheckJobProcessor : ICodeCheckJobProcessor, ISingletonDependency { - private readonly TransformBlock _codeCheckTransformBlock; + private TransformBlock _codeCheckTransformBlock; private List> _codeCheckProcessesJobTransformBlock; private readonly CodeCheckOptions _codeCheckOptions; private readonly ICheckedCodeHashProvider _checkedCodeHashProvider; private readonly ICodeCheckService _codeCheckService; private readonly IProposalService _proposalService; private readonly ICodeCheckProposalService _codeCheckProposalService; - + public ILogger Logger { get; set; } public CodeCheckJobProcessor(IOptionsSnapshot codeCheckOptions, @@ -42,7 +42,18 @@ public CodeCheckJobProcessor(IOptionsSnapshot codeCheckOptions public async Task SendAsync(CodeCheckJob job) { - return await _codeCheckTransformBlock.SendAsync(job); + var codeCheckJobSendResult = await _codeCheckTransformBlock.SendAsync(job); + if (!codeCheckJobSendResult) + { + Logger.LogError( + $"Failed to send code check job. " + + $"Input count: {_codeCheckTransformBlock.InputCount}, " + + $"output count: {_codeCheckTransformBlock.OutputCount}"); + //Logger.LogError("Trying to recovery."); + //_codeCheckTransformBlock = CreateCodeCheckBufferBlock(); + } + + return codeCheckJobSendResult; } public async Task CompleteAsync() @@ -61,7 +72,7 @@ private TransformBlock CreateCodeCheckBufferBlock() BoundedCapacity = Math.Max(_codeCheckOptions.MaxBoundedCapacity, 1), MaxDegreeOfParallelism = _codeCheckOptions.MaxDegreeOfParallelism }); - + _codeCheckProcessesJobTransformBlock = new List>(); for (var i = 0; i < _codeCheckOptions.MaxDegreeOfParallelism; i++) { @@ -83,41 +94,45 @@ private TransformBlock CreateCodeCheckBufferBlock() private async Task ProcessCodeCheckJobAsync(CodeCheckJob job) { - var codeCheckResult = await _codeCheckService.PerformCodeCheckAsync(job.ContractCode, job.BlockHash, - job.BlockHeight, job.ContractCategory, job.IsSystemContract, job.IsUserContract); - - var codeHash = HashHelper.ComputeFrom(job.ContractCode); - Logger.LogInformation("Code check result: {codeCheckResult}, code hash: {codeHash}", codeCheckResult, - codeHash.ToHex()); - - if (!codeCheckResult) - return; - - if (job.IsUserContract) + try { - _codeCheckProposalService.AddReleasableProposal(job.CodeCheckProposalId, job.ProposedContractInputHash, - job.BlockHeight); - } + var codeCheckResult = await _codeCheckService.PerformCodeCheckAsync(job.ContractCode, job.BlockHash, + job.BlockHeight, job.ContractCategory, job.IsSystemContract, job.IsUserContract); + + var codeHash = HashHelper.ComputeFrom(job.ContractCode); + + if (!codeCheckResult) + { + Logger.LogError("Code check failed for code hash: {codeHash}", codeHash.ToHex()); + return; + } + + if (job.IsUserContract) + { + _codeCheckProposalService.AddReleasableProposal(job.CodeCheckProposalId, job.ProposedContractInputHash, + job.BlockHeight); + } - // Cache proposal id to generate system approval transaction later - _proposalService.AddNotApprovedProposal(job.CodeCheckProposalId, job.BlockHeight); + _proposalService.AddNotApprovedProposal(job.CodeCheckProposalId, job.BlockHeight); - await _checkedCodeHashProvider.AddCodeHashAsync(new BlockIndex + await _checkedCodeHashProvider.AddCodeHashAsync(new BlockIndex + { + BlockHash = job.BlockHash, + BlockHeight = job.BlockHeight + }, codeHash); + } + catch (Exception e) { - BlockHash = job.BlockHash, - BlockHeight = job.BlockHeight - }, codeHash); + Logger.LogError("Error while processing code check job: {e}", e); + throw; + } } - + private CodeCheckJob UpdateBucketIndex(CodeCheckJob job) { - var assemblyLoadContext = new AssemblyLoadContext(null, true); - var assembly = assemblyLoadContext.LoadFromStream(new MemoryStream(job.ContractCode)); - job.BucketIndex = - Math.Abs(HashHelper.ComputeFrom(assembly.GetName().Name).ToInt64() % _codeCheckOptions.MaxDegreeOfParallelism); - assemblyLoadContext.Unload(); - + Math.Abs(HashHelper.ComputeFrom(job.ContractCode).ToInt64() % _codeCheckOptions.MaxDegreeOfParallelism); + return job; } } \ No newline at end of file diff --git a/src/AElf.Kernel.CodeCheck/Application/CodeCheckProposalService.cs b/src/AElf.Kernel.CodeCheck/Application/CodeCheckProposalService.cs index 7fe9ebc680..4fc0828431 100644 --- a/src/AElf.Kernel.CodeCheck/Application/CodeCheckProposalService.cs +++ b/src/AElf.Kernel.CodeCheck/Application/CodeCheckProposalService.cs @@ -37,7 +37,7 @@ public void AddReleasableProposal(Hash proposalId, Hash proposalInputHash, long public async Task> GetReleasableProposalListAsync(Address from, Hash blockHash, long blockHeight) { - var allOpenProposals = _codeCheckProposalProvider.GetAllProposals(); + var allOpenProposals = _codeCheckProposalProvider.GetAllProposals().ToList(); if (allOpenProposals.Count == 0) return null; var releaseThresholdReachedProposals = await _contractReaderFactory.Create(new ContractReaderContext diff --git a/src/AElf.Kernel.CodeCheck/Application/CodeCheckValidationProvider.cs b/src/AElf.Kernel.CodeCheck/Application/CodeCheckValidationProvider.cs index 0d772880e4..357e127ac1 100644 --- a/src/AElf.Kernel.CodeCheck/Application/CodeCheckValidationProvider.cs +++ b/src/AElf.Kernel.CodeCheck/Application/CodeCheckValidationProvider.cs @@ -15,8 +15,7 @@ internal class CodeCheckValidationProvider : IBlockValidationProvider public CodeCheckValidationProvider(ISmartContractAddressService smartContractAddressService, IContractReaderFactory contractReaderFactory, - ICheckedCodeHashProvider checkedCodeHashProvider, - IOptionsSnapshot codeCheckOptions) + ICheckedCodeHashProvider checkedCodeHashProvider) { _smartContractAddressService = smartContractAddressService; _contractReaderFactory = contractReaderFactory; diff --git a/src/AElf.Kernel.CodeCheck/Application/ICheckedCodeHashProvider.cs b/src/AElf.Kernel.CodeCheck/Application/ICheckedCodeHashProvider.cs index ac8ccc666a..3b33064455 100644 --- a/src/AElf.Kernel.CodeCheck/Application/ICheckedCodeHashProvider.cs +++ b/src/AElf.Kernel.CodeCheck/Application/ICheckedCodeHashProvider.cs @@ -13,10 +13,14 @@ public interface ICheckedCodeHashProvider internal class CheckedCodeHashProvider : BlockExecutedDataBaseProvider, ICheckedCodeHashProvider, ISingletonDependency { + private readonly CodeCheckOptions _codeCheckOptions; + public CheckedCodeHashProvider( - ICachedBlockchainExecutedDataService cachedBlockchainExecutedDataService) : + ICachedBlockchainExecutedDataService cachedBlockchainExecutedDataService, + IOptionsMonitor codeCheckOptions) : base(cachedBlockchainExecutedDataService) { + _codeCheckOptions = codeCheckOptions.CurrentValue; Logger = NullLogger.Instance; } @@ -32,6 +36,11 @@ public async Task AddCodeHashAsync(BlockIndex blockIndex, Hash codeHash) public bool IsCodeHashExists(BlockIndex blockIndex, Hash codeHash) { + if (!_codeCheckOptions.CodeCheckEnabled) + { + return true; + } + var codeHashMap = GetBlockExecutedData(blockIndex); if (codeHashMap == null) return false; diff --git a/src/AElf.Kernel.CodeCheck/CodeCheckRequiredLogEventProcessor.cs b/src/AElf.Kernel.CodeCheck/CodeCheckRequiredLogEventProcessor.cs index 7abeea313b..4c84a307a8 100644 --- a/src/AElf.Kernel.CodeCheck/CodeCheckRequiredLogEventProcessor.cs +++ b/src/AElf.Kernel.CodeCheck/CodeCheckRequiredLogEventProcessor.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using AElf.CSharp.Core.Extension; @@ -48,28 +49,38 @@ public override async Task ProcessAsync(Block block, Dictionary l.Name == nameof(ProposalCreated)).NonIndexed) - .ProposalId; - - var code = eventData.Code.ToByteArray(); - var sendResult = await _codeCheckJobProcessor.SendAsync(new CodeCheckJob + try { - BlockHash = block.GetHash(), - BlockHeight = block.Height, - ContractCode = code, - ContractCategory = eventData.Category, - IsSystemContract = eventData.IsSystemContract, - IsUserContract = eventData.IsUserContract, - CodeCheckProposalId = proposalId, - ProposedContractInputHash = eventData.ProposedContractInputHash - }); + var proposalId = ProposalCreated.Parser + .ParseFrom(transactionResult.Logs.First(l => l.Name == nameof(ProposalCreated)).NonIndexed) + .ProposalId; + + var code = eventData.Code.ToByteArray(); + var codeCheckJob = new CodeCheckJob + { + BlockHash = block.GetHash(), + BlockHeight = block.Height, + ContractCode = code, + ContractCategory = eventData.Category, + IsSystemContract = eventData.IsSystemContract, + IsUserContract = eventData.IsUserContract, + CodeCheckProposalId = proposalId, + ProposedContractInputHash = eventData.ProposedContractInputHash + }; + var sendResult = await _codeCheckJobProcessor.SendAsync(codeCheckJob); - if (!sendResult) + if (!sendResult) + { + Logger.LogError( + "Unable to perform code check. BlockHash: {BlockHash}, BlockHeight: {BlockHeight}, CodeHash: {CodeHash}, ProposalId: {ProposalId}", + block.GetHash().ToHex(), block.Height, HashHelper.ComputeFrom(code).ToHex(), + proposalId.ToHex()); + } + } + catch (Exception e) { - Logger.LogError( - "Unable to perform code check. BlockHash: {BlockHash}, BlockHeight: {BlockHeight}, CodeHash: {CodeHash}, ProposalId: {ProposalId}", - block.GetHash(), block.Height, HashHelper.ComputeFrom(code).ToHex(), proposalId.ToHex()); + Logger.LogError("Error while processing CodeCheckRequired log event. {0}", e); + throw new CodeCheckJobException($"Error while processing CodeCheckRequired log event. {e}"); } } } diff --git a/src/AElf.Kernel.CodeCheck/ContractCodeHashMap.cs b/src/AElf.Kernel.CodeCheck/ContractCodeHashMap.cs index 329f6cca7e..1dcc588c7c 100644 --- a/src/AElf.Kernel.CodeCheck/ContractCodeHashMap.cs +++ b/src/AElf.Kernel.CodeCheck/ContractCodeHashMap.cs @@ -6,11 +6,9 @@ internal partial class ContractCodeHashMap { public void TryAdd(long blockHeight, Hash codeHash) { - if (Value.ContainsKey(blockHeight)) + if (Value.TryGetValue(blockHeight, out var hashList)) { - var hashList = Value[blockHeight]; hashList.Value.Add(codeHash); - Value[blockHeight] = hashList; } else { diff --git a/src/AElf.Kernel.CodeCheck/Exception/CodeCheckJobException.cs b/src/AElf.Kernel.CodeCheck/Exception/CodeCheckJobException.cs new file mode 100644 index 0000000000..703de9fe62 --- /dev/null +++ b/src/AElf.Kernel.CodeCheck/Exception/CodeCheckJobException.cs @@ -0,0 +1,14 @@ +using System; + +namespace AElf.Kernel.CodeCheck; + +public class CodeCheckJobException : Exception +{ + public CodeCheckJobException() + { + } + + public CodeCheckJobException(string message) : base(message) + { + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.CodeCheck/Infrastructure/CodeCheckProposalProvider.cs b/src/AElf.Kernel.CodeCheck/Infrastructure/CodeCheckProposalProvider.cs index 864039c4ec..c2849fefb3 100644 --- a/src/AElf.Kernel.CodeCheck/Infrastructure/CodeCheckProposalProvider.cs +++ b/src/AElf.Kernel.CodeCheck/Infrastructure/CodeCheckProposalProvider.cs @@ -1,6 +1,5 @@ using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; using AElf.Kernel.CodeCheck.Application; namespace AElf.Kernel.CodeCheck.Infrastructure; @@ -11,25 +10,20 @@ public class CodeCheckProposalProvider : ICodeCheckProposalProvider, ISingletonD public void AddProposal(Hash proposalId, Hash proposalInputHash, long height) { - // keep the higher block index - _proposalsToRelease.AddOrUpdate(proposalId, new CodeCheckProposal + var newProposal = new CodeCheckProposal { ProposalId = proposalId, ProposedContractInputHash = proposalInputHash, BlockHeight = height - }, (hash, proposal) => proposal.BlockHeight >= height - ? proposal - : new CodeCheckProposal - { - ProposalId = proposalId, - BlockHeight = height, - ProposedContractInputHash = proposalInputHash - }); + }; + + _proposalsToRelease.AddOrUpdate(proposalId, newProposal, + (hash, proposal) => proposal.BlockHeight >= height ? proposal : newProposal); } - public List GetAllProposals() + public IEnumerable GetAllProposals() { - return _proposalsToRelease.Values.ToList(); + return _proposalsToRelease.Values; } public bool TryGetProposalCreatedHeight(Hash proposalId, out long height) diff --git a/src/AElf.Kernel.CodeCheck/Infrastructure/ICodeCheckProposalProvider.cs b/src/AElf.Kernel.CodeCheck/Infrastructure/ICodeCheckProposalProvider.cs index 403114fd39..b582b74e5e 100644 --- a/src/AElf.Kernel.CodeCheck/Infrastructure/ICodeCheckProposalProvider.cs +++ b/src/AElf.Kernel.CodeCheck/Infrastructure/ICodeCheckProposalProvider.cs @@ -6,7 +6,7 @@ namespace AElf.Kernel.CodeCheck.Infrastructure; public interface ICodeCheckProposalProvider { void AddProposal(Hash proposalId, Hash proposalInputHash, long height); - List GetAllProposals(); + IEnumerable GetAllProposals(); bool TryGetProposalCreatedHeight(Hash proposalId, out long height); void RemoveProposalById(Hash proposalId); } \ No newline at end of file diff --git a/src/AElf.Kernel.Configuration/AElf.Kernel.Configuration.csproj b/src/AElf.Kernel.Configuration/AElf.Kernel.Configuration.csproj index 842741825b..e6cb671608 100644 --- a/src/AElf.Kernel.Configuration/AElf.Kernel.Configuration.csproj +++ b/src/AElf.Kernel.Configuration/AElf.Kernel.Configuration.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 latest AElf.Kernel.Configuration true @@ -25,6 +25,6 @@ - + \ No newline at end of file diff --git a/src/AElf.Kernel.Consensus.AEDPoS/AElf.Kernel.Consensus.AEDPoS.csproj b/src/AElf.Kernel.Consensus.AEDPoS/AElf.Kernel.Consensus.AEDPoS.csproj index fc3fc47069..0df27c0df6 100644 --- a/src/AElf.Kernel.Consensus.AEDPoS/AElf.Kernel.Consensus.AEDPoS.csproj +++ b/src/AElf.Kernel.Consensus.AEDPoS/AElf.Kernel.Consensus.AEDPoS.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 latest AElf.Kernel.Consensus.AEDPoS true diff --git a/src/AElf.Kernel.Consensus.Core/AElf.Kernel.Consensus.Core.csproj b/src/AElf.Kernel.Consensus.Core/AElf.Kernel.Consensus.Core.csproj index d24ddf32c1..8bf006e0a9 100644 --- a/src/AElf.Kernel.Consensus.Core/AElf.Kernel.Consensus.Core.csproj +++ b/src/AElf.Kernel.Consensus.Core/AElf.Kernel.Consensus.Core.csproj @@ -1,7 +1,7 @@ - - + + - net6.0 + net8.0 AElf.Kernel.Consensus AElf.Kernel.Consensus.Core true @@ -10,7 +10,7 @@ - + diff --git a/src/AElf.Kernel.Consensus.Core/Application/ConsensusService.cs b/src/AElf.Kernel.Consensus.Core/Application/ConsensusService.cs index 50a75d9f90..21a3a41fbf 100644 --- a/src/AElf.Kernel.Consensus.Core/Application/ConsensusService.cs +++ b/src/AElf.Kernel.Consensus.Core/Application/ConsensusService.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AElf.CSharp.Core.Extension; @@ -18,6 +19,7 @@ internal class ConsensusService : IConsensusService, ISingletonDependency { private readonly IBlockTimeProvider _blockTimeProvider; private readonly IConsensusReaderContextService _consensusReaderContextService; + private readonly IMiningTimeProvider _miningTimeProvider; private readonly IConsensusScheduler _consensusScheduler; private readonly IContractReaderFactory @@ -31,13 +33,15 @@ private readonly IContractReaderFactory contractReaderFactory, ITriggerInformationProvider triggerInformationProvider, - IBlockTimeProvider blockTimeProvider, IConsensusReaderContextService consensusReaderContextService) + IBlockTimeProvider blockTimeProvider, IConsensusReaderContextService consensusReaderContextService, + IMiningTimeProvider miningTimeProvider) { _contractReaderFactory = contractReaderFactory; _triggerInformationProvider = triggerInformationProvider; _blockTimeProvider = blockTimeProvider; _consensusReaderContextService = consensusReaderContextService; _consensusScheduler = consensusScheduler; + _miningTimeProvider = miningTimeProvider; Logger = NullLogger.Instance; LocalEventBus = NullLocalEventBus.Instance; @@ -86,11 +90,19 @@ public async Task TriggerConsensusAsync(ChainContext chainContext) ? new Duration { Seconds = ConsensusConstants.MaximumLeftMillisecondsForNextBlock } : leftMilliseconds; + var configuredMiningTime = await _miningTimeProvider.GetLimitMillisecondsOfMiningBlockAsync(new BlockIndex + { + BlockHeight = chainContext.BlockHeight, + BlockHash = chainContext.BlockHash + }); + var limitMillisecondsOfMiningBlock = configuredMiningTime == 0 + ? _consensusCommand.LimitMillisecondsOfMiningBlock + : configuredMiningTime; // Update consensus scheduler. var blockMiningEventData = new ConsensusRequestMiningEventData(chainContext.BlockHash, chainContext.BlockHeight, _nextMiningTime, - TimestampHelper.DurationFromMilliseconds(_consensusCommand.LimitMillisecondsOfMiningBlock), + TimestampHelper.DurationFromMilliseconds(limitMillisecondsOfMiningBlock), _consensusCommand.MiningDueTime); _consensusScheduler.CancelCurrentEvent(); _consensusScheduler.NewEvent(leftMilliseconds.Milliseconds(), blockMiningEventData); diff --git a/src/AElf.Kernel.Consensus.Core/Application/IMiningTimeProvider.cs b/src/AElf.Kernel.Consensus.Core/Application/IMiningTimeProvider.cs new file mode 100644 index 0000000000..06500adeed --- /dev/null +++ b/src/AElf.Kernel.Consensus.Core/Application/IMiningTimeProvider.cs @@ -0,0 +1,50 @@ +using System.Threading.Tasks; +using AElf.Kernel.SmartContract.Application; +using Google.Protobuf.WellKnownTypes; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.Consensus.Application; + +public interface IMiningTimeProvider +{ + Task SetLimitMillisecondsOfMiningBlockAsync(IBlockIndex blockIndex, long limit); + Task GetLimitMillisecondsOfMiningBlockAsync(IBlockIndex blockIndex); +} + +public class MiningTimeProvider : BlockExecutedDataBaseProvider, + IMiningTimeProvider, ISingletonDependency +{ + private const string BlockExecutedDataName = "LimitMillisecondsOfMiningBlock"; + + public MiningTimeProvider( + ICachedBlockchainExecutedDataService cachedBlockchainExecutedDataService) : base( + cachedBlockchainExecutedDataService) + { + Logger = NullLogger.Instance; + } + + public ILogger Logger { get; set; } + + public Task GetLimitMillisecondsOfMiningBlockAsync(IBlockIndex blockIndex) + { + var limit = GetBlockExecutedData(blockIndex); + return Task.FromResult(limit?.Value ?? 0); + } + + public async Task SetLimitMillisecondsOfMiningBlockAsync(IBlockIndex blockIndex, long limit) + { + var blockTransactionLimit = new Int64Value + { + Value = limit + }; + await AddBlockExecutedDataAsync(blockIndex, blockTransactionLimit); + Logger.LogDebug($"LimitMillisecondsOfMiningBlock has been changed to {limit}"); + } + + protected override string GetBlockExecutedDataName() + { + return BlockExecutedDataName; + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.Consensus.Core/Application/MiningTimeConfigurationProcessor.cs b/src/AElf.Kernel.Consensus.Core/Application/MiningTimeConfigurationProcessor.cs new file mode 100644 index 0000000000..db407cd710 --- /dev/null +++ b/src/AElf.Kernel.Consensus.Core/Application/MiningTimeConfigurationProcessor.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using AElf.Kernel.Configuration; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.Consensus.Application; + +public class MiningTimeConfigurationProcessor : IConfigurationProcessor, ITransientDependency +{ + private readonly IMiningTimeProvider _miningTimeProvider; + + public MiningTimeConfigurationProcessor(IMiningTimeProvider miningTimeProvider) + { + _miningTimeProvider = miningTimeProvider; + } + + public string ConfigurationName => ConsensusConstants.MiningTimeConfigurationName; + + public async Task ProcessConfigurationAsync(ByteString byteString, BlockIndex blockIndex) + { + var limit = new Int64Value(); + limit.MergeFrom(byteString); + if (limit.Value < 0) return; + await _miningTimeProvider.SetLimitMillisecondsOfMiningBlockAsync(blockIndex, limit.Value); + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.Consensus.Core/ConsensusConstants.cs b/src/AElf.Kernel.Consensus.Core/ConsensusConstants.cs index 4b838b9fac..7bd3766d46 100644 --- a/src/AElf.Kernel.Consensus.Core/ConsensusConstants.cs +++ b/src/AElf.Kernel.Consensus.Core/ConsensusConstants.cs @@ -5,4 +5,6 @@ public static class ConsensusConstants public const long MaximumLeftMillisecondsForNextBlock = 3600_000; public const string ConsensusExtraDataKey = "Consensus"; + + public const string MiningTimeConfigurationName = "MiningTime"; } \ No newline at end of file diff --git a/src/AElf.Kernel.Consensus.Core/CoreConsensusAElfModule.cs b/src/AElf.Kernel.Consensus.Core/CoreConsensusAElfModule.cs index 4535545f26..0437a38b78 100644 --- a/src/AElf.Kernel.Consensus.Core/CoreConsensusAElfModule.cs +++ b/src/AElf.Kernel.Consensus.Core/CoreConsensusAElfModule.cs @@ -1,4 +1,5 @@ using AElf.Kernel.Blockchain.Application; +using AElf.Kernel.Configuration; using AElf.Kernel.Consensus.Application; using AElf.Kernel.Miner.Application; using AElf.Modularity; @@ -7,6 +8,7 @@ namespace AElf.Kernel.Consensus; +[DependsOn(typeof(ConfigurationAElfModule))] public class CoreConsensusAElfModule : AElfModule { public override void ConfigureServices(ServiceConfigurationContext context) @@ -15,5 +17,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddTransient(); context.Services.AddSingleton(); context.Services.AddTransient(); + context.Services.AddTransient(typeof(IConfigurationProcessor), + typeof(MiningTimeConfigurationProcessor)); } } \ No newline at end of file diff --git a/src/AElf.Kernel.Consensus.Scheduler.FluentScheduler/AElf.Kernel.Consensus.Scheduler.FluentScheduler.csproj b/src/AElf.Kernel.Consensus.Scheduler.FluentScheduler/AElf.Kernel.Consensus.Scheduler.FluentScheduler.csproj index 5eca3a7a60..1a6814fffe 100644 --- a/src/AElf.Kernel.Consensus.Scheduler.FluentScheduler/AElf.Kernel.Consensus.Scheduler.FluentScheduler.csproj +++ b/src/AElf.Kernel.Consensus.Scheduler.FluentScheduler/AElf.Kernel.Consensus.Scheduler.FluentScheduler.csproj @@ -1,19 +1,19 @@ - - + + - net6.0 + net8.0 AElf.Kernel.Consensus.Scheduler.FluentScheduler true Scheduler implementation for AEDPos using FluentScheduler. - + - + diff --git a/src/AElf.Kernel.Consensus.Scheduler.RxNet/AElf.Kernel.Consensus.Scheduler.RxNet.csproj b/src/AElf.Kernel.Consensus.Scheduler.RxNet/AElf.Kernel.Consensus.Scheduler.RxNet.csproj index dfd729dd0c..963881ceea 100644 --- a/src/AElf.Kernel.Consensus.Scheduler.RxNet/AElf.Kernel.Consensus.Scheduler.RxNet.csproj +++ b/src/AElf.Kernel.Consensus.Scheduler.RxNet/AElf.Kernel.Consensus.Scheduler.RxNet.csproj @@ -1,19 +1,19 @@ - - + + - net6.0 + net8.0 AElf.Kernel.Consensus.Scheduler.RxNet true Scheduler implementation for AEDPos using RxNet. - + - + diff --git a/src/AElf.Kernel.Core/AElf.Kernel.Core.csproj b/src/AElf.Kernel.Core/AElf.Kernel.Core.csproj index 99ddd91f24..e96f07073b 100644 --- a/src/AElf.Kernel.Core/AElf.Kernel.Core.csproj +++ b/src/AElf.Kernel.Core/AElf.Kernel.Core.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Kernel latest AElf.Kernel.Core @@ -13,8 +13,10 @@ true + + - + diff --git a/src/AElf.Kernel.Core/Blockchain/Domain/IChainManager.cs b/src/AElf.Kernel.Core/Blockchain/Domain/IChainManager.cs index 06bcd4b719..7f6ca2cb4e 100644 --- a/src/AElf.Kernel.Core/Blockchain/Domain/IChainManager.cs +++ b/src/AElf.Kernel.Core/Blockchain/Domain/IChainManager.cs @@ -2,6 +2,7 @@ using System.Linq; using AElf.Kernel.Blockchain.Infrastructure; using AElf.Kernel.Infrastructure; +using Microsoft.Extensions.Caching.Memory; namespace AElf.Kernel.Blockchain.Domain; @@ -49,6 +50,7 @@ public class ChainManager : IChainManager, ISingletonDependency private readonly IChainBlockLinkCacheProvider _chainBlockLinkCacheProvider; private readonly IBlockchainStore _chainBlockLinks; private readonly IBlockchainStore _chains; + private readonly Dictionary _chainCache; private readonly IStaticChainInformationProvider _staticChainInformationProvider; @@ -63,6 +65,7 @@ public ChainManager(IBlockchainStore chains, _chainBlockIndexes = chainBlockIndexes; _staticChainInformationProvider = staticChainInformationProvider; _chainBlockLinkCacheProvider = chainBlockLinkCacheProvider; + _chainCache = new Dictionary(); } private int ChainId => _staticChainInformationProvider.ChainId; @@ -104,12 +107,19 @@ await SetChainBlockLinkAsync(new ChainBlockLink await _chains.SetAsync(ChainId.ToStorageKey(), chain); + // Update the cache. + _chainCache[ChainId] = chain; return chain; } public async Task GetAsync() { - var chain = await _chains.GetAsync(ChainId.ToStorageKey()); + if (_chainCache.TryGetValue(ChainId, out var chain)) + { + return chain?.Clone(); + } + chain = await _chains.GetAsync(ChainId.ToStorageKey()); + _chainCache[ChainId] = chain; return chain; } @@ -220,6 +230,9 @@ public async Task AttachBlockToChainAsync(Chain chai Logger.LogInformation($"Attach {chainBlockLink.BlockHash} to longest chain, status: {status}, " + $"longest chain height: {chain.LongestChainHeight}, longest chain hash: {chain.LongestChainHash}"); + // Update the cache. + _chainCache[ChainId] = chain; + return status; } @@ -250,6 +263,9 @@ public async Task SetIrreversibleBlockAsync(Chain chain, Hash irreversible chain.LastIrreversibleBlockHeight = links.First().Height; await _chains.SetAsync(chain.Id.ToStorageKey(), chain); + // Update the cache. + _chainCache[ChainId] = chain; + Logger.LogDebug( $"Setting chain lib height: {chain.LastIrreversibleBlockHeight}, chain lib hash: {chain.LastIrreversibleBlockHash}"); @@ -322,6 +338,9 @@ public async Task SetBestChainAsync(Chain chain, long bestChainHeight, Hash best chain.BestChainHash = bestChainHash; await _chains.SetAsync(chain.Id.ToStorageKey(), chain); + + // Update the cache. + _chainCache[ChainId] = chain; } public int GetChainId() @@ -417,6 +436,9 @@ public async Task CleanChainBranchAsync(Chain chain, DiscardedBranch discardedBr $"Clean chain branch, Branches: [{discardedBranch.BranchKeys.JoinAsString(",")}], NotLinkedBlocks: [{discardedBranch.NotLinkedKeys.JoinAsString(",")}]"); await _chains.SetAsync(chain.Id.ToStorageKey(), chain); + + // Update the cache. + _chainCache[ChainId] = chain; } public async Task RemoveLongestBranchAsync(Chain chain) @@ -430,6 +452,9 @@ public async Task RemoveLongestBranchAsync(Chain chain) $"Switch Longest chain to height: {chain.LongestChainHeight}, hash: {chain.LongestChainHash}."); await _chains.SetAsync(chain.Id.ToStorageKey(), chain); + + // Update the cache. + _chainCache[ChainId] = chain; } public async Task ResetChainToLibAsync(Chain chain) @@ -465,6 +490,9 @@ public async Task ResetChainToLibAsync(Chain chain) Logger.LogInformation($"Rollback to height {chain.BestChainHeight}, hash {chain.BestChainHash}."); await _chains.SetAsync(chain.Id.ToStorageKey(), chain); + // Update the cache. + _chainCache[ChainId] = chain; + return chain; } diff --git a/src/AElf.Kernel.Core/Blockchain/Domain/IInvalidTransactionResultManager.cs b/src/AElf.Kernel.Core/Blockchain/Domain/IInvalidTransactionResultManager.cs new file mode 100644 index 0000000000..9c29556ad1 --- /dev/null +++ b/src/AElf.Kernel.Core/Blockchain/Domain/IInvalidTransactionResultManager.cs @@ -0,0 +1,33 @@ +using System.Linq; +using AElf.Kernel.Blockchain.Infrastructure; +using AElf.Kernel.Infrastructure; + +namespace AElf.Kernel.Blockchain.Domain; + +public interface IInvalidTransactionResultManager +{ + Task AddInvalidTransactionResultAsync(InvalidTransactionResult transactionResult); + Task GetInvalidTransactionResultAsync(Hash transactionId); +} + +public class InvalidTransactionResultManager : IInvalidTransactionResultManager +{ + private readonly IBlockchainStore _invalidTransactionResultStore; + + public InvalidTransactionResultManager(IBlockchainStore invalidTransactionResultStore) + { + _invalidTransactionResultStore = invalidTransactionResultStore; + } + + public async Task AddInvalidTransactionResultAsync(InvalidTransactionResult transactionResult) + { + await _invalidTransactionResultStore.SetAsync(transactionResult.TransactionId.ToStorageKey(), transactionResult); + } + + + public async Task GetInvalidTransactionResultAsync(Hash transactionId) + { + return await _invalidTransactionResultStore.GetAsync(transactionId.ToStorageKey()); + } + +} \ No newline at end of file diff --git a/src/AElf.Kernel.Core/CoreKernelAElfModule.cs b/src/AElf.Kernel.Core/CoreKernelAElfModule.cs index 86df74b631..0dcf8b87bb 100644 --- a/src/AElf.Kernel.Core/CoreKernelAElfModule.cs +++ b/src/AElf.Kernel.Core/CoreKernelAElfModule.cs @@ -39,7 +39,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) services.AddStoreKeyPrefixProvide("ti"); services.AddStoreKeyPrefixProvide("tr"); services.AddStoreKeyPrefixProvide("vs"); - + services.AddStoreKeyPrefixProvide("ir"); services.AddTransient(typeof(IStateStore<>), typeof(StateStore<>)); services.AddSingleton(typeof(INotModifiedCachedStateStore<>), typeof(NotModifiedCachedStateStore<>)); diff --git a/src/AElf.Kernel.Core/Plugin/Application/IPluginContractProvider.cs b/src/AElf.Kernel.Core/Plugin/Application/IPluginContractProvider.cs new file mode 100644 index 0000000000..73f04c6d47 --- /dev/null +++ b/src/AElf.Kernel.Core/Plugin/Application/IPluginContractProvider.cs @@ -0,0 +1,6 @@ +namespace AElf.Kernel.Plugin.Application; + +public interface IPluginContractProvider +{ + string GetContractName(); +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj b/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj new file mode 100644 index 0000000000..7b39f518d5 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable.Core/AElf.Kernel.FeatureDisable.Core.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableConstants.cs b/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableConstants.cs new file mode 100644 index 0000000000..84ce24c6fa --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableConstants.cs @@ -0,0 +1,6 @@ +namespace AElf.Kernel.FeatureDisable.Core; + +public class FeatureDisableConstants +{ + public const string FeatureDisableConfigurationName = "DisableFeatureNameList"; +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableCoreAElfModule.cs b/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableCoreAElfModule.cs new file mode 100644 index 0000000000..c9e524ec01 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable.Core/FeatureDisableCoreAElfModule.cs @@ -0,0 +1,11 @@ +using AElf.Modularity; +using Volo.Abp.Modularity; + +namespace AElf.Kernel.FeatureDisable.Core; + +public class FeatureDisableCoreAElfModule : AElfModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable.Core/IFeatureDisableService.cs b/src/AElf.Kernel.FeatureDisable.Core/IFeatureDisableService.cs new file mode 100644 index 0000000000..0131adc57b --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable.Core/IFeatureDisableService.cs @@ -0,0 +1,16 @@ +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.FeatureDisable.Core; + +public interface IFeatureDisableService +{ + Task IsFeatureDisabledAsync(params string[] featureNames); +} + +public class DefaultFeatureDisableService : IFeatureDisableService, ITransientDependency +{ + public Task IsFeatureDisabledAsync(params string[] featureNames) + { + return Task.FromResult(false); + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj b/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj new file mode 100644 index 0000000000..fae7fc0cdf --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/AElf.Kernel.FeatureDisable.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/src/AElf.Kernel.FeatureDisable/DisableFeatureOptions.cs b/src/AElf.Kernel.FeatureDisable/DisableFeatureOptions.cs new file mode 100644 index 0000000000..f5968ba95a --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/DisableFeatureOptions.cs @@ -0,0 +1,6 @@ +namespace AElf.Kernel.FeatureDisable; + +public class DisableFeatureOptions +{ + public List FeatureNameList { get; set; } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable/FeatureDisableAElfModule.cs b/src/AElf.Kernel.FeatureDisable/FeatureDisableAElfModule.cs new file mode 100644 index 0000000000..705246e612 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/FeatureDisableAElfModule.cs @@ -0,0 +1,15 @@ +using AElf.Kernel.Configuration; +using AElf.Kernel.FeatureDisable.Core; +using AElf.Modularity; +using Volo.Abp.Modularity; + +namespace AElf.Kernel.FeatureDisable; + +[DependsOn(typeof(FeatureDisableCoreAElfModule), + typeof(ConfigurationAElfModule))] +public class FeatureDisableAElfModule : AElfModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable/FeatureDisableConfigurationProcessor.cs b/src/AElf.Kernel.FeatureDisable/FeatureDisableConfigurationProcessor.cs new file mode 100644 index 0000000000..1adb8c45a9 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/FeatureDisableConfigurationProcessor.cs @@ -0,0 +1,26 @@ +using AElf.Kernel.Configuration; +using AElf.Kernel.FeatureDisable.Core; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.FeatureDisable; + +public class FeatureDisableConfigurationProcessor : IConfigurationProcessor, ITransientDependency +{ + private readonly IDisabledFeatureListProvider _disabledFeatureListProvider; + + public FeatureDisableConfigurationProcessor(IDisabledFeatureListProvider disabledFeatureListProvider) + { + _disabledFeatureListProvider = disabledFeatureListProvider; + } + + public string ConfigurationName => FeatureDisableConstants.FeatureDisableConfigurationName; + + public async Task ProcessConfigurationAsync(ByteString byteString, BlockIndex blockIndex) + { + var featureNameList = new StringValue(); + featureNameList.MergeFrom(byteString); + await _disabledFeatureListProvider.SetDisabledFeatureListAsync(blockIndex, featureNameList.Value); + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable/FeatureDisableService.cs b/src/AElf.Kernel.FeatureDisable/FeatureDisableService.cs new file mode 100644 index 0000000000..2ac30dbe73 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/FeatureDisableService.cs @@ -0,0 +1,41 @@ +using AElf.Kernel.Blockchain.Application; +using AElf.Kernel.FeatureDisable.Core; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.FeatureDisable; + +public class FeatureDisableService : IFeatureDisableService, ITransientDependency +{ + private readonly IDisabledFeatureListProvider _disabledFeatureListProvider; + private readonly IBlockchainService _blockchainService; + + public FeatureDisableService(IDisabledFeatureListProvider disabledFeatureListProvider, + IBlockchainService blockchainService) + { + _disabledFeatureListProvider = disabledFeatureListProvider; + _blockchainService = blockchainService; + } + + public async Task IsFeatureDisabledAsync(params string[] featureNames) + { + var chain = await _blockchainService.GetChainAsync(); + if (chain == null || chain.BestChainHeight <= 1) + { + // Which means chain hasn't been created yet or only genesis block exists. + return false; + } + + var nameList = await _disabledFeatureListProvider.GetDisabledFeatureListAsync(new BlockIndex + { + BlockHash = chain.BestChainHash, + BlockHeight = chain.BestChainHeight + }); + if (nameList.Length == 0) + { + return false; + } + + var isDisabled = nameList.Select(n => n.Trim()).Intersect(featureNames).Any(); + return isDisabled; + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureDisable/IDisabledFeatureListProvider.cs b/src/AElf.Kernel.FeatureDisable/IDisabledFeatureListProvider.cs new file mode 100644 index 0000000000..36b05ecad1 --- /dev/null +++ b/src/AElf.Kernel.FeatureDisable/IDisabledFeatureListProvider.cs @@ -0,0 +1,49 @@ +using AElf.Kernel.SmartContract.Application; +using Google.Protobuf.WellKnownTypes; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.FeatureDisable; + +public interface IDisabledFeatureListProvider +{ + Task SetDisabledFeatureListAsync(IBlockIndex blockIndex, string disabledFeatures); + Task GetDisabledFeatureListAsync(IBlockIndex blockIndex); +} + +public class DisabledFeatureListProvider : BlockExecutedDataBaseProvider, + IDisabledFeatureListProvider, ISingletonDependency +{ + private const string BlockExecutedDataName = "DisabledFeatureList"; + + public ILogger Logger { get; set; } + + public DisabledFeatureListProvider( + ICachedBlockchainExecutedDataService cachedBlockchainExecutedDataService) : base( + cachedBlockchainExecutedDataService) + { + Logger = NullLogger.Instance; + } + + public async Task SetDisabledFeatureListAsync(IBlockIndex blockIndex, string disabledFeatures) + { + var blockTransactionLimit = new StringValue + { + Value = disabledFeatures + }; + await AddBlockExecutedDataAsync(blockIndex, blockTransactionLimit); + Logger.LogDebug($"DisabledFeatureList has been changed to {disabledFeatures}"); + } + + public Task GetDisabledFeatureListAsync(IBlockIndex blockIndex) + { + var limit = GetBlockExecutedData(blockIndex); + return Task.FromResult(limit?.Value.Split(',') ?? Array.Empty()); + } + + protected override string GetBlockExecutedDataName() + { + return BlockExecutedDataName; + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.FeatureManager/AElf.Kernel.FeatureManager.csproj b/src/AElf.Kernel.FeatureManager/AElf.Kernel.FeatureManager.csproj index dc52cc861d..20260d21b7 100644 --- a/src/AElf.Kernel.FeatureManager/AElf.Kernel.FeatureManager.csproj +++ b/src/AElf.Kernel.FeatureManager/AElf.Kernel.FeatureManager.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 latest AElf.Kernel.FeatureManager true @@ -9,7 +9,7 @@ - + diff --git a/src/AElf.Kernel.FeeCalculation/AElf.Kernel.FeeCalculation.csproj b/src/AElf.Kernel.FeeCalculation/AElf.Kernel.FeeCalculation.csproj index 1bb381ee7d..9cf99272d6 100644 --- a/src/AElf.Kernel.FeeCalculation/AElf.Kernel.FeeCalculation.csproj +++ b/src/AElf.Kernel.FeeCalculation/AElf.Kernel.FeeCalculation.csproj @@ -1,15 +1,15 @@ - + - net6.0 + net8.0 latest AElf.Kernel.FeeCalculation true Fee Calculation Project. - - + + diff --git a/src/AElf.Kernel.FeeCalculation/Extensions/TransactionResultExtensions.cs b/src/AElf.Kernel.FeeCalculation/Extensions/TransactionResultExtensions.cs index ff1233b211..138d7853f3 100644 --- a/src/AElf.Kernel.FeeCalculation/Extensions/TransactionResultExtensions.cs +++ b/src/AElf.Kernel.FeeCalculation/Extensions/TransactionResultExtensions.cs @@ -8,21 +8,30 @@ namespace AElf.Kernel.FeeCalculation.Extensions; public static class TransactionResultExtensions { - public static Dictionary GetChargedTransactionFees(this TransactionResult transactionResult) + public static Dictionary> GetChargedTransactionFees( + this TransactionResult transactionResult) { return transactionResult.Logs .Where(l => l.Name == nameof(TransactionFeeCharged)) - .Select(l => TransactionFeeCharged.Parser.ParseFrom(l.NonIndexed)) - .GroupBy(fee => fee.Symbol, fee => fee.Amount) - .ToDictionary(g => g.Key, g => g.Sum()); + .GroupBy( + log => TransactionFeeCharged.Parser.ParseFrom(log.Indexed[0]).ChargingAddress, + log => TransactionFeeCharged.Parser.ParseFrom(log.NonIndexed)) + .ToDictionary(e => e.Key, + e => e + .GroupBy(fee => fee.Symbol, fee => fee.Amount) + .ToDictionary(g => g.Key, g => g.Sum())); } - public static Dictionary GetConsumedResourceTokens(this TransactionResult transactionResult) + public static Dictionary> GetConsumedResourceTokens(this TransactionResult transactionResult) { var relatedLogs = transactionResult.Logs.Where(l => l.Name == nameof(ResourceTokenCharged)).ToList(); - if (!relatedLogs.Any()) return new Dictionary(); + if (!relatedLogs.Any()) return new Dictionary>(); return relatedLogs.Select(l => ResourceTokenCharged.Parser.ParseFrom(l.NonIndexed)) - .ToDictionary(e => e.Symbol, e => e.Amount); + .GroupBy(g => g.ContractAddress) + .ToDictionary(e => e.Key, + e => e + .GroupBy(fee => fee.Symbol, fee => fee.Amount) + .ToDictionary(g => g.Key, g => g.Sum())); } public static Dictionary GetOwningResourceTokens(this TransactionResult transactionResult) diff --git a/src/AElf.Kernel.Node/AElf.Kernel.Node.csproj b/src/AElf.Kernel.Node/AElf.Kernel.Node.csproj index 886b346a0a..80bb01b239 100644 --- a/src/AElf.Kernel.Node/AElf.Kernel.Node.csproj +++ b/src/AElf.Kernel.Node/AElf.Kernel.Node.csproj @@ -1,17 +1,17 @@ - - + + - net6.0 + net8.0 AElf.Kernel.Node true Base Module for building a node. - - - + + + diff --git a/src/AElf.Kernel.Proposal/AElf.Kernel.Proposal.csproj b/src/AElf.Kernel.Proposal/AElf.Kernel.Proposal.csproj index 417f66fc5f..c767d0942d 100644 --- a/src/AElf.Kernel.Proposal/AElf.Kernel.Proposal.csproj +++ b/src/AElf.Kernel.Proposal/AElf.Kernel.Proposal.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 latest AElf.Kernel.Proposal true @@ -9,7 +9,7 @@ - + diff --git a/src/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.csproj b/src/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.csproj index 8fa28f5c0b..6edbbe8a55 100644 --- a/src/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.csproj +++ b/src/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.csproj @@ -1,16 +1,16 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold true ACS 5 execution plugin. - - + + diff --git a/src/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.csproj b/src/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.csproj index 3c6ca0f576..d4eba82866 100644 --- a/src/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.csproj +++ b/src/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForMethodFee true ACS 1 execution plugin. diff --git a/src/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.csproj b/src/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.csproj index 3abe851ea8..fe23cb0e68 100644 --- a/src/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.csproj +++ b/src/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.csproj @@ -1,16 +1,16 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForResourceFee true ACS 8 execution plugin. - - + + @@ -35,6 +35,6 @@ - + diff --git a/src/AElf.Kernel.SmartContract.Parallel/AElf.Kernel.SmartContract.Parallel.csproj b/src/AElf.Kernel.SmartContract.Parallel/AElf.Kernel.SmartContract.Parallel.csproj index dc8ed0e072..b195f0eb27 100644 --- a/src/AElf.Kernel.SmartContract.Parallel/AElf.Kernel.SmartContract.Parallel.csproj +++ b/src/AElf.Kernel.SmartContract.Parallel/AElf.Kernel.SmartContract.Parallel.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContract.Parallel true Service module for parallel execution. @@ -21,6 +21,6 @@ - + diff --git a/src/AElf.Kernel.SmartContract.Parallel/Domain/ResourceExtractionService.cs b/src/AElf.Kernel.SmartContract.Parallel/Domain/ResourceExtractionService.cs index 028188e88b..8fd9598c7a 100644 --- a/src/AElf.Kernel.SmartContract.Parallel/Domain/ResourceExtractionService.cs +++ b/src/AElf.Kernel.SmartContract.Parallel/Domain/ResourceExtractionService.cs @@ -61,6 +61,22 @@ public async Task> GetResourcesAsync( return transactionResourceList; } + // TODO: Fix + // public async Task> GetResourcesAsync( + // IChainContext chainContext, + // IEnumerable transactions, CancellationToken ct) + // { + // var contractResourceInfoCache = new ConcurrentDictionary(); + // var transactionResourceList = await transactions.AsParallel().WithCancellation(ct).Select(async transaction => + // { + // var transactionResourcePair = + // await GetResourcesForOneWithCacheAsync(chainContext, transaction, ct, contractResourceInfoCache); + // return transactionResourcePair; + // }).WhenAll(); + // + // return transactionResourceList; + // } + public void ClearConflictingTransactionsResourceCache(IEnumerable transactionIds) { ClearResourceCache(transactionIds); @@ -215,6 +231,7 @@ public async Task HandleNewIrreversibleBlockFoundAsync(NewIrreversibleBlockFound try { ClearResourceCache(_resourceCache + //.AsParallel() .Where(c => c.Value.ResourceUsedBlockHeight <= eventData.BlockHeight) .Select(c => c.Key).Distinct().ToList()); } diff --git a/src/AElf.Kernel.SmartContract.Shared/AElf.Kernel.SmartContract.Shared.csproj b/src/AElf.Kernel.SmartContract.Shared/AElf.Kernel.SmartContract.Shared.csproj index c69bed6d92..899d51e6fa 100644 --- a/src/AElf.Kernel.SmartContract.Shared/AElf.Kernel.SmartContract.Shared.csproj +++ b/src/AElf.Kernel.SmartContract.Shared/AElf.Kernel.SmartContract.Shared.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContract AElf.Kernel.SmartContract.Shared true @@ -10,7 +10,7 @@ - + diff --git a/src/AElf.Kernel.SmartContract.Shared/ISmartContractBridgeContext.cs b/src/AElf.Kernel.SmartContract.Shared/ISmartContractBridgeContext.cs index 5f119f84b5..8840c15b01 100644 --- a/src/AElf.Kernel.SmartContract.Shared/ISmartContractBridgeContext.cs +++ b/src/AElf.Kernel.SmartContract.Shared/ISmartContractBridgeContext.cs @@ -202,4 +202,24 @@ public StateOverSizeException(string message, Exception inner) : base(message, i protected StateOverSizeException(SerializationInfo info, StreamingContext context) : base(info, context) { } +} + +[Serializable] +public class StateKeyOverSizeException : SmartContractBridgeException +{ + public StateKeyOverSizeException() + { + } + + public StateKeyOverSizeException(string message) : base(message) + { + } + + public StateKeyOverSizeException(string message, Exception inner) : base(message, inner) + { + } + + protected StateKeyOverSizeException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } \ No newline at end of file diff --git a/src/AElf.Kernel.SmartContract/AElf.Kernel.SmartContract.csproj b/src/AElf.Kernel.SmartContract/AElf.Kernel.SmartContract.csproj index 15a367eef4..ab2cf443cf 100644 --- a/src/AElf.Kernel.SmartContract/AElf.Kernel.SmartContract.csproj +++ b/src/AElf.Kernel.SmartContract/AElf.Kernel.SmartContract.csproj @@ -1,18 +1,19 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContract true High level smart contract definitions and core functionality implementation. - + + diff --git a/src/AElf.Kernel.SmartContract/Application/PlainTransactionExecutingService.cs b/src/AElf.Kernel.SmartContract/Application/PlainTransactionExecutingService.cs index 66045dc7bc..79b09034f9 100644 --- a/src/AElf.Kernel.SmartContract/Application/PlainTransactionExecutingService.cs +++ b/src/AElf.Kernel.SmartContract/Application/PlainTransactionExecutingService.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using AElf.Kernel.FeatureDisable.Core; using AElf.Kernel.SmartContract.Domain; using AElf.Kernel.SmartContract.Infrastructure; using AElf.Types; @@ -21,13 +22,15 @@ public class PlainTransactionExecutingService : IPlainTransactionExecutingServic private readonly List _prePlugins; private readonly ISmartContractExecutiveService _smartContractExecutiveService; private readonly ITransactionContextFactory _transactionContextFactory; + private readonly IFeatureDisableService _featureDisableService; public PlainTransactionExecutingService(ISmartContractExecutiveService smartContractExecutiveService, IEnumerable postPlugins, IEnumerable prePlugins, - ITransactionContextFactory transactionContextFactory) + ITransactionContextFactory transactionContextFactory, IFeatureDisableService featureDisableService) { _smartContractExecutiveService = smartContractExecutiveService; _transactionContextFactory = transactionContextFactory; + _featureDisableService = featureDisableService; _prePlugins = GetUniquePlugins(prePlugins); _postPlugins = GetUniquePlugins(postPlugins); Logger = NullLogger.Instance; @@ -250,6 +253,11 @@ private async Task ExecutePluginOnPreTransactionStageAsync(IExecutive exec TieredStateCache internalStateCache, CancellationToken cancellationToken) { + if (await _featureDisableService.IsFeatureDisabledAsync("TxPlugin", "PrePlugin")) + { + return true; + } + var trace = txContext.Trace; foreach (var plugin in _prePlugins) { @@ -296,6 +304,11 @@ private async Task ExecutePluginOnPostTransactionStageAsync(IExecutive exe TieredStateCache internalStateCache, CancellationToken cancellationToken) { + if (await _featureDisableService.IsFeatureDisabledAsync("TxPlugin", "PostPlugin")) + { + return true; + } + var trace = txContext.Trace; if (!trace.IsSuccessful()) diff --git a/src/AElf.Kernel.SmartContract/Application/SmartContractExecutiveService.cs b/src/AElf.Kernel.SmartContract/Application/SmartContractExecutiveService.cs index 06d0bff8dd..9b013653e2 100644 --- a/src/AElf.Kernel.SmartContract/Application/SmartContractExecutiveService.cs +++ b/src/AElf.Kernel.SmartContract/Application/SmartContractExecutiveService.cs @@ -14,7 +14,7 @@ namespace AElf.Kernel.SmartContract.Application; public class SmartContractExecutiveService : ISmartContractExecutiveService, ISingletonDependency { private const int ExecutiveExpirationTime = 3600; // 1 Hour - private const int ExecutiveClearLimit = 10; + private const int ExecutiveClearLimit = 50; private readonly IDefaultContractZeroCodeProvider _defaultContractZeroCodeProvider; private readonly IHostSmartContractBridgeContextService _hostSmartContractBridgeContextService; diff --git a/src/AElf.Kernel.SmartContract/HostSmartContractBridgeContext.cs b/src/AElf.Kernel.SmartContract/HostSmartContractBridgeContext.cs index 5f867b012d..3b723c3227 100644 --- a/src/AElf.Kernel.SmartContract/HostSmartContractBridgeContext.cs +++ b/src/AElf.Kernel.SmartContract/HostSmartContractBridgeContext.cs @@ -111,6 +111,11 @@ public void Initialize(ITransactionContext transactionContext) public async Task GetStateAsync(string key) { + if (key.Length > SmartContractConstants.StateKeyMaximumLength) + { + throw new StateKeyOverSizeException( + $"Length of state key {key} exceeds limit of {SmartContractConstants.StateKeyMaximumLength}."); + } return await _smartContractBridgeService.GetStateAsync( Self, key, CurrentHeight - 1, PreviousBlockHash); } diff --git a/src/AElf.Kernel.SmartContract/SmartContractAElfModule.cs b/src/AElf.Kernel.SmartContract/SmartContractAElfModule.cs index e8e62a97c8..670ee60cdb 100644 --- a/src/AElf.Kernel.SmartContract/SmartContractAElfModule.cs +++ b/src/AElf.Kernel.SmartContract/SmartContractAElfModule.cs @@ -1,3 +1,4 @@ +using AElf.Kernel.FeatureDisable.Core; using AElf.Kernel.SmartContract.Application; using AElf.Kernel.SmartContract.Infrastructure; using AElf.Modularity; @@ -6,7 +7,8 @@ namespace AElf.Kernel.SmartContract; -[DependsOn(typeof(CoreKernelAElfModule))] +[DependsOn(typeof(CoreKernelAElfModule), + typeof(FeatureDisableCoreAElfModule))] public class SmartContractAElfModule : AElfModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/src/AElf.Kernel.SmartContract/SmartContractConstants.cs b/src/AElf.Kernel.SmartContract/SmartContractConstants.cs index 0a6cb05208..9a210289ce 100644 --- a/src/AElf.Kernel.SmartContract/SmartContractConstants.cs +++ b/src/AElf.Kernel.SmartContract/SmartContractConstants.cs @@ -7,4 +7,7 @@ public class SmartContractConstants public const int ExecutionBranchThreshold = 15000; public const int StateSizeLimit = 128 * 1024; + + // The prefix `vs` occupies 2 lengths. + public const int StateKeyMaximumLength = 255 - 2; } \ No newline at end of file diff --git a/src/AElf.Kernel.SmartContractExecution/AElf.Kernel.SmartContractExecution.csproj b/src/AElf.Kernel.SmartContractExecution/AElf.Kernel.SmartContractExecution.csproj index ab40e1634d..c1ae56325e 100644 --- a/src/AElf.Kernel.SmartContractExecution/AElf.Kernel.SmartContractExecution.csproj +++ b/src/AElf.Kernel.SmartContractExecution/AElf.Kernel.SmartContractExecution.csproj @@ -1,15 +1,15 @@ - - + + - net6.0 + net8.0 AElf.Kernel.SmartContractExecution true Smart contract execution related components. - - + + diff --git a/src/AElf.Kernel.SmartContractExecution/Application/BlockExecutionResultProcessingService.cs b/src/AElf.Kernel.SmartContractExecution/Application/BlockExecutionResultProcessingService.cs index 0c02156f93..d8871bc2e4 100644 --- a/src/AElf.Kernel.SmartContractExecution/Application/BlockExecutionResultProcessingService.cs +++ b/src/AElf.Kernel.SmartContractExecution/Application/BlockExecutionResultProcessingService.cs @@ -53,8 +53,8 @@ await LocalEventBus.PublishAsync(new BlocksExecutionSucceededEvent BlockExecutedSets = blockExecutionResult.SuccessBlockExecutedSets }); - Logger.LogInformation( - $"Attach blocks to best chain, best chain hash: {chain.BestChainHash}, height: {chain.BestChainHeight}"); + // Logger.LogInformation( + // $"Attach blocks to best chain, best chain hash: {chain.BestChainHash}, height: {chain.BestChainHeight}"); } private async Task SetBlockExecutionStatusAsync(IEnumerable blockHashes, diff --git a/src/AElf.Kernel.SmartContractExecution/Extensions/BlockchainServiceExtensions.cs b/src/AElf.Kernel.SmartContractExecution/Extensions/BlockchainServiceExtensions.cs index 0d35970d9c..1cabfd0161 100644 --- a/src/AElf.Kernel.SmartContractExecution/Extensions/BlockchainServiceExtensions.cs +++ b/src/AElf.Kernel.SmartContractExecution/Extensions/BlockchainServiceExtensions.cs @@ -11,9 +11,8 @@ public static class BlockchainServiceExtensions public static async Task> GetBlocksAsync(this IBlockchainService blockchainService, IEnumerable blockHashes) { - var list = blockHashes - .Select(async blockHash => await blockchainService.GetBlockByHashAsync(blockHash)); - - return (await Task.WhenAll(list)).ToList(); + var tasks = blockHashes.Select(blockchainService.GetBlockByHashAsync); + var blocks = await Task.WhenAll(tasks); + return blocks.ToList(); } } \ No newline at end of file diff --git a/src/AElf.Kernel.Token/AElf.Kernel.Token.csproj b/src/AElf.Kernel.Token/AElf.Kernel.Token.csproj index 0ed272fad3..33d51d7019 100644 --- a/src/AElf.Kernel.Token/AElf.Kernel.Token.csproj +++ b/src/AElf.Kernel.Token/AElf.Kernel.Token.csproj @@ -1,16 +1,16 @@ - - + + - net6.0 + net8.0 AElf.Kernel.Token true Core token package. - - + + diff --git a/src/AElf.Kernel.TransactionPool/AElf.Kernel.TransactionPool.csproj b/src/AElf.Kernel.TransactionPool/AElf.Kernel.TransactionPool.csproj index 59b7350b5d..0cbf5e63a7 100644 --- a/src/AElf.Kernel.TransactionPool/AElf.Kernel.TransactionPool.csproj +++ b/src/AElf.Kernel.TransactionPool/AElf.Kernel.TransactionPool.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Kernel.TransactionPool true latest @@ -10,7 +10,7 @@ - + diff --git a/src/AElf.Kernel.TransactionPool/Application/IInvalidTransactionResultService.cs b/src/AElf.Kernel.TransactionPool/Application/IInvalidTransactionResultService.cs new file mode 100644 index 0000000000..0a1d13c0bf --- /dev/null +++ b/src/AElf.Kernel.TransactionPool/Application/IInvalidTransactionResultService.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using AElf.Kernel.Blockchain.Domain; +using AElf.Types; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.TransactionPool.Application; + + +public interface IInvalidTransactionResultService +{ + Task AddInvalidTransactionResultsAsync(InvalidTransactionResult transactionResult); + Task GetInvalidTransactionResultAsync(Hash transactionId); +} + +public class InvalidTransactionResultService : IInvalidTransactionResultService, ITransientDependency +{ + private readonly IInvalidTransactionResultManager _invalidTransactionResultManager; + + public InvalidTransactionResultService(IInvalidTransactionResultManager invalidTransactionResultManager) + { + _invalidTransactionResultManager = invalidTransactionResultManager; + } + + public async Task AddInvalidTransactionResultsAsync(InvalidTransactionResult transactionResult) + { + await _invalidTransactionResultManager.AddInvalidTransactionResultAsync(transactionResult); + } + + public async Task GetInvalidTransactionResultAsync(Hash transactionId) + { + return await _invalidTransactionResultManager.GetInvalidTransactionResultAsync(transactionId); + } +} \ No newline at end of file diff --git a/src/AElf.Kernel.TransactionPool/Application/TransactionValidationService.cs b/src/AElf.Kernel.TransactionPool/Application/TransactionValidationService.cs index fc33b15bbc..324cfb14d6 100644 --- a/src/AElf.Kernel.TransactionPool/Application/TransactionValidationService.cs +++ b/src/AElf.Kernel.TransactionPool/Application/TransactionValidationService.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AElf.Kernel.Blockchain.Application; using AElf.Kernel.Txn.Application; @@ -32,31 +33,32 @@ public TransactionValidationService( /// /// /// - public async Task ValidateTransactionWhileCollectingAsync(IChainContext chainContext, - Transaction transaction) + public async Task ValidateTransactionWhileCollectingAsync(IChainContext chainContext, Transaction transaction) { - foreach (var provider in _transactionValidationProviders) + var validationTasks = _transactionValidationProviders.AsParallel().Select(async provider => { - if (await provider.ValidateTransactionAsync(transaction, chainContext)) continue; + if (await provider.ValidateTransactionAsync(transaction, chainContext)) return true; Logger.LogDebug( $"[ValidateTransactionWhileCollectingAsync]Transaction {transaction.GetHash()} validation failed in {provider.GetType()}"); return false; - } + }); - return true; + var results = await Task.WhenAll(validationTasks); + return results.All(result => result); } public async Task ValidateTransactionWhileSyncingAsync(Transaction transaction) { - foreach (var provider in _transactionValidationProviders) - { - if (!provider.ValidateWhileSyncing || - await provider.ValidateTransactionAsync(transaction)) continue; - Logger.LogDebug( - $"[ValidateTransactionWhileSyncingAsync]Transaction {transaction.GetHash()} validation failed in {provider.GetType()}"); - return false; - } + var validationTasks = _transactionValidationProviders.AsParallel() + .Where(provider => provider.ValidateWhileSyncing).Select(async provider => + { + if (await provider.ValidateTransactionAsync(transaction)) return true; + Logger.LogDebug( + $"[ValidateTransactionWhileSyncingAsync]Transaction {transaction.GetHash()} validation failed in {provider.GetType()}"); + return false; + }); - return true; + var results = await Task.WhenAll(validationTasks); + return results.All(result => result); } } \ No newline at end of file diff --git a/src/AElf.Kernel.TransactionPool/Handler/TransactionValidationStatusFailedEventHandler.cs b/src/AElf.Kernel.TransactionPool/Handler/TransactionValidationStatusFailedEventHandler.cs new file mode 100644 index 0000000000..414cc76036 --- /dev/null +++ b/src/AElf.Kernel.TransactionPool/Handler/TransactionValidationStatusFailedEventHandler.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using AElf.Kernel.TransactionPool.Application; +using AElf.Types; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus; + +namespace AElf.Kernel.TransactionPool.Handler; + +public class TransactionValidationStatusFailedEventHandler : + ILocalEventHandler, + ITransientDependency +{ + private readonly IEnumerable _failStatus = new List + { + TransactionResultStatus.Failed, TransactionResultStatus.NodeValidationFailed, TransactionResultStatus.Conflict + }; + + private readonly IInvalidTransactionResultService _invalidTransactionResultService; + private readonly TransactionOptions _transactionOptions; + + public TransactionValidationStatusFailedEventHandler( + IOptionsMonitor transactionOptionsMonitor, + IInvalidTransactionResultService invalidTransactionResultService) + { + _invalidTransactionResultService = invalidTransactionResultService; + _transactionOptions = transactionOptionsMonitor.CurrentValue; + } + + public async Task HandleEventAsync(TransactionValidationStatusChangedEvent eventData) + { + if (!_failStatus.Contains(eventData.TransactionResultStatus)) return; + if (!_transactionOptions.StoreInvalidTransactionResultEnabled) return; + + // save to storage + await _invalidTransactionResultService.AddInvalidTransactionResultsAsync( + new InvalidTransactionResult + { + TransactionId = eventData.TransactionId, + Status = eventData.TransactionResultStatus, + Error = TakeErrorMessage(eventData.Error) + }); + } + + private string TakeErrorMessage(string transactionResultError) + { + if (string.IsNullOrWhiteSpace(transactionResultError)) + return null; + using var stringReader = new StringReader(transactionResultError); + return stringReader.ReadLine(); + } + +} \ No newline at end of file diff --git a/src/AElf.Kernel.TransactionPool/Infrastructure/TxHub.cs b/src/AElf.Kernel.TransactionPool/Infrastructure/TxHub.cs index eeb7a21242..2412494f97 100644 --- a/src/AElf.Kernel.TransactionPool/Infrastructure/TxHub.cs +++ b/src/AElf.Kernel.TransactionPool/Infrastructure/TxHub.cs @@ -55,7 +55,8 @@ public TxHub(ITransactionManager transactionManager, IBlockchainService blockcha public ILocalEventBus LocalEventBus { get; set; } - public async Task GetExecutableTransactionSetAsync(Hash blockHash, int transactionCount) + public async Task GetExecutableTransactionSetAsync( + Hash blockHash, int transactionCount) { var output = new ExecutableTransactionSet { diff --git a/src/AElf.Kernel.TransactionPool/TransactionOptions.cs b/src/AElf.Kernel.TransactionPool/TransactionOptions.cs index 7847da5094..b2dfbc08ea 100644 --- a/src/AElf.Kernel.TransactionPool/TransactionOptions.cs +++ b/src/AElf.Kernel.TransactionPool/TransactionOptions.cs @@ -17,4 +17,12 @@ public class TransactionOptions /// But common node needs to enable it to prevent transaction flood attack /// public bool EnableTransactionExecutionValidation { get; set; } = true; + + public static int BlockTransactionLimit { get; set; } = 512; + + /// + /// Configuration whether to save failed transaction results + /// + public bool StoreInvalidTransactionResultEnabled { get; set; } + } \ No newline at end of file diff --git a/src/AElf.Kernel.Types/AElf.Kernel.Types.csproj b/src/AElf.Kernel.Types/AElf.Kernel.Types.csproj index 2b4ff86a2a..e2b894cd30 100644 --- a/src/AElf.Kernel.Types/AElf.Kernel.Types.csproj +++ b/src/AElf.Kernel.Types/AElf.Kernel.Types.csproj @@ -1,7 +1,7 @@ - - + + - net6.0 + net8.0 AElf.Kernel AElf.Kernel.Types true @@ -9,7 +9,7 @@ - + diff --git a/src/AElf.Kernel/AElf.Kernel.csproj b/src/AElf.Kernel/AElf.Kernel.csproj index 20e2f545d3..d45c62fa75 100644 --- a/src/AElf.Kernel/AElf.Kernel.csproj +++ b/src/AElf.Kernel/AElf.Kernel.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Kernel true Main kernel module for building the kernel. @@ -13,6 +13,7 @@ + diff --git a/src/AElf.Kernel/KernelAElfModule.cs b/src/AElf.Kernel/KernelAElfModule.cs index d587922d61..5e27d0dd72 100644 --- a/src/AElf.Kernel/KernelAElfModule.cs +++ b/src/AElf.Kernel/KernelAElfModule.cs @@ -1,5 +1,6 @@ using AElf.Kernel.ChainController; using AElf.Kernel.Configuration; +using AElf.Kernel.FeatureDisable; using AElf.Kernel.Miner; using AElf.Kernel.Node; using AElf.Kernel.Proposal; @@ -17,6 +18,7 @@ namespace AElf.Kernel; typeof(CoreKernelAElfModule), typeof(ChainControllerAElfModule), typeof(SmartContractAElfModule), + typeof(FeatureDisableAElfModule), typeof(NodeAElfModule), typeof(SmartContractExecutionAElfModule), typeof(TransactionPoolAElfModule), diff --git a/src/AElf.Kernel/Miner/Application/MinerService.cs b/src/AElf.Kernel/Miner/Application/MinerService.cs index 6dafb7bed9..6450a58ff0 100644 --- a/src/AElf.Kernel/Miner/Application/MinerService.cs +++ b/src/AElf.Kernel/Miner/Application/MinerService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using AElf.Kernel.Blockchain; +using AElf.Kernel.TransactionPool; using AElf.Kernel.TransactionPool.Application; using AElf.Kernel.Txn.Application; using Google.Protobuf.WellKnownTypes; @@ -37,8 +38,7 @@ public async Task MineAsync(Hash previousBlockHash, long previ Timestamp blockTime, Duration blockExecutionTime) { - var txList = new List(); - + var txList = new List(TransactionOptions.BlockTransactionLimit); var chainContext = new ChainContext { BlockHash = previousBlockHash, @@ -46,6 +46,7 @@ public async Task MineAsync(Hash previousBlockHash, long previ }; var limit = await _blockTransactionLimitProvider.GetLimitAsync(chainContext); + if (_transactionPackingOptionProvider.IsTransactionPackable(chainContext)) { var executableTransactionSet = await _transactionPoolService.GetExecutableTransactionSetAsync( @@ -54,9 +55,9 @@ public async Task MineAsync(Hash previousBlockHash, long previ txList.AddRange(executableTransactionSet.Transactions); } - Logger.LogInformation( - "Start mining with previous hash: {PreviousBlockHash}, previous height: {PreviousBlockHeight}", - previousBlockHash.ToHex(), previousBlockHeight); + // Logger.LogInformation( + // "Start mining with previous hash: {PreviousBlockHash}, previous height: {PreviousBlockHeight}", + // previousBlockHash.ToHex(), previousBlockHeight); return await _miningService.MineAsync( new RequestMiningDto { diff --git a/src/AElf.Kernel/Miner/Application/MiningService.cs b/src/AElf.Kernel/Miner/Application/MiningService.cs index 319e27fbfe..46900722cb 100644 --- a/src/AElf.Kernel/Miner/Application/MiningService.cs +++ b/src/AElf.Kernel/Miner/Application/MiningService.cs @@ -61,12 +61,12 @@ public async Task MineAsync(RequestMiningDto requestMiningDto, cts.CancelAfter(ts); } - var block = await GenerateBlock(requestMiningDto.PreviousBlockHash, - requestMiningDto.PreviousBlockHeight, blockTime); - var systemTransactions = await GenerateSystemTransactions(requestMiningDto.PreviousBlockHash, - requestMiningDto.PreviousBlockHeight); + var block = await GenerateBlock(requestMiningDto.PreviousBlockHash, requestMiningDto.PreviousBlockHeight, blockTime); + var systemTransactions = await GenerateSystemTransactions(requestMiningDto.PreviousBlockHash, requestMiningDto.PreviousBlockHeight); + _systemTransactionExtraDataProvider.SetSystemTransactionCount(systemTransactions.Count, block.Header); + var txTotalCount = transactions.Count + systemTransactions.Count; var pending = txTotalCount > requestMiningDto.TransactionCountLimit @@ -79,12 +79,15 @@ public async Task MineAsync(RequestMiningDto requestMiningDto, block = blockExecutedSet.Block; await SignBlockAsync(block); - Logger.LogInformation("Generated block: {Block}, " + - "previous: {PreviousBlockHash}, " + - "executed transactions: {TransactionsCount}, " + - "not executed transactions {NotExecutedTransactionsCount}", - block.ToDiagnosticString(), block.Header.PreviousBlockHash.ToHex(), block.Body.TransactionsCount, - pending.Count + systemTransactions.Count - block.Body.TransactionsCount); + if (block.Body.TransactionsCount > 2) + { + Logger.LogInformation("Generated block: {Block}, " + + "previous: {PreviousBlockHash}, " + + "executed transactions: {TransactionsCount}, " + + "not executed transactions {NotExecutedTransactionsCount}", + block.ToDiagnosticString(), block.Header.PreviousBlockHash.ToHex(), block.Body.TransactionsCount, + pending.Count + systemTransactions.Count - block.Body.TransactionsCount); + } return blockExecutedSet; } catch (Exception e) diff --git a/src/AElf.Launcher/AElf.Launcher.csproj b/src/AElf.Launcher/AElf.Launcher.csproj index 663c4536de..06559583c6 100644 --- a/src/AElf.Launcher/AElf.Launcher.csproj +++ b/src/AElf.Launcher/AElf.Launcher.csproj @@ -1,7 +1,7 @@  Exe - net6.0 + net8.0 true @@ -15,8 +15,8 @@ - - + + diff --git a/src/AElf.Launcher/Startup.cs b/src/AElf.Launcher/Startup.cs index 1c293abd9a..42a4537bde 100644 --- a/src/AElf.Launcher/Startup.cs +++ b/src/AElf.Launcher/Startup.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.IO; using System.Linq; using AElf.Blockchains.MainChain; using AElf.Blockchains.SideChain; @@ -9,7 +10,8 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.Modularity; +using Volo.Abp; +using Volo.Abp.Modularity.PlugIns; namespace AElf.Launcher; @@ -28,13 +30,23 @@ public Startup(IConfiguration configuration) public void ConfigureServices(IServiceCollection services) { var chainType = _configuration.GetValue("ChainType", ChainType.MainChain); + var pluginSourcesFolder = _configuration.GetValue("PluginSourcesFolder", Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), + "aelf", "plugins")); + Action optionsAction = options => + { + if (Directory.Exists(pluginSourcesFolder)) + { + options.PlugInSources.AddFolder(pluginSourcesFolder); + } + }; switch (chainType) { case ChainType.SideChain: - AddApplication(services); + services.AddApplication(optionsAction); break; - default: - AddApplication(services); + case ChainType.MainChain: + services.AddApplication(optionsAction); break; } @@ -56,11 +68,6 @@ public void ConfigureServices(IServiceCollection services) }); } - private static void AddApplication(IServiceCollection services) where T : IAbpModule - { - services.AddApplication(); - } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // ReSharper disable once UnusedMember.Global public void Configure(IApplicationBuilder app, IWebHostEnvironment env) diff --git a/src/AElf.Launcher/appsettings.json b/src/AElf.Launcher/appsettings.json index 80b0e93f8f..c4e11c7af8 100644 --- a/src/AElf.Launcher/appsettings.json +++ b/src/AElf.Launcher/appsettings.json @@ -5,12 +5,12 @@ "AllowedHosts": "*", "CorsOrigins": "*", "ConnectionStrings": { - "BlockchainDb": "redis://localhost:6379?db=1", - "StateDb": "redis://localhost:6379?db=1" + "BlockchainDb": "redis://localhost:6666?db=1", + "StateDb": "redis://localhost:6666?db=1" }, "Account": { - "NodeAccount": "", - "NodeAccountPassword": "" + "NodeAccount": "2E2zpf8zMzZBenM4eqtKJhX2m91UxhR1aPEw7hpBNhnJmzbkbp", + "NodeAccountPassword": "12345678" }, "Network": { "BootNodes": [], @@ -30,6 +30,12 @@ "PeriodSeconds": 604800, "MinerIncreaseInterval": 31536000 }, + "MiningTime": { + "LimitMillisecondsOfMiningBlock": 400 + }, + "DisableFeature": { + "FeatureNameList": ["TxPlugin"] + }, "Transaction": { "PoolLimit": 10240 }, diff --git a/src/AElf.OS.Core/AElf.OS.Core.csproj b/src/AElf.OS.Core/AElf.OS.Core.csproj index 47ea5135a5..4c47b99c2f 100644 --- a/src/AElf.OS.Core/AElf.OS.Core.csproj +++ b/src/AElf.OS.Core/AElf.OS.Core.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.OS AElf.OS.Core true diff --git a/src/AElf.OS.Network.Grpc/AElf.OS.Network.Grpc.csproj b/src/AElf.OS.Network.Grpc/AElf.OS.Network.Grpc.csproj index e4a8dfcc99..f47b94d80c 100644 --- a/src/AElf.OS.Network.Grpc/AElf.OS.Network.Grpc.csproj +++ b/src/AElf.OS.Network.Grpc/AElf.OS.Network.Grpc.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.OS.Network.Grpc true gRPC implementations of AElf's network communication layer. diff --git a/src/AElf.OS/AElf.OS.csproj b/src/AElf.OS/AElf.OS.csproj index 531d4f7d4d..7da7c68f76 100644 --- a/src/AElf.OS/AElf.OS.csproj +++ b/src/AElf.OS/AElf.OS.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.OS true Main module for the OS layer. @@ -15,7 +15,7 @@ - + diff --git a/src/AElf.Runtime.CSharp.Core/AElf.Runtime.CSharp.Core.csproj b/src/AElf.Runtime.CSharp.Core/AElf.Runtime.CSharp.Core.csproj index 4cd89b4173..48a59a9535 100644 --- a/src/AElf.Runtime.CSharp.Core/AElf.Runtime.CSharp.Core.csproj +++ b/src/AElf.Runtime.CSharp.Core/AElf.Runtime.CSharp.Core.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Runtime.CSharp.Core AElf.Runtime.CSharp.Core true @@ -10,7 +10,7 @@ - + diff --git a/src/AElf.Runtime.CSharp.Core/ContractCodeLoadContext.cs b/src/AElf.Runtime.CSharp.Core/ContractCodeLoadContext.cs index 507ef7bdcc..c8df9a2114 100644 --- a/src/AElf.Runtime.CSharp.Core/ContractCodeLoadContext.cs +++ b/src/AElf.Runtime.CSharp.Core/ContractCodeLoadContext.cs @@ -28,7 +28,7 @@ protected override Assembly Load(AssemblyName assemblyName) /// private Assembly LoadFromFolderOrDefault(AssemblyName assemblyName) { - if (assemblyName.Name.StartsWith("AElf.Sdk")) + if ("AElf.Sdk.CSharp".Equals(assemblyName.Name)) { // Sdk assembly should NOT be shared using var stream = _sdkStreamManager.GetStream(assemblyName); diff --git a/src/AElf.Runtime.CSharp.ExecutiveTokenPlugin/AElf.Runtime.CSharp.ExecutiveTokenPlugin.csproj b/src/AElf.Runtime.CSharp.ExecutiveTokenPlugin/AElf.Runtime.CSharp.ExecutiveTokenPlugin.csproj index ab7eccbf55..215dbf3a3f 100644 --- a/src/AElf.Runtime.CSharp.ExecutiveTokenPlugin/AElf.Runtime.CSharp.ExecutiveTokenPlugin.csproj +++ b/src/AElf.Runtime.CSharp.ExecutiveTokenPlugin/AElf.Runtime.CSharp.ExecutiveTokenPlugin.csproj @@ -1,15 +1,15 @@ - - + + - net6.0 + net8.0 AElf.Runtime.CSharp.ExecutiveTokenPlugin true Executive plugin for C# smart contracts. - + diff --git a/src/AElf.Runtime.CSharp/AElf.Runtime.CSharp.csproj b/src/AElf.Runtime.CSharp/AElf.Runtime.CSharp.csproj index 576dc9d875..1efbfe0e18 100644 --- a/src/AElf.Runtime.CSharp/AElf.Runtime.CSharp.csproj +++ b/src/AElf.Runtime.CSharp/AElf.Runtime.CSharp.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Runtime.CSharp AElf.Runtime.CSharp true @@ -14,14 +14,17 @@ - - - - + + + + - + + + + diff --git a/src/AElf.RuntimeSetup/AElf.RuntimeSetup.csproj b/src/AElf.RuntimeSetup/AElf.RuntimeSetup.csproj index 75a439494b..ea1434095c 100644 --- a/src/AElf.RuntimeSetup/AElf.RuntimeSetup.csproj +++ b/src/AElf.RuntimeSetup/AElf.RuntimeSetup.csproj @@ -1,20 +1,20 @@ - - + + - net6.0 + net8.0 AElf.RuntimeSetup true Module for the nodes runtime setup (logging for example). - + - - + + diff --git a/src/AElf.Sdk.CSharp.Internal/AElf.Sdk.CSharp.Internal.csproj b/src/AElf.Sdk.CSharp.Internal/AElf.Sdk.CSharp.Internal.csproj new file mode 100644 index 0000000000..7f5bd490af --- /dev/null +++ b/src/AElf.Sdk.CSharp.Internal/AElf.Sdk.CSharp.Internal.csproj @@ -0,0 +1,28 @@ + + + + net8.0 + AElf.Sdk.CSharp.Internal + true + latest + Types for the C# smart contract SDK. + AElf.Sdk.CSharp.Internal + + + + + all + + + all + + + all + + + + + + + + diff --git a/src/AElf.Sdk.CSharp.Internal/AssemblyInfo.cs b/src/AElf.Sdk.CSharp.Internal/AssemblyInfo.cs new file mode 100644 index 0000000000..1b80097c7f --- /dev/null +++ b/src/AElf.Sdk.CSharp.Internal/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("AElf.Sdk.CSharp")] \ No newline at end of file diff --git a/src/AElf.Sdk.CSharp.Internal/InternalBuiltIns.cs b/src/AElf.Sdk.CSharp.Internal/InternalBuiltIns.cs new file mode 100644 index 0000000000..0d61e255b8 --- /dev/null +++ b/src/AElf.Sdk.CSharp.Internal/InternalBuiltIns.cs @@ -0,0 +1,61 @@ +using System; +using AElf.Sdk.CSharp.Spec; +using Bn254.Net; +using Nethereum.Util; + +namespace AElf.Sdk.CSharp.Internal; + +internal class InternalBuiltIns : IBuiltIns +{ + public static void Initialize() + { + // call this method to ensure this assembly is loaded in the runtime. + } + + public bool Ed25519Verify(byte[] signature, byte[] message, byte[] publicKey) + { + try + { + var instance = new Rebex.Security.Cryptography.Ed25519(); + instance.FromPublicKey(publicKey); + return instance.VerifyMessage(message, signature); + } + catch (Exception e) + { + return false; + } + } + + public byte[] Keccak256(byte[] message) + { + return Sha3Keccack.Current.CalculateHash(message); + } + + public (byte[] x, byte[] y) Bn254G1Mul(byte[] x1, byte[] y1, byte[] s) + { + var (xUInt256, yUInt256) = Bn254.Net.Bn254.Mul(UInt256.FromBigEndianBytes(x1), UInt256.FromBigEndianBytes(y1), + UInt256.FromBigEndianBytes(s)); + return (xUInt256.ToBigEndianBytes(), yUInt256.ToBigEndianBytes()); + } + + public (byte[] x3, byte[] y3) Bn254G1Add(byte[] x1, byte[] y1, byte[] x2, byte[] y2) + { + var (x3UInt256, y3UInt256) = Bn254.Net.Bn254.Add(UInt256.FromBigEndianBytes(x1), UInt256.FromBigEndianBytes(y1), + UInt256.FromBigEndianBytes(x2), UInt256.FromBigEndianBytes(y2)); + return (x3UInt256.ToBigEndianBytes(), y3UInt256.ToBigEndianBytes()); + } + + public bool Bn254Pairing((byte[], byte[], byte[], byte[], byte[], byte[])[] input) + { + var elements = new (UInt256, UInt256, UInt256, UInt256, UInt256, UInt256)[input.Length]; + for (var i = 0; i < input.Length; i++) + { + var (x1, y1, x2, y2, x3, y3) = input[i]; + elements[i] = (UInt256.FromBigEndianBytes(x1), UInt256.FromBigEndianBytes(y1), + UInt256.FromBigEndianBytes(x2), UInt256.FromBigEndianBytes(y2), + UInt256.FromBigEndianBytes(x3), UInt256.FromBigEndianBytes(y3)); + } + + return Bn254.Net.Bn254.Pairing(elements); + } +} \ No newline at end of file diff --git a/src/AElf.Sdk.CSharp.Spec/AElf.Sdk.CSharp.Spec.csproj b/src/AElf.Sdk.CSharp.Spec/AElf.Sdk.CSharp.Spec.csproj new file mode 100644 index 0000000000..3a63532952 --- /dev/null +++ b/src/AElf.Sdk.CSharp.Spec/AElf.Sdk.CSharp.Spec.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/AElf.Sdk.CSharp.Spec/IBuiltIns.cs b/src/AElf.Sdk.CSharp.Spec/IBuiltIns.cs new file mode 100644 index 0000000000..f19de71ebe --- /dev/null +++ b/src/AElf.Sdk.CSharp.Spec/IBuiltIns.cs @@ -0,0 +1,10 @@ +namespace AElf.Sdk.CSharp.Spec; + +public interface IBuiltIns +{ + bool Ed25519Verify(byte[] signature, byte[] message, byte[] publicKey); + byte[] Keccak256(byte[] message); + (byte[] x, byte[] y) Bn254G1Mul(byte[] x1, byte[] y1, byte[] s); + (byte[] x3, byte[] y3) Bn254G1Add(byte[] x1, byte[] y1, byte[] x2, byte[] y2); + bool Bn254Pairing((byte[], byte[], byte[], byte[], byte[], byte[])[] input); +} \ No newline at end of file diff --git a/src/AElf.Sdk.CSharp/AElf.Sdk.CSharp.csproj b/src/AElf.Sdk.CSharp/AElf.Sdk.CSharp.csproj index 1138bc5cc3..00cf548872 100644 --- a/src/AElf.Sdk.CSharp/AElf.Sdk.CSharp.csproj +++ b/src/AElf.Sdk.CSharp/AElf.Sdk.CSharp.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.Sdk.CSharp true latest @@ -10,9 +10,10 @@ - - - + + + + diff --git a/src/AElf.Sdk.CSharp/CSharpSmartContractAbstract.cs b/src/AElf.Sdk.CSharp/CSharpSmartContractAbstract.cs index 31d642fdf0..5553b6eb5a 100644 --- a/src/AElf.Sdk.CSharp/CSharpSmartContractAbstract.cs +++ b/src/AElf.Sdk.CSharp/CSharpSmartContractAbstract.cs @@ -1,5 +1,6 @@ using AElf.Kernel.SmartContract; using AElf.Types; +using AElf.Sdk.CSharp.Spec; namespace AElf.Sdk.CSharp; @@ -20,4 +21,6 @@ protected void Assert(bool asserted, string message = "Assertion failed!") } internal abstract void InternalInitialize(ISmartContractBridgeContext bridgeContext); + + public IBuiltIns BuiltIns { get; internal set; } } \ No newline at end of file diff --git a/src/AElf.Sdk.CSharp/CSharpSmartContractContext.cs b/src/AElf.Sdk.CSharp/CSharpSmartContractContext.cs index 5e3ed6c94a..146c0ba31c 100644 --- a/src/AElf.Sdk.CSharp/CSharpSmartContractContext.cs +++ b/src/AElf.Sdk.CSharp/CSharpSmartContractContext.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using AElf.Kernel.SmartContract; +using AElf.Sdk.CSharp.Internal; +using AElf.Sdk.CSharp.Spec; using AElf.Types; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; @@ -12,11 +14,14 @@ namespace AElf.Sdk.CSharp; /// base class for smart contracts (Context property). It provides access to properties and methods useful for /// implementing the logic in smart contracts. /// -public class CSharpSmartContractContext : ISmartContractBridgeContext +public class CSharpSmartContractContext : ISmartContractBridgeContext, IBuiltIns { + private IBuiltIns BuiltInsImplementation { get; } + public CSharpSmartContractContext(ISmartContractBridgeContext smartContractBridgeContextImplementation) { SmartContractBridgeContextImplementation = smartContractBridgeContextImplementation; + BuiltInsImplementation = new InternalBuiltIns(); } public ISmartContractBridgeContext SmartContractBridgeContextImplementation { get; } @@ -85,7 +90,7 @@ public void FireLogEvent(LogEvent logEvent) /// The height of the block that contains the transaction before charging. /// public Transaction Transaction => SmartContractBridgeContextImplementation.Transaction; - + /// /// The time included in the current blocks header. /// @@ -148,7 +153,7 @@ public void DeployContract(Address address, SmartContractRegistration registrati { SmartContractBridgeContextImplementation.DeployContract(address, registration, name); } - + /// /// Update a smart contract (only the genesis contract can call it). /// @@ -159,17 +164,21 @@ public void UpdateContract(Address address, SmartContractRegistration registrati { SmartContractBridgeContextImplementation.UpdateContract(address, registration, name); } - + public ContractInfoDto DeploySmartContract(Address address, SmartContractRegistration registration, Hash name) { - return SmartContractBridgeContextImplementation.DeploySmartContract(address,registration,name); + return SmartContractBridgeContextImplementation.DeploySmartContract(address, registration, name); } - public ContractInfoDto UpdateSmartContract(Address address, SmartContractRegistration registration, Hash name,string previousContractVersion) + + public ContractInfoDto UpdateSmartContract(Address address, SmartContractRegistration registration, Hash name, + string previousContractVersion) { - return SmartContractBridgeContextImplementation.UpdateSmartContract(address,registration,name,previousContractVersion); + return SmartContractBridgeContextImplementation.UpdateSmartContract(address, registration, name, + previousContractVersion); } - public ContractVersionCheckDto CheckContractVersion(string previousContractVersion, SmartContractRegistration registration) + public ContractVersionCheckDto CheckContractVersion(string previousContractVersion, + SmartContractRegistration registration) { return SmartContractBridgeContextImplementation.CheckContractVersion(previousContractVersion, registration); } @@ -221,13 +230,14 @@ public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string SmartContractBridgeContextImplementation.SendVirtualInline(fromVirtualAddress, toAddress, methodName, args); } - - public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string methodName, ByteString args,bool logTransaction) + + public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string methodName, ByteString args, + bool logTransaction) { SmartContractBridgeContextImplementation.SendVirtualInline(fromVirtualAddress, toAddress, methodName, - args,logTransaction); + args, logTransaction); } - + /// /// Sends a virtual inline transaction to another contract. This method is only available to system smart contract. @@ -245,7 +255,7 @@ public void SendVirtualInlineBySystemContract(Hash fromVirtualAddress, Address t SmartContractBridgeContextImplementation.SendVirtualInlineBySystemContract(fromVirtualAddress, toAddress, methodName, args); } - + public void SendVirtualInlineBySystemContract(Hash fromVirtualAddress, Address toAddress, string methodName, ByteString args, bool logTransaction) { @@ -386,9 +396,34 @@ public Address ConvertVirtualAddressToContractAddressWithContractHashName(Hash v return SmartContractBridgeContextImplementation.ConvertVirtualAddressToContractAddressWithContractHashName( virtualAddress); } - + public bool ECVrfVerify(byte[] pubKey, byte[] alpha, byte[] pi, out byte[] beta) { return SmartContractBridgeContextImplementation.ECVrfVerify(pubKey, alpha, pi, out beta); } + + public bool Ed25519Verify(byte[] signature, byte[] message, byte[] publicKey) + { + return BuiltInsImplementation.Ed25519Verify(signature, message, publicKey); + } + + public byte[] Keccak256(byte[] message) + { + return BuiltInsImplementation.Keccak256(message); + } + + public (byte[] x, byte[] y) Bn254G1Mul(byte[] x1, byte[] y1, byte[] s) + { + return BuiltInsImplementation.Bn254G1Mul(x1, y1, s); + } + + public (byte[] x3, byte[] y3) Bn254G1Add(byte[] x1, byte[] y1, byte[] x2, byte[] y2) + { + return BuiltInsImplementation.Bn254G1Add(x1, y1, x2, y2); + } + + public bool Bn254Pairing((byte[], byte[], byte[], byte[], byte[], byte[])[] input) + { + return BuiltInsImplementation.Bn254Pairing(input); + } } \ No newline at end of file diff --git a/src/AElf.Types/AElf.Types.csproj b/src/AElf.Types/AElf.Types.csproj index f819ee9d12..867163cd35 100644 --- a/src/AElf.Types/AElf.Types.csproj +++ b/src/AElf.Types/AElf.Types.csproj @@ -1,7 +1,7 @@ - - + + - netstandard2.1;net6.0 + netstandard2.1;net8.0 AElf AElf.Types true @@ -11,7 +11,7 @@ true - + diff --git a/src/AElf.Types/Extensions/StringExtensions.cs b/src/AElf.Types/Extensions/StringExtensions.cs index 7e714a9a65..f97f6d7a79 100644 --- a/src/AElf.Types/Extensions/StringExtensions.cs +++ b/src/AElf.Types/Extensions/StringExtensions.cs @@ -1,4 +1,5 @@ using System.Text; +using Google.Protobuf.Collections; namespace AElf { @@ -9,5 +10,10 @@ public static byte[] GetBytes(this string value) { return Encoding.UTF8.GetBytes(value); } + + public static void MergeFrom(this MapField field, MapField others) + { + field.Add(others); + } } } \ No newline at end of file diff --git a/src/AElf.Types/Types/BigIntValue.cs b/src/AElf.Types/Types/BigIntValue.cs index 38ddc94df6..f65c8897a3 100644 --- a/src/AElf.Types/Types/BigIntValue.cs +++ b/src/AElf.Types/Types/BigIntValue.cs @@ -5,9 +5,30 @@ namespace AElf.Types { - public partial class BigIntValue : IComparable, IComparable { + #region Frequent Values + + public static BigIntValue Zero => new BigIntValue { Value = "0" }; + public static BigIntValue One => new BigIntValue { Value = "1" }; + + #endregion + + public static BigIntValue FromBigEndianBytes(byte[] bigEndianBytes) + { + var bigInteger = new BigInteger(bigEndianBytes, true, true); + return new BigIntValue + { + Value = bigInteger.ToString() + }; + } + + public byte[] ToBigEndianBytes() + { + var bigInteger = ConvertStringToBigInteger(Value); + return bigInteger.ToByteArray(true, true); + } + public int CompareTo(object obj) { if (!(obj is BigIntValue bigInt)) throw new InvalidOperationException(); @@ -126,6 +147,43 @@ private static bool LessThan(in BigIntValue a, in BigIntValue b) return aBigInt < bBigInt; } + #region Operators + + public static BigIntValue operator %(BigIntValue a, BigIntValue b) + { + return BigInteger.Remainder(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value)) + .ToString(); + } + + public static BigIntValue operator +(BigIntValue a, BigIntValue b) + { + return BigInteger.Add(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value)).ToString(); + } + + public static BigIntValue operator -(BigIntValue a, BigIntValue b) + { + return BigInteger.Subtract(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value)) + .ToString(); + } + + public static BigIntValue operator *(BigIntValue a, BigIntValue b) + { + return BigInteger.Multiply(ConvertStringToBigInteger(a.Value), ConvertStringToBigInteger(b.Value)) + .ToString(); + } + + public static bool operator ==(BigIntValue a, BigIntValue b) + { + return ConvertStringToBigInteger(a?.Value ?? "0") == ConvertStringToBigInteger(b?.Value ?? "0"); + } + + public static bool operator !=(BigIntValue a, BigIntValue b) + { + return !(a == b); + } + + #endregion + #region < <= > >= public static bool operator <(in BigIntValue a, in BigIntValue b) @@ -149,5 +207,6 @@ private static bool LessThan(in BigIntValue a, in BigIntValue b) } #endregion + } } \ No newline at end of file diff --git a/src/AElf.WebApp.Application.Chain/AElf.WebApp.Application.Chain.csproj b/src/AElf.WebApp.Application.Chain/AElf.WebApp.Application.Chain.csproj index 575f4c97e2..7d3417b81e 100644 --- a/src/AElf.WebApp.Application.Chain/AElf.WebApp.Application.Chain.csproj +++ b/src/AElf.WebApp.Application.Chain/AElf.WebApp.Application.Chain.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.WebApp.Application.Chain true $(NoWarn);1591 @@ -19,7 +19,7 @@ - + diff --git a/src/AElf.WebApp.Application.Chain/Dto/CalculateTransactionFeeOutput.cs b/src/AElf.WebApp.Application.Chain/Dto/CalculateTransactionFeeOutput.cs index bbba632175..1446177873 100644 --- a/src/AElf.WebApp.Application.Chain/Dto/CalculateTransactionFeeOutput.cs +++ b/src/AElf.WebApp.Application.Chain/Dto/CalculateTransactionFeeOutput.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using AElf.Types; namespace AElf.WebApp.Application.Chain.Dto; @@ -6,7 +8,21 @@ public class CalculateTransactionFeeOutput { public bool Success { get; set; } + [Obsolete("This property is deprecated and will be removed in the next version. Use the TransactionFees instead.")] public Dictionary TransactionFee { get; set; } - + + [Obsolete("This property is deprecated and will be removed in the next version. Use the ResourceFees instead.")] public Dictionary ResourceFee { get; set; } + + public FeeDto TransactionFees { get; set; } + + public FeeDto ResourceFees { get; set; } + + public string Error { get; set; } +} + +public class FeeDto +{ + public string ChargingAddress { get; set; } + public Dictionary Fee { get; set; } } \ No newline at end of file diff --git a/src/AElf.WebApp.Application.Chain/Services/TransactionAppService.cs b/src/AElf.WebApp.Application.Chain/Services/TransactionAppService.cs index 01b8459811..f4836f8128 100644 --- a/src/AElf.WebApp.Application.Chain/Services/TransactionAppService.cs +++ b/src/AElf.WebApp.Application.Chain/Services/TransactionAppService.cs @@ -17,6 +17,7 @@ using Google.Protobuf.WellKnownTypes; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.EventBus.Local; using Volo.Abp.ObjectMapping; @@ -47,17 +48,21 @@ public class TransactionAppService : AElfAppService, ITransactionAppService private readonly ITransactionReadOnlyExecutionService _transactionReadOnlyExecutionService; private readonly ITransactionResultStatusCacheProvider _transactionResultStatusCacheProvider; private readonly IPlainTransactionExecutingService _plainTransactionExecutingService; + private readonly WebAppOptions _webAppOptions; + public TransactionAppService(ITransactionReadOnlyExecutionService transactionReadOnlyExecutionService, IBlockchainService blockchainService, IObjectMapper objectMapper, ITransactionResultStatusCacheProvider transactionResultStatusCacheProvider, - IPlainTransactionExecutingService plainTransactionExecutingService) + IPlainTransactionExecutingService plainTransactionExecutingService, + IOptionsMonitor webAppOptions) { _transactionReadOnlyExecutionService = transactionReadOnlyExecutionService; _blockchainService = blockchainService; _objectMapper = objectMapper; _transactionResultStatusCacheProvider = transactionResultStatusCacheProvider; _plainTransactionExecutingService = plainTransactionExecutingService; + _webAppOptions = webAppOptions.CurrentValue; LocalEventBus = NullLocalEventBus.Instance; Logger = NullLogger.Instance; @@ -293,17 +298,39 @@ private async Task EstimateTransactionFee(Transac executionReturnSets.FirstOrDefault()?.TransactionResult.GetChargedTransactionFees(); var resourceFees = executionReturnSets.FirstOrDefault()?.TransactionResult.GetConsumedResourceTokens(); result.Success = true; - result.TransactionFee = transactionFees; - result.ResourceFee = resourceFees; + result.TransactionFee = GetFeeValue(transactionFees); + result.ResourceFee = GetFeeValue(resourceFees); + result.TransactionFees = GetFee(transactionFees); + result.ResourceFees = GetFee(resourceFees); } else { result.Success = false; + result.Error = TransactionErrorResolver.TakeErrorMessage( + executionReturnSets.FirstOrDefault()?.TransactionResult.Error, _webAppOptions.IsDebugMode); } return result; } + private Dictionary GetFeeValue(Dictionary> feeMap) + { + return feeMap?.SelectMany(pair => pair.Value) + .GroupBy(p => p.Key) + .ToDictionary(g => g.Key, g => g.Sum(pair => pair.Value)); + } + + private FeeDto GetFee(Dictionary> feeMap) + { + var fee = feeMap?.Select(f => new FeeDto + { + ChargingAddress = f.Key.ToBase58(), + Fee = f.Value + }).FirstOrDefault(); + + return fee; + } + private async Task PublishTransactionsAsync(string[] rawTransactions) { var txIds = new string[rawTransactions.Length]; diff --git a/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs b/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs index 08552f42e5..483dbb4366 100644 --- a/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs +++ b/src/AElf.WebApp.Application.Chain/Services/TransactionResultAppService.cs @@ -7,6 +7,7 @@ using AElf.Kernel.Blockchain.Application; using AElf.Kernel.Blockchain.Domain; using AElf.Kernel.SmartContract.Application; +using AElf.Kernel.TransactionPool; using AElf.Types; using AElf.WebApp.Application.Chain.Dto; using AElf.WebApp.Application.Chain.Infrastructure; @@ -39,6 +40,7 @@ public class TransactionResultAppService : AElfAppService, ITransactionResultApp private readonly ITransactionResultProxyService _transactionResultProxyService; private readonly ITransactionResultStatusCacheProvider _transactionResultStatusCacheProvider; private readonly WebAppOptions _webAppOptions; + private readonly TransactionOptions _transactionOptions; public TransactionResultAppService(ITransactionResultProxyService transactionResultProxyService, ITransactionManager transactionManager, @@ -46,7 +48,7 @@ public TransactionResultAppService(ITransactionResultProxyService transactionRes ITransactionReadOnlyExecutionService transactionReadOnlyExecutionService, IObjectMapper objectMapper, ITransactionResultStatusCacheProvider transactionResultStatusCacheProvider, - IOptionsMonitor optionsSnapshot) + IOptionsMonitor optionsSnapshot, IOptionsMonitor transactionOptions) { _transactionResultProxyService = transactionResultProxyService; _transactionManager = transactionManager; @@ -54,6 +56,7 @@ public TransactionResultAppService(ITransactionResultProxyService transactionRes _transactionReadOnlyExecutionService = transactionReadOnlyExecutionService; _objectMapper = objectMapper; _transactionResultStatusCacheProvider = transactionResultStatusCacheProvider; + _transactionOptions = transactionOptions.CurrentValue; _webAppOptions = optionsSnapshot.CurrentValue; Logger = NullLogger.Instance; @@ -88,23 +91,36 @@ public async Task GetTransactionResultAsync(string transac output.Transaction = _objectMapper.Map(transaction); output.TransactionSize = transaction?.CalculateSize() ?? 0; - if (transactionResult.Status == TransactionResultStatus.NotExisted) + if (transactionResult.Status != TransactionResultStatus.NotExisted) { - var validationStatus = - _transactionResultStatusCacheProvider.GetTransactionResultStatus(transactionIdHash); - if (validationStatus != null) - { - output.Status = validationStatus.TransactionResultStatus.ToString().ToUpper(); - output.Error = - TransactionErrorResolver.TakeErrorMessage(validationStatus.Error, _webAppOptions.IsDebugMode); - } + await FormatTransactionParamsAsync(output.Transaction, transaction.Params); + return output; + } + var validationStatus = _transactionResultStatusCacheProvider.GetTransactionResultStatus(transactionIdHash); + if (validationStatus != null) + { + output.Status = validationStatus.TransactionResultStatus.ToString().ToUpper(); + output.Error = + TransactionErrorResolver.TakeErrorMessage(validationStatus.Error, _webAppOptions.IsDebugMode); return output; } - - await FormatTransactionParamsAsync(output.Transaction, transaction.Params); - + + if (_transactionOptions.StoreInvalidTransactionResultEnabled) + { + var failedTransactionResult = + await _transactionResultProxyService.InvalidTransactionResultService.GetInvalidTransactionResultAsync( + transactionIdHash); + if (failedTransactionResult != null) + { + output.Status = failedTransactionResult.Status.ToString().ToUpper(); + output.Error = failedTransactionResult.Error; + return output; + } + } + return output; + } /// diff --git a/src/AElf.WebApp.Application.Chain/Services/TransactionResultProxyService.cs b/src/AElf.WebApp.Application.Chain/Services/TransactionResultProxyService.cs index 5ebfcc8598..9d13296930 100644 --- a/src/AElf.WebApp.Application.Chain/Services/TransactionResultProxyService.cs +++ b/src/AElf.WebApp.Application.Chain/Services/TransactionResultProxyService.cs @@ -7,17 +7,21 @@ public interface ITransactionResultProxyService { ITransactionPoolService TransactionPoolService { get; } ITransactionResultQueryService TransactionResultQueryService { get; } + IInvalidTransactionResultService InvalidTransactionResultService { get; } } public class TransactionResultProxyService : ITransactionResultProxyService { public TransactionResultProxyService(ITransactionPoolService transactionPoolService, - ITransactionResultQueryService transactionResultQueryService) + ITransactionResultQueryService transactionResultQueryService, + IInvalidTransactionResultService invalidTransactionResultService) { TransactionPoolService = transactionPoolService; TransactionResultQueryService = transactionResultQueryService; + InvalidTransactionResultService = invalidTransactionResultService; } public ITransactionPoolService TransactionPoolService { get; set; } public ITransactionResultQueryService TransactionResultQueryService { get; set; } + public IInvalidTransactionResultService InvalidTransactionResultService { get; } } \ No newline at end of file diff --git a/src/AElf.WebApp.Application.Core/AElf.WebApp.Application.Core.csproj b/src/AElf.WebApp.Application.Core/AElf.WebApp.Application.Core.csproj index b85df20afb..ae0fe7ad3b 100644 --- a/src/AElf.WebApp.Application.Core/AElf.WebApp.Application.Core.csproj +++ b/src/AElf.WebApp.Application.Core/AElf.WebApp.Application.Core.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 AElf.WebApp.Application true AElf.WebApp.Application.Core @@ -11,12 +11,12 @@ - - + + - + diff --git a/src/AElf.WebApp.Application.Net/AElf.WebApp.Application.Net.csproj b/src/AElf.WebApp.Application.Net/AElf.WebApp.Application.Net.csproj index d2d0066780..01beab4148 100644 --- a/src/AElf.WebApp.Application.Net/AElf.WebApp.Application.Net.csproj +++ b/src/AElf.WebApp.Application.Net/AElf.WebApp.Application.Net.csproj @@ -1,8 +1,8 @@ - - + + - net6.0 + net8.0 $(NoWarn);1591 true AElf.WebApp.Application.Net @@ -11,12 +11,12 @@ - - + + - + diff --git a/src/AElf.WebApp.Web/AElf.WebApp.Web.csproj b/src/AElf.WebApp.Web/AElf.WebApp.Web.csproj index 33a752255d..b11907855a 100644 --- a/src/AElf.WebApp.Web/AElf.WebApp.Web.csproj +++ b/src/AElf.WebApp.Web/AElf.WebApp.Web.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.WebApp.Web true Main module for the node's Web API. @@ -14,13 +14,13 @@ - - - - - - - + + + + + + + diff --git a/templates/build-template-linux.yml b/templates/build-template-linux.yml index 62148b2d1d..37be791f86 100644 --- a/templates/build-template-linux.yml +++ b/templates/build-template-linux.yml @@ -21,7 +21,7 @@ jobs: - task: UseDotNet@2 displayName: 'Install .NET Core SDK' inputs: - version: 6.0.x + version: 8.0.303 - script: bash scripts/install_protobuf.sh - script: bash scripts/download_binary.sh - script: bash build.sh --target=Test-with-Codecov-N --parts=${{ parameters.parts }} --number=${{ parameters.n }} --codecoverage=${{ parameters.codecoverage }} diff --git a/templates/build-template-macos.yml b/templates/build-template-macos.yml index 5c3c543811..de6a350a35 100644 --- a/templates/build-template-macos.yml +++ b/templates/build-template-macos.yml @@ -21,7 +21,7 @@ jobs: - task: UseDotNet@2 displayName: 'Install .NET Core SDK' inputs: - version: 6.0.x + version: 8.0.303 - script: bash scripts/install_protobuf.sh - script: bash scripts/download_binary.sh - script: bash build.sh --target=Test-with-Codecov-N --parts=${{ parameters.parts }} --number=${{ parameters.n }} --codecoverage=${{ parameters.codecoverage }} diff --git a/templates/build-template-window.yml b/templates/build-template-window.yml index a222d4b8d1..e5e6d20dc9 100644 --- a/templates/build-template-window.yml +++ b/templates/build-template-window.yml @@ -21,7 +21,7 @@ jobs: - task: UseDotNet@2 displayName: 'Install .NET Core SDK' inputs: - version: 6.0.x + version: 8.0.303 - script: choco install protoc --version=3.19.4 -y displayName: 'Install protobuf' - script: choco install unzip diff --git a/test/AElf.CSharp.CodeOps.Tests/AElf.CSharp.CodeOps.Tests.csproj b/test/AElf.CSharp.CodeOps.Tests/AElf.CSharp.CodeOps.Tests.csproj index b801d4a542..8d675e45ed 100644 --- a/test/AElf.CSharp.CodeOps.Tests/AElf.CSharp.CodeOps.Tests.csproj +++ b/test/AElf.CSharp.CodeOps.Tests/AElf.CSharp.CodeOps.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.CSharp.CodeOps false @@ -13,9 +13,9 @@ all runtime; build; native; contentfiles; analyzers - + - + all @@ -25,30 +25,30 @@ all runtime; build; native; contentfiles; analyzers - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/test/AElf.CSharp.CodeOps.Tests/ContractAuditorTests.cs b/test/AElf.CSharp.CodeOps.Tests/ContractAuditorTests.cs index ca6affbda5..56be0fc22c 100644 --- a/test/AElf.CSharp.CodeOps.Tests/ContractAuditorTests.cs +++ b/test/AElf.CSharp.CodeOps.Tests/ContractAuditorTests.cs @@ -111,7 +111,7 @@ public void AuditTimeout() var codeOpsOptions = GetRequiredService>(); codeOpsOptions.CurrentValue.AuditTimeoutDuration = 0; Should.Throw(() => - _auditor.Audit(ReadPatchedContractCode(typeof(TokenContract)), true)); + _auditor.Audit(ReadPatchedContractCode(typeof(TokenContract)), true)); } [Fact] diff --git a/test/AElf.CSharp.CodeOps.UnitTests/AElf.CSharp.CodeOps.UnitTests.csproj b/test/AElf.CSharp.CodeOps.UnitTests/AElf.CSharp.CodeOps.UnitTests.csproj index 5fc8f412c4..f80d415417 100644 --- a/test/AElf.CSharp.CodeOps.UnitTests/AElf.CSharp.CodeOps.UnitTests.csproj +++ b/test/AElf.CSharp.CodeOps.UnitTests/AElf.CSharp.CodeOps.UnitTests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 enable enable diff --git a/test/AElf.CSharp.CodeOps.UnitTests/CSharpCodeOpsTestBase.cs b/test/AElf.CSharp.CodeOps.UnitTests/CSharpCodeOpsTestBase.cs index 338ae2accd..8e95404725 100644 --- a/test/AElf.CSharp.CodeOps.UnitTests/CSharpCodeOpsTestBase.cs +++ b/test/AElf.CSharp.CodeOps.UnitTests/CSharpCodeOpsTestBase.cs @@ -104,7 +104,7 @@ protected static string DecompileType(TypeDefinition typ) static CSharpCodeOpsTestBase() { - AddNet6References(); + AddNet8References(); AddSmartContractReferences(); } @@ -145,9 +145,9 @@ public static void AddAssemblies(params string[] assemblies) } - public static void AddNet6References() + public static void AddNet8References() { - foreach (var portableExecutableReference in Basic.Reference.Assemblies.Net60.References.All) + foreach (var portableExecutableReference in Basic.Reference.Assemblies.Net80.References.All) { References.Add(portableExecutableReference); } diff --git a/test/AElf.CSharp.Core.Tests/AElf.CSharp.Core.Tests.csproj b/test/AElf.CSharp.Core.Tests/AElf.CSharp.Core.Tests.csproj index 2fb02a1378..844a0d183d 100644 --- a/test/AElf.CSharp.Core.Tests/AElf.CSharp.Core.Tests.csproj +++ b/test/AElf.CSharp.Core.Tests/AElf.CSharp.Core.Tests.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 false - - + + @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.ContractDeployer.Tests/AElf.ContractDeployer.Tests.csproj b/test/AElf.ContractDeployer.Tests/AElf.ContractDeployer.Tests.csproj index 7a238fd81a..f0b58e0b74 100644 --- a/test/AElf.ContractDeployer.Tests/AElf.ContractDeployer.Tests.csproj +++ b/test/AElf.ContractDeployer.Tests/AElf.ContractDeployer.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.ContractDeployer @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,8 +22,8 @@ - - + + diff --git a/test/AElf.ContractTestBase.Tests/AElf.ContractTestBase.Tests.csproj b/test/AElf.ContractTestBase.Tests/AElf.ContractTestBase.Tests.csproj index 9a4c5e6b0a..ca8838ea8a 100644 --- a/test/AElf.ContractTestBase.Tests/AElf.ContractTestBase.Tests.csproj +++ b/test/AElf.ContractTestBase.Tests/AElf.ContractTestBase.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -10,7 +10,7 @@ - + @@ -161,9 +161,9 @@ runtime; build; native; contentfiles; analyzers - + - + all runtime; build; native; contentfiles; analyzers diff --git a/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AEDPoSExtensionDemoTestBase.cs b/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AEDPoSExtensionDemoTestBase.cs index a3550cb210..fd6ff9c9be 100644 --- a/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AEDPoSExtensionDemoTestBase.cs +++ b/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AEDPoSExtensionDemoTestBase.cs @@ -15,6 +15,7 @@ using AElf.EconomicSystem; using AElf.GovernmentSystem; using AElf.Kernel; +using AElf.Kernel.Configuration; using AElf.Kernel.Consensus; using AElf.Kernel.Proposal; using AElf.Kernel.Token; @@ -74,7 +75,8 @@ internal void InitialContracts() ParliamentSmartContractAddressNameProvider.Name, ElectionSmartContractAddressNameProvider.Name, AssociationSmartContractAddressNameProvider.Name, - ReferendumSmartContractAddressNameProvider.Name + ReferendumSmartContractAddressNameProvider.Name, + ConfigurationSmartContractAddressNameProvider.Name, })); } diff --git a/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AElf.Contracts.AEDPoSExtension.Demo.Tests.csproj b/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AElf.Contracts.AEDPoSExtension.Demo.Tests.csproj index 5a03f644f1..0e01048c51 100644 --- a/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AElf.Contracts.AEDPoSExtension.Demo.Tests.csproj +++ b/test/AElf.Contracts.AEDPoSExtension.Demo.Tests/AElf.Contracts.AEDPoSExtension.Demo.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -23,8 +23,8 @@ - - + + @@ -34,7 +34,7 @@ PreserveNewest - + diff --git a/test/AElf.Contracts.Association.Tests/AElf.Contracts.Association.Tests.csproj b/test/AElf.Contracts.Association.Tests/AElf.Contracts.Association.Tests.csproj index f0517749dd..849bcfa27f 100644 --- a/test/AElf.Contracts.Association.Tests/AElf.Contracts.Association.Tests.csproj +++ b/test/AElf.Contracts.Association.Tests/AElf.Contracts.Association.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.Association false @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -28,7 +28,7 @@ - + @@ -86,5 +86,5 @@ - + diff --git a/test/AElf.Contracts.Association.Tests/AssociationContractTests.cs b/test/AElf.Contracts.Association.Tests/AssociationContractTests.cs index 0da11d0fa3..89ec1025ed 100644 --- a/test/AElf.Contracts.Association.Tests/AssociationContractTests.cs +++ b/test/AElf.Contracts.Association.Tests/AssociationContractTests.cs @@ -169,6 +169,8 @@ public async Task Get_Proposal_Test() getProposal.Output.OrganizationAddress.ShouldBe(organizationAddress); getProposal.Output.ToAddress.ShouldBe(TokenContractAddress); getProposal.Output.Params.ShouldBe(transferInput.ToByteString()); + getProposal.Output.Title.ShouldNotBeNullOrEmpty(); + getProposal.Output.Description.ShouldNotBeNullOrEmpty(); } } @@ -1231,7 +1233,9 @@ private async Task CreateProposalAsync(ECKeyPair proposalKeyPair, Address ToAddress = TokenContractAddress, Params = transferInput.ToByteString(), ExpiredTime = BlockTimeProvider.GetBlockTime().AddDays(2), - OrganizationAddress = organizationAddress + OrganizationAddress = organizationAddress, + Title = "Token Transfer", + Description = "Transfer 100 ELF to Reviewer1's address", }; var proposal = await associationContractStub.CreateProposal.SendAsync(createProposalInput); var proposalCreated = ProposalCreated.Parser.ParseFrom(proposal.TransactionResult.Logs diff --git a/test/AElf.Contracts.Configuration.Tests/AElf.Contracts.Configuration.Tests.csproj b/test/AElf.Contracts.Configuration.Tests/AElf.Contracts.Configuration.Tests.csproj index 3f108c2698..11cf5249e2 100644 --- a/test/AElf.Contracts.Configuration.Tests/AElf.Contracts.Configuration.Tests.csproj +++ b/test/AElf.Contracts.Configuration.Tests/AElf.Contracts.Configuration.Tests.csproj @@ -1,13 +1,13 @@  - net6.0 + net8.0 AElf.Contracts.ConfigurationContract.Tests false - + false Contract @@ -57,6 +57,6 @@ - + diff --git a/test/AElf.Contracts.Consensus.AEDPoS.Tests/AElf.Contracts.Consensus.AEDPoS.Tests.csproj b/test/AElf.Contracts.Consensus.AEDPoS.Tests/AElf.Contracts.Consensus.AEDPoS.Tests.csproj index f9397a21b3..35e2ad70cf 100644 --- a/test/AElf.Contracts.Consensus.AEDPoS.Tests/AElf.Contracts.Consensus.AEDPoS.Tests.csproj +++ b/test/AElf.Contracts.Consensus.AEDPoS.Tests/AElf.Contracts.Consensus.AEDPoS.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.Consensus.AEDPoS false diff --git a/test/AElf.Contracts.CrossChain.Tests/AElf.Contracts.CrossChain.Tests.csproj b/test/AElf.Contracts.CrossChain.Tests/AElf.Contracts.CrossChain.Tests.csproj index a27276b8c9..abb1a0b320 100644 --- a/test/AElf.Contracts.CrossChain.Tests/AElf.Contracts.CrossChain.Tests.csproj +++ b/test/AElf.Contracts.CrossChain.Tests/AElf.Contracts.CrossChain.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.CrossChain.Tests AElf.Contracts.CrossChain.Tests false @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -23,7 +23,7 @@ runtime; build; native; contentfiles; analyzers - + Protobuf\Proto\authority_info.proto @@ -93,6 +93,6 @@ - + diff --git a/test/AElf.Contracts.Economic.AEDPoSExtension.Tests/AElf.Contracts.Economic.AEDPoSExtension.Tests.csproj b/test/AElf.Contracts.Economic.AEDPoSExtension.Tests/AElf.Contracts.Economic.AEDPoSExtension.Tests.csproj index 732176b7fe..978a185781 100644 --- a/test/AElf.Contracts.Economic.AEDPoSExtension.Tests/AElf.Contracts.Economic.AEDPoSExtension.Tests.csproj +++ b/test/AElf.Contracts.Economic.AEDPoSExtension.Tests/AElf.Contracts.Economic.AEDPoSExtension.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -23,11 +23,11 @@ - - - + + + - + Protobuf\Proto\authority_info.proto diff --git a/test/AElf.Contracts.Economic.TestBase/AElf.Contracts.Economic.TestBase.csproj b/test/AElf.Contracts.Economic.TestBase/AElf.Contracts.Economic.TestBase.csproj index c0b204fe14..6756f5c799 100644 --- a/test/AElf.Contracts.Economic.TestBase/AElf.Contracts.Economic.TestBase.csproj +++ b/test/AElf.Contracts.Economic.TestBase/AElf.Contracts.Economic.TestBase.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false 0436 diff --git a/test/AElf.Contracts.EconomicSystem.Tests/AElf.Contracts.EconomicSystem.Tests.csproj b/test/AElf.Contracts.EconomicSystem.Tests/AElf.Contracts.EconomicSystem.Tests.csproj index dbad41ec40..e738b21493 100644 --- a/test/AElf.Contracts.EconomicSystem.Tests/AElf.Contracts.EconomicSystem.Tests.csproj +++ b/test/AElf.Contracts.EconomicSystem.Tests/AElf.Contracts.EconomicSystem.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false diff --git a/test/AElf.Contracts.Election.Tests/AElf.Contracts.Election.Tests.csproj b/test/AElf.Contracts.Election.Tests/AElf.Contracts.Election.Tests.csproj index e472065cfe..8934ab1474 100644 --- a/test/AElf.Contracts.Election.Tests/AElf.Contracts.Election.Tests.csproj +++ b/test/AElf.Contracts.Election.Tests/AElf.Contracts.Election.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Contracts.Election false diff --git a/test/AElf.Contracts.Election.Tests/Full/ReleaseProfitsFromTreasury.cs b/test/AElf.Contracts.Election.Tests/Full/ReleaseProfitsFromTreasury.cs index cbe677415b..96657c3cd2 100644 --- a/test/AElf.Contracts.Election.Tests/Full/ReleaseProfitsFromTreasury.cs +++ b/test/AElf.Contracts.Election.Tests/Full/ReleaseProfitsFromTreasury.cs @@ -383,11 +383,11 @@ public async Task CheckTreasuryProfitsDistribution_Test() })).Balance; var profitTester = GetProfitContractTester(VoterKeyPairs[0]); - var profitAmount = (await profitTester.GetProfitAmount.CallAsync(new GetProfitAmountInput + var profitAmount = (await profitTester.GetAllProfitAmount.CallAsync(new GetAllProfitAmountInput { SchemeId = ProfitItemsIds[ProfitType.CitizenWelfare], Symbol = EconomicContractsTestConstants.NativeTokenSymbol - })).Value; + })).OneTimeClaimableProfitAmount; profitAmount.ShouldBeGreaterThan(0); var profitResult = await profitTester.ClaimProfits.SendAsync(new ClaimProfitsInput @@ -636,11 +636,11 @@ private async Task GetProfitAmount(ProfitType type) break; } - return (await stub.GetProfitAmount.CallAsync(new GetProfitAmountInput + return (await stub.GetAllProfitAmount.CallAsync(new GetAllProfitAmountInput { SchemeId = ProfitItemsIds[type], Symbol = EconomicContractsTestConstants.NativeTokenSymbol - })).Value; + })).OneTimeClaimableProfitAmount; } private async Task GetReleasedAmount() diff --git a/test/AElf.Contracts.Genesis.Tests/AElf.Contracts.Genesis.Tests.csproj b/test/AElf.Contracts.Genesis.Tests/AElf.Contracts.Genesis.Tests.csproj index c439d16de0..8921a2c5c3 100644 --- a/test/AElf.Contracts.Genesis.Tests/AElf.Contracts.Genesis.Tests.csproj +++ b/test/AElf.Contracts.Genesis.Tests/AElf.Contracts.Genesis.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -10,7 +10,7 @@ - + false Contract @@ -27,7 +27,7 @@ Contract PreserveNewest - + false Contract diff --git a/test/AElf.Contracts.Genesis.Tests/GenesisContractAuthTest.cs b/test/AElf.Contracts.Genesis.Tests/GenesisContractAuthTest.cs index 3962b989b8..a5d5b5bde9 100644 --- a/test/AElf.Contracts.Genesis.Tests/GenesisContractAuthTest.cs +++ b/test/AElf.Contracts.Genesis.Tests/GenesisContractAuthTest.cs @@ -1372,6 +1372,67 @@ public async Task ChangeCodeCheckController_Test() } } + [Fact] + public async Task SetCodeCheckProposalExpirationTime_Test() + { + var createOrganizationResult = await Tester.ExecuteContractWithMiningAsync(ParliamentAddress, + nameof(ParliamentContractImplContainer.ParliamentContractImplStub.CreateOrganization), + new CreateOrganizationInput + { + ProposalReleaseThreshold = new ProposalReleaseThreshold + { + MinimalApprovalThreshold = 1000, + MinimalVoteThreshold = 1000 + } + }); + var organizationAddress = Address.Parser.ParseFrom(createOrganizationResult.ReturnValue); + + var defaultTime = await Tester.CallContractMethodAsync(BasicContractZeroAddress, + nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.GetCodeCheckProposalExpirationTimePeriod), + new Empty()); + var proposalExpirationTime = Int32Value.Parser.ParseFrom(defaultTime); + Assert.True(proposalExpirationTime.Value == 900); + + var byteResult = await Tester.CallContractMethodAsync(BasicContractZeroAddress, + nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.GetContractDeploymentController), + new Empty()); + var contractDeploymentController = AuthorityInfo.Parser.ParseFrom(byteResult); + + const string methodName = + nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.SetCodeCheckProposalExpirationTimePeriod); + { + var proposalId = await CreateProposalAsync(Tester, ParliamentAddress, + organizationAddress, methodName, + new Int32Value + { + Value = 86400 + } + ); + await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); + var txResult = await ReleaseProposalAsync(Tester, ParliamentAddress, proposalId); + txResult.Status.ShouldBe(TransactionResultStatus.Failed); + txResult.Error.ShouldContain("Unauthorized behavior."); + } + { + var proposalId = await CreateProposalAsync(Tester, ParliamentAddress, + contractDeploymentController.OwnerAddress, methodName, + new Int32Value + { + Value = 86400 + }); + await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); + var txResult2 = await ReleaseProposalAsync(Tester, ParliamentAddress, proposalId); + txResult2.Status.ShouldBe(TransactionResultStatus.Mined); + + byteResult = await Tester.CallContractMethodAsync(BasicContractZeroAddress, + nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub + .GetCodeCheckProposalExpirationTimePeriod), + new Empty()); + var newProposalExpirationTime = Int32Value.Parser.ParseFrom(byteResult); + Assert.True(newProposalExpirationTime.Value == 86400); + } + } + [Fact] public async Task SetContractProposalExpirationTime_Test() { @@ -1386,18 +1447,18 @@ public async Task SetContractProposalExpirationTime_Test() } }); var organizationAddress = Address.Parser.ParseFrom(createOrganizationResult.ReturnValue); - + var defaultTime = await Tester.CallContractMethodAsync(BasicContractZeroAddress, nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.GetContractProposalExpirationTimePeriod), new Empty()); var contractProposalExpirationTime = Int32Value.Parser.ParseFrom(defaultTime); Assert.True(contractProposalExpirationTime.Value == 259200); - + var byteResult = await Tester.CallContractMethodAsync(BasicContractZeroAddress, nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.GetContractDeploymentController), new Empty()); var contractDeploymentController = AuthorityInfo.Parser.ParseFrom(byteResult); - + const string methodName = nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.SetContractProposalExpirationTimePeriod); { @@ -1422,9 +1483,10 @@ public async Task SetContractProposalExpirationTime_Test() await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); var txResult2 = await ReleaseProposalAsync(Tester, ParliamentAddress, proposalId); txResult2.Status.ShouldBe(TransactionResultStatus.Mined); - + byteResult = await Tester.CallContractMethodAsync(BasicContractZeroAddress, - nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub.GetContractProposalExpirationTimePeriod), + nameof(BasicContractZeroImplContainer.BasicContractZeroImplStub + .GetContractProposalExpirationTimePeriod), new Empty()); var newContractProposalExpirationTime = Int32Value.Parser.ParseFrom(byteResult); Assert.True(newContractProposalExpirationTime.Value == 86400); diff --git a/test/AElf.Contracts.GenesisUpdate/AElf.Contracts.GenesisUpdate.csproj b/test/AElf.Contracts.GenesisUpdate/AElf.Contracts.GenesisUpdate.csproj index 6382b39aa6..37b89f1a71 100644 --- a/test/AElf.Contracts.GenesisUpdate/AElf.Contracts.GenesisUpdate.csproj +++ b/test/AElf.Contracts.GenesisUpdate/AElf.Contracts.GenesisUpdate.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 1.3.0 @@ -14,7 +14,7 @@ - + diff --git a/test/AElf.Contracts.MultiToken.Tests/AElf.Contracts.MultiToken.Tests.csproj b/test/AElf.Contracts.MultiToken.Tests/AElf.Contracts.MultiToken.Tests.csproj index a7de2a24a1..c23a5bd985 100644 --- a/test/AElf.Contracts.MultiToken.Tests/AElf.Contracts.MultiToken.Tests.csproj +++ b/test/AElf.Contracts.MultiToken.Tests/AElf.Contracts.MultiToken.Tests.csproj @@ -1,12 +1,12 @@  - net6.0 + net8.0 AElf.Contracts.MultiToken false - + false Contract @@ -63,9 +63,9 @@ all runtime; build; native; contentfiles; analyzers - - - + + + all diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/ACS2_TokenResourceTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/ACS2_TokenResourceTests.cs index 35f84f7154..8729acf7c1 100644 --- a/test/AElf.Contracts.MultiToken.Tests/BVT/ACS2_TokenResourceTests.cs +++ b/test/AElf.Contracts.MultiToken.Tests/BVT/ACS2_TokenResourceTests.cs @@ -48,6 +48,24 @@ public async Task ACS2_GetResourceInfo_TransferFrom_Test() result.NonParallelizable.ShouldBeFalse(); result.WritePaths.Count.ShouldBeGreaterThan(0); } + + [Fact] + public async Task ACS2_GetResourceInfo_TransferFrom_NFT_Test() + { + var transaction = GenerateTokenTransaction(Accounts[0].Address, nameof(TokenContractStub.TransferFrom), + new TransferFromInput + { + Amount = 100, + Symbol = "ABC-1", + From = Accounts[1].Address, + To = Accounts[2].Address, + Memo = "Test get resource" + }); + + var result = await Acs2BaseStub.GetResourceInfo.CallAsync(transaction); + result.NonParallelizable.ShouldBeFalse(); + result.WritePaths.Count.ShouldBeGreaterThan(0); + } private async Task
GetDefaultParliamentAddressAsync() { @@ -179,7 +197,7 @@ await TokenContractStubDelegate3.SetTransactionFeeDelegateInfos.SendAsync(new Se var result = await Acs2BaseStub.GetResourceInfo.CallAsync(transaction); result.NonParallelizable.ShouldBeFalse(); - result.WritePaths.Count.ShouldBe(9); + result.WritePaths.Count.ShouldBe(10); } [Fact] diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs index 24055b432b..9c2dfab8a2 100644 --- a/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs +++ b/test/AElf.Contracts.MultiToken.Tests/BVT/NftApplicationTests.cs @@ -17,6 +17,7 @@ public static class NftCollectionMetaFields public static string BaseUriKey = "__nft_base_uri"; public static string NftType = "__nft_type"; public const string IsItemIdReuseKey = "__nft_is_item_id_reuse"; + public const string NftCreateChainIdExternalInfoKey = "__nft_create_chain_id"; } public static class NftInfoMetaFields @@ -184,6 +185,47 @@ private async Task> CreateNftCollectionAndNft(bool reuseItemId = tr return symbols; } + private async Task CreateNftFailed() + { + var collectionInfo = new TokenInfo + { + Symbol = NftCollection1155Info.Symbol, + TokenName = NftCollection1155Info.TokenName, + TotalSupply = NftCollection1155Info.TotalSupply, + Decimals = NftCollection1155Info.Decimals, + Issuer = NftCollection1155Info.Issuer, + IssueChainId = NftCollection1155Info.IssueChainId, + ExternalInfo = new ExternalInfo() + { + Value = + { + { + NftCollectionMetaFields.NftCreateChainIdExternalInfoKey, + "1234" + } + } + }, + Owner = NftCollection1155Info.Issuer + }; + var createCollectionRes = await CreateNftCollectionAsync(collectionInfo); + createCollectionRes.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + var createNft2Res = await TokenContractStub.Create.SendWithExceptionAsync(new CreateInput + { + Symbol = $"{collectionInfo.Symbol}{Nft1155Info.Symbol}", + TokenName = Nft1155Info.TokenName, + TotalSupply = Nft1155Info.TotalSupply, + Decimals = Nft1155Info.Decimals, + Issuer = Nft1155Info.Issuer, + IsBurnable = Nft1155Info.IsBurnable, + IssueChainId = Nft1155Info.IssueChainId, + ExternalInfo = Nft1155Info.ExternalInfo, + Owner = Nft1155Info.Issuer + }); + createNft2Res.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); + createNft2Res.TransactionResult.Error.Contains("NFT create ChainId must be collection's NFT create chainId") + .ShouldBeTrue(); + } + private void AssertTokenEqual(TokenCreated log, TokenInfo input) { Assert.Equal(log.TokenName, input.TokenName); @@ -204,6 +246,12 @@ public async Task MultiTokenContract_Create_1155Nft_Test() await CreateNftCollectionAndNft(); } + [Fact(DisplayName = "[MultiToken_Nft] Create 1155 nfts failed.")] + public async Task MultiTokenContract_Create_1155Nft_failed_Test() + { + await CreateNftFailed(); + } + [Fact(DisplayName = "[MultiToken_Nft] Create 721 nfts.")] public async Task MultiTokenContract_Create_721Nft_Test() { @@ -214,27 +262,26 @@ public async Task MultiTokenContract_Create_721Nft_Test() public async Task MultiTokenContract_Create_NFTCollection_Input_Check_Test() { var input = NftCollection721Info; - // Decimals check + // Symbol check { - var result = await CreateMutiTokenWithExceptionAsync(TokenContractStub, new CreateInput + var seedInput = BuildSeedCreateInput( new CreateInput { - Symbol = $"{input.Symbol}0", + Symbol = "ABC123", TokenName = input.TokenName, TotalSupply = input.TotalSupply, - Decimals = 8, + Decimals = input.Decimals, Issuer = input.Issuer, IssueChainId = input.IssueChainId, ExternalInfo = input.ExternalInfo, Owner = input.Owner }); - result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); - result.TransactionResult.Error.ShouldContain("NFT's decimals must be 0"); - } - // Symbol check - { - var seedInput = BuildSeedCreateInput( new CreateInput + + var result = await TokenContractStub.Create.SendAsync(seedInput); + result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + + seedInput = BuildSeedCreateInput(new CreateInput { - Symbol = "ABC123", + Symbol = "ABC123()", TokenName = input.TokenName, TotalSupply = input.TotalSupply, Decimals = input.Decimals, @@ -243,8 +290,8 @@ public async Task MultiTokenContract_Create_NFTCollection_Input_Check_Test() ExternalInfo = input.ExternalInfo, Owner = input.Owner }); - - var result = await TokenContractStub.Create.SendWithExceptionAsync(seedInput);; + + result = await TokenContractStub.Create.SendWithExceptionAsync(seedInput); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); result.TransactionResult.Error.ShouldContain("Invalid Symbol input"); } @@ -289,21 +336,6 @@ public async Task MultiTokenContract_Create_NFT_Input_Check_Test() await CreateNftCollectionAsync(NftCollection721Info); var input = Nft721Info; - // Decimals check - { - var result = await CreateMutiTokenWithExceptionAsync(TokenContractStub, new CreateInput - { - Symbol = "GHJ-0", - TokenName = input.TokenName, - TotalSupply = input.TotalSupply, - Decimals = 8, - Issuer = input.Issuer, - IssueChainId = input.IssueChainId, - ExternalInfo = input.ExternalInfo - }); - result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); - result.TransactionResult.Error.ShouldContain("NFT's decimals must be 0"); - } // Symbol check { var result = await CreateSeedNftWithExceptionAsync(TokenContractStub, new CreateInput @@ -378,7 +410,7 @@ public async Task MultiTokenContract_Create_NFT_Input_Check_Test() Owner = input.Owner }); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); - result.TransactionResult.Error.ShouldContain("NFT create ChainId must be collection's issue chainId"); + result.TransactionResult.Error.ShouldContain("NFT issue ChainId must be collection's issue chainId"); } } diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/SymbolValidationTest.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/SymbolValidationTest.cs new file mode 100644 index 0000000000..3d3f94dd9a --- /dev/null +++ b/test/AElf.Contracts.MultiToken.Tests/BVT/SymbolValidationTest.cs @@ -0,0 +1,23 @@ +using System.Text.RegularExpressions; +using Shouldly; +using Xunit; + +namespace AElf.Contracts.MultiToken; + +public class SymbolValidationTest +{ + private const string RegexPattern = "^[a-zA-Z0-9]+(-[0-9]+)?$"; + + [Theory] + [InlineData("ELF", true)] + [InlineData("ELF-", false)] + [InlineData("ABC-123", true)] + [InlineData("abc-1", true)] + [InlineData("ABC-ABC", false)] + [InlineData("ABC--", false)] + [InlineData("121-1", true)] + public void SymbolValidation(string symbol, bool isValid) + { + Regex.IsMatch(symbol, RegexPattern).ShouldBe(isValid); + } +} \ No newline at end of file diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenAliasTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenAliasTests.cs new file mode 100644 index 0000000000..d95e92816a --- /dev/null +++ b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenAliasTests.cs @@ -0,0 +1,379 @@ +using System.Threading.Tasks; +using AElf.Types; +using Google.Protobuf.WellKnownTypes; +using Shouldly; +using Xunit; + +namespace AElf.Contracts.MultiToken; + +public partial class MultiTokenContractTests +{ + public const string TokenAliasExternalInfoKey = "aelf_token_alias"; + + [Fact] + public async Task SetTokenAlias_NFTCollection_Test() + { + var symbols = await CreateNftCollectionAndNft(); + await TokenContractStub.SetSymbolAlias.SendAsync(new SetSymbolAliasInput + { + Symbol = symbols[1], + Alias = "TP" + }); + + { + // Check TokenInfo of NFT Collection. + var tokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = symbols[0] + }); + tokenInfo.ExternalInfo.Value.ContainsKey(TokenAliasExternalInfoKey); + tokenInfo.ExternalInfo.Value[TokenAliasExternalInfoKey].ShouldBe("{\"TP-31175\":\"TP\"}"); + } + + { + // Check TokenInfo of NFT Item. + var tokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = "TP" + }); + tokenInfo.Symbol.ShouldBe(symbols[1]); + } + + { + // Check alias. + var alias = await TokenContractStub.GetTokenAlias.CallAsync(new StringValue { Value = "TP-31175" }); + alias.Value.ShouldBe("TP"); + } + + { + var alias = await TokenContractStub.GetSymbolByAlias.CallAsync(new StringValue { Value = "TP" }); + alias.Value.ShouldBe("TP-31175"); + } + } + + [Fact] + public async Task SetTokenAlias_NFTCollection_CollectionSymbol_Test() + { + await CreateNftCollectionAndNft(); + await TokenContractStub.SetSymbolAlias.SendAsync(new SetSymbolAliasInput + { + Symbol = "TP-0", + Alias = "TP" + }); + + { + // Check TokenInfo of NFT Collection. + var tokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = "TP-0" + }); + tokenInfo.ExternalInfo.Value.ContainsKey(TokenAliasExternalInfoKey); + tokenInfo.ExternalInfo.Value[TokenAliasExternalInfoKey].ShouldBe("{\"TP-0\":\"TP\"}"); + } + + { + // Check TokenInfo of NFT Item. + var tokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = "TP" + }); + tokenInfo.Symbol.ShouldBe("TP-0"); + } + + { + // Check alias. + var alias = await TokenContractStub.GetTokenAlias.CallAsync(new StringValue { Value = "TP-0" }); + alias.Value.ShouldBe("TP"); + } + + { + var alias = await TokenContractStub.GetSymbolByAlias.CallAsync(new StringValue { Value = "TP" }); + alias.Value.ShouldBe("TP-0"); + } + } + + [Fact] + public async Task SetTokenAlias_FT_Test() + { + await CreateNormalTokenAsync(); + + // Set token alias for FT. + var result = await TokenContractStub.SetSymbolAlias.SendWithExceptionAsync(new SetSymbolAliasInput + { + Symbol = AliceCoinTokenInfo.Symbol, + }); + result.TransactionResult.Error.ShouldContain("Token alias can only be set for NFT Item."); + } + + [Fact] + public async Task CreateTokenWithAlias_Test() + { + var createCollectionResult = await CreateNftCollectionAsync(NftCollection1155WithAliasInfo); + createCollectionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + + await CreateNftAsync(NftCollection1155WithAliasInfo.Symbol, Nft721Info); + + { + // Check alias. + var alias = await TokenContractStub.GetTokenAlias.CallAsync(new StringValue { Value = "TP-31175" }); + alias.Value.ShouldBe("TP"); + } + + { + // Check TokenInfo of NFT Item. + var tokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = "TP" + }); + tokenInfo.Symbol.ShouldBe("TP-31175"); + } + } + + [Fact] + public async Task CreateTokenWithAlias_FT_Test() + { + var createInput = new CreateInput + { + Symbol = AliceCoinTokenInfo.Symbol, + TokenName = AliceCoinTokenInfo.TokenName, + TotalSupply = AliceCoinTokenInfo.TotalSupply, + Decimals = AliceCoinTokenInfo.Decimals, + Issuer = AliceCoinTokenInfo.Issuer, + Owner = AliceCoinTokenInfo.Issuer, + IsBurnable = AliceCoinTokenInfo.IsBurnable, + LockWhiteList = + { + BasicFunctionContractAddress, + OtherBasicFunctionContractAddress, + TokenConverterContractAddress, + TreasuryContractAddress + }, + ExternalInfo = new ExternalInfo + { + Value = + { + { TokenAliasExternalInfoKey, "{\"ALICE-111\":\"ALICE\"}" } + } + } + }; + await CreateSeedNftAsync(TokenContractStub, createInput); + var result = await TokenContractStub.Create.SendWithExceptionAsync(createInput); + result.TransactionResult.Error.ShouldContain("Token alias can only be set for NFT Item."); + } + + [Fact] + public async Task TransferViaAlias_Test() + { + await CreateTokenWithAlias_Test(); + + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "TP-31175", + Amount = 1, + To = DefaultAddress + }); + + { + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = DefaultAddress, + Symbol = "TP" + }); + balance.Balance.ShouldBe(1); + } + + await TokenContractStub.Transfer.SendAsync(new TransferInput + { + // Transfer via alias. + Symbol = "TP", + Amount = 1, + To = User1Address + }); + + { + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User1Address, + Symbol = "TP" + }); + balance.Balance.ShouldBe(1); + } + } + + [Fact] + public async Task ApproveAndTransferFromViaAlias_Test() + { + await CreateTokenWithAlias_Test(); + + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "TP-31175", + Amount = 1, + To = DefaultAddress + }); + + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Symbol = "TP", + Amount = 1, + Spender = User1Address + }); + + await TokenContractStubUser.TransferFrom.SendAsync(new TransferFromInput + { + Symbol = "TP", + Amount = 1, + From = DefaultAddress, + To = User2Address, + }); + + { + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User2Address, + Symbol = "TP" + }); + balance.Balance.ShouldBe(1); + } + } + + [Fact] + public async Task GetBalanceOfNotExistToken_Test() + { + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User2Address, + Symbol = "TP" + }); + balance.Balance.ShouldBe(0); + } + + [Fact] + public async Task GetAllowanceOfNotExistToken_Test() + { + var allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = User2Address, + Symbol = "TP", + Spender = DefaultAddress + }); + allowance.Allowance.ShouldBe(0); + } + + [Fact] + public async Task BatchApproveWithAlias_Test() + { + await SetTokenAlias_NFTCollection_Test(); + await CreateTokenAndIssue(); + var approveBasisResult = (await TokenContractStub.BatchApprove.SendAsync(new BatchApproveInput + { + Value = + { + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 2000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = "TP", + Amount = 1000L, + Spender = OtherBasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 5000L, + Spender = TreasuryContractAddress + } + } + })).TransactionResult; + approveBasisResult.Status.ShouldBe(TransactionResultStatus.Mined); + + var basicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = BasicFunctionContractAddress, + Symbol = SymbolForTest + }); + basicAllowanceOutput.Allowance.ShouldBe(2000L); + var otherBasicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = OtherBasicFunctionContractAddress, + Symbol = "TP" + }); + otherBasicAllowanceOutput.Allowance.ShouldBe(1000L); + var treasuryAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = TreasuryContractAddress, + Symbol = SymbolForTest + }); + treasuryAllowanceOutput.Allowance.ShouldBe(5000L); + + approveBasisResult = (await TokenContractStub.BatchApprove.SendAsync(new BatchApproveInput + { + Value = + { + new ApproveInput + { + Symbol = "TP", + Amount = 1000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 3000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 3000L, + Spender = TreasuryContractAddress + } + } + })).TransactionResult; + approveBasisResult.Status.ShouldBe(TransactionResultStatus.Mined); + basicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = BasicFunctionContractAddress, + Symbol = SymbolForTest + }); + basicAllowanceOutput.Allowance.ShouldBe(3000L); + + treasuryAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = TreasuryContractAddress, + Symbol = SymbolForTest + }); + treasuryAllowanceOutput.Allowance.ShouldBe(3000L); + } + + private TokenInfo NftCollection1155WithAliasInfo => new() + { + Symbol = "TP-", + TokenName = "Trump Digital Trading Cards #1155", + TotalSupply = TotalSupply, + Decimals = 0, + Issuer = DefaultAddress, + IssueChainId = _chainId, + ExternalInfo = new ExternalInfo + { + Value = + { + { + NftCollectionMetaFields.ImageUrlKey, + "https://i.seadn.io/gcs/files/0f5cdfaaf687de2ebb5834b129a5bef3.png?auto=format&w=3840" + }, + { NftCollectionMetaFields.NftType, NftType }, + { TokenAliasExternalInfoKey, "{\"TP-31175\":\"TP\"}" } + } + } + }; +} \ No newline at end of file diff --git a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs index b4aa6e54d7..201e56d6e6 100644 --- a/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs +++ b/test/AElf.Contracts.MultiToken.Tests/BVT/TokenApplicationTests.cs @@ -171,6 +171,145 @@ public async Task MultiTokenContract_Approve_ContractAddress_Test() basicAllowanceOutput.Allowance.ShouldBe(2000L); } + [Fact(DisplayName = "[MultiToken] BatchApprove token to Contract")] + public async Task MultiTokenContract_BatchApprove_ContractAddress_Test() + { + await CreateTokenAndIssue(); + var approveBasisResult = (await TokenContractStub.BatchApprove.SendAsync(new BatchApproveInput + { + Value = + { + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 2000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 1000L, + Spender = OtherBasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 5000L, + Spender = TreasuryContractAddress + } + } + })).TransactionResult; + approveBasisResult.Status.ShouldBe(TransactionResultStatus.Mined); + + var basicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = BasicFunctionContractAddress, + Symbol = SymbolForTest + }); + basicAllowanceOutput.Allowance.ShouldBe(2000L); + var otherBasicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = OtherBasicFunctionContractAddress, + Symbol = SymbolForTest + }); + otherBasicAllowanceOutput.Allowance.ShouldBe(1000L); + var treasuryAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = TreasuryContractAddress, + Symbol = SymbolForTest + }); + treasuryAllowanceOutput.Allowance.ShouldBe(5000L); + + approveBasisResult = (await TokenContractStub.BatchApprove.SendAsync(new BatchApproveInput + { + Value = + { + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 1000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 3000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 3000L, + Spender = TreasuryContractAddress + } + } + })).TransactionResult; + approveBasisResult.Status.ShouldBe(TransactionResultStatus.Mined); + basicAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = BasicFunctionContractAddress, + Symbol = SymbolForTest + }); + basicAllowanceOutput.Allowance.ShouldBe(3000L); + + treasuryAllowanceOutput = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = TreasuryContractAddress, + Symbol = SymbolForTest + }); + treasuryAllowanceOutput.Allowance.ShouldBe(3000L); + } + + [Fact] + public async Task MultiTokenContract_SetMaximumBatchApproveCount_Test() + { + var result = await TokenContractStub.SetMaxBatchApproveCount.SendWithExceptionAsync(new Int32Value + { + Value = 1 + }); + result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); + result.TransactionResult.Error.ShouldContain("Unauthorized behavior"); + var maximumBatchApproveCountOutput = await TokenContractStub.GetMaxBatchApproveCount.CallAsync(new Empty()); + maximumBatchApproveCountOutput.Value.ShouldBe(100); + var defaultParliament = await ParliamentContractStub.GetDefaultOrganizationAddress.CallAsync(new Empty()); + var proposalId = await CreateProposalAsync(TokenContractAddress, + defaultParliament, nameof(TokenContractStub.SetMaxBatchApproveCount), + new Int32Value + { + Value = 1 + }); + await ApproveWithMinersAsync(proposalId); + await ParliamentContractStub.Release.SendAsync(proposalId); + maximumBatchApproveCountOutput = await TokenContractStub.GetMaxBatchApproveCount.CallAsync(new Empty()); + maximumBatchApproveCountOutput.Value.ShouldBe(1); + await CreateTokenAndIssue(); + var approveBasisResult = (await TokenContractStub.BatchApprove.SendWithExceptionAsync(new BatchApproveInput + { + Value = + { + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 2000L, + Spender = BasicFunctionContractAddress + }, + new ApproveInput + { + Symbol = SymbolForTest, + Amount = 1000L, + Spender = OtherBasicFunctionContractAddress + } + } + })).TransactionResult; + approveBasisResult.Status.ShouldBe(TransactionResultStatus.Failed); + approveBasisResult.Error.ShouldContain("Exceeds the max batch approve count"); + } + [Fact(DisplayName = "[MultiToken] Approve token out of owner's balance")] public async Task MultiTokenContract_Approve_OutOfAmount_Test() { @@ -365,6 +504,452 @@ await TreasuryContractStub.Donate.SendAsync(new DonateInput afterTransferFromBalance.Balance.ShouldBe(beforeTransferFromBalance.Balance.Sub(transferAmount)); } + private async Task CreateNft() + { + await CreateMutiTokenAsync(TokenContractStub, new CreateInput + { + TokenName = "Test", + TotalSupply = TotalSupply, + Decimals = 0, + Issuer = DefaultAddress, + Owner = DefaultAddress, + IssueChainId = _chainId, + Symbol = "ABC-0" + }); + await TokenContractStub.Create.SendAsync(new CreateInput + { + TokenName = "Test", + TotalSupply = TotalSupply, + Decimals = 0, + Issuer = DefaultAddress, + Owner = DefaultAddress, + IssueChainId = _chainId, + Symbol = "ABC-1" + }); + } + [Fact] + public async Task MultiTokenContract_TransferFrom_Nft_Global_Test() + { + await CreateNft(); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "ABC-1", + Amount = 100, + To = DefaultAddress, + Memo = "test" + }); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "ABC-1", + Amount = 200, + To = User1Address, + Memo = "test" + }); + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = DefaultAddress, + Symbol = "ABC-1" + }); + balance.Balance.ShouldBe(100); + balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User1Address, + Symbol = "ABC-1" + }); + balance.Balance.ShouldBe(200); + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Amount = 1000, + Symbol = "*", + Spender = User1Address + }); + + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Amount = 1, + Symbol = "ABC-*", + Spender = User1Address + }); + var allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + allowance.Allowance.ShouldBe(0); + allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ELF" + }); + allowance.Allowance.ShouldBe(0); + { + var realAllowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + realAllowance.Allowance.ShouldBe(1000); + } + { + var realAllowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ELF" + }); + realAllowance.Allowance.ShouldBe(1000); + } + var user1Stub = + GetTester(TokenContractAddress, User1KeyPair); + var result2 = await user1Stub.TransferFrom.SendAsync(new TransferFromInput + { + Amount = 50, + From = DefaultAddress, + Memo = "test", + Symbol = "ABC-1", + To = User1Address + }); + result2.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + { + var realAllowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + realAllowance.Allowance.ShouldBe(0); + } + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + allowance.Allowance.ShouldBe(1000-50); + balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = DefaultAddress, + Symbol = "ABC-1" + }); + balance.Balance.ShouldBe(50); + balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User1Address, + Symbol = "ABC-1" + }); + balance.Balance.ShouldBe(250); + } + + [Fact] + public async Task MultiTokenContract_TransferFrom_Nft_Collection_Test() + { + await CreateNft(); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "ABC-1", + Amount = 100, + To = DefaultAddress, + Memo = "test" + }); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "ABC-1", + Amount = 200, + To = User1Address, + Memo = "test" + }); + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Amount = 20, + Symbol = "*", + Spender = User1Address + }); + + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Amount = 1000, + Symbol = "ABC-*", + Spender = User1Address + }); + { + var realAllowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + realAllowance.Allowance.ShouldBe(0); + } + var allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + allowance.Allowance.ShouldBe(1000); + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ELF" + }); + allowance.Allowance.ShouldBe(20); + var user1Stub = + GetTester(TokenContractAddress, User1KeyPair); + var result2 = await user1Stub.TransferFrom.SendAsync(new TransferFromInput + { + Amount = 50, + From = DefaultAddress, + Memo = "test", + Symbol = "ABC-1", + To = User1Address + }); + result2.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ABC-1" + }); + allowance.Allowance.ShouldBe(1000-50); + allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "*" + }); + allowance.Allowance.ShouldBe(20); + + } + + [Fact] + public async Task MultiTokenContract_TransferFrom_Token_Test() + { + await CreateAndIssueToken(); + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Amount = 100_00000000, + Symbol = "*", + Spender = User1Address + }); + var allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + allowance.Allowance.ShouldBe(0); + { + var realAllowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + realAllowance.Allowance.ShouldBe(100_00000000); + } + allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "ELF" + }); + allowance.Allowance.ShouldBe(0); + { + var realAllowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + realAllowance.Allowance.ShouldBe(100_00000000); + } + var user1Stub = + GetTester(TokenContractAddress, User1KeyPair); + var result2 = await user1Stub.TransferFrom.SendAsync(new TransferFromInput + { + Amount = 50_00000000, + From = DefaultAddress, + Memo = "test", + Symbol = "SSS", + To = User1Address + }); + result2.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + allowance.Allowance.ShouldBe(100_00000000-50_00000000); + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = DefaultAddress, + Symbol = "SSS" + }); + balance.Balance.ShouldBe(TotalSupply - 50_00000000); + balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = User1Address, + Symbol = "SSS" + }); + balance.Balance.ShouldBe(50_00000000); + } + + private async Task CreateAndIssueToken() + { + await CreateMutiTokenAsync(TokenContractStub, new CreateInput + { + TokenName = "Test", + TotalSupply = TotalSupply, + Decimals = 8, + Issuer = DefaultAddress, + Owner = DefaultAddress, + IssueChainId = _chainId, + Symbol = "SSS" + }); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "SSS", + Amount = TotalSupply, + To = DefaultAddress, + Memo = "Issue" + }); + var balance = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput + { + Owner = DefaultAddress, + Symbol = "SSS" + }); + balance.Balance.ShouldBe(TotalSupply); + } + [Fact] + public async Task MultiTokenContract_Approve_Test_New() + { + await CreateAndIssueToken(); + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "SSS", + Amount = 100_000000000 + }); + var allowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + allowance.Allowance.ShouldBe(100_000000000); + await TokenContractStub.Approve.SendAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "*", + Amount = 200_000000000 + }); + { + var realAllowance = await TokenContractStub.GetAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + realAllowance.Allowance.ShouldBe(100_000000000); + } + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "SSS" + }); + allowance.Allowance.ShouldBe(200_000000000); + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "*" + }); + allowance.Allowance.ShouldBe(200_000000000); + await TokenContractStub.UnApprove.SendAsync(new UnApproveInput + { + Spender = User1Address, + Symbol = "*", + Amount = 20_000000000 + }); + allowance = await TokenContractStub.GetAvailableAllowance.CallAsync(new GetAllowanceInput + { + Owner = DefaultAddress, + Spender = User1Address, + Symbol = "*" + }); + allowance.Allowance.ShouldBe(200_000000000-20_000000000); + } + + [Fact] + public async Task MultiTokenContract_Approve_Test_New_Fail() + { + await CreateAndIssueToken(); + { + var executionResult = await TokenContractStub.Approve.SendWithExceptionAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "SSS*", + Amount = 100_000000000 + }); + executionResult.TransactionResult.Error.ShouldContain("Invalid symbol."); + } + { + var executionResult = await TokenContractStub.Approve.SendWithExceptionAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "SSS**", + Amount = 100_000000000 + }); + executionResult.TransactionResult.Error.ShouldContain("Invalid symbol."); + } + { + var executionResult = await TokenContractStub.Approve.SendWithExceptionAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "*-*", + Amount = 100_000000000 + }); + executionResult.TransactionResult.Error.ShouldContain("Token is not found"); + } + } + + [Fact] + public async Task MultiTokenContract_Approve_Test_New_Nft_Fail() + { + await CreateNft(); + await TokenContractStub.Issue.SendAsync(new IssueInput + { + Symbol = "ABC-1", + Amount = 100, + To = DefaultAddress, + Memo = "test" + }); + { + var executionResult = await TokenContractStub.Approve.SendWithExceptionAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "AB*-*", + Amount = 100_000000000 + }); + executionResult.TransactionResult.Error.ShouldContain("Invalid Symbol"); + } + { + var executionResult = await TokenContractStub.Approve.SendWithExceptionAsync(new ApproveInput + { + Spender = User1Address, + Symbol = "ABC-*9", + Amount = 100_000000000 + }); + executionResult.TransactionResult.Error.ShouldContain("Invalid NFT Symbol."); + } + } + private async Task CreateTokenAndIssue(List
whitelist = null, Address issueTo = null) { if (whitelist == null) @@ -999,16 +1584,21 @@ public async Task Side_Chain_Creat_Token_Test() }); await ApproveWithMinersAsync(proposalId); await ParliamentContractStub.Release.SendAsync(proposalId); - var createTokenRet = await TokenContractStub.Create.SendWithExceptionAsync(new CreateInput - { - Symbol = "ALI", - TokenName = "Ali", - Decimals = 4, - TotalSupply = 100_000, - Issuer = DefaultAddress, - Owner = DefaultAddress - }); - createTokenRet.TransactionResult.Error.ShouldContain( + + proposalId = await CreateProposalAsync(TokenContractAddress, + defaultParliament, nameof(TokenContractStub.Create), + new CreateInput + { + Symbol = "ALI", + TokenName = "Ali", + Decimals = 4, + TotalSupply = 100_000, + Issuer = DefaultAddress, + Owner = DefaultAddress + }); + await ApproveWithMinersAsync(proposalId); + var createTokenRe = await ParliamentContractStub.Release.SendWithExceptionAsync(proposalId); + createTokenRe.TransactionResult.Error.ShouldContain( "Failed to create token if side chain creator already set."); } @@ -1227,4 +1817,80 @@ await TokenContractStub.Issue.SendAsync(new IssueInput checkTokenInfo.IsBurnable.ShouldBe(createTokenInput.IsBurnable); checkTokenInfo.ExternalInfo.Value.ShouldBe(createTokenInput.ExternalInfo.Value); } + + [Fact] + public async Task TokenIssuerAndOwnerModification_Test() + { + var result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput()); + result.TransactionResult.Error.ShouldContain("Invalid input symbol."); + + result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = "TEST" + }); + result.TransactionResult.Error.ShouldContain("Invalid input issuer."); + + result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = "TEST", + Issuer = DefaultAddress + }); + result.TransactionResult.Error.ShouldContain("Invalid input owner."); + + result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = "TEST", + Issuer = DefaultAddress, + Owner = DefaultAddress + }); + result.TransactionResult.Error.ShouldContain("Token is not found."); + + result = await TokenContractStubUser.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = DefaultSymbol, + Issuer = DefaultAddress, + Owner = DefaultAddress + }); + result.TransactionResult.Error.ShouldContain("Only token issuer can set token issuer and owner."); + + result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = DefaultSymbol, + Issuer = DefaultAddress, + Owner = DefaultAddress + }); + result.TransactionResult.Error.ShouldContain("Can only set token which does not have owner."); + + var output = await TokenContractStub.GetTokenIssuerAndOwnerModificationEnabled.CallAsync(new Empty()); + output.Value.ShouldBeTrue(); + + result = await TokenContractStub.SetTokenIssuerAndOwnerModificationEnabled.SendWithExceptionAsync( + new SetTokenIssuerAndOwnerModificationEnabledInput + { + Enabled = false + }); + result.TransactionResult.Error.ShouldContain("Unauthorized behavior."); + + var defaultParliament = await ParliamentContractStub.GetDefaultOrganizationAddress.CallAsync(new Empty()); + var proposalId = await CreateProposalAsync(TokenContractAddress, + defaultParliament, nameof(TokenContractStub.SetTokenIssuerAndOwnerModificationEnabled), + new SetTokenIssuerAndOwnerModificationEnabledInput + { + Enabled = false + }); + await ApproveWithMinersAsync(proposalId); + await ParliamentContractStub.Release.SendAsync(proposalId); + + output = await TokenContractStub.GetTokenIssuerAndOwnerModificationEnabled.CallAsync(new Empty()); + output.Value.ShouldBeFalse(); + + result = await TokenContractStub.ModifyTokenIssuerAndOwner.SendWithExceptionAsync(new ModifyTokenIssuerAndOwnerInput + { + Symbol = DefaultSymbol, + Issuer = DefaultAddress, + Owner = DefaultAddress + }); + result.TransactionResult.Error.ShouldContain("Set token issuer and owner disabled."); + + } } \ No newline at end of file diff --git a/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/AElf.Contracts.MultiTokenCrossChainTransfer.Tests.csproj b/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/AElf.Contracts.MultiTokenCrossChainTransfer.Tests.csproj index d913d0ca09..d1a1ac78b4 100644 --- a/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/AElf.Contracts.MultiTokenCrossChainTransfer.Tests.csproj +++ b/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/AElf.Contracts.MultiTokenCrossChainTransfer.Tests.csproj @@ -1,11 +1,11 @@ - + - net6.0 + net8.0 AElf.Contracts.MultiTokenCrossSideChain false - + false Contract @@ -59,7 +59,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/MultiTokenContractCrossChainTest.cs b/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/MultiTokenContractCrossChainTest.cs index 4c76a04b09..30a6d59c74 100644 --- a/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/MultiTokenContractCrossChainTest.cs +++ b/test/AElf.Contracts.MultiTokenCrossChainTransfer.Tests/MultiTokenContractCrossChainTest.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using AElf.Contracts.Parliament; using AElf.ContractTestBase.ContractTestKit; @@ -11,6 +12,7 @@ using AElf.Standards.ACS7; using AElf.Types; using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; using Shouldly; using Xunit; @@ -19,11 +21,13 @@ namespace AElf.Contracts.MultiToken; public class MultiTokenContractCrossChainTest : MultiTokenContractCrossChainTestBase { private const string SymbolForTesting = "ELFTEST"; + private const string NFTSymbolForTesting = "ELFNFT"; private const string NativeToken = "ELF"; private static readonly long _totalSupply = 1000L; private readonly Hash _fakeBlockHeader = HashHelper.ComputeFrom("fakeBlockHeader"); private readonly int _parentChainHeightOfCreation = 5; private readonly string sideChainSymbol = "STA"; + public const string TokenAliasExternalInfoKey = "aelf_token_alias"; #region register test @@ -321,7 +325,7 @@ public async Task SideChain_CrossChainSideChainCreateToken_Test() } - [Fact] + [Fact(Skip = "Now we allow this.")] public async Task SideChain_CrossChainCreateToken_WithAlreadyCreated_Test() { await GenerateSideChainAsync(); @@ -387,6 +391,146 @@ public async Task CrossChainCreateToken_With_Invalid_Verification_Test() Assert.True(result.Status == TransactionResultStatus.Failed); Assert.Contains("Invalid transaction", result.Error); } + + [Fact] + public async Task SideChain_CrossChainSideChainCreateToken_WithAlias_Test() + { + await GenerateSideChainAsync(); + await RegisterSideChainContractAddressOnMainChainAsync(); + + // Main chain create token + await BootMinerChangeRoundAsync(AEDPoSContractStub, true); + var createTransaction = await CreateTransactionForNFTCreation(TokenContractStub, + DefaultAccount.Address, $"{NFTSymbolForTesting}-0", TokenContractAddress); + var blockExecutedSet = await MineAsync(new List { createTransaction }); + var createResult = blockExecutedSet.TransactionResultMap[createTransaction.GetHash()]; + Assert.True(createResult.Status == TransactionResultStatus.Mined, createResult.Error); + + var createdTokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = $"{NFTSymbolForTesting}-0" + }); + var tokenValidationTransaction = CreateTokenInfoValidationTransaction(createdTokenInfo, + TokenContractStub); + + blockExecutedSet = await MineAsync(new List { tokenValidationTransaction }); + var merklePath = GetTransactionMerklePathAndRoot(tokenValidationTransaction, out var blockRoot); + await IndexMainChainTransactionAsync(blockExecutedSet.Height, blockRoot, blockRoot); + var crossChainCreateTokenInput = new CrossChainCreateTokenInput + { + FromChainId = MainChainId, + ParentChainHeight = blockExecutedSet.Height, + TransactionBytes = tokenValidationTransaction.ToByteString(), + MerklePath = merklePath + }; + // Side chain cross chain create + var executionResult = + await SideChainTokenContractStub.CrossChainCreateToken.SendAsync(crossChainCreateTokenInput); + executionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined, + executionResult.TransactionResult.Error); + + var newTokenInfo = await SideChainTokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = $"{NFTSymbolForTesting}-0" + }); + newTokenInfo.TotalSupply.ShouldBe(_totalSupply); + + var alias = await SideChainTokenContractStub.GetTokenAlias.CallAsync(new StringValue + { + Value = $"{NFTSymbolForTesting}-{1}" + }); + alias.Value.ShouldBe(NFTSymbolForTesting); + } + + [Fact] + public async Task SideChain_CrossChainSideChainCreateToken_SetAliasAndSyncAgain_Test() + { + await GenerateSideChainAsync(); + await RegisterSideChainContractAddressOnMainChainAsync(); + + // Main chain create token + await BootMinerChangeRoundAsync(AEDPoSContractStub, true); + var createTransaction = await CreateTransactionForNFTCreation(TokenContractStub, + DefaultAccount.Address, $"{NFTSymbolForTesting}-0", TokenContractAddress, false); + var blockExecutedSet = await MineAsync(new List { createTransaction }); + var createResult = blockExecutedSet.TransactionResultMap[createTransaction.GetHash()]; + Assert.True(createResult.Status == TransactionResultStatus.Mined, createResult.Error); + + // Sync for the first time + { + var createdTokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = $"{NFTSymbolForTesting}-0" + }); + var tokenValidationTransaction = CreateTokenInfoValidationTransaction(createdTokenInfo, + TokenContractStub); + + blockExecutedSet = await MineAsync(new List { tokenValidationTransaction }); + var merklePath = GetTransactionMerklePathAndRoot(tokenValidationTransaction, out var blockRoot); + await IndexMainChainTransactionAsync(blockExecutedSet.Height, blockRoot, blockRoot); + var crossChainCreateTokenInput = new CrossChainCreateTokenInput + { + FromChainId = MainChainId, + ParentChainHeight = blockExecutedSet.Height, + TransactionBytes = tokenValidationTransaction.ToByteString(), + MerklePath = merklePath + }; + // Side chain cross chain create + var executionResult = + await SideChainTokenContractStub.CrossChainCreateToken.SendAsync(crossChainCreateTokenInput); + executionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined, + executionResult.TransactionResult.Error); + } + + // Set Alias + { + var setAliasTransaction = await TokenContractStub.SetSymbolAlias.SendAsync(new SetSymbolAliasInput + { + Symbol = $"{NFTSymbolForTesting}-1", + Alias = NFTSymbolForTesting + }); + var setAliasResult = setAliasTransaction.TransactionResult; + setAliasResult.Status.ShouldBe(TransactionResultStatus.Mined); + } + + // Sync for the second time + { + var createdTokenInfo = await TokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = $"{NFTSymbolForTesting}-0" + }); + var tokenValidationTransaction = CreateTokenInfoValidationTransaction(createdTokenInfo, + TokenContractStub); + + blockExecutedSet = await MineAsync(new List { tokenValidationTransaction }); + var merklePath = GetTransactionMerklePathAndRoot(tokenValidationTransaction, out var blockRoot); + await IndexMainChainTransactionAsync(blockExecutedSet.Height, blockRoot, blockRoot); + var crossChainCreateTokenInput = new CrossChainCreateTokenInput + { + FromChainId = MainChainId, + ParentChainHeight = blockExecutedSet.Height, + TransactionBytes = tokenValidationTransaction.ToByteString(), + MerklePath = merklePath + }; + // Side chain cross chain create + var executionResult = + await SideChainTokenContractStub.CrossChainCreateToken.SendAsync(crossChainCreateTokenInput); + executionResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined, + executionResult.TransactionResult.Error); + } + + var newTokenInfo = await SideChainTokenContractStub.GetTokenInfo.CallAsync(new GetTokenInfoInput + { + Symbol = $"{NFTSymbolForTesting}-0" + }); + newTokenInfo.TotalSupply.ShouldBe(_totalSupply); + + var alias = await SideChainTokenContractStub.GetTokenAlias.CallAsync(new StringValue + { + Value = $"{NFTSymbolForTesting}-1" + }); + alias.Value.ShouldBe(NFTSymbolForTesting); + } #endregion @@ -891,12 +1035,48 @@ private async Task CreateTransactionForTokenCreation( await CreateSeedNftAsync(tokenContractImplStub, input, lockWhiteAddress); return tokenContractImplStub.Create.GetTransaction(input); } + + private async Task CreateTransactionForNFTCreation( + TokenContractImplContainer.TokenContractImplStub tokenContractImplStub, + Address issuer, string symbol, Address lockWhiteAddress, bool withAlias = true) + { + await CreateSeedNftCollection(tokenContractImplStub, issuer); + var tokenInfo = GetTokenInfo(symbol, issuer); + var input = new CreateInput + { + Symbol = tokenInfo.Symbol, + Decimals = 0, + Issuer = tokenInfo.Issuer, + Owner = tokenInfo.Issuer, + IsBurnable = tokenInfo.IsBurnable, + TokenName = tokenInfo.TokenName, + TotalSupply = tokenInfo.TotalSupply, + }; + if (withAlias) + { + input.ExternalInfo = new ExternalInfo + { + Value = + { + { + TokenAliasExternalInfoKey, JsonSerializer.Serialize(new Dictionary + { + { $"{NFTSymbolForTesting}-{1}", NFTSymbolForTesting } + }) + } + } + }; + } + + await CreateSeedNftAsync(tokenContractImplStub, input, lockWhiteAddress); + return tokenContractImplStub.Create.GetTransaction(input); + } private Transaction CreateTokenInfoValidationTransaction(TokenInfo createdTokenInfo, TokenContractImplContainer.TokenContractImplStub tokenContractImplStub) { - return tokenContractImplStub.ValidateTokenInfoExists.GetTransaction(new ValidateTokenInfoExistsInput + var input = new ValidateTokenInfoExistsInput { TokenName = createdTokenInfo.TokenName, Symbol = createdTokenInfo.Symbol, @@ -906,7 +1086,12 @@ private Transaction CreateTokenInfoValidationTransaction(TokenInfo createdTokenI IsBurnable = createdTokenInfo.IsBurnable, TotalSupply = createdTokenInfo.TotalSupply, IssueChainId = createdTokenInfo.IssueChainId - }); + }; + if (createdTokenInfo.ExternalInfo != null) + { + input.ExternalInfo.Add(createdTokenInfo.ExternalInfo.Value); + } + return tokenContractImplStub.ValidateTokenInfoExists.GetTransaction(input); } private TokenInfo GetTokenInfo(string symbol, Address issuer, bool isBurnable = true) diff --git a/test/AElf.Contracts.NFT.Tests/AElf.Contracts.NFT.Tests.csproj b/test/AElf.Contracts.NFT.Tests/AElf.Contracts.NFT.Tests.csproj index 1fcbbe1435..7943f658f4 100644 --- a/test/AElf.Contracts.NFT.Tests/AElf.Contracts.NFT.Tests.csproj +++ b/test/AElf.Contracts.NFT.Tests/AElf.Contracts.NFT.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Contracts.NFT false diff --git a/test/AElf.Contracts.Parliament.Tests/AElf.Contracts.Parliament.Tests.csproj b/test/AElf.Contracts.Parliament.Tests/AElf.Contracts.Parliament.Tests.csproj index 525f9f9403..196851f316 100644 --- a/test/AElf.Contracts.Parliament.Tests/AElf.Contracts.Parliament.Tests.csproj +++ b/test/AElf.Contracts.Parliament.Tests/AElf.Contracts.Parliament.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.Parliament false @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -27,8 +27,8 @@ - - + + @@ -95,5 +95,5 @@ - + diff --git a/test/AElf.Contracts.Parliament.Tests/ParliamentContractTest.cs b/test/AElf.Contracts.Parliament.Tests/ParliamentContractTest.cs index 5a82089232..caeb34f557 100644 --- a/test/AElf.Contracts.Parliament.Tests/ParliamentContractTest.cs +++ b/test/AElf.Contracts.Parliament.Tests/ParliamentContractTest.cs @@ -108,6 +108,8 @@ public async Task Get_Proposal_Test() getProposal.Output.ProposalId.ShouldBe(proposalId); getProposal.Output.OrganizationAddress.ShouldBe(organizationAddress); getProposal.Output.ToAddress.ShouldBe(TokenContractAddress); + getProposal.Output.Title.ShouldNotBeNullOrEmpty(); + getProposal.Output.Description.ShouldNotBeNullOrEmpty(); var transferParam = TransferInput.Parser.ParseFrom(getProposal.Output.Params); transferParam.Symbol.ShouldBe(transferInput.Symbol); @@ -1541,7 +1543,9 @@ private async Task CreateProposalAsync(ECKeyPair proposalKeyPair, Address ToAddress = TokenContractAddress, Params = transferInput.ToByteString(), ExpiredTime = BlockTimeProvider.GetBlockTime().AddDays(2), - OrganizationAddress = organizationAddress + OrganizationAddress = organizationAddress, + Title = "Token Transfer", + Description = "Transfer 100 ELF to Tester's address", }; var parliamentContractStub = GetParliamentContractTester(proposalKeyPair); var proposal = await parliamentContractStub.CreateProposal.SendAsync(createProposalInput); diff --git a/test/AElf.Contracts.Profit.Tests/AElf.Contracts.Profit.Tests.csproj b/test/AElf.Contracts.Profit.Tests/AElf.Contracts.Profit.Tests.csproj index 53b98d7d62..a86fafe9e7 100644 --- a/test/AElf.Contracts.Profit.Tests/AElf.Contracts.Profit.Tests.csproj +++ b/test/AElf.Contracts.Profit.Tests/AElf.Contracts.Profit.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.Profit false diff --git a/test/AElf.Contracts.Profit.Tests/ProfitContractTestConstants.cs b/test/AElf.Contracts.Profit.Tests/ProfitContractTestConstants.cs index d4f937117a..bda82297c0 100644 --- a/test/AElf.Contracts.Profit.Tests/ProfitContractTestConstants.cs +++ b/test/AElf.Contracts.Profit.Tests/ProfitContractTestConstants.cs @@ -5,4 +5,5 @@ public class ProfitContractTestConstants public const string NativeTokenSymbol = "ELF"; public const long NativeTokenTotalSupply = 1_000_000_000_00000000; public const int MaximumProfitReceivingDuePeriodCount = 1024; + public const int DefaultMaximumProfitReceivingPeriodCountOfOneTime = 100; } \ No newline at end of file diff --git a/test/AElf.Contracts.Profit.Tests/ProfitTests.cs b/test/AElf.Contracts.Profit.Tests/ProfitTests.cs index 34979069da..601fd7ccf6 100644 --- a/test/AElf.Contracts.Profit.Tests/ProfitTests.cs +++ b/test/AElf.Contracts.Profit.Tests/ProfitTests.cs @@ -3,6 +3,7 @@ using AElf.Contracts.MultiToken; using AElf.CSharp.Core; using AElf.Types; +using Google.Protobuf.WellKnownTypes; using Shouldly; using Xunit; @@ -1604,13 +1605,32 @@ await creator.DistributeProfits.SendAsync(new DistributeProfitsInput Symbol = tokenSymbol, SchemeId = schemeId }); + profitAmount.Value.ShouldBe(amount); + + var allProfitAmount = await ProfitContractStub.GetAllProfitAmount.CallAsync(new GetAllProfitAmountInput + { + Beneficiary = receiver, + Symbol = tokenSymbol, + SchemeId = schemeId + }); + allProfitAmount.AllProfitAmount.ShouldBe(amount); + allProfitAmount.OneTimeClaimableProfitAmount.ShouldBe(amount); var profitMap = await ProfitContractStub.GetProfitsMap.CallAsync(new ClaimProfitsInput { SchemeId = schemeId, Beneficiary = receiver }); + profitMap.Value[tokenSymbol].ShouldBe(amount); + + var allProfitMap = await ProfitContractStub.GetAllProfitsMap.CallAsync(new GetAllProfitsMapInput + { + SchemeId = schemeId, + Beneficiary = receiver + }); + allProfitMap.AllProfitsMap[tokenSymbol].ShouldBe(amount); + allProfitMap.OneTimeClaimableProfitsMap[tokenSymbol].ShouldBe(amount); } // after claim @@ -1633,12 +1653,30 @@ await ProfitContractStub.ClaimProfits.SendAsync(new ClaimProfitsInput SchemeId = schemeId }); profitAmount.Value.ShouldBe(0); + + var allProfitAmount = await ProfitContractStub.GetAllProfitAmount.CallAsync(new GetAllProfitAmountInput + { + Beneficiary = receiver, + Symbol = tokenSymbol, + SchemeId = schemeId + }); + allProfitAmount.AllProfitAmount.ShouldBe(0); + allProfitAmount.OneTimeClaimableProfitAmount.ShouldBe(0); + var profitMap = await ProfitContractStub.GetProfitsMap.CallAsync(new ClaimProfitsInput { SchemeId = schemeId, Beneficiary = receiver }); profitMap.Value.ShouldNotContainKey(tokenSymbol); + + var allProfitMap = await ProfitContractStub.GetAllProfitsMap.CallAsync(new GetAllProfitsMapInput + { + SchemeId = schemeId, + Beneficiary = receiver + }); + allProfitMap.AllProfitsMap.ShouldNotContainKey(tokenSymbol); + allProfitMap.OneTimeClaimableProfitsMap.ShouldNotContainKey(tokenSymbol); } //second time @@ -1659,12 +1697,28 @@ await creator.DistributeProfits.SendAsync(new DistributeProfitsInput SchemeId = schemeId }); profitAmount.Value.ShouldBe(amount); + var allProfitAmount = await ProfitContractStub.GetAllProfitAmount.CallAsync(new GetAllProfitAmountInput + { + Beneficiary = receiver, + Symbol = tokenSymbol, + SchemeId = schemeId + }); + allProfitAmount.AllProfitAmount.ShouldBe(amount); + allProfitAmount.OneTimeClaimableProfitAmount.ShouldBe(amount); var profitMap = await ProfitContractStub.GetProfitsMap.CallAsync(new ClaimProfitsInput { SchemeId = schemeId, Beneficiary = receiver }); profitMap.Value[tokenSymbol].ShouldBe(amount); + + var allProfitMap = await ProfitContractStub.GetAllProfitsMap.CallAsync(new GetAllProfitsMapInput + { + SchemeId = schemeId, + Beneficiary = receiver + }); + allProfitMap.AllProfitsMap[tokenSymbol].ShouldBe(amount); + allProfitMap.OneTimeClaimableProfitsMap[tokenSymbol].ShouldBe(amount); await ProfitContractStub.ClaimProfits.SendAsync(new ClaimProfitsInput { @@ -1680,6 +1734,47 @@ await ProfitContractStub.ClaimProfits.SendAsync(new ClaimProfitsInput } } + + [Fact] + public async Task MaximumProfitReceivingPeriodCount_Test() + { + var maximumProfitReceivingPeriodCount = + await ProfitContractStub.GetMaximumProfitReceivingPeriodCount.CallAsync(new Empty()); + maximumProfitReceivingPeriodCount.Value.ShouldBe(ProfitContractTestConstants + .DefaultMaximumProfitReceivingPeriodCountOfOneTime); + var maxPeriodCount = 10; + var result = await ProfitContractStub.SetMaximumProfitReceivingPeriodCount.SendWithExceptionAsync(new Int32Value + { + Value = maxPeriodCount + }); + result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); + result.TransactionResult.Error.ShouldContain("No permission"); + + var defaultOrganizationAddress = + await ParliamentContractStub.GetDefaultOrganizationAddress.CallAsync(new Empty()); + var proposalId = await CreateProposalAsync(ProfitContractAddress, + defaultOrganizationAddress, nameof(ProfitContractStub.SetMaximumProfitReceivingPeriodCount), new Int32Value + { + Value = 0 + }); + await ApproveWithMinersAsync(proposalId); + result = await ParliamentContractStub.Release.SendWithExceptionAsync(proposalId); + result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); + result.TransactionResult.Error.ShouldContain("Invalid maximum profit receiving period count"); + + proposalId = await CreateProposalAsync(ProfitContractAddress, + defaultOrganizationAddress, nameof(ProfitContractStub.SetMaximumProfitReceivingPeriodCount), new Int32Value + { + Value = maxPeriodCount + }); + await ApproveWithMinersAsync(proposalId); + await ParliamentContractStub.Release.SendAsync(proposalId); + + maximumProfitReceivingPeriodCount = + await ProfitContractStub.GetMaximumProfitReceivingPeriodCount.CallAsync(new Empty()); + maximumProfitReceivingPeriodCount.Value.ShouldBe(maxPeriodCount); + } + private async Task ContributeProfits(Hash schemeId, long amount = 100) { await ProfitContractStub.ContributeProfits.SendAsync(new ContributeProfitsInput diff --git a/test/AElf.Contracts.Referendum.Tests/AElf.Contracts.Referendum.Tests.csproj b/test/AElf.Contracts.Referendum.Tests/AElf.Contracts.Referendum.Tests.csproj index 417c55448b..a63f0c6b22 100644 --- a/test/AElf.Contracts.Referendum.Tests/AElf.Contracts.Referendum.Tests.csproj +++ b/test/AElf.Contracts.Referendum.Tests/AElf.Contracts.Referendum.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.Referendum false @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -28,13 +28,13 @@ - - - - - - - + + + + + + + diff --git a/test/AElf.Contracts.Referendum.Tests/ReferendumContractTest.cs b/test/AElf.Contracts.Referendum.Tests/ReferendumContractTest.cs index d22a250401..81dd45896c 100644 --- a/test/AElf.Contracts.Referendum.Tests/ReferendumContractTest.cs +++ b/test/AElf.Contracts.Referendum.Tests/ReferendumContractTest.cs @@ -110,6 +110,8 @@ public async Task Get_Proposal_Test() getProposal.Output.OrganizationAddress.ShouldBe(organizationAddress); getProposal.Output.ToAddress.ShouldBe(TokenContractAddress); getProposal.Output.Params.ShouldBe(createInput.ToByteString()); + getProposal.Output.Title.ShouldNotBeNullOrEmpty(); + getProposal.Output.Description.ShouldNotBeNullOrEmpty(); } [Fact] @@ -1320,7 +1322,9 @@ private async Task CreateProposalAsync(ECKeyPair proposalKeyPair, Address ToAddress = TokenContractAddress, Params = createInput.ToByteString(), ExpiredTime = timestamp ?? BlockTimeProvider.GetBlockTime().AddSeconds(1000), - OrganizationAddress = organizationAddress + OrganizationAddress = organizationAddress, + Title = "Create token: NEW", + Description = "Create a new token named NEW." }; ReferendumContractStub = GetReferendumContractTester(proposalKeyPair); var proposal = await ReferendumContractStub.CreateProposal.SendAsync(createProposalInput); diff --git a/test/AElf.Contracts.TestBase.Tests/AElf.Contracts.TestBase.Tests.csproj b/test/AElf.Contracts.TestBase.Tests/AElf.Contracts.TestBase.Tests.csproj index 134f6b7250..63bac56eb0 100644 --- a/test/AElf.Contracts.TestBase.Tests/AElf.Contracts.TestBase.Tests.csproj +++ b/test/AElf.Contracts.TestBase.Tests/AElf.Contracts.TestBase.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -23,8 +23,8 @@ - - + + false Contract @@ -42,5 +42,5 @@ - + diff --git a/test/AElf.Contracts.TestBase/AElf.Contracts.TestBase.csproj b/test/AElf.Contracts.TestBase/AElf.Contracts.TestBase.csproj index 2f987b9204..1ad7c881a8 100644 --- a/test/AElf.Contracts.TestBase/AElf.Contracts.TestBase.csproj +++ b/test/AElf.Contracts.TestBase/AElf.Contracts.TestBase.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -15,7 +15,7 @@ Contract PreserveNewest - + false Contract @@ -28,17 +28,17 @@ - - - - - - - - - - - + + + + + + + + + + + false Contract diff --git a/test/AElf.Contracts.TestContract.A/AElf.Contracts.TestContract.A.csproj b/test/AElf.Contracts.TestContract.A/AElf.Contracts.TestContract.A.csproj index 2d93fecc34..b16dce2ac5 100644 --- a/test/AElf.Contracts.TestContract.A/AElf.Contracts.TestContract.A.csproj +++ b/test/AElf.Contracts.TestContract.A/AElf.Contracts.TestContract.A.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -9,7 +9,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.B/AElf.Contracts.TestContract.B.csproj b/test/AElf.Contracts.TestContract.B/AElf.Contracts.TestContract.B.csproj index 3315de616a..443237c2f5 100644 --- a/test/AElf.Contracts.TestContract.B/AElf.Contracts.TestContract.B.csproj +++ b/test/AElf.Contracts.TestContract.B/AElf.Contracts.TestContract.B.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -9,7 +9,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.BasicFunction/AElf.Contracts.TestContract.BasicFunction.csproj b/test/AElf.Contracts.TestContract.BasicFunction/AElf.Contracts.TestContract.BasicFunction.csproj index a126d734c2..0aa5cb2dee 100644 --- a/test/AElf.Contracts.TestContract.BasicFunction/AElf.Contracts.TestContract.BasicFunction.csproj +++ b/test/AElf.Contracts.TestContract.BasicFunction/AElf.Contracts.TestContract.BasicFunction.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 1.2.0 AElf.Contracts.TestContract.BasicFunction diff --git a/test/AElf.Contracts.TestContract.BasicFunctionWithParallel/AElf.Contracts.TestContract.BasicFunctionWithParallel.csproj b/test/AElf.Contracts.TestContract.BasicFunctionWithParallel/AElf.Contracts.TestContract.BasicFunctionWithParallel.csproj index af22ae709f..4b5cbe53e4 100644 --- a/test/AElf.Contracts.TestContract.BasicFunctionWithParallel/AElf.Contracts.TestContract.BasicFunctionWithParallel.csproj +++ b/test/AElf.Contracts.TestContract.BasicFunctionWithParallel/AElf.Contracts.TestContract.BasicFunctionWithParallel.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.BasicFunctionWithParallel @@ -14,7 +14,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.BasicSecurity/AElf.Contracts.TestContract.BasicSecurity.csproj b/test/AElf.Contracts.TestContract.BasicSecurity/AElf.Contracts.TestContract.BasicSecurity.csproj index e95c2af876..01305ab328 100644 --- a/test/AElf.Contracts.TestContract.BasicSecurity/AElf.Contracts.TestContract.BasicSecurity.csproj +++ b/test/AElf.Contracts.TestContract.BasicSecurity/AElf.Contracts.TestContract.BasicSecurity.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.BasicSecurity 1.3.0 diff --git a/test/AElf.Contracts.TestContract.BasicUpdate/AElf.Contracts.TestContract.BasicUpdate.csproj b/test/AElf.Contracts.TestContract.BasicUpdate/AElf.Contracts.TestContract.BasicUpdate.csproj index 4fc971a3c3..8d26667737 100644 --- a/test/AElf.Contracts.TestContract.BasicUpdate/AElf.Contracts.TestContract.BasicUpdate.csproj +++ b/test/AElf.Contracts.TestContract.BasicUpdate/AElf.Contracts.TestContract.BasicUpdate.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.BasicUpdate 1.3.0 @@ -15,7 +15,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.BigIntValue/AElf.Contracts.TestContract.BigIntValue.csproj b/test/AElf.Contracts.TestContract.BigIntValue/AElf.Contracts.TestContract.BigIntValue.csproj index 0de8c68964..0049e79e86 100644 --- a/test/AElf.Contracts.TestContract.BigIntValue/AElf.Contracts.TestContract.BigIntValue.csproj +++ b/test/AElf.Contracts.TestContract.BigIntValue/AElf.Contracts.TestContract.BigIntValue.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Contracts.TestContract.BigIntValue AElf.Contracts.TestContract.BigIntValue @@ -15,7 +15,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.C/AElf.Contracts.TestContract.C.csproj b/test/AElf.Contracts.TestContract.C/AElf.Contracts.TestContract.C.csproj index 9c006d0980..23cedffd2a 100644 --- a/test/AElf.Contracts.TestContract.C/AElf.Contracts.TestContract.C.csproj +++ b/test/AElf.Contracts.TestContract.C/AElf.Contracts.TestContract.C.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -9,7 +9,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.DApp/AElf.Contracts.TestContract.DApp.csproj b/test/AElf.Contracts.TestContract.DApp/AElf.Contracts.TestContract.DApp.csproj index 055e91deb0..a0991a0dce 100644 --- a/test/AElf.Contracts.TestContract.DApp/AElf.Contracts.TestContract.DApp.csproj +++ b/test/AElf.Contracts.TestContract.DApp/AElf.Contracts.TestContract.DApp.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -13,7 +13,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.Events/AElf.Contracts.TestContract.Events.csproj b/test/AElf.Contracts.TestContract.Events/AElf.Contracts.TestContract.Events.csproj index 55554c6d93..f92b7644b8 100644 --- a/test/AElf.Contracts.TestContract.Events/AElf.Contracts.TestContract.Events.csproj +++ b/test/AElf.Contracts.TestContract.Events/AElf.Contracts.TestContract.Events.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.Events @@ -27,7 +27,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.MethodCallThreshold/AElf.Contracts.TestContract.MethodCallThreshold.csproj b/test/AElf.Contracts.TestContract.MethodCallThreshold/AElf.Contracts.TestContract.MethodCallThreshold.csproj index 0d545b6fec..ab554493ac 100644 --- a/test/AElf.Contracts.TestContract.MethodCallThreshold/AElf.Contracts.TestContract.MethodCallThreshold.csproj +++ b/test/AElf.Contracts.TestContract.MethodCallThreshold/AElf.Contracts.TestContract.MethodCallThreshold.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.MethodCallThreshold AElf.Contracts.TestContract.MethodCallThreshold false - + diff --git a/test/AElf.Contracts.TestContract.MockParliament/AElf.Contracts.TestContract.MockParliament.csproj b/test/AElf.Contracts.TestContract.MockParliament/AElf.Contracts.TestContract.MockParliament.csproj index b9228e40c9..8aaf0217fd 100644 --- a/test/AElf.Contracts.TestContract.MockParliament/AElf.Contracts.TestContract.MockParliament.csproj +++ b/test/AElf.Contracts.TestContract.MockParliament/AElf.Contracts.TestContract.MockParliament.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 1.2.0 AElf.Contracts.TestContract.MockParliament AElf.Contracts.TestContract.MockParliament diff --git a/test/AElf.Contracts.TestContract.Performance/AElf.Contracts.TestContract.Performance.csproj b/test/AElf.Contracts.TestContract.Performance/AElf.Contracts.TestContract.Performance.csproj index b7f3170b75..b01b79b009 100644 --- a/test/AElf.Contracts.TestContract.Performance/AElf.Contracts.TestContract.Performance.csproj +++ b/test/AElf.Contracts.TestContract.Performance/AElf.Contracts.TestContract.Performance.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.Performance @@ -10,7 +10,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.RandomNumberProvider/AElf.Contracts.TestContract.RandomNumberProvider.csproj b/test/AElf.Contracts.TestContract.RandomNumberProvider/AElf.Contracts.TestContract.RandomNumberProvider.csproj index 7a8ce3c515..cf77b1697c 100644 --- a/test/AElf.Contracts.TestContract.RandomNumberProvider/AElf.Contracts.TestContract.RandomNumberProvider.csproj +++ b/test/AElf.Contracts.TestContract.RandomNumberProvider/AElf.Contracts.TestContract.RandomNumberProvider.csproj @@ -1,14 +1,14 @@ - + - net6.0 + net8.0 AElf.Contracts.TestContract.RandomNumberProvider AElf.Contracts.TestContract.RandomNumberProvider false - + diff --git a/test/AElf.Contracts.TestContract.ResourceSpender/AElf.Contracts.TestContract.ResourceSpender.csproj b/test/AElf.Contracts.TestContract.ResourceSpender/AElf.Contracts.TestContract.ResourceSpender.csproj index 0576361b4c..750aacbc5d 100644 --- a/test/AElf.Contracts.TestContract.ResourceSpender/AElf.Contracts.TestContract.ResourceSpender.csproj +++ b/test/AElf.Contracts.TestContract.ResourceSpender/AElf.Contracts.TestContract.ResourceSpender.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.ResourceSpender AElf.Contracts.TestContract.ResourceSpender false - + diff --git a/test/AElf.Contracts.TestContract.Tests/AElf.Contracts.TestContract.Tests.csproj b/test/AElf.Contracts.TestContract.Tests/AElf.Contracts.TestContract.Tests.csproj index e2b3567e17..b38736f190 100644 --- a/test/AElf.Contracts.TestContract.Tests/AElf.Contracts.TestContract.Tests.csproj +++ b/test/AElf.Contracts.TestContract.Tests/AElf.Contracts.TestContract.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contract.TestContract false @@ -17,7 +17,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -50,8 +50,8 @@ Contract PreserveNewest - - + + false Contract @@ -163,7 +163,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.Tests/PatchedContractSecurityTests.cs b/test/AElf.Contracts.TestContract.Tests/PatchedContractSecurityTests.cs index 587a9fff7a..b2c8df1424 100644 --- a/test/AElf.Contracts.TestContract.Tests/PatchedContractSecurityTests.cs +++ b/test/AElf.Contracts.TestContract.Tests/PatchedContractSecurityTests.cs @@ -262,7 +262,7 @@ await TestBasicSecurityContractStub.TestMappedState.SendAsync(new ProtobufInput StringValue = str } }); - txResult.TransactionResult.Error.ShouldContain($"exceeds limit of {stateSizeLimit}"); + txResult.TransactionResult.Error.ShouldContain($"exceeds limit"); var str1 = Encoding.UTF8.GetString(new byte[10]); var message = new ProtobufMessage @@ -309,7 +309,7 @@ await TestBasicSecurityContractStub.TestMapped2State.SendAsync(new ProtobufInput { ProtobufValue = new ProtobufMessage() }); - txResult.TransactionResult.Error.ShouldContain($"exceeds limit of {stateSizeLimit}"); + txResult.TransactionResult.Error.ShouldContain($"exceeds limit"); var str1 = Encoding.UTF8.GetString(new byte[10]); var message = new ProtobufMessage diff --git a/test/AElf.Contracts.TestContract.TransactionFeeCharging/AElf.Contracts.TestContract.TransactionFeeCharging.csproj b/test/AElf.Contracts.TestContract.TransactionFeeCharging/AElf.Contracts.TestContract.TransactionFeeCharging.csproj index 3671ada17c..db9f5b986b 100644 --- a/test/AElf.Contracts.TestContract.TransactionFeeCharging/AElf.Contracts.TestContract.TransactionFeeCharging.csproj +++ b/test/AElf.Contracts.TestContract.TransactionFeeCharging/AElf.Contracts.TestContract.TransactionFeeCharging.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.TransactionFeeCharging AElf.Contracts.TestContract.TransactionFeeCharging false - + diff --git a/test/AElf.Contracts.TestContract.TransactionFees/AElf.Contracts.TestContract.TransactionFees.csproj b/test/AElf.Contracts.TestContract.TransactionFees/AElf.Contracts.TestContract.TransactionFees.csproj index 80cbb8a162..cc48a779b2 100644 --- a/test/AElf.Contracts.TestContract.TransactionFees/AElf.Contracts.TestContract.TransactionFees.csproj +++ b/test/AElf.Contracts.TestContract.TransactionFees/AElf.Contracts.TestContract.TransactionFees.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Contracts.TestContract.TransactionFees @@ -11,7 +11,7 @@ - + diff --git a/test/AElf.Contracts.TestContract.VirtualAddress/AElf.Contracts.TestContract.VirtualAddress.csproj b/test/AElf.Contracts.TestContract.VirtualAddress/AElf.Contracts.TestContract.VirtualAddress.csproj index 79dacdf5f2..ea78dda337 100644 --- a/test/AElf.Contracts.TestContract.VirtualAddress/AElf.Contracts.TestContract.VirtualAddress.csproj +++ b/test/AElf.Contracts.TestContract.VirtualAddress/AElf.Contracts.TestContract.VirtualAddress.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Contracts.TestContract.VirtualAddress AElf.Contracts.TestContract.VirtualAddress false diff --git a/test/AElf.Contracts.TestContract.VirtualTransactionEvent/AElf.Contracts.TestContract.VirtualTransactionEvent.csproj b/test/AElf.Contracts.TestContract.VirtualTransactionEvent/AElf.Contracts.TestContract.VirtualTransactionEvent.csproj index 01cbf1667c..2f4b9607e0 100644 --- a/test/AElf.Contracts.TestContract.VirtualTransactionEvent/AElf.Contracts.TestContract.VirtualTransactionEvent.csproj +++ b/test/AElf.Contracts.TestContract.VirtualTransactionEvent/AElf.Contracts.TestContract.VirtualTransactionEvent.csproj @@ -1,8 +1,8 @@ - + - net6.0 + net8.0 AElf.Contracts.TestContract.VirtualTransactionEvent AElf.Contracts.TestContract.VirtualTransactionEvent false diff --git a/test/AElf.Contracts.TestContract.Vote/AElf.Contracts.TestContract.Vote.csproj b/test/AElf.Contracts.TestContract.Vote/AElf.Contracts.TestContract.Vote.csproj index 2924bb78db..bac61a35f4 100644 --- a/test/AElf.Contracts.TestContract.Vote/AElf.Contracts.TestContract.Vote.csproj +++ b/test/AElf.Contracts.TestContract.Vote/AElf.Contracts.TestContract.Vote.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 1.1.0 diff --git a/test/AElf.Contracts.TokenConverter.Internal.Tests/AElf.Contracts.TokenConverter.Internal.Tests.csproj b/test/AElf.Contracts.TokenConverter.Internal.Tests/AElf.Contracts.TokenConverter.Internal.Tests.csproj index d8ff4f55d0..87112d8b29 100644 --- a/test/AElf.Contracts.TokenConverter.Internal.Tests/AElf.Contracts.TokenConverter.Internal.Tests.csproj +++ b/test/AElf.Contracts.TokenConverter.Internal.Tests/AElf.Contracts.TokenConverter.Internal.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -20,7 +20,7 @@ - + diff --git a/test/AElf.Contracts.TokenConverter.Tests/AElf.Contracts.TokenConverter.Tests.csproj b/test/AElf.Contracts.TokenConverter.Tests/AElf.Contracts.TokenConverter.Tests.csproj index 551170282f..27099aa8ec 100644 --- a/test/AElf.Contracts.TokenConverter.Tests/AElf.Contracts.TokenConverter.Tests.csproj +++ b/test/AElf.Contracts.TokenConverter.Tests/AElf.Contracts.TokenConverter.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Contracts.TokenConverter false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -24,8 +24,8 @@ - - + + @@ -79,5 +79,5 @@ - + diff --git a/test/AElf.Contracts.TokenConverter.Tests/ConnectorTokenMigrateTest.cs b/test/AElf.Contracts.TokenConverter.Tests/ConnectorTokenMigrateTest.cs new file mode 100644 index 0000000000..e6ec3b2886 --- /dev/null +++ b/test/AElf.Contracts.TokenConverter.Tests/ConnectorTokenMigrateTest.cs @@ -0,0 +1,154 @@ +using System; +using System.Threading.Tasks; +using AElf.CSharp.Core; +using AElf.Types; +using Google.Protobuf.WellKnownTypes; +using Shouldly; +using Xunit; + +namespace AElf.Contracts.TokenConverter; + +public partial class TokenConverterContractTests +{ + [Fact] + public async Task CanBuyResourceTokenAfterMigration() + { + await CreateWriteToken(); + await InitializeTreasuryContractAsync(); + await InitializeTokenConverterContract(); + await PrepareToBuyAndSell(); + + await DefaultStub.MigrateConnectorTokens.SendAsync(new Empty()); + + //check the price and fee + var fromConnectorBalance = ELFConnector.VirtualBalance; + var fromConnectorWeight = decimal.Parse(ELFConnector.Weight); + var toConnectorBalance = await GetBalanceAsync(WriteSymbol, TokenConverterContractAddress); + var toConnectorWeight = decimal.Parse(WriteConnector.Weight); + + var amountToPay = BancorHelper.GetAmountToPayFromReturn(fromConnectorBalance, fromConnectorWeight, + toConnectorBalance, toConnectorWeight, 1000L); + var depositAmountBeforeBuy = await DefaultStub.GetDepositConnectorBalance.CallAsync(new StringValue + { + Value = WriteConnector.Symbol + }); + var fee = Convert.ToInt64(amountToPay * 5 / 1000); + + var buyResult = (await DefaultStub.Buy.SendAsync( + new BuyInput + { + Symbol = WriteConnector.Symbol, + Amount = 1000L, + PayLimit = amountToPay + fee + 10L + })).TransactionResult; + buyResult.Status.ShouldBe(TransactionResultStatus.Mined); + + //Verify the outcome of the transaction + var depositAmountAfterBuy = await DefaultStub.GetDepositConnectorBalance.CallAsync(new StringValue + { + Value = WriteConnector.Symbol + }); + depositAmountAfterBuy.Value.Sub(depositAmountBeforeBuy.Value).ShouldBe(amountToPay); + var balanceOfTesterWrite = await GetBalanceAsync(WriteSymbol, DefaultSender); + balanceOfTesterWrite.ShouldBe(1000L); + + var elfBalanceLoggedInTokenConvert = await DefaultStub.GetDepositConnectorBalance.CallAsync(new StringValue + { + Value = WriteConnector.Symbol + }); + elfBalanceLoggedInTokenConvert.Value.ShouldBe(ELFConnector.VirtualBalance + amountToPay); + var balanceOfElfToken = await GetBalanceAsync(NativeSymbol, TokenConverterContractAddress); + balanceOfElfToken.ShouldBe(amountToPay); + + var donatedFee = await TreasuryContractStub.GetUndistributedDividends.CallAsync(new Empty()); + donatedFee.Value[NativeSymbol].ShouldBe(fee.Div(2)); + + var balanceOfRamToken = await GetBalanceAsync(WriteSymbol, TokenConverterContractAddress); + balanceOfRamToken.ShouldBe(100_0000L - 1000L); + + var balanceOfTesterToken = await GetBalanceAsync(NativeSymbol, DefaultSender); + balanceOfTesterToken.ShouldBe(100_0000L - amountToPay - fee); + } + + [Fact] + public async Task CanSellResourceTokenAfterMigration() + { + await CreateWriteToken(); + await InitializeTreasuryContractAsync(); + await InitializeTokenConverterContract(); + await PrepareToBuyAndSell(); + + await DefaultStub.MigrateConnectorTokens.SendAsync(new Empty()); + + var buyResult = (await DefaultStub.Buy.SendAsync( + new BuyInput + { + Symbol = WriteConnector.Symbol, + Amount = 1000L, + PayLimit = 1010L + })).TransactionResult; + buyResult.Status.ShouldBe(TransactionResultStatus.Mined); + + //Balance before Sell + var treasuryBeforeSell = + (await TreasuryContractStub.GetUndistributedDividends.CallAsync(new Empty())).Value[NativeSymbol]; + var balanceOfElfToken = await GetBalanceAsync(NativeSymbol, TokenConverterContractAddress); + var balanceOfTesterToken = await GetBalanceAsync(NativeSymbol, DefaultSender); + + //check the price and fee + var toConnectorBalance = ELFConnector.VirtualBalance + balanceOfElfToken; + var toConnectorWeight = decimal.Parse(ELFConnector.Weight); + var fromConnectorBalance = await GetBalanceAsync(WriteSymbol, TokenConverterContractAddress); + var fromConnectorWeight = decimal.Parse(WriteConnector.Weight); + + var amountToReceive = BancorHelper.GetReturnFromPaid(fromConnectorBalance, fromConnectorWeight, + toConnectorBalance, toConnectorWeight, 1000L); + var depositAmountBeforeSell = await DefaultStub.GetDepositConnectorBalance.CallAsync(new StringValue + { + Value = WriteConnector.Symbol + }); + var fee = Convert.ToInt64(amountToReceive * 5 / 1000); + + var sellResult = (await DefaultStub.Sell.SendAsync(new SellInput + { + Symbol = WriteConnector.Symbol, + Amount = 1000L, + ReceiveLimit = amountToReceive - fee - 10L + })).TransactionResult; + sellResult.Status.ShouldBe(TransactionResultStatus.Mined); + + //Verify the outcome of the transaction + var depositAmountAfterSell = await DefaultStub.GetDepositConnectorBalance.CallAsync(new StringValue + { + Value = WriteConnector.Symbol + }); + depositAmountBeforeSell.Value.Sub(depositAmountAfterSell.Value).ShouldBe(amountToReceive); + var balanceOfTesterRam = await GetBalanceAsync(WriteSymbol, DefaultSender); + balanceOfTesterRam.ShouldBe(0L); + + var treasuryAfterSell = await TreasuryContractStub.GetUndistributedDividends.CallAsync(new Empty()); + treasuryAfterSell.Value[NativeSymbol].ShouldBe(fee.Div(2) + treasuryBeforeSell); + + var balanceOfElfTokenAfterSell = await GetBalanceAsync(NativeSymbol, TokenConverterContractAddress); + balanceOfElfTokenAfterSell.ShouldBe(balanceOfElfToken - amountToReceive); + + var balanceOfRamToken = await GetBalanceAsync(WriteSymbol, TokenConverterContractAddress); + balanceOfRamToken.ShouldBe(100_0000L); + + var balanceOfTesterTokenAfterSell = await GetBalanceAsync(NativeSymbol, DefaultSender); + balanceOfTesterTokenAfterSell.ShouldBe(balanceOfTesterToken + amountToReceive - fee); + } + + [Fact] + public async Task MigrateTwiceTest() + { + await CreateWriteToken(); + await InitializeTreasuryContractAsync(); + await InitializeTokenConverterContract(); + await PrepareToBuyAndSell(); + + await DefaultStub.MigrateConnectorTokens.SendAsync(new Empty()); + var result = await DefaultStub.MigrateConnectorTokens.SendWithExceptionAsync(new Empty()); + result.TransactionResult.Error.ShouldContain("Already migrated."); + } +} \ No newline at end of file diff --git a/test/AElf.Contracts.TokenConverter.Tests/TokenConvertConnectorTest.cs b/test/AElf.Contracts.TokenConverter.Tests/TokenConvertConnectorTest.cs index 6c462e1d96..eadfb2f2f2 100644 --- a/test/AElf.Contracts.TokenConverter.Tests/TokenConvertConnectorTest.cs +++ b/test/AElf.Contracts.TokenConverter.Tests/TokenConvertConnectorTest.cs @@ -87,7 +87,7 @@ await ExecuteProposalForParliamentTransaction(TokenConverterContractAddress, [Theory] [InlineData("WRITE", "0.5", "0.5", "resource token symbol has existed")] [InlineData("", "0.5", "0.5", "resource token symbol should not be empty")] - [InlineData("N89", "0.2", "0.5", "Invalid symbol.")] + [InlineData("N89()", "0.2", "0.5", "Invalid symbol.")] [InlineData("MKA", "0", "0.5", "Connector Shares has to be a decimal between 0 and 1.")] [InlineData("JUN", "0.9", "1", "Connector Shares has to be a decimal between 0 and 1.")] public async Task AddPairConnector_With_Invalid_Input_Test(string tokenSymbol, string resourceWeight, diff --git a/test/AElf.Contracts.TokenConverter.Tests/TokenConverterContractTests.cs b/test/AElf.Contracts.TokenConverter.Tests/TokenConverterContractTests.cs index 2f598d96e1..c783813905 100644 --- a/test/AElf.Contracts.TokenConverter.Tests/TokenConverterContractTests.cs +++ b/test/AElf.Contracts.TokenConverter.Tests/TokenConverterContractTests.cs @@ -84,7 +84,7 @@ public async Task Initialize_Failed_Test() //Base token symbol is invalid. { var input = GetLegalInitializeInput(); - input.BaseTokenSymbol = "elf1"; + input.BaseTokenSymbol = "elf1<>"; var result = (await DefaultStub.Initialize.SendWithExceptionAsync(input)).TransactionResult; result.Status.ShouldBe(TransactionResultStatus.Failed); result.Error.Contains("Base token symbol is invalid.").ShouldBeTrue(); @@ -111,7 +111,7 @@ public async Task Initialize_Failed_Test() //Invalid connector symbol { var input = GetLegalInitializeInput(); - input.Connectors[0].Symbol = "write"; + input.Connectors[0].Symbol = "write-0"; var result = (await DefaultStub.Initialize.SendWithExceptionAsync(input)).TransactionResult; result.Status.ShouldBe(TransactionResultStatus.Failed); result.Error.Contains("Invalid symbol.").ShouldBeTrue(); @@ -158,7 +158,7 @@ public async Task Initialize_With_Default_Base_Token_Test() [Fact] public async Task Buy_Success_Test() { - await CreateRamToken(); + await CreateWriteToken(); await InitializeTreasuryContractAsync(); await InitializeTokenConverterContract(); await PrepareToBuyAndSell(); @@ -216,7 +216,7 @@ public async Task Buy_Success_Test() [Fact] public async Task Buy_With_Invalid_Input_Test() { - await CreateRamToken(); + await CreateWriteToken(); await InitializeTokenConverterContract(); await PrepareToBuyAndSell(); @@ -244,7 +244,7 @@ public async Task Buy_With_Invalid_Input_Test() [Fact] public async Task Sell_Success_Test() { - await CreateRamToken(); + await CreateWriteToken(); await InitializeTreasuryContractAsync(); await InitializeTokenConverterContract(); await PrepareToBuyAndSell(); @@ -311,7 +311,7 @@ public async Task Sell_Success_Test() [Fact] public async Task Sell_With_Invalid_Input_Test() { - await CreateRamToken(); + await CreateWriteToken(); await InitializeTreasuryContractAsync(); await InitializeTokenConverterContract(); await PrepareToBuyAndSell(); @@ -361,7 +361,7 @@ private InitializeInput GetLegalInitializeInput() }; } - private async Task CreateRamToken() + private async Task CreateWriteToken() { await ExecuteProposalForParliamentTransaction(TokenContractAddress, nameof(TokenContractStub.Create), new CreateInput diff --git a/test/AElf.Contracts.TokenHolder.Tests/AElf.Contracts.TokenHolder.Tests.csproj b/test/AElf.Contracts.TokenHolder.Tests/AElf.Contracts.TokenHolder.Tests.csproj index 92957ed179..6049bacb46 100644 --- a/test/AElf.Contracts.TokenHolder.Tests/AElf.Contracts.TokenHolder.Tests.csproj +++ b/test/AElf.Contracts.TokenHolder.Tests/AElf.Contracts.TokenHolder.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Contracts.TokenHolder false diff --git a/test/AElf.Contracts.VirtualTransactionEventContract.Tests/AElf.Contracts.VirtualTransactionEventContract.Tests.csproj b/test/AElf.Contracts.VirtualTransactionEventContract.Tests/AElf.Contracts.VirtualTransactionEventContract.Tests.csproj index a2bcf0cb45..237875d951 100644 --- a/test/AElf.Contracts.VirtualTransactionEventContract.Tests/AElf.Contracts.VirtualTransactionEventContract.Tests.csproj +++ b/test/AElf.Contracts.VirtualTransactionEventContract.Tests/AElf.Contracts.VirtualTransactionEventContract.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Contracts.TestContract.VirtualTransactionEvent false diff --git a/test/AElf.Contracts.Vote.AEDPoSExtension.Tests/AElf.Contracts.Vote.AEDPoSExtension.Tests.csproj b/test/AElf.Contracts.Vote.AEDPoSExtension.Tests/AElf.Contracts.Vote.AEDPoSExtension.Tests.csproj index 48c97757ba..7014e31396 100644 --- a/test/AElf.Contracts.Vote.AEDPoSExtension.Tests/AElf.Contracts.Vote.AEDPoSExtension.Tests.csproj +++ b/test/AElf.Contracts.Vote.AEDPoSExtension.Tests/AElf.Contracts.Vote.AEDPoSExtension.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Contract.Vote false @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -24,8 +24,8 @@ - - + + diff --git a/test/AElf.Contracts.Vote.Tests/AElf.Contracts.Vote.Tests.csproj b/test/AElf.Contracts.Vote.Tests/AElf.Contracts.Vote.Tests.csproj index 5ad16fa9b5..f6cc22c50d 100644 --- a/test/AElf.Contracts.Vote.Tests/AElf.Contracts.Vote.Tests.csproj +++ b/test/AElf.Contracts.Vote.Tests/AElf.Contracts.Vote.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Contract.Vote false @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -27,13 +27,13 @@ - - - - - - - + + + + + + + false Contract diff --git a/test/AElf.Core.Tests/AElf.Core.Tests.csproj b/test/AElf.Core.Tests/AElf.Core.Tests.csproj index 78cf86ca08..737e5851d7 100644 --- a/test/AElf.Core.Tests/AElf.Core.Tests.csproj +++ b/test/AElf.Core.Tests/AElf.Core.Tests.csproj @@ -1,13 +1,13 @@  - net6.0 + net8.0 AElf false - + @@ -16,7 +16,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.CrossChain.Core.Tests/AElf.CrossChain.Core.Tests.csproj b/test/AElf.CrossChain.Core.Tests/AElf.CrossChain.Core.Tests.csproj index 93e998483b..21b37bf8ab 100644 --- a/test/AElf.CrossChain.Core.Tests/AElf.CrossChain.Core.Tests.csproj +++ b/test/AElf.CrossChain.Core.Tests/AElf.CrossChain.Core.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.CrossChain false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,9 +22,9 @@ - - - + + + @@ -44,5 +44,5 @@ Protobuf\Proto\cross_chain_contract_impl.proto - + diff --git a/test/AElf.CrossChain.Grpc.Tests/AElf.CrossChain.Grpc.Tests.csproj b/test/AElf.CrossChain.Grpc.Tests/AElf.CrossChain.Grpc.Tests.csproj index ff92a0a8f1..6f74926793 100644 --- a/test/AElf.CrossChain.Grpc.Tests/AElf.CrossChain.Grpc.Tests.csproj +++ b/test/AElf.CrossChain.Grpc.Tests/AElf.CrossChain.Grpc.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.CrossChain.Grpc false @@ -9,9 +9,9 @@ all runtime; build; native; contentfiles; analyzers - + - + all @@ -23,7 +23,7 @@ - - + + diff --git a/test/AElf.CrossChain.Tests/AElf.CrossChain.Tests.csproj b/test/AElf.CrossChain.Tests/AElf.CrossChain.Tests.csproj index 6665195b02..fc8e6ffb0f 100644 --- a/test/AElf.CrossChain.Tests/AElf.CrossChain.Tests.csproj +++ b/test/AElf.CrossChain.Tests/AElf.CrossChain.Tests.csproj @@ -1,12 +1,12 @@  - net6.0 + net8.0 AElf.CrossChain false - + all runtime; build; native; contentfiles; analyzers @@ -24,9 +24,9 @@ - - - + + + diff --git a/test/AElf.Cryptography.Tests/AElf.Cryptography.Tests.csproj b/test/AElf.Cryptography.Tests/AElf.Cryptography.Tests.csproj index 7ef8543522..74dcc8734d 100644 --- a/test/AElf.Cryptography.Tests/AElf.Cryptography.Tests.csproj +++ b/test/AElf.Cryptography.Tests/AElf.Cryptography.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false diff --git a/test/AElf.Cryptography.Tests/CryptoHelperTests.cs b/test/AElf.Cryptography.Tests/CryptoHelperTests.cs index 7ec4e7c59e..4b5d2915d7 100644 --- a/test/AElf.Cryptography.Tests/CryptoHelperTests.cs +++ b/test/AElf.Cryptography.Tests/CryptoHelperTests.cs @@ -2,9 +2,8 @@ using System.Text; using AElf.Cryptography.Exceptions; using AElf.Types; -using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Crypto; using Shouldly; -using Virgil.Crypto; using Xunit; namespace AElf.Cryptography.Tests; @@ -100,30 +99,12 @@ public void Decrypt_Message_Test() // Bob decrypt the message. var decrypt = CryptoHelper.DecryptMessage(alice.PublicKey, bob.PrivateKey, cipherText); - Assert.True(decrypt.BytesEqual(plainText)); + decrypt.ShouldBe(plainText); // Sam can't decrypt this message. var func = new Func(() => CryptoHelper.DecryptMessage(alice.PublicKey, sam.PrivateKey, cipherText)); - Assert.Throws(func); - } - - [Fact] - public void Ecdh_Test() - { - var alice = CryptoHelper.GenerateKeyPair(); - var bob = CryptoHelper.GenerateKeyPair(); - - var ecdhKey1 = CryptoHelper.Ecdh(alice.PrivateKey, bob.PublicKey); - var ecdhKey2 = CryptoHelper.Ecdh(bob.PrivateKey, alice.PublicKey); - - Assert.Equal(ecdhKey1.ToHex(), ecdhKey2.ToHex()); - } - - [Fact] - public void Ecdh_BadArgument_ShouldThrowException() - { - Assert.Throws(() => CryptoHelper.Ecdh(new byte[32], new byte[33])); + Assert.Throws(func); } [Fact] diff --git a/test/AElf.Database.Tests/AElf.Database.Tests.csproj b/test/AElf.Database.Tests/AElf.Database.Tests.csproj index af0016902d..fd1be28a2e 100644 --- a/test/AElf.Database.Tests/AElf.Database.Tests.csproj +++ b/test/AElf.Database.Tests/AElf.Database.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -9,7 +9,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -21,7 +21,7 @@ - - + + \ No newline at end of file diff --git a/test/AElf.EconomicSystem.Tests/AElf.EconomicSystem.Tests.csproj b/test/AElf.EconomicSystem.Tests/AElf.EconomicSystem.Tests.csproj index 0b450dee06..80a9edf1f9 100644 --- a/test/AElf.EconomicSystem.Tests/AElf.EconomicSystem.Tests.csproj +++ b/test/AElf.EconomicSystem.Tests/AElf.EconomicSystem.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -14,7 +14,7 @@ all runtime; build; native; contentfiles; analyzers - + all @@ -23,7 +23,7 @@ - - + + diff --git a/test/AElf.GovernmentSystem.Tests/AElf.GovernmentSystem.Tests.csproj b/test/AElf.GovernmentSystem.Tests/AElf.GovernmentSystem.Tests.csproj index 966b67b28e..0e42f91fb2 100644 --- a/test/AElf.GovernmentSystem.Tests/AElf.GovernmentSystem.Tests.csproj +++ b/test/AElf.GovernmentSystem.Tests/AElf.GovernmentSystem.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -14,7 +14,7 @@ all runtime; build; native; contentfiles; analyzers - + all @@ -23,8 +23,8 @@ - - + + diff --git a/test/AElf.Kernel.ChainController.Tests/AElf.Kernel.ChainController.Tests.csproj b/test/AElf.Kernel.ChainController.Tests/AElf.Kernel.ChainController.Tests.csproj index b6137fa2b3..d6b52e47ed 100644 --- a/test/AElf.Kernel.ChainController.Tests/AElf.Kernel.ChainController.Tests.csproj +++ b/test/AElf.Kernel.ChainController.Tests/AElf.Kernel.ChainController.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.ChainController false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,7 +22,7 @@ - - + + diff --git a/test/AElf.Kernel.CodeCheck.Tests/AElf.Kernel.CodeCheck.Tests.csproj b/test/AElf.Kernel.CodeCheck.Tests/AElf.Kernel.CodeCheck.Tests.csproj index 050b715175..c36b8f08c6 100644 --- a/test/AElf.Kernel.CodeCheck.Tests/AElf.Kernel.CodeCheck.Tests.csproj +++ b/test/AElf.Kernel.CodeCheck.Tests/AElf.Kernel.CodeCheck.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Kernel.CodeCheck diff --git a/test/AElf.Kernel.CodeCheck.Tests/Application/CodeCheckJobProcessorTests.cs b/test/AElf.Kernel.CodeCheck.Tests/Application/CodeCheckJobProcessorTests.cs index 693faf3d8e..48bd37750d 100644 --- a/test/AElf.Kernel.CodeCheck.Tests/Application/CodeCheckJobProcessorTests.cs +++ b/test/AElf.Kernel.CodeCheck.Tests/Application/CodeCheckJobProcessorTests.cs @@ -65,7 +65,7 @@ public async Task CodeCheckTest(bool isUserContract) if (isUserContract) { - var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals(); + var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals().ToList(); codeCheckProposals.Count.ShouldBe(1); codeCheckProposals[0].ProposalId.ShouldBe(job.CodeCheckProposalId); codeCheckProposals[0].ProposedContractInputHash.ShouldBe(job.ProposedContractInputHash); @@ -103,7 +103,7 @@ public async Task CodeCheck_Failed_Test() var notApprovedProposalIdList = _proposalProvider.GetAllProposals(); notApprovedProposalIdList.Count.ShouldBe(0); - var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals(); + var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals().ToList(); codeCheckProposals.Count.ShouldBe(0); var codeHashExists = _checkedCodeHashProvider.IsCodeHashExists(new BlockIndex @@ -143,7 +143,7 @@ public async Task CodeCheck_Parallel_Test() var notApprovedProposalIdList = _proposalProvider.GetAllProposals(); notApprovedProposalIdList.Count.ShouldBe(jobs.Count); - var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals(); + var codeCheckProposals = _codeCheckProposalProvider.GetAllProposals().ToList(); codeCheckProposals.Count.ShouldBe(jobs.Count); foreach (var codeHashExists in jobs.Select(job => _checkedCodeHashProvider.IsCodeHashExists(new BlockIndex diff --git a/test/AElf.Kernel.CodeCheck.Tests/Infrastructure/CodeCheckProposalProviderTests.cs b/test/AElf.Kernel.CodeCheck.Tests/Infrastructure/CodeCheckProposalProviderTests.cs index a6239107be..477915f298 100644 --- a/test/AElf.Kernel.CodeCheck.Tests/Infrastructure/CodeCheckProposalProviderTests.cs +++ b/test/AElf.Kernel.CodeCheck.Tests/Infrastructure/CodeCheckProposalProviderTests.cs @@ -1,3 +1,4 @@ +using System.Linq; using System.Threading.Tasks; using AElf.Kernel.CodeCheck.Tests; using Shouldly; @@ -20,7 +21,7 @@ public async Task ProposalTest() var proposalId = HashHelper.ComputeFrom("ProposalId"); var proposedContractInputHash = HashHelper.ComputeFrom("ProposedContractInputHash"); var blockHeight = 10; - var proposalList = _codeCheckProposalProvider.GetAllProposals(); + var proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.ShouldBeEmpty(); var getHeightResult = _codeCheckProposalProvider.TryGetProposalCreatedHeight(proposalId, out var createdHeight); @@ -28,7 +29,7 @@ public async Task ProposalTest() createdHeight.ShouldBe(0); _codeCheckProposalProvider.AddProposal(proposalId, proposedContractInputHash, blockHeight); - proposalList = _codeCheckProposalProvider.GetAllProposals(); + proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.Count.ShouldBe(1); proposalList[0].BlockHeight.ShouldBe(blockHeight); proposalList[0].ProposalId.ShouldBe(proposalId); @@ -40,7 +41,7 @@ public async Task ProposalTest() var lowerHeight = blockHeight - 1; _codeCheckProposalProvider.AddProposal(proposalId, proposedContractInputHash, lowerHeight); - proposalList = _codeCheckProposalProvider.GetAllProposals(); + proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.Count.ShouldBe(1); proposalList[0].BlockHeight.ShouldBe(blockHeight); proposalList[0].ProposalId.ShouldBe(proposalId); @@ -52,7 +53,7 @@ public async Task ProposalTest() var higherHeight = blockHeight + 1; _codeCheckProposalProvider.AddProposal(proposalId, proposedContractInputHash, higherHeight); - proposalList = _codeCheckProposalProvider.GetAllProposals(); + proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.Count.ShouldBe(1); proposalList[0].BlockHeight.ShouldBe(higherHeight); proposalList[0].ProposalId.ShouldBe(proposalId); @@ -66,12 +67,12 @@ public async Task ProposalTest() var newBlockHeight = 100; _codeCheckProposalProvider.AddProposal(newProposalId, proposedContractInputHash, newBlockHeight); - proposalList = _codeCheckProposalProvider.GetAllProposals(); + proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.Count.ShouldBe(2); _codeCheckProposalProvider.RemoveProposalById(newProposalId); - proposalList = _codeCheckProposalProvider.GetAllProposals(); + proposalList = _codeCheckProposalProvider.GetAllProposals().ToList(); proposalList.Count.ShouldBe(1); proposalList[0].BlockHeight.ShouldBe(higherHeight); proposalList[0].ProposalId.ShouldBe(proposalId); diff --git a/test/AElf.Kernel.Configuration.Tests/AElf.Kernel.Configuration.Tests.csproj b/test/AElf.Kernel.Configuration.Tests/AElf.Kernel.Configuration.Tests.csproj index 14144cde8b..6be4f0c20c 100644 --- a/test/AElf.Kernel.Configuration.Tests/AElf.Kernel.Configuration.Tests.csproj +++ b/test/AElf.Kernel.Configuration.Tests/AElf.Kernel.Configuration.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false @@ -15,7 +15,7 @@ all runtime; build; native; contentfiles; analyzers - + all @@ -45,7 +45,7 @@ Contract PreserveNewest - + diff --git a/test/AElf.Kernel.Consensus.AEDPoS.Tests/AElf.Kernel.Consensus.AEDPoS.Tests.csproj b/test/AElf.Kernel.Consensus.AEDPoS.Tests/AElf.Kernel.Consensus.AEDPoS.Tests.csproj index 5189f1564b..ec2bd1c7e6 100644 --- a/test/AElf.Kernel.Consensus.AEDPoS.Tests/AElf.Kernel.Consensus.AEDPoS.Tests.csproj +++ b/test/AElf.Kernel.Consensus.AEDPoS.Tests/AElf.Kernel.Consensus.AEDPoS.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.Consensus.DPoS.Tests false @@ -12,7 +12,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -24,9 +24,9 @@ - - - + + + diff --git a/test/AElf.Kernel.Consensus.Tests/AElf.Kernel.Consensus.Tests.csproj b/test/AElf.Kernel.Consensus.Tests/AElf.Kernel.Consensus.Tests.csproj index 2f7cd9894d..6e9c018681 100644 --- a/test/AElf.Kernel.Consensus.Tests/AElf.Kernel.Consensus.Tests.csproj +++ b/test/AElf.Kernel.Consensus.Tests/AElf.Kernel.Consensus.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 AElf.Kernel.Consensus false @@ -11,7 +11,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -23,12 +23,12 @@ - - - - - - + + + + + + diff --git a/test/AElf.Kernel.Core.Tests/AElf.Kernel.Core.Tests.csproj b/test/AElf.Kernel.Core.Tests/AElf.Kernel.Core.Tests.csproj index 0da9830237..f70d4d2944 100644 --- a/test/AElf.Kernel.Core.Tests/AElf.Kernel.Core.Tests.csproj +++ b/test/AElf.Kernel.Core.Tests/AElf.Kernel.Core.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel AElf.Kernel.Core.Tests false diff --git a/test/AElf.Kernel.FeatureDisable.Tests/AElf.Kernel.FeatureDisable.Tests.csproj b/test/AElf.Kernel.FeatureDisable.Tests/AElf.Kernel.FeatureDisable.Tests.csproj new file mode 100644 index 0000000000..b4e597e5e3 --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/AElf.Kernel.FeatureDisable.Tests.csproj @@ -0,0 +1,85 @@ + + + + net8.0 + enable + enable + false + AElf.Kernel.FeatureDisable.Tests + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + false + Contract + PreserveNewest + + + false + Contract + PreserveNewest + + + False + Contract + PreserveNewest + + + + + + + + + Protobuf\Proto\authority_info.proto + + + + + Protobuf\Proto\acs3.proto + + + Protobuf\Proto\acs4.proto + + + Protobuf\Proto\acs6.proto + + + Protobuf\Proto\reference\acs10.proto + + + Protobuf\Proto\reference\acs11.proto + + + + + Protobuf\Proto\aedpos_contract.proto + + + Protobuf\Proto\aedpos_contract_impl.proto + + + Protobuf\Proto\parliament_contract.proto + + + Protobuf\Proto\parliament_contract_impl.proto + + + Protobuf\Proto\configuration_contract.proto + + + + diff --git a/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTest.cs b/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTest.cs new file mode 100644 index 0000000000..2343599aeb --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTest.cs @@ -0,0 +1,55 @@ +using AElf.Contracts.Configuration; +using AElf.CSharp.Core.Extension; +using AElf.Kernel.Blockchain.Application; +using AElf.Kernel.FeatureDisable.Core; +using AElf.Standards.ACS3; +using AElf.TestBase; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; +using Shouldly; +using Xunit; + +namespace AElf.Kernel.FeatureDisable.Tests; + +public class FeatureDisableTest : KernelFeatureDisableTestBase +{ + private readonly IMockService _mockService; + private readonly IBlockchainService _blockchainService; + + public FeatureDisableTest() + { + _mockService = GetRequiredService(); + _blockchainService = GetRequiredService(); + } + + [Fact] + public async Task IsFeatureDisabledTest() + { + await DeployContractsAsync(); + await ConfigDisabledFeaturesAsync("FeatureA, FeatureB, FeatureBAndC"); + (await _mockService.IsFeatureADisabledAsync()).ShouldBeTrue(); + (await _mockService.IsFeatureBDisabledAsync()).ShouldBeTrue(); + (await _mockService.IsFeatureCDisabledAsync()).ShouldBeTrue(); + (await _mockService.IsFeatureDDisabledAsync()).ShouldBeFalse(); + } + + private async Task ConfigDisabledFeaturesAsync(string disableFeatureNames) + { + var chain = await _blockchainService.GetChainAsync(); + await _blockchainService.SetIrreversibleBlockAsync(chain, chain.BestChainHeight, chain.BestChainHash); + var proposalId = (await ParliamentContractStub.CreateProposal.SendAsync(new CreateProposalInput + { + ContractMethodName = "SetConfiguration", + ExpiredTime = TimestampHelper.GetUtcNow().AddDays(1), + Params = new SetConfigurationInput + { + Key = FeatureDisableConstants.FeatureDisableConfigurationName, + Value = new StringValue { Value = disableFeatureNames }.ToByteString() + }.ToByteString(), + ToAddress = ConfigurationContractAddress, + OrganizationAddress = await ParliamentContractStub.GetDefaultOrganizationAddress.CallAsync(new Empty()) + })).Output; + await ParliamentContractStub.Approve.SendAsync(proposalId); + await ParliamentContractStub.Release.SendAsync(proposalId); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTestModule.cs b/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTestModule.cs new file mode 100644 index 0000000000..63bd29b6ee --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/FeatureDisableTestModule.cs @@ -0,0 +1,25 @@ +using AElf.ContractTestKit; +using AElf.Kernel.SmartContract; +using AElf.Kernel.SmartContract.Application; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Modularity; + +namespace AElf.Kernel.FeatureDisable.Tests; + +[DependsOn( + typeof(ContractTestModule), + typeof(FeatureDisableAElfModule), + typeof(KernelAElfModule))] +public class FeatureDisableTestModule : ContractTestModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(typeof(LogEventProcessingService<>)); + context.Services + .Replace(ServiceDescriptor + .Singleton, + OptionalLogEventProcessingService>()); + Configure(o => o.ContractDeploymentAuthorityRequired = false); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureDisable.Tests/IMockService.cs b/test/AElf.Kernel.FeatureDisable.Tests/IMockService.cs new file mode 100644 index 0000000000..ee837e1ad5 --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/IMockService.cs @@ -0,0 +1,44 @@ +using AElf.Kernel.FeatureDisable.Core; +using Volo.Abp.DependencyInjection; + +namespace AElf.Kernel.FeatureDisable.Tests; + +public interface IMockService +{ + Task IsFeatureADisabledAsync(); + Task IsFeatureBDisabledAsync(); + Task IsFeatureCDisabledAsync(); + Task IsFeatureDDisabledAsync(); +} + +public class MockService : IMockService, ITransientDependency +{ + private readonly IFeatureDisableService _featureDisableService; + + public MockService(IFeatureDisableService featureDisableService) + { + _featureDisableService = featureDisableService; + } + + public Task IsFeatureADisabledAsync() + { + return _featureDisableService.IsFeatureDisabledAsync("FeatureA"); + } + + public Task IsFeatureBDisabledAsync() + { + return _featureDisableService.IsFeatureDisabledAsync("FeatureB", "FeatureBAndC"); + + } + + public Task IsFeatureCDisabledAsync() + { + return _featureDisableService.IsFeatureDisabledAsync("FeatureC", "FeatureBAndC"); + + } + + public Task IsFeatureDDisabledAsync() + { + return _featureDisableService.IsFeatureDisabledAsync("FeatureD"); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureDisable.Tests/KernelFeatureManagerTestBase.cs b/test/AElf.Kernel.FeatureDisable.Tests/KernelFeatureManagerTestBase.cs new file mode 100644 index 0000000000..7a81535514 --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/KernelFeatureManagerTestBase.cs @@ -0,0 +1,60 @@ +using AElf.Contracts.Configuration; +using AElf.Contracts.Consensus.AEDPoS; +using AElf.Contracts.Parliament; +using AElf.ContractTestKit; +using AElf.Cryptography.ECDSA; +using AElf.Kernel.Configuration; +using AElf.Kernel.Consensus; +using AElf.Kernel.Proposal; +using AElf.Kernel.SmartContract.Application; +using AElf.Types; +using Google.Protobuf; + +namespace AElf.Kernel.FeatureDisable.Tests; + +public class KernelFeatureDisableTestBase : ContractTestBase +{ + internal ConfigurationContainer.ConfigurationStub ConfigurationStub; + internal ParliamentContractImplContainer.ParliamentContractImplStub ParliamentContractStub; + internal Address ParliamentContractAddress { get; set; } + internal Address ConfigurationContractAddress { get; set; } + internal ECKeyPair DefaultSenderKeyPair => Accounts[0].KeyPair; + + protected async Task DeployContractsAsync() + { + const int category = KernelConstants.CodeCoverageRunnerCategory; + var code = Codes.Single(kv => kv.Key.Split(",").First().EndsWith("Configuration")).Value; + OptionalLogEventProcessingService.Enabled = true; + ConfigurationContractAddress = await DeploySystemSmartContract(category, code, + ConfigurationSmartContractAddressNameProvider.Name, DefaultSenderKeyPair); + ConfigurationStub = + GetTester(ConfigurationContractAddress, + DefaultSenderKeyPair); + + var consensusContractCode = Codes.Single(kv => kv.Key.Split(",").First().EndsWith("Consensus.AEDPoS")).Value; + var consensusContractAddress = await DeploySystemSmartContract(category, consensusContractCode, + ConsensusSmartContractAddressNameProvider.Name, DefaultSenderKeyPair); + var consensusStub = GetTester(consensusContractAddress, + DefaultSenderKeyPair); + + await consensusStub.FirstRound.SendAsync( + new MinerList + { + Pubkeys = { ByteString.CopyFrom(DefaultSenderKeyPair.PublicKey) } + }.GenerateFirstRoundOfNewTerm(4000, TimestampHelper.GetUtcNow()) + ); + + var parliamentContractCode = Codes.Single(kv => kv.Key.Split(",").First().EndsWith("Parliament")).Value; + ParliamentContractAddress = await DeploySystemSmartContract(category, parliamentContractCode, + ParliamentSmartContractAddressNameProvider.Name, DefaultSenderKeyPair); + ParliamentContractStub = GetTester( + ParliamentContractAddress, + DefaultSenderKeyPair); + + await ParliamentContractStub.Initialize.SendAsync(new InitializeInput + { + ProposerAuthorityRequired = true, + PrivilegedProposer = Address.FromPublicKey(DefaultSenderKeyPair.PublicKey) + }); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureDisable.Tests/MinerList.cs b/test/AElf.Kernel.FeatureDisable.Tests/MinerList.cs new file mode 100644 index 0000000000..0ef019af8c --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/MinerList.cs @@ -0,0 +1,50 @@ +using System.Linq; +using AElf.CSharp.Core.Extension; +using AElf.Types; +using Google.Protobuf; +using Google.Protobuf.WellKnownTypes; + +namespace AElf.Contracts.Consensus.AEDPoS; + +internal partial class MinerList +{ + public Round GenerateFirstRoundOfNewTerm(int miningInterval, + Timestamp currentBlockTime, long currentRoundNumber = 0, long currentTermNumber = 0) + { + var sortedMiners = + (from obj in Pubkeys + .ToDictionary(miner => miner.ToHex(), miner => miner[0]) + orderby obj.Value descending + select obj.Key).ToList(); + + var round = new Round(); + + for (var i = 0; i < sortedMiners.Count; i++) + { + var minerInRound = new MinerInRound(); + + // The first miner will be the extra block producer of first round of each term. + if (i == 0) minerInRound.IsExtraBlockProducer = true; + + minerInRound.Pubkey = sortedMiners[i]; + minerInRound.Order = i + 1; + minerInRound.ExpectedMiningTime = currentBlockTime.AddMilliseconds(i * miningInterval + miningInterval); + // Should be careful during validation. + minerInRound.PreviousInValue = Hash.Empty; + + round.RealTimeMinersInformation.Add(sortedMiners[i], minerInRound); + } + + round.RoundNumber = currentRoundNumber + 1; + round.TermNumber = currentTermNumber + 1; + round.IsMinerListJustChanged = true; + + return round; + } + + public Hash GetMinersHash() + { + var orderedMiners = Pubkeys.OrderBy(p => p); + return HashHelper.ComputeFrom(orderedMiners.Aggregate("", (current, publicKey) => current + publicKey)); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureDisable.Tests/OptionalLogEventProcessingService.cs b/test/AElf.Kernel.FeatureDisable.Tests/OptionalLogEventProcessingService.cs new file mode 100644 index 0000000000..4a5d9a0bb9 --- /dev/null +++ b/test/AElf.Kernel.FeatureDisable.Tests/OptionalLogEventProcessingService.cs @@ -0,0 +1,21 @@ +using AElf.Kernel.Blockchain; +using AElf.Kernel.SmartContract.Application; + +namespace AElf.Kernel.FeatureDisable.Tests; + +public class OptionalLogEventProcessingService : ILogEventProcessingService where T : ILogEventProcessor +{ + private readonly LogEventProcessingService _inner; + + public OptionalLogEventProcessingService(LogEventProcessingService inner) + { + _inner = inner; + } + + public static bool Enabled { get; set; } + + public async Task ProcessAsync(List blockExecutedSets) + { + if (Enabled) await _inner.ProcessAsync(blockExecutedSets); + } +} \ No newline at end of file diff --git a/test/AElf.Kernel.FeatureManager.Tests/AElf.Kernel.FeatureManager.Tests.csproj b/test/AElf.Kernel.FeatureManager.Tests/AElf.Kernel.FeatureManager.Tests.csproj index df20fffd91..d85c33fa68 100644 --- a/test/AElf.Kernel.FeatureManager.Tests/AElf.Kernel.FeatureManager.Tests.csproj +++ b/test/AElf.Kernel.FeatureManager.Tests/AElf.Kernel.FeatureManager.Tests.csproj @@ -1,15 +1,15 @@ - + - net6.0 + net8.0 enable false - - + + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -41,8 +41,8 @@ Contract PreserveNewest - - + + diff --git a/test/AElf.Kernel.FeeCalculation.Tests/AElf.Kernel.FeeCalculation.Tests.csproj b/test/AElf.Kernel.FeeCalculation.Tests/AElf.Kernel.FeeCalculation.Tests.csproj index d61476a858..578295502d 100644 --- a/test/AElf.Kernel.FeeCalculation.Tests/AElf.Kernel.FeeCalculation.Tests.csproj +++ b/test/AElf.Kernel.FeeCalculation.Tests/AElf.Kernel.FeeCalculation.Tests.csproj @@ -1,6 +1,6 @@ - + - net6.0 + net8.0 AElf.Kernel.FeeCalculation false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,7 +22,7 @@ - - + + diff --git a/test/AElf.Kernel.FeeCalculation.Tests/Infrastructure/CalculateFunctionTest.cs b/test/AElf.Kernel.FeeCalculation.Tests/Infrastructure/CalculateFunctionTest.cs index 2e8484cd82..211d309fb0 100644 --- a/test/AElf.Kernel.FeeCalculation.Tests/Infrastructure/CalculateFunctionTest.cs +++ b/test/AElf.Kernel.FeeCalculation.Tests/Infrastructure/CalculateFunctionTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using AElf.Contracts.MultiToken; using AElf.CSharp.Core.Extension; @@ -65,30 +66,47 @@ public void GetChargedTransactionFees_Test() var transactionResult = new TransactionResult(); transactionResult.Logs.Add(new TransactionFeeCharged { + ChargingAddress = SampleAddress.AddressList[0], Amount = 1, Symbol = "ELF" }.ToLogEvent()); transactionResult.Logs.Add(new TransactionFeeCharged { + ChargingAddress = SampleAddress.AddressList[0], Amount = 2, Symbol = "ELF" }.ToLogEvent()); transactionResult.Logs.Add(new TransactionFeeCharged { + ChargingAddress = SampleAddress.AddressList[0], + Amount = 3, + Symbol = "USDT" + }.ToLogEvent()); + transactionResult.Logs.Add(new TransactionFeeCharged + { + ChargingAddress = SampleAddress.AddressList[0], + Amount = 4, + Symbol = "USDT" + }.ToLogEvent()); + transactionResult.Logs.Add(new TransactionFeeCharged + { + ChargingAddress = SampleAddress.AddressList[1], Amount = 3, Symbol = "TEST" }.ToLogEvent()); transactionResult.Logs.Add(new TransactionFeeCharged { + ChargingAddress = SampleAddress.AddressList[1], Amount = 4, Symbol = "TEST" }.ToLogEvent()); var feeDic = transactionResult.GetChargedTransactionFees(); feeDic.Count.ShouldBe(2); - feeDic.Keys.First().ShouldBe("ELF"); - feeDic.Values.First().ShouldBe(3); - feeDic.Keys.Last().ShouldBe("TEST"); - feeDic.Values.Last().ShouldBe(7); + feeDic.Keys.First().ShouldBe(SampleAddress.AddressList[0]); + feeDic.Values.First()["ELF"].ShouldBe(3); + feeDic.Values.First()["USDT"].ShouldBe(7); + feeDic.Keys.Last().ShouldBe(SampleAddress.AddressList[1]); + feeDic.Values.Last()["TEST"].ShouldBe(7); } [Fact] diff --git a/test/AElf.Kernel.Node.Tests/AElf.Kernel.Node.Tests.csproj b/test/AElf.Kernel.Node.Tests/AElf.Kernel.Node.Tests.csproj index 583e6f2452..2b742c06c2 100644 --- a/test/AElf.Kernel.Node.Tests/AElf.Kernel.Node.Tests.csproj +++ b/test/AElf.Kernel.Node.Tests/AElf.Kernel.Node.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false AElf.Kernel.Node @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,8 +22,8 @@ - - - + + + diff --git a/test/AElf.Kernel.Proposal.Tests/AElf.Kernel.Proposal.Tests.csproj b/test/AElf.Kernel.Proposal.Tests/AElf.Kernel.Proposal.Tests.csproj index 7bc3a24986..1dc00fcc5f 100644 --- a/test/AElf.Kernel.Proposal.Tests/AElf.Kernel.Proposal.Tests.csproj +++ b/test/AElf.Kernel.Proposal.Tests/AElf.Kernel.Proposal.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 @@ -14,7 +14,7 @@ all runtime; build; native; contentfiles; analyzers - + all @@ -23,8 +23,8 @@ - - + + diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract.csproj index cc88e79370..80703eb7cc 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.TestContract @@ -10,7 +10,7 @@ true - + diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.csproj index 572810cff3..025aa71f5e 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests/AElf.Kernel.SmartContract.ExecutionPluginForCallThreshold.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -25,13 +25,13 @@ - - - - + + + + - + false Contract diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract.csproj index d2729b3029..e925a6dcfe 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.TestContract @@ -10,7 +10,7 @@ true - + diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.csproj index 8a46bd22dc..c3b35edf1d 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeTest.cs b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeTest.cs index b265f1cca9..1264e6fb14 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeTest.cs +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeTest.cs @@ -268,14 +268,14 @@ public async Task ChargeFee_SuccessfulTest() chargingAddress.ShouldContain(dummy.Transaction.From); var transactionFeeDic = dummy.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(DefaultSender,transactionFeeDic); var after = await tokenContractStub.GetBalance.CallAsync(new GetBalanceInput { Owner = DefaultSender, Symbol = "ELF" }); - after.Balance.ShouldBe(before.Balance - transactionFeeDic[before.Symbol]); + after.Balance.ShouldBe(before.Balance - transactionFeeDic[DefaultAddress][before.Symbol]); } private static List
GetChargingAddress(TransactionResult transactionResult) @@ -284,7 +284,7 @@ private static List
GetChargingAddress(TransactionResult transactionRes return relatedLogs.Select(l => TransactionFeeCharged.Parser.ParseFrom(l.Indexed[0]).ChargingAddress).ToList(); } - private async Task CheckTransactionFeesMapAsync(Dictionary transactionFeeDic) + private async Task CheckTransactionFeesMapAsync(Address chargingAddress, Dictionary> transactionFeeDic) { var chain = await _blockchainService.GetChainAsync(); var transactionFeesMap = await _totalTransactionFeesMapProvider.GetTotalTransactionFeesMapAsync(new ChainContext @@ -293,7 +293,13 @@ private async Task CheckTransactionFeesMapAsync(Dictionary transac BlockHeight = chain.BestChainHeight }); foreach (var transactionFee in transactionFeeDic) - transactionFeesMap.Value[transactionFee.Key].ShouldBe(transactionFee.Value); + { + transactionFee.Key.ShouldBe(chargingAddress); + foreach (var value in transactionFee.Value) + { + transactionFeesMap.Value[value.Key].ShouldBe(value.Value); + } + } } [Fact] @@ -324,7 +330,7 @@ await tokenContractStub.Transfer.SendAsync(new TransferInput dummy.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); dummy.TransactionResult.Error.ShouldBe("Pre-Error: Transaction fee not enough."); var transactionFeeDic = dummy.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(Accounts[1].Address,transactionFeeDic); var afterFee = (await tokenContractStub.GetBalance.CallAsync(new GetBalanceInput { @@ -332,7 +338,7 @@ await tokenContractStub.Transfer.SendAsync(new TransferInput Symbol = "ELF" })).Balance; afterFee.ShouldBe(0); - transactionFeeDic["ELF"].ShouldBe(issueAmount); + transactionFeeDic[Accounts[1].Address]["ELF"].ShouldBe(issueAmount); } [Theory] @@ -378,7 +384,7 @@ await tokenContractStub.Transfer.SendAsync(new TransferInput Symbol = chargedSymbol ?? "ELF" })).Balance; - Dictionary transactionFeeDic; + Dictionary> transactionFeeDic; var userTestContractStub = GetTester(_testContractAddress, Accounts[1].KeyPair); if (isChargingSuccessful) @@ -387,8 +393,9 @@ await tokenContractStub.Transfer.SendAsync(new TransferInput dummyResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); if (chargedSymbol != null) { - dummyResult.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(chargedSymbol); - dummyResult.TransactionResult.GetChargedTransactionFees().Values.ShouldContain(chargedAmount); + dummyResult.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(Accounts[1].Address); + dummyResult.TransactionResult.GetChargedTransactionFees()[Accounts[1].Address].Keys.ShouldContain(chargedSymbol); + dummyResult.TransactionResult.GetChargedTransactionFees()[Accounts[1].Address].Values.ShouldContain(chargedAmount); } transactionFeeDic = dummyResult.TransactionResult.GetChargedTransactionFees(); @@ -399,13 +406,13 @@ await tokenContractStub.Transfer.SendAsync(new TransferInput dummyResult.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); dummyResult.TransactionResult.Error.ShouldBe("Pre-Error: Transaction fee not enough."); if (chargedSymbol != null) - dummyResult.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(chargedSymbol); + dummyResult.TransactionResult.GetChargedTransactionFees()[Accounts[1].Address].Keys.ShouldContain(chargedSymbol); transactionFeeDic = dummyResult.TransactionResult.GetChargedTransactionFees(); } - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(Accounts[1].Address,transactionFeeDic); if (chargedSymbol != null) - transactionFeeDic[chargedSymbol].ShouldBe(chargedAmount); + transactionFeeDic[Accounts[1].Address][chargedSymbol].ShouldBe(chargedAmount); var finalBalance = (await tokenContractStub.GetBalance.CallAsync(new GetBalanceInput { diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeWithForkTest.cs b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeWithForkTest.cs index 6a6ffe5a73..02aebc36aa 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeWithForkTest.cs +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForMethodFeeWithForkTest.cs @@ -55,8 +55,9 @@ await SetMethodFeeWithProposalAsync(new MethodFees Memo = Guid.NewGuid().ToString(), To = SampleAddress.AddressList[0] }); + var fromAddress = Address.FromPublicKey(Tester.KeyPair.PublicKey); var transactionResult = await Tester.GetTransactionResultAsync(result.Item2.GetHash()); - var targetFee = transactionResult.GetChargedTransactionFees().First().Value; + var targetFee = transactionResult.GetChargedTransactionFees()[fromAddress].First().Value; var transactionFeesMap = await GetTransactionFeesMapAsync(new ChainContext { @@ -97,7 +98,7 @@ await SetMethodFeeWithProposalAsync(new MethodFees To = SampleAddress.AddressList[0] }); transactionResult = await Tester.GetTransactionResultAsync(result.Item2.GetHash()); - var fee = transactionResult.GetChargedTransactionFees().First().Value; + var fee = transactionResult.GetChargedTransactionFees()[fromAddress].First().Value; transactionFeesMap = await GetTransactionFeesMapAsync(new ChainContext { BlockHash = result.Item1.GetHash(), BlockHeight = result.Item1.Height diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForUserContractMethodFeeTest.cs b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForUserContractMethodFeeTest.cs index 25e8daa5f4..aebf96ff37 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForUserContractMethodFeeTest.cs +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/ExecutionPluginForUserContractMethodFeeTest.cs @@ -75,14 +75,14 @@ public async Task ChargeUserContractFeeTest_Success() var result = await _testContractStub.TestMethod.SendAsync(new Empty()); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); var transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(DefaultAddress,transactionFeeDic); var after = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput { Owner = DefaultAddress, Symbol = "ELF" }); - after.Balance.ShouldBe(beforeBalance.Balance - transactionFeeDic[beforeBalance.Symbol]); + after.Balance.ShouldBe(beforeBalance.Balance - transactionFeeDic[DefaultAddress][beforeBalance.Symbol]); } [Fact] @@ -97,7 +97,7 @@ public async Task ChargeUserContractFeeTest_Success_BaseFeeIsFree() var result = await _testContractStub.TestMethod.SendAsync(new Empty()); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); var transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(DefaultAddress,transactionFeeDic); var after = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput { @@ -193,7 +193,7 @@ await TokenContractStub.Transfer.SendAsync(new TransferInput Symbol = chargedSymbol ?? "ELF" })).Balance; - Dictionary transactionFeeDic; + Dictionary> transactionFeeDic; var userTestContractStub = GetTester(_testContractAddress, Accounts[1].KeyPair); if (isChargingSuccessful) @@ -202,8 +202,13 @@ await TokenContractStub.Transfer.SendAsync(new TransferInput result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); if (chargedSymbol != null) { - result.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(chargedSymbol); - result.TransactionResult.GetChargedTransactionFees().Values.ShouldContain(chargedAmount); + var token = new Dictionary + { + [chargedSymbol] = chargedAmount + }; + result.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(Accounts[1].Address); + var fee = result.TransactionResult.GetChargedTransactionFees()[Accounts[1].Address]; + fee.ShouldContainKeyAndValue(chargedSymbol,chargedAmount); } transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); @@ -214,13 +219,21 @@ await TokenContractStub.Transfer.SendAsync(new TransferInput result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); result.TransactionResult.Error.ShouldBe("Pre-Error: Transaction fee not enough."); if (chargedSymbol != null) - result.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(chargedSymbol); + { + var token = new Dictionary + { + [chargedSymbol] = chargedAmount + }; + result.TransactionResult.GetChargedTransactionFees().Keys.ShouldContain(Accounts[1].Address); + var fee = result.TransactionResult.GetChargedTransactionFees()[Accounts[1].Address]; + fee.ShouldContainKeyAndValue(chargedSymbol,chargedAmount); + } transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); } - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(Accounts[1].Address,transactionFeeDic); if (chargedSymbol != null) - transactionFeeDic[chargedSymbol].ShouldBe(chargedAmount); + transactionFeeDic[Accounts[1].Address][chargedSymbol].ShouldBe(chargedAmount); var finalBalance = (await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput { @@ -253,7 +266,7 @@ public async Task ChargeFee_SizeFeeIsFree() var result = await _testContractStub.TestMethod.SendAsync(new Empty()); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); var transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(DefaultAddress, transactionFeeDic); var after = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput { @@ -282,7 +295,8 @@ public async Task ChargeFee_SpecConfigurationFee() }; var createProposalInput = new SetConfigurationInput { - Key = $"{ConfigurationKey}_{_testContractAddress}_{nameof(TestContractContainer.TestContractStub.TestMethod)}", + Key = + $"{ConfigurationKey}_{_testContractAddress.ToBase58()}_{nameof(TestContractContainer.TestContractStub.TestMethod)}", Value = transactionFee.ToByteString() }; await ConfigurationStub.SetConfiguration.SendAsync(createProposalInput); @@ -294,7 +308,7 @@ public async Task ChargeFee_SpecConfigurationFee() var result = await _testContractStub.TestMethod.SendAsync(new Empty()); result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); var transactionFeeDic = result.TransactionResult.GetChargedTransactionFees(); - await CheckTransactionFeesMapAsync(transactionFeeDic); + await CheckTransactionFeesMapAsync(DefaultAddress, transactionFeeDic); var after = await TokenContractStub.GetBalance.CallAsync(new GetBalanceInput { @@ -356,7 +370,7 @@ private async Task Initialize() } } - private async Task CheckTransactionFeesMapAsync(Dictionary transactionFeeDic) + private async Task CheckTransactionFeesMapAsync(Address chargingAddress, Dictionary> transactionFeeDic) { var chain = await _blockchainService.GetChainAsync(); var transactionFeesMap = await _totalTransactionFeesMapProvider.GetTotalTransactionFeesMapAsync(new ChainContext @@ -365,7 +379,14 @@ private async Task CheckTransactionFeesMapAsync(Dictionary transac BlockHeight = chain.BestChainHeight }); foreach (var transactionFee in transactionFeeDic) - transactionFeesMap.Value[transactionFee.Key].ShouldBe(transactionFee.Value); + { + transactionFee.Key.ShouldBe(chargingAddress); + foreach (var value in transactionFee.Value) + { + transactionFeesMap.Value[value.Key].ShouldBe(value.Value); + } + } + } private async Task SetUserContractFeeAsync(int amount) diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/Service/PlainTransactionExecutingAsPluginService.cs b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/Service/PlainTransactionExecutingAsPluginService.cs index 2ea2db6654..f43cef0e42 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/Service/PlainTransactionExecutingAsPluginService.cs +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForMethodFee.Tests/Service/PlainTransactionExecutingAsPluginService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AElf.Kernel.FeatureDisable.Core; using AElf.Kernel.SmartContract.Application; using AElf.Kernel.SmartContract.Domain; using AElf.Kernel.SmartContract.Infrastructure; @@ -20,8 +21,8 @@ public class PlainTransactionExecutingAsPluginService : PlainTransactionExecutin public PlainTransactionExecutingAsPluginService (ISmartContractExecutiveService smartContractExecutiveService, IEnumerable postPlugins, IEnumerable prePlugins, - ITransactionContextFactory transactionContextFactory) : base( - smartContractExecutiveService, postPlugins, prePlugins, transactionContextFactory) + ITransactionContextFactory transactionContextFactory, IFeatureDisableService featureDisableService) : base( + smartContractExecutiveService, postPlugins, prePlugins, transactionContextFactory, featureDisableService) { _smartContractExecutiveService = smartContractExecutiveService; } diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract.csproj index a52621689a..41682307a9 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.TestContract true @@ -11,7 +11,7 @@ true - + diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.csproj index 6413e7f543..de9d8be462 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/ExecutionPluginForResourceFeeTest.cs b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/ExecutionPluginForResourceFeeTest.cs index 6a47875b59..af015ab1bb 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/ExecutionPluginForResourceFeeTest.cs +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForResourceFee.Tests/ExecutionPluginForResourceFeeTest.cs @@ -258,8 +258,8 @@ public async Task CompareConsumptions() write.ShouldBeGreaterThan(write1); traffic.ShouldBe(traffic1); - var consumedTokens1 = txResult1.GetConsumedResourceTokens(); - var consumedTokens2 = txResult2.GetConsumedResourceTokens(); + var consumedTokens1 = txResult1.GetConsumedResourceTokens()[TestContractAddress]; + var consumedTokens2 = txResult2.GetConsumedResourceTokens()[TestContractAddress]; consumedTokens1["READ"].ShouldBeGreaterThan(consumedTokens2["READ"]); consumedTokens1["WRITE"].ShouldBeGreaterThan(consumedTokens2["WRITE"]); consumedTokens1["TRAFFIC"].ShouldBe(consumedTokens2["TRAFFIC"]); diff --git a/test/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract.csproj b/test/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract.csproj index 2e31987432..979af2ea9b 100644 --- a/test/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract.csproj +++ b/test/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract/AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract AElf.Kernel.SmartContract.ExecutionPluginForUserContractFee.Tests.TestContract diff --git a/test/AElf.Kernel.SmartContract.Parallel.Tests/AElf.Kernel.SmartContract.Parallel.Tests.csproj b/test/AElf.Kernel.SmartContract.Parallel.Tests/AElf.Kernel.SmartContract.Parallel.Tests.csproj index f900ca7ae4..d3e0c77eea 100644 --- a/test/AElf.Kernel.SmartContract.Parallel.Tests/AElf.Kernel.SmartContract.Parallel.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.Parallel.Tests/AElf.Kernel.SmartContract.Parallel.Tests.csproj @@ -1,17 +1,17 @@  - net6.0 + net8.0 false - - - - - + + + + + - + false Contract @@ -65,8 +65,8 @@ runtime; build; native; contentfiles; analyzers - - + + all diff --git a/test/AElf.Kernel.SmartContract.Shared.Tests/AElf.Kernel.SmartContract.Shared.Tests.csproj b/test/AElf.Kernel.SmartContract.Shared.Tests/AElf.Kernel.SmartContract.Shared.Tests.csproj index 7c886c44f7..3c87021fde 100644 --- a/test/AElf.Kernel.SmartContract.Shared.Tests/AElf.Kernel.SmartContract.Shared.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.Shared.Tests/AElf.Kernel.SmartContract.Shared.Tests.csproj @@ -1,12 +1,12 @@ - + - net6.0 + net8.0 AElf.Kernel.SmartContract.Shared.Tests - + @@ -15,7 +15,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.Kernel.SmartContract.Tests/AElf.Kernel.SmartContract.Tests.csproj b/test/AElf.Kernel.SmartContract.Tests/AElf.Kernel.SmartContract.Tests.csproj index d8848b909f..0dd224e854 100644 --- a/test/AElf.Kernel.SmartContract.Tests/AElf.Kernel.SmartContract.Tests.csproj +++ b/test/AElf.Kernel.SmartContract.Tests/AElf.Kernel.SmartContract.Tests.csproj @@ -1,15 +1,15 @@  - net6.0 + net8.0 AElf.Kernel.SmartContract false - - - - - + + + + + @@ -29,7 +29,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.Kernel.SmartContract.Tests/Application/SmartContractExecutiveServiceTests.cs b/test/AElf.Kernel.SmartContract.Tests/Application/SmartContractExecutiveServiceTests.cs index c75d5d4a53..07eafbf4a8 100644 --- a/test/AElf.Kernel.SmartContract.Tests/Application/SmartContractExecutiveServiceTests.cs +++ b/test/AElf.Kernel.SmartContract.Tests/Application/SmartContractExecutiveServiceTests.cs @@ -190,7 +190,7 @@ public async Task CleanIdleExecutive_Test() }; var executives = new List(); - for (var i = 0; i < 11; i++) + for (var i = 0; i < 51; i++) { var executive = await _smartContractExecutiveService.GetExecutiveAsync(chainContext, address); executives.Add(executive); @@ -199,23 +199,23 @@ public async Task CleanIdleExecutive_Test() foreach (var executive in executives) await _smartContractExecutiveService.PutExecutiveAsync(chainContext, address, executive); _smartContractExecutiveProvider.TryGetValue(address, out pool); - pool.Count.ShouldBe(11); + pool.Count.ShouldBe(51); _smartContractExecutiveService.CleanIdleExecutive(); - pool.Count.ShouldBe(10); + pool.Count.ShouldBe(50); _smartContractExecutiveProvider.TryGetValue(address, out pool); - pool.Count.ShouldBe(10); + pool.Count.ShouldBe(50); pool.TryPeek(out var item); item.LastUsedTime = item.LastUsedTime.AddHours(-2); _smartContractExecutiveService.CleanIdleExecutive(); _smartContractExecutiveProvider.TryGetValue(address, out pool); - pool.Count.ShouldBe(9); + pool.Count.ShouldBe(49); pool.TryPeek(out item); item.LastUsedTime = item.LastUsedTime.AddHours(-2); _smartContractExecutiveService.CleanIdleExecutive(); _smartContractExecutiveProvider.TryGetValue(address, out pool); - pool.Count.ShouldBe(8); + pool.Count.ShouldBe(48); } [Fact] diff --git a/test/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract.csproj b/test/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract.csproj index 9eaaad2806..e819c686e3 100644 --- a/test/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract.csproj +++ b/test/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract/AElf.Kernel.SmartContractExecution.Parallel.Tests.TestContract.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -13,6 +13,6 @@ - + diff --git a/test/AElf.Kernel.SmartContractExecution.Tests/AElf.Kernel.SmartContractExecution.Tests.csproj b/test/AElf.Kernel.SmartContractExecution.Tests/AElf.Kernel.SmartContractExecution.Tests.csproj index 55cbcd56cf..525376a71a 100644 --- a/test/AElf.Kernel.SmartContractExecution.Tests/AElf.Kernel.SmartContractExecution.Tests.csproj +++ b/test/AElf.Kernel.SmartContractExecution.Tests/AElf.Kernel.SmartContractExecution.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Kernel.SmartContractExecution false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,9 +22,9 @@ - - - + + + diff --git a/test/AElf.Kernel.TestBase/AElf.Kernel.TestBase.csproj b/test/AElf.Kernel.TestBase/AElf.Kernel.TestBase.csproj index 3f97c6eea1..993eeca963 100644 --- a/test/AElf.Kernel.TestBase/AElf.Kernel.TestBase.csproj +++ b/test/AElf.Kernel.TestBase/AElf.Kernel.TestBase.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 AElf.Kernel false - - + + diff --git a/test/AElf.Kernel.Tests/AElf.Kernel.Tests.csproj b/test/AElf.Kernel.Tests/AElf.Kernel.Tests.csproj index 9410aa71fb..3c017d6a7c 100644 --- a/test/AElf.Kernel.Tests/AElf.Kernel.Tests.csproj +++ b/test/AElf.Kernel.Tests/AElf.Kernel.Tests.csproj @@ -1,16 +1,16 @@  - net6.0 + net8.0 AElf.Kernel false - - - - - - + + + + + + @@ -18,7 +18,7 @@ runtime; build; native; contentfiles; analyzers - + all diff --git a/test/AElf.Kernel.Token.Tests/AElf.Kernel.Token.Tests.csproj b/test/AElf.Kernel.Token.Tests/AElf.Kernel.Token.Tests.csproj index d0056f5676..6588651a1c 100644 --- a/test/AElf.Kernel.Token.Tests/AElf.Kernel.Token.Tests.csproj +++ b/test/AElf.Kernel.Token.Tests/AElf.Kernel.Token.Tests.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 false @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -27,9 +27,9 @@ - - - + + + diff --git a/test/AElf.Kernel.TransactionPool.Tests/AElf.Kernel.TransactionPool.Tests.csproj b/test/AElf.Kernel.TransactionPool.Tests/AElf.Kernel.TransactionPool.Tests.csproj index ab3834c03d..144af8c51c 100644 --- a/test/AElf.Kernel.TransactionPool.Tests/AElf.Kernel.TransactionPool.Tests.csproj +++ b/test/AElf.Kernel.TransactionPool.Tests/AElf.Kernel.TransactionPool.Tests.csproj @@ -1,17 +1,17 @@  - net6.0 + net8.0 AElf.Kernel.TransactionPool false - + all runtime; build; native; contentfiles; analyzers - + all @@ -23,7 +23,7 @@ - - + + \ No newline at end of file diff --git a/test/AElf.Kernel.Types.Tests/AElf.Kernel.Types.Tests.csproj b/test/AElf.Kernel.Types.Tests/AElf.Kernel.Types.Tests.csproj index 35ed188b9e..bf7b9f2962 100644 --- a/test/AElf.Kernel.Types.Tests/AElf.Kernel.Types.Tests.csproj +++ b/test/AElf.Kernel.Types.Tests/AElf.Kernel.Types.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -9,7 +9,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -21,7 +21,7 @@ - - + + diff --git a/test/AElf.OS.Core.Tests/AElf.OS.Core.Tests.csproj b/test/AElf.OS.Core.Tests/AElf.OS.Core.Tests.csproj index 11e1fe7758..1f6428d77f 100644 --- a/test/AElf.OS.Core.Tests/AElf.OS.Core.Tests.csproj +++ b/test/AElf.OS.Core.Tests/AElf.OS.Core.Tests.csproj @@ -1,12 +1,12 @@  - net6.0 + net8.0 AElf.OS false - - + + @@ -14,7 +14,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -26,5 +26,5 @@ - + diff --git a/test/AElf.OS.Network.Grpc.Tests/AElf.OS.Network.Grpc.Tests.csproj b/test/AElf.OS.Network.Grpc.Tests/AElf.OS.Network.Grpc.Tests.csproj index 4ff60eec84..8265c66783 100644 --- a/test/AElf.OS.Network.Grpc.Tests/AElf.OS.Network.Grpc.Tests.csproj +++ b/test/AElf.OS.Network.Grpc.Tests/AElf.OS.Network.Grpc.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false AElf.OS.Network.Grpc diff --git a/test/AElf.OS.TestBase/AElf.OS.TestBase.csproj b/test/AElf.OS.TestBase/AElf.OS.TestBase.csproj index 1e84ca5e86..f94b070120 100644 --- a/test/AElf.OS.TestBase/AElf.OS.TestBase.csproj +++ b/test/AElf.OS.TestBase/AElf.OS.TestBase.csproj @@ -1,18 +1,18 @@  - net6.0 + net8.0 AElf.OS false - - - - - - - - + + + + + + + + diff --git a/test/AElf.OS.TestBase/MockTxHub.cs b/test/AElf.OS.TestBase/MockTxHub.cs index c7f5d3314d..c4870757c9 100644 --- a/test/AElf.OS.TestBase/MockTxHub.cs +++ b/test/AElf.OS.TestBase/MockTxHub.cs @@ -26,7 +26,8 @@ public MockTxHub(ITransactionManager transactionManager, IBlockchainService bloc _blockchainService = blockchainService; } - public Task GetExecutableTransactionSetAsync(Hash blockHash, int transactionCount = 0) + public Task GetExecutableTransactionSetAsync(Hash blockHash, + int transactionCount) { return Task.FromResult(new ExecutableTransactionSet { diff --git a/test/AElf.OS.Tests/AElf.OS.Tests.csproj b/test/AElf.OS.Tests/AElf.OS.Tests.csproj index 174bf21bb6..001264e0bc 100644 --- a/test/AElf.OS.Tests/AElf.OS.Tests.csproj +++ b/test/AElf.OS.Tests/AElf.OS.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.OS false diff --git a/test/AElf.Parallel.Tests/AElf.Parallel.Tests.csproj b/test/AElf.Parallel.Tests/AElf.Parallel.Tests.csproj index 15bada8c30..6f836e139e 100644 --- a/test/AElf.Parallel.Tests/AElf.Parallel.Tests.csproj +++ b/test/AElf.Parallel.Tests/AElf.Parallel.Tests.csproj @@ -1,18 +1,18 @@  - net6.0 + net8.0 false 0436 - + all runtime; build; native; contentfiles; analyzers - + all @@ -24,8 +24,8 @@ - - + + diff --git a/test/AElf.Runtime.CSharp.Core.Tests/AElf.Runtime.CSharp.Core.Tests.csproj b/test/AElf.Runtime.CSharp.Core.Tests/AElf.Runtime.CSharp.Core.Tests.csproj index c376b7a839..76bacc1375 100644 --- a/test/AElf.Runtime.CSharp.Core.Tests/AElf.Runtime.CSharp.Core.Tests.csproj +++ b/test/AElf.Runtime.CSharp.Core.Tests/AElf.Runtime.CSharp.Core.Tests.csproj @@ -1,6 +1,6 @@ - + - net6.0 + net8.0 AElf.Runtime.CSharp.Core false @@ -10,7 +10,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -22,10 +22,10 @@ - - - - + + + + diff --git a/test/AElf.Runtime.CSharp.Tests.BadContract/AElf.Runtime.CSharp.Tests.BadContract.csproj b/test/AElf.Runtime.CSharp.Tests.BadContract/AElf.Runtime.CSharp.Tests.BadContract.csproj index f38e72b499..c883a7dd37 100644 --- a/test/AElf.Runtime.CSharp.Tests.BadContract/AElf.Runtime.CSharp.Tests.BadContract.csproj +++ b/test/AElf.Runtime.CSharp.Tests.BadContract/AElf.Runtime.CSharp.Tests.BadContract.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Runtime.CSharp.Tests.BadContract AElf.Runtime.CSharp.Tests.BadContract false @@ -8,8 +8,8 @@ true - - + + diff --git a/test/AElf.Runtime.CSharp.Tests.TestContract/AElf.Runtime.CSharp.Tests.TestContract.csproj b/test/AElf.Runtime.CSharp.Tests.TestContract/AElf.Runtime.CSharp.Tests.TestContract.csproj index 6faf712389..439e856813 100644 --- a/test/AElf.Runtime.CSharp.Tests.TestContract/AElf.Runtime.CSharp.Tests.TestContract.csproj +++ b/test/AElf.Runtime.CSharp.Tests.TestContract/AElf.Runtime.CSharp.Tests.TestContract.csproj @@ -1,12 +1,12 @@  - net6.0 + net8.0 AElf.Runtime.CSharp.Tests.TestContract AElf.Runtime.CSharp.Tests.TestContract false - + diff --git a/test/AElf.Runtime.CSharp.Tests/AElf.Runtime.CSharp.Tests.csproj b/test/AElf.Runtime.CSharp.Tests/AElf.Runtime.CSharp.Tests.csproj index 26738d1e1f..8e4954bf65 100644 --- a/test/AElf.Runtime.CSharp.Tests/AElf.Runtime.CSharp.Tests.csproj +++ b/test/AElf.Runtime.CSharp.Tests/AElf.Runtime.CSharp.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 AElf.Runtime.CSharp false @@ -9,10 +9,10 @@ all runtime; build; native; contentfiles; analyzers - - - - + + + + all runtime; build; native; contentfiles; analyzers @@ -21,29 +21,29 @@ all runtime; build; native; contentfiles; analyzers - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/AElf.Sdk.CSharp.Tests.TestContract/AElf.Sdk.CSharp.Tests.TestContract.csproj b/test/AElf.Sdk.CSharp.Tests.TestContract/AElf.Sdk.CSharp.Tests.TestContract.csproj index 8e292cb90a..ccfcfd29cd 100644 --- a/test/AElf.Sdk.CSharp.Tests.TestContract/AElf.Sdk.CSharp.Tests.TestContract.csproj +++ b/test/AElf.Sdk.CSharp.Tests.TestContract/AElf.Sdk.CSharp.Tests.TestContract.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 AElf.Sdk.CSharp.Tests.TestContract2 false - + Protobuf\Proto\reference\acs0.proto diff --git a/test/AElf.Sdk.CSharp.Tests/AElf.Sdk.CSharp.Tests.csproj b/test/AElf.Sdk.CSharp.Tests/AElf.Sdk.CSharp.Tests.csproj index e666048ed6..91ff826eca 100644 --- a/test/AElf.Sdk.CSharp.Tests/AElf.Sdk.CSharp.Tests.csproj +++ b/test/AElf.Sdk.CSharp.Tests/AElf.Sdk.CSharp.Tests.csproj @@ -1,16 +1,16 @@  - net6.0 + net8.0 false - + all runtime; build; native; contentfiles; analyzers - + all @@ -22,12 +22,18 @@ - - + + - - - - + + + + + + + + + all + \ No newline at end of file diff --git a/test/AElf.Sdk.CSharp.Tests/CSharpSmartContractContextTests.cs b/test/AElf.Sdk.CSharp.Tests/CSharpSmartContractContextTests.cs index 4e0f98d97a..48dcf22768 100644 --- a/test/AElf.Sdk.CSharp.Tests/CSharpSmartContractContextTests.cs +++ b/test/AElf.Sdk.CSharp.Tests/CSharpSmartContractContextTests.cs @@ -1,3 +1,4 @@ +using System; using AElf.Cryptography; using AElf.Kernel; using AElf.Kernel.SmartContract; @@ -12,6 +13,51 @@ namespace AElf.Sdk.CSharp.Tests; public class CSharpSmartContractContextTests : SdkCSharpTestBase { + [Fact] + public void Verify_Ed25519Verify() + { + var bridgeContext = GetRequiredService().Create(); + var origin = SampleAddress.AddressList[0]; + bridgeContext.TransactionContext = new TransactionContext + { + Origin = origin, + Transaction = new Transaction + { + From = SampleAddress.AddressList[1], + To = SampleAddress.AddressList[2] + } + }; + var contractContext = new CSharpSmartContractContext(bridgeContext); + var publicKey = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; + var message = ""; + var signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"; + var ed25519VerifyResult = contractContext.Ed25519Verify( + ByteArrayHelper.HexStringToByteArray(signature), + ByteArrayHelper.HexStringToByteArray(message), + ByteArrayHelper.HexStringToByteArray(publicKey)); + ed25519VerifyResult.ShouldBe(true); + + var contractContext1 = new CSharpSmartContractContext(bridgeContext); + var publicKey1 = "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; + var message1 = "1"; + var signature1 = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"; + Should.Throw(() => contractContext1.Ed25519Verify( + ByteArrayHelper.HexStringToByteArray(signature1), + ByteArrayHelper.HexStringToByteArray(message1), + ByteArrayHelper.HexStringToByteArray(publicKey1))); + + // var contractContext2 = new CSharpSmartContractContext(bridgeContext); + // var publicKey2 = "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c"; + // var message2 = "72"; + // var signature2 = "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00"; + // var ed25519VerifyResult2 = contractContext2.Ed25519Verify( + // ByteArrayHelper.HexStringToByteArray(signature2), + // ByteArrayHelper.HexStringToByteArray(message2), + // ByteArrayHelper.HexStringToByteArray(publicKey2)); + // ed25519VerifyResult2.ShouldBe(true); + + } + [Fact] public void Verify_Transaction_Origin_SetValue() { diff --git a/test/AElf.Sdk.CSharp.Tests/ed25519_testdata.json b/test/AElf.Sdk.CSharp.Tests/ed25519_testdata.json new file mode 100644 index 0000000000..60d4a2bad4 --- /dev/null +++ b/test/AElf.Sdk.CSharp.Tests/ed25519_testdata.json @@ -0,0 +1,44 @@ +[ + { + "secret_key": "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "public_key": "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "message": "", + "signed": "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b", + "signature": "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" + }, + { + "secret_key": "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "public_key": "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "message": "72", + "signed": "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c0072", + "signature": "92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00" + }, + { + "secret_key": "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", + "public_key": "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", + "message": "af82", + "signed": "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40aaf82", + "signature": "6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a" + }, + { + "secret_key": "0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9", + "public_key": "e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057", + "message": "cbc77b", + "signed": "d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00ccbc77b", + "signature": "d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c" + }, + { + "secret_key": "6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebb", + "public_key": "c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7", + "message": "5f4c8989", + "signed": "124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c075f4c8989", + "signature": "124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07" + }, + { + "secret_key": "b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293c", + "public_key": "e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01", + "message": "18b6bec097", + "signed": "b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c0918b6bec097", + "signature": "b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09" + } +] \ No newline at end of file diff --git a/test/AElf.TestBase/AElf.TestBase.csproj b/test/AElf.TestBase/AElf.TestBase.csproj index cf517abde8..a35ba40e35 100644 --- a/test/AElf.TestBase/AElf.TestBase.csproj +++ b/test/AElf.TestBase/AElf.TestBase.csproj @@ -1,20 +1,20 @@  - net6.0 + net8.0 false - + - - - - + + + + - - + + - + diff --git a/test/AElf.Types.Tests/AElf.Types.Tests.csproj b/test/AElf.Types.Tests/AElf.Types.Tests.csproj index f97e75afb0..4d2622f091 100644 --- a/test/AElf.Types.Tests/AElf.Types.Tests.csproj +++ b/test/AElf.Types.Tests/AElf.Types.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false @@ -9,7 +9,7 @@ runtime; build; native; contentfiles; analyzers - + all @@ -21,6 +21,6 @@ - + \ No newline at end of file diff --git a/test/AElf.WebApp.Application.Chain.Tests/AElf.WebApp.Application.Chain.Tests.csproj b/test/AElf.WebApp.Application.Chain.Tests/AElf.WebApp.Application.Chain.Tests.csproj index f629badebd..625df18fbf 100644 --- a/test/AElf.WebApp.Application.Chain.Tests/AElf.WebApp.Application.Chain.Tests.csproj +++ b/test/AElf.WebApp.Application.Chain.Tests/AElf.WebApp.Application.Chain.Tests.csproj @@ -1,6 +1,6 @@  - net6.0 + net8.0 false diff --git a/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs b/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs index b898977dc3..67e9db0b83 100644 --- a/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs +++ b/test/AElf.WebApp.Application.Chain.Tests/BlockChainAppServiceTest.cs @@ -15,6 +15,7 @@ using AElf.Kernel.SmartContract.Application; using AElf.Kernel.SmartContract.Domain; using AElf.Kernel.Token; +using AElf.Kernel.TransactionPool.Handler; using AElf.Kernel.TransactionPool.Infrastructure; using AElf.OS; using AElf.Runtime.CSharp; @@ -44,6 +45,8 @@ public sealed class BlockChainAppServiceTest : WebAppTestBase private readonly ISmartContractAddressService _smartContractAddressService; private readonly ITransactionResultStatusCacheProvider _transactionResultStatusCacheProvider; private readonly TransactionValidationStatusChangedEventHandler _transactionValidationStatusChangedEventHandler; + private readonly TransactionValidationStatusFailedEventHandler _transactionExecutionValidationFailedEventHandler; + private readonly ITransactionResultProxyService _transactionResultProxyService; private readonly ITxHub _txHub; private IReadOnlyDictionary _codes; @@ -58,6 +61,9 @@ public BlockChainAppServiceTest(ITestOutputHelper outputHelper) : base(outputHel _osTestHelper = GetRequiredService(); _accountService = GetRequiredService(); _blockStateSetManger = GetRequiredService(); + _transactionResultProxyService = GetRequiredService(); + _transactionExecutionValidationFailedEventHandler = + GetRequiredService(); _transactionValidationStatusChangedEventHandler = GetRequiredService(); } @@ -1682,6 +1688,12 @@ public async Task CalculateTransactionFee_Success_Test() }; var response = await PostResponseAsObjectAsync("/api/blockChain/CalculateTransactionFee", parameters); response.Success.ShouldBe(true); + response.TransactionFees.ChargingAddress.ShouldBe(transaction.From.ToBase58()); + response.TransactionFees.Fee.First().Key.ShouldBe("ELF"); + response.TransactionFees.Fee.First().Value.ShouldBeGreaterThan(10000000L); + response.TransactionFee.First().Key.ShouldBe("ELF"); + response.TransactionFee.First().Value.ShouldBeGreaterThan(10000000L); + } [Fact] @@ -1822,4 +1834,31 @@ await PostResponseAsObjectAsync("/api/blockChain/sendTran response.Transaction.Params.ShouldNotBe( AddOptionInput.Parser.ParseFrom(transaction.Params).ToString()); } + + [Fact] + public async Task InvalidTransactionResultTest() + { + + var txId = HashHelper.ComputeFrom("InvalidTransactionResultTest"); + await _transactionExecutionValidationFailedEventHandler.HandleEventAsync(new TransactionValidationStatusChangedEvent + { + TransactionId = txId, + TransactionResultStatus = TransactionResultStatus.NodeValidationFailed, + Error = "tx error" + }); + + var invalidResult = await _transactionResultProxyService.InvalidTransactionResultService + .GetInvalidTransactionResultAsync(txId); + invalidResult.ShouldNotBeNull(); + invalidResult.Status.ShouldBe(TransactionResultStatus.NodeValidationFailed); + invalidResult.Error.ShouldBe("tx error"); + + var response = await GetResponseAsObjectAsync( + $"/api/blockChain/transactionResult?transactionId={txId.ToHex()}"); + response.ShouldNotBeNull(); + response.Status.ShouldBe(TransactionResultStatus.NodeValidationFailed.ToString().ToUpper()); + response.Error.ShouldBe("tx error"); + + } + } \ No newline at end of file diff --git a/test/AElf.WebApp.Application.Net.Tests/AElf.WebApp.Application.Net.Tests.csproj b/test/AElf.WebApp.Application.Net.Tests/AElf.WebApp.Application.Net.Tests.csproj index d388dbb19d..da690ecf7d 100644 --- a/test/AElf.WebApp.Application.Net.Tests/AElf.WebApp.Application.Net.Tests.csproj +++ b/test/AElf.WebApp.Application.Net.Tests/AElf.WebApp.Application.Net.Tests.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 false - - + + all runtime; build; native; contentfiles; analyzers @@ -21,8 +21,8 @@ runtime; build; native; contentfiles; analyzers - + - + diff --git a/test/AElf.WebApp.Application.TestBase/AElf.WebApp.Application.TestBase.csproj b/test/AElf.WebApp.Application.TestBase/AElf.WebApp.Application.TestBase.csproj index 34f640be6b..191105c3d2 100644 --- a/test/AElf.WebApp.Application.TestBase/AElf.WebApp.Application.TestBase.csproj +++ b/test/AElf.WebApp.Application.TestBase/AElf.WebApp.Application.TestBase.csproj @@ -1,14 +1,14 @@  - net6.0 + net8.0 AElf.WebApp.Application false - - - - + + + + all runtime; build; native; contentfiles; analyzers @@ -16,8 +16,8 @@ - - + + diff --git a/test/AElf.WebApp.Application.TestBase/WebAppTestAElfModule.cs b/test/AElf.WebApp.Application.TestBase/WebAppTestAElfModule.cs index c2d6783b8f..c9dcf809ec 100644 --- a/test/AElf.WebApp.Application.TestBase/WebAppTestAElfModule.cs +++ b/test/AElf.WebApp.Application.TestBase/WebAppTestAElfModule.cs @@ -6,6 +6,7 @@ using AElf.Kernel.FeeCalculation; using AElf.Kernel.SmartContract.Application; using AElf.Kernel.SmartContract.ExecutionPluginForMethodFee; +using AElf.Kernel.TransactionPool; using AElf.Modularity; using AElf.OS; using AElf.OS.Network.Application; @@ -88,5 +89,9 @@ public override void ConfigureServices(ServiceConfigurationContext context) options.UserName = BasicAuth.DefaultUserName; options.Password = BasicAuth.DefaultPassword; }); + Configure(o => { + o.PoolLimit = 20; + o.StoreInvalidTransactionResultEnabled = true; + }); } } \ No newline at end of file diff --git a/test/ZkTreeVerifier.Tests/ZkTreeVerifier.Tests.csproj b/test/ZkTreeVerifier.Tests/ZkTreeVerifier.Tests.csproj new file mode 100644 index 0000000000..efdd597d36 --- /dev/null +++ b/test/ZkTreeVerifier.Tests/ZkTreeVerifier.Tests.csproj @@ -0,0 +1,43 @@ + + + + net8.0 + AElf.Contracts.ZkTreeVerifier + false + + + + 0436 + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + Protobuf\Proto\stub\acs0.proto + + + Protobuf\Proto\stub\zk_tree_verifier_contract.proto + + + + diff --git a/test/ZkTreeVerifier.Tests/ZkTreeVerifierTest.cs b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTest.cs new file mode 100644 index 0000000000..5e197bd93f --- /dev/null +++ b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTest.cs @@ -0,0 +1,107 @@ +using System.Threading.Tasks; +using AElf.Contracts.ZkTreeVerifier; +using AElf.Kernel.Blockchain.Application; +using AElf.Kernel.SmartContract; +using AElf.Kernel.SmartContract.Application; +using AElf.Types; +using Shouldly; +using Xunit; + +namespace AElf.Contracts.ZkWasmVerifier; + +public class ZkTreeVerifierTest : ZkTreeVerifierTestBase +{ + private readonly IBlockchainService _blockchainService; + private readonly ISmartContractAddressNameProvider _smartContractAddressNameProvider; + private readonly ISmartContractAddressService _smartContractAddressService; + + public ZkTreeVerifierTest() + { + _blockchainService = GetRequiredService(); + _smartContractAddressService = GetRequiredService(); + _smartContractAddressNameProvider = GetRequiredService(); + } + + [Fact] + public async Task ZkWasmVerifier_Verify_Test() + { + var result = await ZkTreeVerifierStub.VerifyProof.SendAsync(GetInput()); + result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Mined); + } + // + // [Fact] + // public async Task ZkWasmVerifier_Verify_InvalidProof_Test() + // { + // var input = GetInput(); + // var invalidProofValue0 = input.Proof[0].Replace("1", "2"); + // input.Proof[0] = invalidProofValue0; + // var result = await ZkTreeVerifierStub.Verify.SendWithExceptionAsync(input); + // result.TransactionResult.Status.ShouldBe(TransactionResultStatus.Failed); + // } + + private VerifyProofInput GetInput() + { + return new VerifyProofInput() + { + Proof = new VerifyProofInput.Types.Proof() + { + A = new VerifyProofInput.Types.G1Point() + { + X = "2153331856662499996051076538230819642090593302283438685828141729152928861078", + Y = "20495207103405864582312617952509144095207901726588009706007940484803667662299", + }, + B = new VerifyProofInput.Types.G2Point() + { + X = new VerifyProofInput.Types.Fp2() + { + First = "4475848984507884668196060555892482119410285219809702955546309039288380061988", + Second = "9215979386460804819323730247391475374617444390304016703370063557678299436332", + }, + Y = new VerifyProofInput.Types.Fp2() + { + First = "10465752260795552834687152738361855405389559549012910153299409915142428605006", + Second = "8951322989288772561314521456384540742686009828350707317833032068265017301495", + } + }, + C = new VerifyProofInput.Types.G1Point() + { + X = "7823756623231971347686901814320384247149959497568781520063439511302207204505", + Y = "14035346942917238856823019345400021595833683521501157999758950235096666725973", + } + }, + Input = + { + "15140580706175849125291604972365990054046394712485534721779098889584978970799", + "3376217485850898635623259527345037392492599525789973564439384597968607340178" + }, + }; + } +/* + * + *{ + "option": 3, + "nullifierHash": "15140580706175849125291604972365990054046394712485534721779098889584978970799", + "root": "3376217485850898635623259527345037392492599525789973564439384597968607340178", + "proof_a": [ + "2153331856662499996051076538230819642090593302283438685828141729152928861078", + "20495207103405864582312617952509144095207901726588009706007940484803667662299" + ], + "proof_b": [ + [ + "4475848984507884668196060555892482119410285219809702955546309039288380061988", + "9215979386460804819323730247391475374617444390304016703370063557678299436332" + ], + [ + "10465752260795552834687152738361855405389559549012910153299409915142428605006", + "8951322989288772561314521456384540742686009828350707317833032068265017301495" + ] + ], + "proof_c": [ + "7823756623231971347686901814320384247149959497568781520063439511302207204505", + "14035346942917238856823019345400021595833683521501157999758950235096666725973" + ] + } + * + * + */ +} \ No newline at end of file diff --git a/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestAElfModule.cs b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestAElfModule.cs new file mode 100644 index 0000000000..969f259c47 --- /dev/null +++ b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestAElfModule.cs @@ -0,0 +1,27 @@ +using AElf.Contracts.TestBase; +using AElf.ContractTestKit; +using AElf.GovernmentSystem; +using AElf.Kernel.SmartContract; +using AElf.Kernel.SmartContract.Application; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Volo.Abp.Modularity; + +namespace AElf.Contracts.ZkWasmVerifier; + +[DependsOn(typeof(ContractTestModule), + typeof(GovernmentSystemAElfModule))] +public class ZkTreeVerifierTestAElfModule : ContractTestModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(o => o.ContractDeploymentAuthorityRequired = false); + context.Services.RemoveAll(); + } +} + +[DependsOn( + typeof(ContractTestAElfModule) +)] +public class ParliamentContractPrivilegeTestAElfModule : ContractTestAElfModule +{ +} \ No newline at end of file diff --git a/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestBase.cs b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestBase.cs new file mode 100644 index 0000000000..2e51ebfcc6 --- /dev/null +++ b/test/ZkTreeVerifier.Tests/ZkTreeVerifierTestBase.cs @@ -0,0 +1,62 @@ +using System.IO; +using AElf.Contracts.ZkWasmVerifier; +using AElf.Cryptography.ECDSA; +using AElf.Kernel; +using AElf.Standards.ACS0; +using AElf.Types; +using Google.Protobuf; +using Volo.Abp.Threading; + +namespace AElf.Contracts.ZkTreeVerifier; + +public class ZkTreeVerifierTestBase : ContractTestKit.ContractTestBase +{ + protected ECKeyPair DefaultKeyPair => Accounts[0].KeyPair; + protected Address DefaultAddress => Accounts[0].Address; + internal ACS0Container.ACS0Stub ZeroContractStub { get; set; } + protected Address ZkTreeVerifierContractAddress { get; set; } + + internal ZkTreeVerifierContainer.ZkTreeVerifierStub ZkTreeVerifierStub { get; set; } + + protected ZkTreeVerifierTestBase() + { + // TokenContractStub = GetTokenContractTester(DefaultKeyPair); + // TokenContractImplStub = GetTester(TokenContractAddress, + // DefaultKeyPair); + ZeroContractStub = GetContractZeroTester(DefaultKeyPair); + var result = AsyncHelper.RunSync(async () => await ZeroContractStub.DeploySmartContract.SendAsync( + new ContractDeploymentInput + { + Category = KernelConstants.CodeCoverageRunnerCategory, + Code = ByteString.CopyFrom( + File.ReadAllBytes(typeof(Contracts.ZkTreeVerifier.ZkTreeVerifier).Assembly.Location)), + ContractOperation = new ContractOperation + { + Deployer = DefaultAddress + } + })); + + ZkTreeVerifierContractAddress = Address.Parser.ParseFrom(result.TransactionResult.ReturnValue); + ZkTreeVerifierStub = GetZkWasmVerifierTester(DefaultKeyPair); + } + + + internal ZkTreeVerifierContainer.ZkTreeVerifierStub GetZkWasmVerifierTester(ECKeyPair keyPair) + { + return GetTester(ZkTreeVerifierContractAddress, + keyPair); + } + + // internal TokenContractImplContainer.TokenContractImplStub GetTokenContractTester( + // ECKeyPair keyPair) + // { + // return GetTester(TokenContractAddress, + // keyPair); + // } + // + internal ACS0Container.ACS0Stub GetContractZeroTester( + ECKeyPair keyPair) + { + return GetTester(ContractZeroAddress, keyPair); + } +} \ No newline at end of file diff --git a/test/ZkWasmVerifier.Tests/ZkWasmVerifier.Tests.csproj b/test/ZkWasmVerifier.Tests/ZkWasmVerifier.Tests.csproj index 4329cf26cb..ee106db9d0 100644 --- a/test/ZkWasmVerifier.Tests/ZkWasmVerifier.Tests.csproj +++ b/test/ZkWasmVerifier.Tests/ZkWasmVerifier.Tests.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 AElf.Contracts.ZkWasmVerifier false @@ -28,7 +28,7 @@ - +