diff --git a/.DS_Store b/.DS_Store new file mode 100755 index 00000000..81229e8d Binary files /dev/null and b/.DS_Store differ diff --git a/.devcontainer.json b/.devcontainer.json old mode 100644 new mode 100755 diff --git a/.editorconfig b/.editorconfig old mode 100644 new mode 100755 index a5addec7..a98c989f --- a/.editorconfig +++ b/.editorconfig @@ -46,10 +46,10 @@ indent_size = 2 # Dotnet code style settings: [*.{cs,vb}] # "This." and "Me." qualifiers -dotnet_style_qualification_for_field =true:suggestion -dotnet_style_qualification_for_property =true:suggestion -dotnet_style_qualification_for_method =true:suggestion -dotnet_style_qualification_for_event =true:suggestion +dotnet_style_qualification_for_field = true:suggestion +dotnet_style_qualification_for_property = true:suggestion +dotnet_style_qualification_for_method = true:suggestion +dotnet_style_qualification_for_event = true:suggestion # Language keywords instead of framework type names for type references dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion @@ -82,7 +82,7 @@ dotnet_style_null_propagation = true:suggestion # CSharp code style settings: [*.cs] # Modifier preferences -csharp_preferred_modifier_order = public,private,protected,internal,const,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion +csharp_preferred_modifier_order = public, private, protected, internal, const, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:suggestion # Implicit and explicit types csharp_style_var_for_built_in_types = true:suggestion diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml old mode 100644 new mode 100755 index 5d517cbd..f0cb2e0a --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -38,39 +38,39 @@ jobs: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository and submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '6.0.x' - include-prerelease: true - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: recursive + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.0.x' + include-prerelease: true + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml old mode 100644 new mode 100755 index 49f79de7..48fc3e6e --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -11,33 +11,33 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository and submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Build the Docker image - env: - build_tag: ${{ github.run_id }} - run: docker build ${GITHUB_WORKSPACE}/src/BrightChain.API --file src/BrightChain.API/Dockerfile --tag therevolutionnetwork/brightchain:${{ env.build_tag }} - - name: Tag the shortcut repo - env: - build_tag: ${{ github.run_id }} - run: docker build ${GITHUB_WORKSPACE}/src/BrightChain.API --file src/BrightChain.API/Dockerfile --tag brightchain/core:${{ env.build_tag }} - - name: Login to Docker Hub - if: ${{ github.base_ref == 'main' }} - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Publish - if: ${{ github.base_ref == 'main' }} - env: - DOCKER_REPO_API_SECRET: ${{ secrets.DOCKER_REPO_API_SECRET }} - build_tag: ${{ github.run_id }} - run: docker push therevolutionnetwork/brightchain:${{ env.build_tag }} - - name: Publish shortcut repo - if: ${{ github.base_ref == 'main' }} - env: - DOCKER_REPO_API_SECRET: ${{ secrets.DOCKER_REPO_API_SECRET }} - build_tag: ${{ github.run_id }} - run: docker push brightchain/core:${{ env.build_tag }} + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: recursive + - name: Build the Docker image + env: + build_tag: ${{ github.run_id }} + run: docker build ${GITHUB_WORKSPACE}/src/BrightChain.API --file src/BrightChain.API/Dockerfile --tag therevolutionnetwork/brightchain:${{ env.build_tag }} + - name: Tag the shortcut repo + env: + build_tag: ${{ github.run_id }} + run: docker build ${GITHUB_WORKSPACE}/src/BrightChain.API --file src/BrightChain.API/Dockerfile --tag brightchain/core:${{ env.build_tag }} + - name: Login to Docker Hub + if: ${{ github.base_ref == 'main' }} + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Publish + if: ${{ github.base_ref == 'main' }} + env: + DOCKER_REPO_API_SECRET: ${{ secrets.DOCKER_REPO_API_SECRET }} + build_tag: ${{ github.run_id }} + run: docker push therevolutionnetwork/brightchain:${{ env.build_tag }} + - name: Publish shortcut repo + if: ${{ github.base_ref == 'main' }} + env: + DOCKER_REPO_API_SECRET: ${{ secrets.DOCKER_REPO_API_SECRET }} + build_tag: ${{ github.run_id }} + run: docker push brightchain/core:${{ env.build_tag }} diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml old mode 100644 new mode 100755 index 6d32dca1..fe5635e9 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,36 +11,36 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository and submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.0.x - include-prerelease: true - - name: Restore dependencies - run: dotnet restore - - name: Build Debug - run: dotnet build -c Debug --no-restore -# TODO: -# - name: CodeCov -# run: .\packages\\OpenCover.Console.exe -register:user -target:"%xunit20%\xunit.console.x86.exe" -targetargs:".\MyUnitTests\bin\Debug\MyUnitTests.dll -noshadow" -filter:"+[UnitTestTargetProject*]* -[MyUnitTests*]*" -output:".\MyProject_coverage.xml" -# - name: CodeCov Process -# run: .\packages\\codecov.exe -f "MyProject_coverage.xml" + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: recursive + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + include-prerelease: true + - name: Restore dependencies + run: dotnet restore + - name: Build Debug + run: dotnet build -c Debug --no-restore + # TODO: + # - name: CodeCov + # run: .\packages\\OpenCover.Console.exe -register:user -target:"%xunit20%\xunit.console.x86.exe" -targetargs:".\MyUnitTests\bin\Debug\MyUnitTests.dll -noshadow" -filter:"+[UnitTestTargetProject*]* -[MyUnitTests*]*" -output:".\MyProject_coverage.xml" + # - name: CodeCov Process + # run: .\packages\\codecov.exe -f "MyProject_coverage.xml" test: runs-on: ubuntu-latest steps: - - name: Checkout repository and submodules - uses: actions/checkout@v2 - with: - submodules: recursive - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.0.x - include-prerelease: true - - name: Test - run: dotnet test --verbosity normal + - name: Checkout repository and submodules + uses: actions/checkout@v2 + with: + submodules: recursive + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + include-prerelease: true + - name: Test + run: dotnet test --verbosity normal diff --git a/.github/workflows/generate-docs.yml b/.github/workflows/generate-docs.yml old mode 100644 new mode 100755 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index a070e3d4..597d557c --- a/.gitignore +++ b/.gitignore @@ -353,3 +353,6 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +#MAC +.DS_Store diff --git a/.gitmodules b/.gitmodules old mode 100644 new mode 100755 index 8210eab2..ad242afd --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ -[submodule "BrightChain.wiki"] +[submodule "docs/articles/BrightChain.wiki"] path = docs/articles/BrightChain.wiki url = https://github.com/BrightChain/BrightChain.wiki.git -[submodule "ENT"] +[submodule "src/ENT"] path = src/ENT url = https://github.com/FreddieMercurial/ENT.git [submodule "src/BrightChain.API"] @@ -13,3 +13,15 @@ [submodule "src/LUHN-mod-n"] path = src/LUHN-mod-n url = https://github.com/BrightChain/LUHN-mod-n.git +[submodule "src/NeuralFabric"] + path = src/NeuralFabric + url = https://github.com/BrightChain/NeuralFabric.git +[submodule "test/NeuralFabric.Tests"] + path = test/NeuralFabric.Tests + url = https://github.com/BrightChain/NeuralFabric.Tests.git +[submodule "src/Shart"] + path = src/Shart + url = https://github.com/FreddieMercurial/Shart.git +[submodule "test/Shart.Test"] + path = test/Shart.Test + url = https://github.com/FreddieMercurial/Shart.Test.git diff --git a/All.sln b/All.sln old mode 100644 new mode 100755 index dee296ed..a52259c1 --- a/All.sln +++ b/All.sln @@ -3,12 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31423.177 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj", "{A1A13294-9595-468D-964C-2281EAB05A7A}" - ProjectSection(ProjectDependencies) = postProject - {E5DDC909-4F18-47F6-B4C8-517EF29B748E} = {E5DDC909-4F18-47F6-B4C8-517EF29B748E} - {98A946BE-ECA9-46FF-908D-A136588ACFB8} = {98A946BE-ECA9-46FF-908D-A136588ACFB8} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3B1CFD0B-0ED3-48AB-A2E9-54F24DC7BB68}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig @@ -41,16 +35,28 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BBP.FasterKVMiner", "src\BB EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BrightChain.API", "src\BrightChain.API\BrightChain.API.csproj", "{1EE859F7-0070-4D78-87BA-15460888329F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "docs", "docs\docs.csproj", "{1D3E7AEC-8A73-40CC-A576-A524DB2C9564}" + ProjectSection(ProjectDependencies) = postProject + {E5DDC909-4F18-47F6-B4C8-517EF29B748E} = {E5DDC909-4F18-47F6-B4C8-517EF29B748E} + {98A946BE-ECA9-46FF-908D-A136588ACFB8} = {98A946BE-ECA9-46FF-908D-A136588ACFB8} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NeuralFabric", "src\NeuralFabric\NeuralFabric.csproj", "{CACA30DD-770D-4F4E-BD50-F36D1D7120A8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NeuralFabric.Tests", "test\NeuralFabric.Tests\NeuralFabric.Tests.csproj", "{9616CACE-D293-42DC-877D-4F2777AFB550}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shart", "src\Shart\Shart.csproj", "{3EEDF5EC-422F-4B97-A931-682B12A0A6DB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shart.Test", "test\Shart.Test\Shart.Test.csproj", "{37DFCF8D-7D60-4235-9FD6-AA6EE6578B4D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BBP.Test", "src\BBPPiCalculator\BBPPiCalculator\BBP.Test\BBP.Test.csproj", "{0F60EE04-30AF-4EDE-A531-002978E06457}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A1A13294-9595-468D-964C-2281EAB05A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A1A13294-9595-468D-964C-2281EAB05A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A1A13294-9595-468D-964C-2281EAB05A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A1A13294-9595-468D-964C-2281EAB05A7A}.Release|Any CPU.Build.0 = Release|Any CPU {B654DE7C-E8B7-4D70-A7D6-D843040F9336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B654DE7C-E8B7-4D70-A7D6-D843040F9336}.Debug|Any CPU.Build.0 = Debug|Any CPU {B654DE7C-E8B7-4D70-A7D6-D843040F9336}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -83,6 +89,30 @@ Global {1EE859F7-0070-4D78-87BA-15460888329F}.Debug|Any CPU.Build.0 = Debug|Any CPU {1EE859F7-0070-4D78-87BA-15460888329F}.Release|Any CPU.ActiveCfg = Release|Any CPU {1EE859F7-0070-4D78-87BA-15460888329F}.Release|Any CPU.Build.0 = Release|Any CPU + {1D3E7AEC-8A73-40CC-A576-A524DB2C9564}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D3E7AEC-8A73-40CC-A576-A524DB2C9564}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D3E7AEC-8A73-40CC-A576-A524DB2C9564}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D3E7AEC-8A73-40CC-A576-A524DB2C9564}.Release|Any CPU.Build.0 = Release|Any CPU + {CACA30DD-770D-4F4E-BD50-F36D1D7120A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CACA30DD-770D-4F4E-BD50-F36D1D7120A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CACA30DD-770D-4F4E-BD50-F36D1D7120A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CACA30DD-770D-4F4E-BD50-F36D1D7120A8}.Release|Any CPU.Build.0 = Release|Any CPU + {9616CACE-D293-42DC-877D-4F2777AFB550}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9616CACE-D293-42DC-877D-4F2777AFB550}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9616CACE-D293-42DC-877D-4F2777AFB550}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9616CACE-D293-42DC-877D-4F2777AFB550}.Release|Any CPU.Build.0 = Release|Any CPU + {3EEDF5EC-422F-4B97-A931-682B12A0A6DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3EEDF5EC-422F-4B97-A931-682B12A0A6DB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3EEDF5EC-422F-4B97-A931-682B12A0A6DB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3EEDF5EC-422F-4B97-A931-682B12A0A6DB}.Release|Any CPU.Build.0 = Release|Any CPU + {37DFCF8D-7D60-4235-9FD6-AA6EE6578B4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {37DFCF8D-7D60-4235-9FD6-AA6EE6578B4D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {37DFCF8D-7D60-4235-9FD6-AA6EE6578B4D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {37DFCF8D-7D60-4235-9FD6-AA6EE6578B4D}.Release|Any CPU.Build.0 = Release|Any CPU + {0F60EE04-30AF-4EDE-A531-002978E06457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F60EE04-30AF-4EDE-A531-002978E06457}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F60EE04-30AF-4EDE-A531-002978E06457}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F60EE04-30AF-4EDE-A531-002978E06457}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/BrightChain-LongPaper.pdf b/BrightChain-LongPaper.pdf old mode 100644 new mode 100755 diff --git a/BrightChain-One-Pager.pdf b/BrightChain-One-Pager.pdf old mode 100644 new mode 100755 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md old mode 100644 new mode 100755 index 5352781a..cd4d6b68 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,12 +2,10 @@ This project welcomes contributions and suggestions. -Contributions must be free of proprietary intellectual property conflicts, such as violating NDAs -or accidentally contributing material that is substantially identical to IP of an employer. +Contributions must be free of proprietary intellectual property conflicts, such as violating NDAs or accidentally contributing material that +is substantially identical to IP of an employer. -Once committed, code becomes the property of the BrightChain Consortium which has yet to materialize, -but will constitute the shard-holders/board of the original/authentic BrightChain federation/quorum. -Until legal formation, Jessica Mulein is the controlling owner. +Once committed, code becomes the property of the BrightChain Consortium which has yet to materialize, but will constitute the +shard-holders/board of the original/authentic BrightChain federation/quorum. Until legal formation, Jessica Mulein is the controlling owner. -Contributions are protected by the license adopted by this project at the time of first commit. -This is presently Apache 2.0. \ No newline at end of file +Contributions are protected by the license adopted by this project at the time of first commit. This is presently Apache 2.0. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md old mode 100644 new mode 100755 index 50e4583e..d9d12f35 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,188 +1,128 @@ # Developers Agreement + * [BrightChain Licensing Discussion](https://github.com/The-Revolution-Network/BrightChain/discussions/25) # License Change -* BrightChain initially published under GPL 3.0 based on lack of knowledge. Code added after July 11, 2021 is only under Apache 2.0. Any previously added code, not borrowed from Microsoft EFCore source under Apache 2.0, will continue to be available under GPLv3 if I understand it correctly. IAmNotALawyer. + +* BrightChain initially published under GPL 3.0 based on lack of knowledge. Code added after July 11, 2021 is only under Apache 2.0. Any + previously added code, not borrowed from Microsoft EFCore source under Apache 2.0, will continue to be available under GPLv3 if I + understand it correctly. IAmNotALawyer. # Apache 2.0 + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this + document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, + or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to + compiled object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright + notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the + purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the + interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that + Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an + individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, + the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly + display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim + or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory + patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such + litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a + readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative + Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an + addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the + License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for + use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, + and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by + You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding + the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor + regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor + provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, + without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You + are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your + exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless + required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to + You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of + this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, + computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the + possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and + charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. + However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other + Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims + asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" @@ -193,16 +133,13 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] +Copyright [yyyy] [name of copyright owner] - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may +obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 61876ae3..a85bf9df --- a/README.md +++ b/README.md @@ -1,73 +1,99 @@ # BrightChain -## (pre-alpha work in progress. Limited alpha testing coming soon!) + +## (pre-alpha work in progress. Limited alpha testing coming soon!) + [![.NET](https://github.com/BrightChain/BrightChain/actions/workflows/dotnet.yml/badge.svg)](https://github.com/BrightChain/BrightChain/actions/workflows/dotnet.yml) [![Docker Image CI](https://github.com/BrightChain/BrightChain/actions/workflows/docker.yml/badge.svg)](https://github.com/BrightChain/BrightChain/actions/workflows/docker.yml) [![CodeQL](https://github.com/BrightChain/BrightChain/actions/workflows/codeql-analysis.yml/badge.svg?branch=main)](https://github.com/BrightChain/BrightChain/actions/workflows/codeql-analysis.yml) [![Generate Documentation](https://github.com/BrightChain/BrightChain/actions/workflows/generate-docs.yml/badge.svg)](https://github.com/BrightChain/BrightChain/actions/workflows/generate-docs.yml) -A Lightweight BlockChain- LightChain based on a Brightnet Blockstore- BrightChain. -All the benefits of blockchain dApps and contracts without the mining and waste. -Unlimited storage for everyone, and a mathematically reinforced and moderated community that will last for the ages. +A Lightweight BlockChain- LightChain based on a Brightnet Blockstore- BrightChain. All the benefits of blockchain dApps and contracts +without the mining and waste. Unlimited storage for everyone, and a mathematically reinforced and moderated community that will last for the +ages. - BrightChain Engine in C#/.Net 6 (Currently requires VS 2022 Preview, or IntelliJ Rider) - Uses a Microsoft FASTER KV store on each node - BrightNet BlockStore and API for BrightChain: The Revolution Network - Wiki: https://github.com/BrightChain/BrightChain/wiki - - The old wiki has been copied/merged into the new wiki, but needs to be formatted and cleaned up. + - The old wiki has been copied/merged into the new wiki, but needs to be formatted and cleaned up. - Auto-generated documentation: http://apidocs.brightchain.org/api/index.html - - Note that some of the classes don't have docblocks yet, but I've gotten many. The "TODO/example" text is in place as well, but if you click into the sections the content is there. + - Note that some of the classes don't have docblocks yet, but I've gotten many. The "TODO/example" text is in place as well, but if you + click into the sections the content is there. # Nutshell + - BrightChain is new. -- No mining, no cryptocurrency at the base level, but third parties could build one on top easily. Moreover it has mechanisms for deduplicating data, content aware meta tagging everything, and forcing everyone to think about what they want to keep. +- No mining, no cryptocurrency at the base level, but third parties could build one on top easily. Moreover it has mechanisms for + deduplicating data, content aware meta tagging everything, and forcing everyone to think about what they want to keep. - BrightChain is all kinds of opposites held in balance. - - Anonymity on condition of good behavior. - - Fully verified identity for governmental voting. - - Fully anonymized data during storage and yet fully meta tagged restored when used. - - Permanent storage for the best, eventual recycling for the rest. + - Anonymity on condition of good behavior. + - Fully verified identity for governmental voting. + - Fully anonymized data during storage and yet fully meta tagged restored when used. + - Permanent storage for the best, eventual recycling for the rest. - Check out ["The Big Picture"](https://github.com/BrightChain/BrightChain/wiki/Big-Picture) in the Wiki. # One-Pager -The BrightChain "One-Pager" is about 3 pages at the moment, but pending some slimming down is about as concise a document as I've put together. + +The BrightChain "One-Pager" is about 3 pages at the moment, but pending some slimming down is about as concise a document as I've put +together. + - https://apertureimagingcom-my.sharepoint.com/:w:/g/personal/jessica_mulein_com/EYoQU8qG_xlGpD0_A-mxhvoBqv3OylrfjeRAohvoC0gDQg?e=0U2XDa - - PDF https://github.com/BrightChain/BrightChain/blob/main/BrightChain-One-Pager.pdf as of 08/13/21 09:44 Pacfic time. - - Feedback welcome. + - PDF https://github.com/BrightChain/BrightChain/blob/main/BrightChain-One-Pager.pdf as of 08/13/21 09:44 Pacfic time. + - Feedback welcome. # "Long-Paper" + The BrightChain "LongPaper" is longer and a work in progress, but goes into plain language detail on all aspects. + - https://apertureimagingcom-my.sharepoint.com/:w:/g/personal/jessica_mulein_com/EQGi-tzRmL9KotpkENN0OXcB5LQwpT7ox3vFo3eIJZrqcg?e=MZOanw - - PDF https://github.com/BrightChain/BrightChain/blob/main/BrightChain-LongPaper.pdf as of 08/16/21 13:00 Pacfic time. - - Feedback welcome of course. + - PDF https://github.com/BrightChain/BrightChain/blob/main/BrightChain-LongPaper.pdf as of 08/16/21 13:00 Pacfic time. + - Feedback welcome of course. # Contributing -This project welcomes contributions and suggestions. Licensing up for debate. Code should eventually belong to BrightChain charitable organiztion as IP holder and generally Apache 2 / MIT / GPLv3 sort of licence. + +This project welcomes contributions and suggestions. Licensing up for debate. Code should eventually belong to BrightChain charitable +organiztion as IP holder and generally Apache 2 / MIT / GPLv3 sort of licence. # Recent thoughts: - - FEC notes for the brokered anonymity https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.120.5485&rep=rep1&type=pdf - - A lot of the reputation and resultant API throttling will be in the line of thinking with: https://en.wikipedia.org/wiki/Hashcash#Advantages_and_disadvantages - - URLs are probably going to be base32 {address}.brightchain.org - - Will have an alias registry for {alias}.brightchain.org - aka BrightChain DNS. - - I think calling BrightChain a LightChain makes sense. it's a lightweight blockchain. It's got blockchain features people want, but without the actual overhead of blockchain, which is unnecessary. - - If you haven't noticed- BrightChain is almost BrightChainS with an S. It's a pool of chains. Each with its own value. - - Something I was implementing in the old code but haven't yet gotten to is also a deduplication for public blocks. Basically any chain that has its CBL block committed to the network will have the hash of the overall chain checked for deduplication. - - API throttle will continue as planned to be mathematically rate limited by minimal proof of works for bad actors and an algorithm to determine the maximum request r/w rates. - - Block consensus will be proof of stake - - its more of a brightnet blockstore and an ethos... what it needs still is some math and a little more vision in the areas I'm not seeing. - - The whole goal is to reward people who contribute good, frequently accessed content, the storage for it, etc. - - Everything is tracked in terms of a unit called the Joule - wondering about using a micro-unit Jansky. - - - Attempting to be somewhat synonymous with the real work unit. - - - There should ideally be a direct maths. - - Ultimately bad users are just bad blocks and will get flushed and expired out while good stuff will get extended on forever. They will have to work too hard for their network access/wasteful contribution/access and will leave. - - It is not the necessity of this chain to store every bit forever. The chain is very transparent and ultimately when things do expire out if not needed by the system, others can easily back them up. Some blocks of course are immediately set immutable with a DateTime.MaxValue and don't need to be renewed. + +- FEC notes for the brokered anonymity https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.120.5485&rep=rep1&type=pdf +- A lot of the reputation and resultant API throttling will be in the line of thinking + with: https://en.wikipedia.org/wiki/Hashcash#Advantages_and_disadvantages +- URLs are probably going to be base32 {address}.brightchain.org +- Will have an alias registry for {alias}.brightchain.org - aka BrightChain DNS. +- I think calling BrightChain a LightChain makes sense. it's a lightweight blockchain. It's got blockchain features people want, but without + the actual overhead of blockchain, which is unnecessary. +- If you haven't noticed- BrightChain is almost BrightChainS with an S. It's a pool of chains. Each with its own value. +- Something I was implementing in the old code but haven't yet gotten to is also a deduplication for public blocks. Basically any chain that + has its CBL block committed to the network will have the hash of the overall chain checked for deduplication. +- API throttle will continue as planned to be mathematically rate limited by minimal proof of works for bad actors and an algorithm to + determine the maximum request r/w rates. +- Block consensus will be proof of stake +- its more of a brightnet blockstore and an ethos... what it needs still is some math and a little more vision in the areas I'm not seeing. +- The whole goal is to reward people who contribute good, frequently accessed content, the storage for it, etc. +- Everything is tracked in terms of a unit called the Joule - wondering about using a micro-unit Jansky. +- + - Attempting to be somewhat synonymous with the real work unit. +- + - There should ideally be a direct maths. +- Ultimately bad users are just bad blocks and will get flushed and expired out while good stuff will get extended on forever. They will + have to work too hard for their network access/wasteful contribution/access and will leave. +- It is not the necessity of this chain to store every bit forever. The chain is very transparent and ultimately when things do expire out + if not needed by the system, others can easily back them up. Some blocks of course are immediately set immutable with a DateTime.MaxValue + and don't need to be renewed. # Eventually + * CLR dApps & Digital Contracts -* Hope to provide a low-overhead digital contract / dApp ecosystem based on the CIL/CLR, without the computational overhead of traditional blockchain, making use of the efficiencies of Brightnet Blockstores and still benefitting from the power of blockchain like properties. +* Hope to provide a low-overhead digital contract / dApp ecosystem based on the CIL/CLR, without the computational overhead of traditional + blockchain, making use of the efficiencies of Brightnet Blockstores and still benefitting from the power of blockchain like properties. # Disclaimers + * This project is still pre-Alpha and is not suitable nor warranted for any level of fitness or function. * This project is not affiliated with GitHub, The DotNet Foundation, Microsoft, or any of its affiliates or holdings. -* This software is open source, and offered as a "best-effort" thereoetical construct at this time and it may well lose all your data at this point in time. +* This software is open source, and offered as a "best-effort" thereoetical construct at this time and it may well lose all your data at + this point in time. Last Updated: diff --git a/docs/.gitignore b/docs/.gitignore old mode 100644 new mode 100755 diff --git a/docs/api/.gitignore b/docs/api/.gitignore old mode 100644 new mode 100755 diff --git a/docs/api/index.md b/docs/api/index.md old mode 100644 new mode 100755 index 3cb8b43b..a8991d27 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -1,3 +1,4 @@ # BrightChain Library -To update this documentation, run "docfx" in the docs directory (choc installed). This is automatically updated on github and pushed to the live gh-pages site whenever main is pushed. +To update this documentation, run "docfx" in the docs directory (choc installed). This is automatically updated on github and pushed to the +live gh-pages site whenever main is pushed. diff --git a/docs/articles/BrightChain.wiki b/docs/articles/BrightChain.wiki index 608f8ea3..315c9640 160000 --- a/docs/articles/BrightChain.wiki +++ b/docs/articles/BrightChain.wiki @@ -1 +1 @@ -Subproject commit 608f8ea39911c40f9dbb688388c4064c0c7e8c55 +Subproject commit 315c9640e5d4055a405267ac6ca3901394b0b3f1 diff --git a/docs/articles/LICENSE.md b/docs/articles/LICENSE.md deleted file mode 120000 index f0608a63..00000000 --- a/docs/articles/LICENSE.md +++ /dev/null @@ -1 +0,0 @@ -../../LICENSE.md \ No newline at end of file diff --git a/docs/articles/LICENSE.md b/docs/articles/LICENSE.md new file mode 100755 index 00000000..e69de29b diff --git a/docs/articles/README.md b/docs/articles/README.md deleted file mode 120000 index fe840054..00000000 --- a/docs/articles/README.md +++ /dev/null @@ -1 +0,0 @@ -../../README.md \ No newline at end of file diff --git a/docs/articles/README.md b/docs/articles/README.md new file mode 100755 index 00000000..e69de29b diff --git a/docs/articles/intro.md b/docs/articles/intro.md old mode 100644 new mode 100755 diff --git a/docs/articles/toc.yml b/docs/articles/toc.yml old mode 100644 new mode 100755 diff --git a/docs/docfx.json b/docs/docfx.json old mode 100644 new mode 100755 diff --git a/docs/docs.csproj b/docs/docs.csproj old mode 100644 new mode 100755 index db39170a..c2745a8d --- a/docs/docs.csproj +++ b/docs/docs.csproj @@ -5,12 +5,16 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + diff --git a/docs/index.md b/docs/index.md old mode 100644 new mode 100755 diff --git a/docs/toc.yml b/docs/toc.yml old mode 100644 new mode 100755 diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit old mode 100644 new mode 100755 diff --git a/src/.editorconfig b/src/.editorconfig old mode 100644 new mode 100755 diff --git a/src/BBPPiCalculator b/src/BBPPiCalculator index 82964332..d4964f72 160000 --- a/src/BBPPiCalculator +++ b/src/BBPPiCalculator @@ -1 +1 @@ -Subproject commit 82964332e740b8636783691d0552c6f183affc83 +Subproject commit d4964f72f1423e6cbcb812081262809180782d4c diff --git a/src/BrightChain.API b/src/BrightChain.API index 63266818..5d714d9d 160000 --- a/src/BrightChain.API +++ b/src/BrightChain.API @@ -1 +1 @@ -Subproject commit 63266818264d878a1874c08d9ef709f3429c9bff +Subproject commit 5d714d9dd33d80b042f6c9ce101eac34a23e0cd3 diff --git a/src/BrightChain.API.HISTORY/.dockerignore b/src/BrightChain.API.HISTORY/.dockerignore old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/.github/workflows/codeql-analysis.yml b/src/BrightChain.API.HISTORY/.github/workflows/codeql-analysis.yml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/.github/workflows/docker.yml b/src/BrightChain.API.HISTORY/.github/workflows/docker.yml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/.github/workflows/dotnet.yml b/src/BrightChain.API.HISTORY/.github/workflows/dotnet.yml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/.gitignore b/src/BrightChain.API.HISTORY/.gitignore old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/App.razor b/src/BrightChain.API.HISTORY/App.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/BrightChainIdentityRole.cs b/src/BrightChain.API.HISTORY/Areas/Identity/BrightChainIdentityRole.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/BrightChainIdentityUser.cs b/src/BrightChain.API.HISTORY/Areas/Identity/BrightChainIdentityUser.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Data/BrightChainIdentityDbContext.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Data/BrightChainIdentityDbContext.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/IdentityHostingStartup.cs b/src/BrightChain.API.HISTORY/Areas/Identity/IdentityHostingStartup.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/IdentityPolicy/CustomPasswordPolicy.cs b/src/BrightChain.API.HISTORY/Areas/Identity/IdentityPolicy/CustomPasswordPolicy.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/IdentityPolicy/CustomUsernameEmailPolicy .cs b/src/BrightChain.API.HISTORY/Areas/Identity/IdentityPolicy/CustomUsernameEmailPolicy .cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/AccessDenied.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/AccessDenied.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/AccessDenied.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/AccessDenied.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmail.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmail.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ExternalLogin.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ExternalLogin.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPassword.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPassword.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPasswordConfirmation.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPasswordConfirmation.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPasswordConfirmation.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ForgotPasswordConfirmation.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Lockout.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Lockout.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Lockout.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Lockout.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LogOut.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LogOut.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Login.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Login.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Login.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Login.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWith2fa.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWith2fa.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Logout.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Logout.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Email.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Email.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Index.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Index.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_Layout.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_Layout.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_StatusMessage.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Manage/_ViewImports.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Register.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Register.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Register.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/Register.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPassword.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPassword.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPasswordConfirmation.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPasswordConfirmation.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPasswordConfirmation.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/ResetPasswordConfirmation.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/_StatusMessage.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/_StatusMessage.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/_ViewImports.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Account/_ViewImports.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Error.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Error.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Error.cshtml.cs b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Error.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Shared/_LoginPartial.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/Shared/_LoginPartial.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/_ViewImports.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/_ViewImports.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/Pages/_ViewStart.cshtml b/src/BrightChain.API.HISTORY/Areas/Identity/Pages/_ViewStart.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs b/src/BrightChain.API.HISTORY/Areas/Identity/RevalidatingIdentityAuthenticationStateProvider.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/BrightChain.API.csproj b/src/BrightChain.API.HISTORY/BrightChain.API.csproj old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/BrightChain.API.sln b/src/BrightChain.API.HISTORY/BrightChain.API.sln old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Commands/DropBlockByIdCommand.cs b/src/BrightChain.API.HISTORY/Commands/DropBlockByIdCommand.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Commands/StoreBlockCommand.cs b/src/BrightChain.API.HISTORY/Commands/StoreBlockCommand.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Commands/UpdateBlockCommand.cs b/src/BrightChain.API.HISTORY/Commands/UpdateBlockCommand.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Controllers/BaseApiController.cs b/src/BrightChain.API.HISTORY/Controllers/BaseApiController.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Controllers/BlockController.cs b/src/BrightChain.API.HISTORY/Controllers/BlockController.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Data/AuthMessageSenderOptions.cs b/src/BrightChain.API.HISTORY/Data/AuthMessageSenderOptions.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Data/WeatherForecast.cs b/src/BrightChain.API.HISTORY/Data/WeatherForecast.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Data/WeatherForecastService.cs b/src/BrightChain.API.HISTORY/Data/WeatherForecastService.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Dockerfile b/src/BrightChain.API.HISTORY/Dockerfile old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Extensions/BrightChainAPIEntityDependencyInjectionExtensions.cs b/src/BrightChain.API.HISTORY/Extensions/BrightChainAPIEntityDependencyInjectionExtensions.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Helpers/StarDateConverter.cs b/src/BrightChain.API.HISTORY/Helpers/StarDateConverter.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Illuminator.cs b/src/BrightChain.API.HISTORY/Illuminator.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Infrastructure/BrightChainRoleManager.cs b/src/BrightChain.API.HISTORY/Infrastructure/BrightChainRoleManager.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Infrastructure/BrightChainRoleStore.cs b/src/BrightChain.API.HISTORY/Infrastructure/BrightChainRoleStore.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Infrastructure/BrightChainUserManager.cs b/src/BrightChain.API.HISTORY/Infrastructure/BrightChainUserManager.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Infrastructure/BrightChainUserStore.cs b/src/BrightChain.API.HISTORY/Infrastructure/BrightChainUserStore.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Infrastructure/DbInitializer.cs b/src/BrightChain.API.HISTORY/Infrastructure/DbInitializer.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Interfaces/IBrightChainDbContext.cs b/src/BrightChain.API.HISTORY/Interfaces/IBrightChainDbContext.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Counter.razor b/src/BrightChain.API.HISTORY/Pages/Counter.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Error.cshtml b/src/BrightChain.API.HISTORY/Pages/Error.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Error.cshtml.cs b/src/BrightChain.API.HISTORY/Pages/Error.cshtml.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/FetchData.razor b/src/BrightChain.API.HISTORY/Pages/FetchData.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Index.razor b/src/BrightChain.API.HISTORY/Pages/Index.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Shared/_Layout.cshtml b/src/BrightChain.API.HISTORY/Pages/Shared/_Layout.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Shared/_LoginPartial.cshtml b/src/BrightChain.API.HISTORY/Pages/Shared/_LoginPartial.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/Shared/_ValidationScriptsPartial.cshtml b/src/BrightChain.API.HISTORY/Pages/Shared/_ValidationScriptsPartial.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/_Host.cshtml b/src/BrightChain.API.HISTORY/Pages/_Host.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/_ViewImports.cshtml b/src/BrightChain.API.HISTORY/Pages/_ViewImports.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Pages/_ViewStart.cshtml b/src/BrightChain.API.HISTORY/Pages/_ViewStart.cshtml old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Properties/ServiceDependencies/local/signalr1.arm.json b/src/BrightChain.API.HISTORY/Properties/ServiceDependencies/local/signalr1.arm.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Properties/launchSettings.json b/src/BrightChain.API.HISTORY/Properties/launchSettings.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Properties/serviceDependencies.json b/src/BrightChain.API.HISTORY/Properties/serviceDependencies.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Properties/serviceDependencies.local.json b/src/BrightChain.API.HISTORY/Properties/serviceDependencies.local.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Queries/GetBlockByIdQuery.cs b/src/BrightChain.API.HISTORY/Queries/GetBlockByIdQuery.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/ScaffoldingReadMe.txt b/src/BrightChain.API.HISTORY/ScaffoldingReadMe.txt old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Services/BrightChainEmailSender.cs b/src/BrightChain.API.HISTORY/Services/BrightChainEmailSender.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/LoginDisplay.razor b/src/BrightChain.API.HISTORY/Shared/LoginDisplay.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/MainLayout.razor b/src/BrightChain.API.HISTORY/Shared/MainLayout.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/MainLayout.razor.css b/src/BrightChain.API.HISTORY/Shared/MainLayout.razor.css old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/NavMenu.razor b/src/BrightChain.API.HISTORY/Shared/NavMenu.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/NavMenu.razor.css b/src/BrightChain.API.HISTORY/Shared/NavMenu.razor.css old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Shared/SurveyPrompt.razor b/src/BrightChain.API.HISTORY/Shared/SurveyPrompt.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/Startup.cs b/src/BrightChain.API.HISTORY/Startup.cs old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/_Imports.razor b/src/BrightChain.API.HISTORY/_Imports.razor old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/appsettings.Development.json b/src/BrightChain.API.HISTORY/appsettings.Development.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/appsettings.json b/src/BrightChain.API.HISTORY/appsettings.json old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/bootstrap/bootstrap.min.css b/src/BrightChain.API.HISTORY/wwwroot/css/bootstrap/bootstrap.min.css old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/bootstrap/bootstrap.min.css.map b/src/BrightChain.API.HISTORY/wwwroot/css/bootstrap/bootstrap.min.css.map old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/FONT-LICENSE b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/FONT-LICENSE old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/ICON-LICENSE b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/ICON-LICENSE old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/README.md b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/README.md old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.eot b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.eot old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.otf b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.otf old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.svg b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.svg old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.woff b/src/BrightChain.API.HISTORY/wwwroot/css/open-iconic/font/fonts/open-iconic.woff old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/css/site.css b/src/BrightChain.API.HISTORY/wwwroot/css/site.css old mode 100644 new mode 100755 diff --git a/src/BrightChain.API.HISTORY/wwwroot/favicon.ico b/src/BrightChain.API.HISTORY/wwwroot/favicon.ico old mode 100644 new mode 100755 diff --git a/src/BrightChain.Engine.Client/BrightChain.Engine.Client.csproj b/src/BrightChain.Engine.Client/BrightChain.Engine.Client.csproj old mode 100644 new mode 100755 index f1823090..7cc11433 --- a/src/BrightChain.Engine.Client/BrightChain.Engine.Client.csproj +++ b/src/BrightChain.Engine.Client/BrightChain.Engine.Client.csproj @@ -1,35 +1,35 @@  - - net6.0 - true - True - True - + + net6.0 + true + True + True + - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - + + + diff --git a/src/BrightChain.Engine.Client/BrightChainClient.cs b/src/BrightChain.Engine.Client/BrightChainClient.cs old mode 100644 new mode 100755 index a1acddba..3fb0bc05 --- a/src/BrightChain.Engine.Client/BrightChainClient.cs +++ b/src/BrightChain.Engine.Client/BrightChainClient.cs @@ -2,41 +2,40 @@ using System.Threading; using System.Threading.Tasks; -namespace BrightChain.Engine.Client +namespace BrightChain.Engine.Client; + +public class BrightChainClient { - public class BrightChainClient + public BrightChainClient(string connectionString, BrightChainClientOptions options) { - public BrightChainClient(string connectionString, BrightChainClientOptions options) - { - this.ConnectionString = connectionString; - this.Options = options; - } + this.ConnectionString = connectionString; + this.Options = options; + } - public BrightChainClient(string endpoint, string key, BrightChainClientOptions options) - { - this.Endpoint = endpoint; - this.Key = key; - this.Options = options; - } + public BrightChainClient(string endpoint, string key, BrightChainClientOptions options) + { + this.Endpoint = endpoint; + this.Key = key; + this.Options = options; + } - public string Endpoint { get; } - public string Key { get; } - public BrightChainClientOptions Options { get; } - public string ConnectionString { get; } + public string Endpoint { get; } + public string Key { get; } + public BrightChainClientOptions Options { get; } + public string ConnectionString { get; } - public void Dispose() - { - throw new NotImplementedException(); - } + public void Dispose() + { + throw new NotImplementedException(); + } - public object GetDatabase(string databaseId) - { - throw new NotImplementedException(); - } + public object GetDatabase(string databaseId) + { + throw new NotImplementedException(); + } - public Task CreateDatabaseIfNotExistsAsync(string databaseId, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } + public Task CreateDatabaseIfNotExistsAsync(string databaseId, CancellationToken cancellationToken) + { + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine.Client/BrightChainClientOptions.cs b/src/BrightChain.Engine.Client/BrightChainClientOptions.cs old mode 100644 new mode 100755 index 09707f15..45bdb630 --- a/src/BrightChain.Engine.Client/BrightChainClientOptions.cs +++ b/src/BrightChain.Engine.Client/BrightChainClientOptions.cs @@ -1,209 +1,222 @@ -namespace BrightChain.Engine.Client +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Http; + +namespace BrightChain.Engine.Client; + +// +// Summary: +// Defines all the configurable options that the CosmosClient requires. +public class BrightChainClientOptions { - using System; - using System.Collections.Generic; - using System.Net; - using System.Net.Http; - - // - // Summary: - // Defines all the configurable options that the CosmosClient requires. - public class BrightChainClientOptions - { - // - // Summary: - // Creates a new BrightChainClientOptions - public BrightChainClientOptions() { } - - // - // Summary: - // Allows optimistic batching of requests to service. Setting this option might - // impact the latency of the operations. Hence this option is recommended for non-latency - // sensitive scenarios only. - public bool AllowBulkExecution { get; set; } - // - // Summary: - // Limits the operations to the provided endpoint on the CosmosClient. - // - // Value: - // Default value is false. - // - // Remarks: - // When the value of this property is false, the SDK will automatically discover - // write and read regions, and use them when the configured application region is - // not available. When set to true, availability is limited to the endpoint specified - // on the CosmosClient constructor. Defining the Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationRegion - // or Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationPreferredRegions is - // not allowed when setting the value to true. - public bool LimitToEndpoint { get; set; } - // - // Summary: - // Get to set an optional JSON serializer. The client will use it to serialize or - // de-serialize user's cosmos request/responses. SDK owned types such as DatabaseProperties - // and ContainerProperties will always use the SDK default serializer. - //[JsonConverter(typeof(ClientOptionJsonConverter))] - //public IBrightChainSerializer Serializer { get; set; } - - // - // Summary: - // Get to set optional serializer options. - public BrightChainSerializationOptions SerializerOptions { get; set; } - // - // Summary: - // (Gateway/Https) Get or set the proxy information used for web requests. - public IWebProxy WebProxy { get; set; } - public TimeSpan? OpenTcpConnectionTimeout { get; set; } - // - // Summary: - // (Direct/TCP) Controls the amount of idle time after which unused connections - // are closed. - // - // Value: - // By default, idle connections are kept open indefinitely. Value must be greater - // than or equal to 10 minutes. Recommended values are between 20 minutes and 24 - // hours. - // - // Remarks: - // Mainly useful for sparse infrequent access to a large database account. - public TimeSpan? IdleTcpConnectionTimeout { get; set; } - // - // Summary: - // Gets or sets the flag to enable address cache refresh on TCP connection reset - // notification. - // - // Value: - // The default value is false - // - // Remarks: - // Does not apply if Microsoft.Azure.Cosmos.ConnectionMode.Gateway is used. - public bool EnableTcpConnectionEndpointRediscovery { get; set; } - // - // Summary: - // Gets or sets the boolean to only return the headers and status code in the Cosmos - // DB response for write item operation like Create, Upsert, Patch and Replace. - // Setting the option to false will cause the response to have a null resource. - // This reduces networking and CPU load by not sending the resource back over the - // network and serializing it on the client. - // - // Remarks: - // This is optimal for workloads where the returned resource is not used. - // This option can be overriden by similar property in ItemRequestOptions and TransactionalBatchItemRequestOptions - public bool? EnableContentResponseOnWrite { get; set; } - // - // Summary: - // Gets or sets the maximum number of retries in the case where the request fails - // because the Azure Cosmos DB service has applied rate limiting on the client. - // - // Value: - // The default value is 9. This means in the case where the request is rate limited, - // the same request will be issued for a maximum of 10 times to the server before - // an error is returned to the application. If the value of this property is set - // to 0, there will be no automatic retry on rate limiting requests from the client - // and the exception needs to be handled at the application level. - // - // Remarks: - // When a client is sending requests faster than the allowed rate, the service will - // return HttpStatusCode 429 (Too Many Requests) to rate limit the client. The current - // implementation in the SDK will then wait for the amount of time the service tells - // it to wait and retry after the time has elapsed. - // For more information, see Handle rate limiting/request rate too large. - public int? MaxRetryAttemptsOnRateLimitedRequests { get; set; } - // - // Summary: - // Gets the handlers run before the process - //[JsonConverter(typeof(ClientOptionJsonConverter))] - //public Collection CustomHandlers { get; } - // - // Summary: - // The SDK does a background refresh based on the time interval set to refresh the - // token credentials. This avoids latency issues because the old token is used until - // the new token is retrieved. - // - // Remarks: - // The recommended minimum value is 5 minutes. The default value is 50% of the token - // expire time. - public TimeSpan? TokenCredentialBackgroundRefreshInterval { get; set; } - // - // Summary: - // Gets the request timeout in seconds when connecting to the Azure Cosmos DB service. - // The number specifies the time to wait for response to come back from network - // peer. - // - // Value: - // Default value is 1 minute. - public TimeSpan RequestTimeout { get; set; } - // - // Summary: - // Get or set the maximum number of concurrent connections allowed for the target - // service endpoint in the Azure Cosmos DB service. - // - // Value: - // Default value is 50. - // - // Remarks: - // This setting is only applicable in Gateway mode. - public int GatewayModeMaxConnectionLimit { get; set; } - // - // Summary: - // Gets and sets the preferred regions for geo-replicated database accounts in the - // Azure Cosmos DB service. - // - // Remarks: - // When this property is specified, the SDK will use the region list in the provided - // order to define the endpoint failover order. This configuration is an alternative - // to Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationRegion, either one can - // be set but not both. - public IReadOnlyList ApplicationPreferredRegions { get; set; } - // - // Summary: - // Get or set the preferred geo-replicated region to be used for Azure Cosmos DB - // service interaction. - // - // Remarks: - // When this property is specified, the SDK prefers the region to perform operations. - // Also SDK auto-selects fallback geo-replicated regions for high availability. - // When this property is not specified, the SDK uses the write region as the preferred - // region for all operations. - public string ApplicationRegion { get; set; } - // - // Summary: - // Get or set user-agent suffix to include with every Azure Cosmos DB service interaction. - // - // Remarks: - // Setting this property after sending any request won't have any effect. - public string ApplicationName { get; set; } - // - // Summary: - // Gets or sets the maximum retry time in seconds for the Azure Cosmos DB service. - // - // Value: - // The default value is 30 seconds. - // - // Remarks: - // The minimum interval is seconds. Any interval that is smaller will be ignored. - // When a request fails due to a rate limiting error, the service sends back a response - // that contains a value indicating the client should not retry before the Microsoft.Azure.Cosmos.CosmosException.RetryAfter - // time period has elapsed. This property allows the application to set a maximum - // wait time for all retry attempts. If the cumulative wait time exceeds the this - // value, the client will stop retrying and return the error to the application. - // For more information, see Handle rate limiting/request rate too large. - public TimeSpan? MaxRetryWaitTimeOnRateLimitedRequests { get; set; } - // - // Summary: - // Gets or sets a delegate to use to obtain an HttpClient instance to be used for - // HTTPS communication. - // - // Remarks: - // HTTPS communication is used when Microsoft.Azure.Cosmos.CosmosClientOptions.ConnectionMode - // is set to Microsoft.Azure.Cosmos.ConnectionMode.Gateway for all operations and - // when Microsoft.Azure.Cosmos.CosmosClientOptions.ConnectionMode is Microsoft.Azure.Cosmos.ConnectionMode.Direct - // (default) for metadata operations. - // Useful in scenarios where the application is using a pool of HttpClient instances - // to be shared, like ASP.NET Core applications with IHttpClientFactory or Blazor - // WebAssembly applications. - // For .NET core applications the default GatewayConnectionLimit will be ignored. - // It must be set on the HttpClientHandler.MaxConnectionsPerServer to limit the - // number of connections - public Func HttpClientFactory { get; set; } - } + // + // Summary: + // Creates a new BrightChainClientOptions + + // + // Summary: + // Allows optimistic batching of requests to service. Setting this option might + // impact the latency of the operations. Hence this option is recommended for non-latency + // sensitive scenarios only. + public bool AllowBulkExecution { get; set; } + + // + // Summary: + // Limits the operations to the provided endpoint on the CosmosClient. + // + // Value: + // Default value is false. + // + // Remarks: + // When the value of this property is false, the SDK will automatically discover + // write and read regions, and use them when the configured application region is + // not available. When set to true, availability is limited to the endpoint specified + // on the CosmosClient constructor. Defining the Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationRegion + // or Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationPreferredRegions is + // not allowed when setting the value to true. + public bool LimitToEndpoint { get; set; } + // + // Summary: + // Get to set an optional JSON serializer. The client will use it to serialize or + // de-serialize user's cosmos request/responses. SDK owned types such as DatabaseProperties + // and ContainerProperties will always use the SDK default serializer. + //[JsonConverter(typeof(ClientOptionJsonConverter))] + //public IBrightChainSerializer Serializer { get; set; } + + // + // Summary: + // Get to set optional serializer options. + public BrightChainSerializationOptions SerializerOptions { get; set; } + + // + // Summary: + // (Gateway/Https) Get or set the proxy information used for web requests. + public IWebProxy WebProxy { get; set; } + + public TimeSpan? OpenTcpConnectionTimeout { get; set; } + + // + // Summary: + // (Direct/TCP) Controls the amount of idle time after which unused connections + // are closed. + // + // Value: + // By default, idle connections are kept open indefinitely. Value must be greater + // than or equal to 10 minutes. Recommended values are between 20 minutes and 24 + // hours. + // + // Remarks: + // Mainly useful for sparse infrequent access to a large database account. + public TimeSpan? IdleTcpConnectionTimeout { get; set; } + + // + // Summary: + // Gets or sets the flag to enable address cache refresh on TCP connection reset + // notification. + // + // Value: + // The default value is false + // + // Remarks: + // Does not apply if Microsoft.Azure.Cosmos.ConnectionMode.Gateway is used. + public bool EnableTcpConnectionEndpointRediscovery { get; set; } + + // + // Summary: + // Gets or sets the boolean to only return the headers and status code in the Cosmos + // DB response for write item operation like Create, Upsert, Patch and Replace. + // Setting the option to false will cause the response to have a null resource. + // This reduces networking and CPU load by not sending the resource back over the + // network and serializing it on the client. + // + // Remarks: + // This is optimal for workloads where the returned resource is not used. + // This option can be overriden by similar property in ItemRequestOptions and TransactionalBatchItemRequestOptions + public bool? EnableContentResponseOnWrite { get; set; } + + // + // Summary: + // Gets or sets the maximum number of retries in the case where the request fails + // because the Azure Cosmos DB service has applied rate limiting on the client. + // + // Value: + // The default value is 9. This means in the case where the request is rate limited, + // the same request will be issued for a maximum of 10 times to the server before + // an error is returned to the application. If the value of this property is set + // to 0, there will be no automatic retry on rate limiting requests from the client + // and the exception needs to be handled at the application level. + // + // Remarks: + // When a client is sending requests faster than the allowed rate, the service will + // return HttpStatusCode 429 (Too Many Requests) to rate limit the client. The current + // implementation in the SDK will then wait for the amount of time the service tells + // it to wait and retry after the time has elapsed. + // For more information, see Handle rate limiting/request rate too large. + public int? MaxRetryAttemptsOnRateLimitedRequests { get; set; } + + // + // Summary: + // Gets the handlers run before the process + //[JsonConverter(typeof(ClientOptionJsonConverter))] + //public Collection CustomHandlers { get; } + // + // Summary: + // The SDK does a background refresh based on the time interval set to refresh the + // token credentials. This avoids latency issues because the old token is used until + // the new token is retrieved. + // + // Remarks: + // The recommended minimum value is 5 minutes. The default value is 50% of the token + // expire time. + public TimeSpan? TokenCredentialBackgroundRefreshInterval { get; set; } + + // + // Summary: + // Gets the request timeout in seconds when connecting to the Azure Cosmos DB service. + // The number specifies the time to wait for response to come back from network + // peer. + // + // Value: + // Default value is 1 minute. + public TimeSpan RequestTimeout { get; set; } + + // + // Summary: + // Get or set the maximum number of concurrent connections allowed for the target + // service endpoint in the Azure Cosmos DB service. + // + // Value: + // Default value is 50. + // + // Remarks: + // This setting is only applicable in Gateway mode. + public int GatewayModeMaxConnectionLimit { get; set; } + + // + // Summary: + // Gets and sets the preferred regions for geo-replicated database accounts in the + // Azure Cosmos DB service. + // + // Remarks: + // When this property is specified, the SDK will use the region list in the provided + // order to define the endpoint failover order. This configuration is an alternative + // to Microsoft.Azure.Cosmos.CosmosClientOptions.ApplicationRegion, either one can + // be set but not both. + public IReadOnlyList ApplicationPreferredRegions { get; set; } + + // + // Summary: + // Get or set the preferred geo-replicated region to be used for Azure Cosmos DB + // service interaction. + // + // Remarks: + // When this property is specified, the SDK prefers the region to perform operations. + // Also SDK auto-selects fallback geo-replicated regions for high availability. + // When this property is not specified, the SDK uses the write region as the preferred + // region for all operations. + public string ApplicationRegion { get; set; } + + // + // Summary: + // Get or set user-agent suffix to include with every Azure Cosmos DB service interaction. + // + // Remarks: + // Setting this property after sending any request won't have any effect. + public string ApplicationName { get; set; } + + // + // Summary: + // Gets or sets the maximum retry time in seconds for the Azure Cosmos DB service. + // + // Value: + // The default value is 30 seconds. + // + // Remarks: + // The minimum interval is seconds. Any interval that is smaller will be ignored. + // When a request fails due to a rate limiting error, the service sends back a response + // that contains a value indicating the client should not retry before the Microsoft.Azure.Cosmos.CosmosException.RetryAfter + // time period has elapsed. This property allows the application to set a maximum + // wait time for all retry attempts. If the cumulative wait time exceeds the this + // value, the client will stop retrying and return the error to the application. + // For more information, see Handle rate limiting/request rate too large. + public TimeSpan? MaxRetryWaitTimeOnRateLimitedRequests { get; set; } + + // + // Summary: + // Gets or sets a delegate to use to obtain an HttpClient instance to be used for + // HTTPS communication. + // + // Remarks: + // HTTPS communication is used when Microsoft.Azure.Cosmos.CosmosClientOptions.ConnectionMode + // is set to Microsoft.Azure.Cosmos.ConnectionMode.Gateway for all operations and + // when Microsoft.Azure.Cosmos.CosmosClientOptions.ConnectionMode is Microsoft.Azure.Cosmos.ConnectionMode.Direct + // (default) for metadata operations. + // Useful in scenarios where the application is using a pool of HttpClient instances + // to be shared, like ASP.NET Core applications with IHttpClientFactory or Blazor + // WebAssembly applications. + // For .NET core applications the default GatewayConnectionLimit will be ignored. + // It must be set on the HttpClientHandler.MaxConnectionsPerServer to limit the + // number of connections + public Func HttpClientFactory { get; set; } } diff --git a/src/BrightChain.Engine.Client/BrightChainSerializationOptions.cs b/src/BrightChain.Engine.Client/BrightChainSerializationOptions.cs old mode 100644 new mode 100755 index 3900875d..4b35082d --- a/src/BrightChain.Engine.Client/BrightChainSerializationOptions.cs +++ b/src/BrightChain.Engine.Client/BrightChainSerializationOptions.cs @@ -1,25 +1,24 @@ -namespace BrightChain.Engine.Client +namespace BrightChain.Engine.Client; + +public class BrightChainSerializationOptions { - public class BrightChainSerializationOptions - { - // - // Summary: - // Create an instance of BrightChainSerializationOptions with default values - public BrightChainSerializationOptions() { } + // + // Summary: + // Create an instance of BrightChainSerializationOptions with default values + + // + // Summary: + // Gets or sets if the serializer should ignore null properties + // + // Remarks: + // The default value is false + public bool IgnoreNullValues { get; set; } - // - // Summary: - // Gets or sets if the serializer should ignore null properties - // - // Remarks: - // The default value is false - public bool IgnoreNullValues { get; set; } - // - // Summary: - // Gets or sets if the serializer should use indentation - // - // Remarks: - // The default value is false - public bool Indented { get; set; } - } + // + // Summary: + // Gets or sets if the serializer should use indentation + // + // Remarks: + // The default value is false + public bool Indented { get; set; } } diff --git a/src/BrightChain.Engine.Quorum b/src/BrightChain.Engine.Quorum new file mode 160000 index 00000000..5f275941 --- /dev/null +++ b/src/BrightChain.Engine.Quorum @@ -0,0 +1 @@ +Subproject commit 5f27594151ab52aa02525972fb15a9e80a984492 diff --git a/src/BrightChain.Engine/BrightChain.Engine.csproj b/src/BrightChain.Engine/BrightChain.Engine.csproj old mode 100644 new mode 100755 index 71c2459b..a2959861 --- a/src/BrightChain.Engine/BrightChain.Engine.csproj +++ b/src/BrightChain.Engine/BrightChain.Engine.csproj @@ -1,100 +1,107 @@  - - net6.0 - true - true - 0.0.0.6 - 0.0.0.6 - 0.0.0.6 - BrightChain: The Revolution(ary) Network - (c) Jessica Mulein, The Revolution Network, BrightChain 2021 - true - Apache-2.0 - https://apidocs.brightchain.org/ - https://github.com/BrightChain/BrightChain - preview - BrightChain.Engine - BrightChain.Engine - Library - true - + + net6.0 + true + true + 0.0.0.6 + 0.0.0.6 + 0.0.0.6 + BrightChain: The Revolution(ary) Network + (c) Jessica Mulein, The Revolution Network, BrightChain 2021 + true + Apache-2.0 + https://apidocs.brightchain.org/ + https://github.com/BrightChain/BrightChain + preview + BrightChain.Engine + BrightChain.Engine + Library + true + - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + - - - + + + - - - - + + + + + - - - PreserveNewest - - - PreserveNewest - - + + + PreserveNewest + + + PreserveNewest + + + + + + + + + diff --git a/src/BrightChain.Engine/BrightChain.Engine.nuspec b/src/BrightChain.Engine/BrightChain.Engine.nuspec old mode 100644 new mode 100755 index 74e3dce0..b961b107 --- a/src/BrightChain.Engine/BrightChain.Engine.nuspec +++ b/src/BrightChain.Engine/BrightChain.Engine.nuspec @@ -16,10 +16,10 @@ --> jessicamulein - + http://github.com/BrightChain/BrightChain - + Apache-2.0 @@ -49,54 +49,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/src/BrightChain.Engine/Enumerations/BlockDataType.cs b/src/BrightChain.Engine/Enumerations/BlockDataType.cs old mode 100644 new mode 100755 index fa072ee7..021e528a --- a/src/BrightChain.Engine/Enumerations/BlockDataType.cs +++ b/src/BrightChain.Engine/Enumerations/BlockDataType.cs @@ -1,8 +1,7 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +public enum BlockDataType { - public enum BlockDataType - { - Stored, - Pi - } + Stored, + Pi, } diff --git a/src/BrightChain.Engine/Enumerations/BlockLocationType.cs b/src/BrightChain.Engine/Enumerations/BlockLocationType.cs new file mode 100755 index 00000000..f40160ca --- /dev/null +++ b/src/BrightChain.Engine/Enumerations/BlockLocationType.cs @@ -0,0 +1,7 @@ +namespace BrightChain.Engine.Enumerations; + +public enum BlockLocationType +{ + LocalDirectory, + LocalFasterKV, +} diff --git a/src/BrightChain.Engine/Enumerations/BlockSize.cs b/src/BrightChain.Engine/Enumerations/BlockSize.cs old mode 100644 new mode 100755 index ab17b704..2a09fbb5 --- a/src/BrightChain.Engine/Enumerations/BlockSize.cs +++ b/src/BrightChain.Engine/Enumerations/BlockSize.cs @@ -1,49 +1,48 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +/// +/// List of the pre-specified block sizes this node supports +/// The BlockSizeMap class contains the map to the actual sizes. +/// +public enum BlockSize { /// - /// List of the pre-specified block sizes this node supports - /// The BlockSizeMap class contains the map to the actual sizes. - /// - public enum BlockSize - { - /// - /// Invalid/indeterminate/unknown block size. - /// - Unknown, - - /// - /// Tiniest block size, best for keys. 128b. - /// - Nano, - - /// - /// Best for extremely small messages. 256b. - /// - Micro, - - /// - /// Message size, such as a small data blob, currently 512b. - /// - Message, - - /// - /// Tiny size, such as smaller messages and configs, currently 1K. - /// - Tiny, - - /// - /// Small size, such as small data files up to a mb or so depending on desired block count, currently 4K. - /// - Small, - - /// - /// Medium size, such as medium data files up to 5-100mb, currently 1M. - /// - Medium, - - /// - /// Large size, such as large data files over 4M up to many terabytes. - /// - Large, - } + /// Invalid/indeterminate/unknown block size. + /// + Unknown, + + /// + /// Tiniest block size, best for keys. 128b. + /// + Nano, + + /// + /// Best for extremely small messages. 256b. + /// + Micro, + + /// + /// Message size, such as a small data blob, currently 512b. + /// + Message, + + /// + /// Tiny size, such as smaller messages and configs, currently 1K. + /// + Tiny, + + /// + /// Small size, such as small data files up to a mb or so depending on desired block count, currently 4K. + /// + Small, + + /// + /// Medium size, such as medium data files up to 5-100mb, currently 1M. + /// + Medium, + + /// + /// Large size, such as large data files over 4M up to many terabytes. + /// + Large, } diff --git a/src/BrightChain.Engine/Enumerations/BrightMailBoxType.cs b/src/BrightChain.Engine/Enumerations/BrightMailBoxType.cs old mode 100644 new mode 100755 index 48012c77..7e328a5f --- a/src/BrightChain.Engine/Enumerations/BrightMailBoxType.cs +++ b/src/BrightChain.Engine/Enumerations/BrightMailBoxType.cs @@ -1,8 +1,7 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +public enum BrightMailBoxType { - public enum BrightMailBoxType - { - Received, - Sent, - } + Received, + Sent, } diff --git a/src/BrightChain.Engine/Enumerations/BrightMessageType.cs b/src/BrightChain.Engine/Enumerations/BrightMessageType.cs old mode 100644 new mode 100755 index e9193a47..829c3a5a --- a/src/BrightChain.Engine/Enumerations/BrightMessageType.cs +++ b/src/BrightChain.Engine/Enumerations/BrightMessageType.cs @@ -1,9 +1,8 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +public enum BrightMessageType { - public enum BrightMessageType - { - Notification, - BrightNote, - BrightMail, - } + Notification, + BrightNote, + BrightMail, } diff --git a/src/BrightChain.Engine/Enumerations/BrightTagType.cs b/src/BrightChain.Engine/Enumerations/BrightTagType.cs old mode 100644 new mode 100755 index 497dc21c..46f1c845 --- a/src/BrightChain.Engine/Enumerations/BrightTagType.cs +++ b/src/BrightChain.Engine/Enumerations/BrightTagType.cs @@ -1,9 +1,8 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +public enum BrightTagType { - public enum BrightTagType - { - Filename, - UserAssigned, - SystemAssigned, - } + Filename, + UserAssigned, + SystemAssigned, } diff --git a/src/BrightChain.Engine/Enumerations/CacheDeviceType.cs b/src/BrightChain.Engine/Enumerations/CacheDeviceType.cs new file mode 100755 index 00000000..0e0421a5 --- /dev/null +++ b/src/BrightChain.Engine/Enumerations/CacheDeviceType.cs @@ -0,0 +1,7 @@ +namespace BrightChain.Engine.Faster.Enumerations; + +public enum CacheDeviceType +{ + Log, + Data, +} diff --git a/src/BrightChain.Engine/Enumerations/FasterCheckpointOperation.cs b/src/BrightChain.Engine/Enumerations/FasterCheckpointOperation.cs new file mode 100755 index 00000000..3072bf63 --- /dev/null +++ b/src/BrightChain.Engine/Enumerations/FasterCheckpointOperation.cs @@ -0,0 +1,8 @@ +namespace BrightChain.Engine.Faster.Enumerations; + +public enum FasterCheckpointOperation +{ + Full, + Hybrid, + Index, +} diff --git a/src/BrightChain.Engine/Enumerations/NodeFeatures.cs b/src/BrightChain.Engine/Enumerations/NodeFeatures.cs old mode 100644 new mode 100755 index ee72c1b1..71d5a311 --- a/src/BrightChain.Engine/Enumerations/NodeFeatures.cs +++ b/src/BrightChain.Engine/Enumerations/NodeFeatures.cs @@ -1,63 +1,62 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +/// +/// Exhaustive list of supported node protocol sources and destinations. +/// +public enum NodeFeatures { /// - /// Exhaustive list of supported node protocol sources and destinations. - /// - public enum NodeFeatures - { - /// - /// This node consumes or offers RandomizerBlocks. - /// - RandomizerCache, - - /// - /// This node consumes or offers public MemoryCache. - /// - MemoryCache, - - /// - /// This node consumes or offers HeapLowPriority storage blocks. - /// - HeapLowStorage, - - /// - /// This node consumes or offers HeapHighPriority storage blocks. - /// - HeapHighStorage, - - /// - /// This node consumes or offers non-replicated magnetic storage. - /// - BasicLocal, - - /// - /// This node consumes or offers non-replicated SSD storage. - /// - FastLocal, - - /// - /// This node consumes or offers replicated magnetic storage. Mirror or better. - /// - RedundantBasicLocal, - - /// - /// This node consumes or offers replicated SSD storage. Mirror or better. - /// - RedundantFastLocal, - - /// - /// This node consumes or offers quorum block validation. - /// - BlockValidation, - - /// - /// This node consumes or offers signed block JavaScript (NodeJS) execution/validation. - /// - JavaScriptCodeExecution, - - /// - /// This node consumes or offers signed block CLR/CIL (C#, VB.NET, etc, even PHP via PeachPie). - /// - CilClrCodeExecution, - } + /// This node consumes or offers RandomizerBlocks. + /// + RandomizerCache, + + /// + /// This node consumes or offers public MemoryCache. + /// + MemoryCache, + + /// + /// This node consumes or offers HeapLowPriority storage blocks. + /// + HeapLowStorage, + + /// + /// This node consumes or offers HeapHighPriority storage blocks. + /// + HeapHighStorage, + + /// + /// This node consumes or offers non-replicated magnetic storage. + /// + BasicLocal, + + /// + /// This node consumes or offers non-replicated SSD storage. + /// + FastLocal, + + /// + /// This node consumes or offers replicated magnetic storage. Mirror or better. + /// + RedundantBasicLocal, + + /// + /// This node consumes or offers replicated SSD storage. Mirror or better. + /// + RedundantFastLocal, + + /// + /// This node consumes or offers quorum block validation. + /// + BlockValidation, + + /// + /// This node consumes or offers signed block JavaScript (NodeJS) execution/validation. + /// + JavaScriptCodeExecution, + + /// + /// This node consumes or offers signed block CLR/CIL (C#, VB.NET, etc, even PHP via PeachPie). + /// + CilClrCodeExecution, } diff --git a/src/BrightChain.Engine/Enumerations/RecipientType.cs b/src/BrightChain.Engine/Enumerations/RecipientType.cs old mode 100644 new mode 100755 index d481509d..2a763c13 --- a/src/BrightChain.Engine/Enumerations/RecipientType.cs +++ b/src/BrightChain.Engine/Enumerations/RecipientType.cs @@ -1,9 +1,8 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +public enum RecipientType { - public enum RecipientType - { - To, - CC, - BCC, - } + To, + CC, + BCC, } diff --git a/src/BrightChain.Engine/Enumerations/RedundancyContractType.cs b/src/BrightChain.Engine/Enumerations/RedundancyContractType.cs old mode 100644 new mode 100755 index 66697d2f..c9e5dddc --- a/src/BrightChain.Engine/Enumerations/RedundancyContractType.cs +++ b/src/BrightChain.Engine/Enumerations/RedundancyContractType.cs @@ -1,39 +1,38 @@ -namespace BrightChain.Engine.Enumerations +namespace BrightChain.Engine.Enumerations; + +/// +/// Determines the minimum replication effort required/desired for a given block +/// TODO: these were just a thought. +/// +public enum RedundancyContractType { /// - /// Determines the minimum replication effort required/desired for a given block - /// TODO: these were just a thought. + /// Invalid or unknown type /// - public enum RedundancyContractType - { - /// - /// Invalid or unknown type - /// - Unknown, + Unknown, - /// - /// Stored on the local node only - /// - LocalNone, + /// + /// Stored on the local node only + /// + LocalNone, - /// - /// Stored locally in at least one cache - /// - LocalMirror, + /// + /// Stored locally in at least one cache + /// + LocalMirror, - /// - /// Stored in BrightChain with automatic replication based on consumption - /// - HeapAuto, + /// + /// Stored in BrightChain with automatic replication based on consumption + /// + HeapAuto, - /// - /// Stored in BrightChain with automatic replication that is not as guaranteed - /// - HeapLowPriority, + /// + /// Stored in BrightChain with automatic replication that is not as guaranteed + /// + HeapLowPriority, - /// - /// Stored in BrightChain with automatic replication at the highest priority - /// - HeapHighPriority, - } + /// + /// Stored in BrightChain with automatic replication at the highest priority + /// + HeapHighPriority, } diff --git a/src/BrightChain.Engine/Enumerations/ResourceUriType.cs b/src/BrightChain.Engine/Enumerations/ResourceUriType.cs new file mode 100755 index 00000000..9afa8e15 --- /dev/null +++ b/src/BrightChain.Engine/Enumerations/ResourceUriType.cs @@ -0,0 +1,8 @@ +namespace BrightChain.Engine.Enumerations; + +public enum ResourceUriType +{ + Single, + Collection, + BrightChainClient, +} diff --git a/src/BrightChain.Engine/Enumerations/TransactionStatus.cs b/src/BrightChain.Engine/Enumerations/TransactionStatus.cs old mode 100644 new mode 100755 index a4c2b00e..c91c02bf --- a/src/BrightChain.Engine/Enumerations/TransactionStatus.cs +++ b/src/BrightChain.Engine/Enumerations/TransactionStatus.cs @@ -3,44 +3,48 @@ namespace BrightChain.Engine.Enumerations; public enum TransactionStatus { /// - /// This block should not be written to disk. - /// initial state, may be added to Memory dictionary only. + /// This block should not be written to disk. + /// initial state, may be added to Memory dictionary only. /// DoNotWrite, /// - /// This block has not been written to disk, but should be. - /// Memory Dictionary only. + /// This block has not been written to disk, but should be. + /// Memory Dictionary only. /// Uncommitted, /// - /// This block explicitly rolled back. Do not write. - /// Effectively dropped. Removed from fasterKV. Memory dictionary only. + /// This block explicitly rolled back. Do not write. + /// Effectively dropped. Removed from fasterKV. Memory dictionary only. /// RolledBackDoNotWrite, /// - /// Another block was rolled back, causing this block to need to be rewritten. - /// Memory dictionary only, pending re-add to FasterKV. + /// Another block was rolled back, causing this block to need to be rewritten. + /// Memory dictionary only, pending re-add to FasterKV. /// RolledBackRewrite, /// - /// Written to disk but transaction not confirmed/completed. FasterKV + MemoryDict. + /// Written to disk but transaction not confirmed/completed. FasterKV + MemoryDict. /// WrittenUnconfirmed, /// - /// Confirmed written to disk and session completed successfully. - /// Removed from MemoryDictionary. FasterKV only. + /// Confirmed written to disk and session completed successfully. + /// Removed from MemoryDictionary. FasterKV only. /// Committed, /// - /// Confirmed removed from disk and session completed successfully. - /// Removed from memory dictionary and fasterkv. - /// Only copies remaining should be variable references to original object. + /// Confirmed removed from disk and session completed successfully. + /// Removed from memory dictionary and fasterkv. + /// Only copies remaining should be variable references to original object. /// DroppedCommitted, + + /// + /// + DroppedUncommitted, } diff --git a/src/BrightChain.Engine/Exceptions/BrightChainException.cs b/src/BrightChain.Engine/Exceptions/BrightChainException.cs old mode 100644 new mode 100755 index 8a9c6191..3266f4d1 --- a/src/BrightChain.Engine/Exceptions/BrightChainException.cs +++ b/src/BrightChain.Engine/Exceptions/BrightChainException.cs @@ -1,115 +1,116 @@ -namespace BrightChain.Engine.Exceptions +using System; +using System.Diagnostics; +using System.Net; +using System.Net.Http.Headers; + +namespace BrightChain.Engine.Exceptions; + +/// +/// Base class for all BrightChain exceptions +/// +public class BrightChainException : Exception { - using System; - using System.Diagnostics; - using System.Net; - using System.Net.Http.Headers; + public BrightChainException(string message) : base(message: message) + { + this.StackTrace = new StackTrace().ToString(); + } - /// - /// Base class for all BrightChain exceptions - /// - public class BrightChainException : Exception + // + // Summary: + // Create a BrightChainException + // + // Parameters: + // message: + // The message associated with the exception. + // + // statusCode: + // The System.Net.HttpStatusCode associated with the exception. + // + // subStatusCode: + // A sub status code associated with the exception. + // + // activityId: + // An ActivityId associated with the operation that generated the exception. + // + // requestCharge: + // A request charge associated with the operation that generated the exception. + public BrightChainException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge) { - public BrightChainException(string message) : base(message) - { - this.StackTrace = new StackTrace().ToString(); - } + } - // - // Summary: - // Create a BrightChainException - // - // Parameters: - // message: - // The message associated with the exception. - // - // statusCode: - // The System.Net.HttpStatusCode associated with the exception. - // - // subStatusCode: - // A sub status code associated with the exception. - // - // activityId: - // An ActivityId associated with the operation that generated the exception. - // - // requestCharge: - // A request charge associated with the operation that generated the exception. - public BrightChainException(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge) - { + // + // Summary: + // The body of the bright chain response message as a string + public virtual string ResponseBody { get; } - } + // + // Summary: + // Gets the request completion status code from the BrightChain service. + // + // Value: + // The request completion status code + public virtual HttpStatusCode StatusCode { get; } - // - // Summary: - // The body of the bright chain response message as a string - public virtual string ResponseBody { get; } - // - // Summary: - // Gets the request completion status code from the BrightChain service. - // - // Value: - // The request completion status code - public virtual HttpStatusCode StatusCode { get; } - // - // Summary: - // Gets the request completion sub status code from the BrightChain service. - // - // Value: - // The request completion status code - public virtual int SubStatusCode { get; } - // - // Summary: - // Gets the request charge for this request from the BrightChain service. - // - // Value: - // The request charge measured in request units. - public virtual double RequestCharge { get; } - // - // Summary: - // Gets the activity ID for the request from the BrightChain service. - // - // Value: - // The activity ID for the request. - public virtual string ActivityId { get; } - // - // Summary: - // Gets the retry after time. This tells how long a request should wait before doing - // a retry. - public virtual TimeSpan? RetryAfter { get; } + // + // Summary: + // Gets the request completion sub status code from the BrightChain service. + // + // Value: + // The request completion status code + public virtual int SubStatusCode { get; } - // - // Summary: - // Gets the response headers - public virtual HttpHeaders Headers { get; } - public override string StackTrace { get; } + // + // Summary: + // Gets the request charge for this request from the BrightChain service. + // + // Value: + // The request charge measured in request units. + public virtual double RequestCharge { get; } - // - // Summary: - // Create a custom string with all the relevant exception information - // - // Returns: - // A string representation of the exception. - public override string ToString() - { - return base.ToString(); - } + // + // Summary: + // Gets the activity ID for the request from the BrightChain service. + // + // Value: + // The activity ID for the request. + public virtual string ActivityId { get; } - // - // Summary: - // Try to get a header from the brightchain response message - // - // Parameters: - // headerName: - // - // value: - // - // Returns: - // A value indicating if the header was read. - public virtual bool TryGetHeader(string headerName, out string value) - { - throw new NotImplementedException(); - } - } -} + // + // Summary: + // Gets the retry after time. This tells how long a request should wait before doing + // a retry. + public virtual TimeSpan? RetryAfter { get; } + // + // Summary: + // Gets the response headers + public virtual HttpHeaders Headers { get; } + public override string StackTrace { get; } + // + // Summary: + // Create a custom string with all the relevant exception information + // + // Returns: + // A string representation of the exception. + public override string ToString() + { + return base.ToString(); + } + + // + // Summary: + // Try to get a header from the brightchain response message + // + // Parameters: + // headerName: + // + // value: + // + // Returns: + // A value indicating if the header was read. + public virtual bool TryGetHeader(string headerName, out string value) + { + throw new NotImplementedException(); + } +} diff --git a/src/BrightChain.Engine/Exceptions/BrightChainExceptionImpossible.cs b/src/BrightChain.Engine/Exceptions/BrightChainExceptionImpossible.cs old mode 100644 new mode 100755 index 86d8aa0e..5250f54e --- a/src/BrightChain.Engine/Exceptions/BrightChainExceptionImpossible.cs +++ b/src/BrightChain.Engine/Exceptions/BrightChainExceptionImpossible.cs @@ -1,18 +1,22 @@ using System.Net; -namespace BrightChain.Engine.Exceptions +namespace BrightChain.Engine.Exceptions; + +/// +/// Base class for all BrightChain exceptions +/// +public class BrightChainExceptionImpossible : BrightChainException { - /// - /// Base class for all BrightChain exceptions - /// - public class BrightChainExceptionImpossible : BrightChainException + public BrightChainExceptionImpossible(string message) : base(message: message) { - public BrightChainExceptionImpossible(string message) : base(message) - { - } + } - public BrightChainExceptionImpossible(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, double requestCharge) : base(message, statusCode, subStatusCode, activityId, requestCharge) - { - } + public BrightChainExceptionImpossible(string message, HttpStatusCode statusCode, int subStatusCode, string activityId, + double requestCharge) : base(message: message, + statusCode: statusCode, + subStatusCode: subStatusCode, + activityId: activityId, + requestCharge: requestCharge) + { } } diff --git a/src/BrightChain.Engine/Exceptions/BrightChainValidationEnumerableException.cs b/src/BrightChain.Engine/Exceptions/BrightChainValidationEnumerableException.cs old mode 100644 new mode 100755 index fea97b25..8ef05536 --- a/src/BrightChain.Engine/Exceptions/BrightChainValidationEnumerableException.cs +++ b/src/BrightChain.Engine/Exceptions/BrightChainValidationEnumerableException.cs @@ -1,18 +1,17 @@ -namespace BrightChain.Engine.Exceptions -{ - using System.Collections.Generic; +using System.Collections.Generic; - /// - /// Base class for all BrightChain exceptions - /// - public class BrightChainValidationEnumerableException : BrightChainException - { - public IEnumerable Exceptions { get; protected set; } +namespace BrightChain.Engine.Exceptions; - public BrightChainValidationEnumerableException(IEnumerable exceptions, string message) - : base(message) - { - this.Exceptions = exceptions; - } +/// +/// Base class for all BrightChain exceptions +/// +public class BrightChainValidationEnumerableException : BrightChainException +{ + public BrightChainValidationEnumerableException(IEnumerable exceptions, string message) + : base(message: message) + { + this.Exceptions = exceptions; } + + public IEnumerable Exceptions { get; protected set; } } diff --git a/src/BrightChain.Engine/Exceptions/BrightChainValidationException.cs b/src/BrightChain.Engine/Exceptions/BrightChainValidationException.cs old mode 100644 new mode 100755 index 2390bd90..f5760921 --- a/src/BrightChain.Engine/Exceptions/BrightChainValidationException.cs +++ b/src/BrightChain.Engine/Exceptions/BrightChainValidationException.cs @@ -1,26 +1,27 @@ -namespace BrightChain.Engine.Exceptions +using System; + +namespace BrightChain.Engine.Exceptions; + +/// +/// Base class for all BrightChain exceptions +/// +public class BrightChainValidationException : BrightChainException { + public BrightChainValidationException(string element, string message) : base(message: message) + { + this.Element = element; + } + /// - /// Base class for all BrightChain exceptions + /// TODO: Why is this here? /// - public class BrightChainValidationException : BrightChainException + /// + /// + public BrightChainValidationException(string element, object _) : base(message: "BOGUS!") { - public string Element { get; protected set; } - - public BrightChainValidationException(string element, string message) : base(message) - { - this.Element = element; - } - - /// - /// TODO: Why is this here? - /// - /// - /// - public BrightChainValidationException(string element, object _) : base("BOGUS!") - { - this.Element = element; - throw new System.Exception("WHY?"); - } + this.Element = element; + throw new Exception(message: "WHY?"); } + + public string Element { get; protected set; } } diff --git a/src/BrightChain.Engine/Extensions/BlockValidationExtensions.cs b/src/BrightChain.Engine/Extensions/BlockValidationExtensions.cs old mode 100644 new mode 100755 index 18c7e1d3..31120486 --- a/src/BrightChain.Engine/Extensions/BlockValidationExtensions.cs +++ b/src/BrightChain.Engine/Extensions/BlockValidationExtensions.cs @@ -1,95 +1,104 @@ -namespace BrightChain.Engine.Extensions +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Extensions; + +public static class BlockValidationExtensions { - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Hashes; - - public static class BlockValidationExtensions + /// + /// return true or throw an exception with the error + /// + /// + public static bool PerformValidation(this Block block, out IEnumerable validationExceptions) { - /// - /// return true or throw an exception with the error - /// - /// - public static bool PerformValidation(this Block block, out IEnumerable validationExceptions) + var exceptions = new List(); + + if (block.BlockSize == BlockSize.Unknown) { - var exceptions = new List(); - - if (block.BlockSize == BlockSize.Unknown) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.BlockSize), - string.Format("{0} is invalid: {1}", nameof(block.BlockSize), block.BlockSize.ToString()))); - } - - if (!BlockSizeMap.LengthIsValid(block.Bytes.Length)) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.Bytes.Length), - string.Format("{0} is not a valid data length", nameof(block.Bytes.Length)))); - } - - if (block.BlockSize != BlockSizeMap.BlockSize(block.Bytes.Length)) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.BlockSize), - string.Format( - "{0} is invalid: {1}, actual {2} bytes", - nameof(block.BlockSize), - block.BlockSize.ToString(), - block.Bytes.Length))); - } - - var recomputedHash = new BlockHash(block); - if (block.Id != recomputedHash) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.Id), - string.Format("{0} is invalid: {1}, actual {2}", nameof(block.Id), block.Id.ToString(), recomputedHash.ToString()))); - } - - if (block.StorageContract.ByteCount != block.Bytes.Length) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.StorageContract.ByteCount), - string.Format("{0} length {1} does not match data length of {2} bytes", nameof(block.StorageContract.ByteCount), - block.StorageContract.ByteCount, block.Bytes.Length))); - } - - if (!block.StorageContract.Equals(block.StorageContract)) - { - exceptions.Add(new BrightChainValidationException( - nameof(block.StorageContract), - string.Format("{0} on redundancy contract does not match StorageContract", nameof(block.StorageContract)))); - } - - // TODO: Validate signature - - // fill the "out" variable - validationExceptions = exceptions.ToArray(); - - return exceptions.Count == 0; + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.BlockSize), + message: string.Format(format: "{0} is invalid: {1}", + arg0: nameof(block.BlockSize), + arg1: block.BlockSize.ToString()))); } - public static bool PerformValidation(this ConstituentBlockListBlock cblBlock, - out IEnumerable validationExceptions) + if (!BlockSizeMap.LengthIsValid(length: block.Bytes.Length)) { - var baseValidation = PerformValidation(cblBlock.AsBlock, out validationExceptions); - if (!baseValidation) - { - return baseValidation; - } + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.Bytes.Length), + message: string.Format(format: "{0} is not a valid data length", + arg0: nameof(block.Bytes.Length)))); + } - var exceptions = new List(); + if (block.BlockSize != BlockSizeMap.BlockSize(blockSize: block.Bytes.Length)) + { + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.BlockSize), + message: string.Format( + format: "{0} is invalid: {1}, actual {2} bytes", + arg0: nameof(block.BlockSize), + arg1: block.BlockSize.ToString(), + arg2: block.Bytes.Length))); + } - // TODO: validate all data against SourceId + var recomputedHash = new BlockHash(block: block); + if (block.Id != recomputedHash) + { + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.Id), + message: string.Format(format: "{0} is invalid: {1}, actual {2}", + arg0: nameof(block.Id), + arg1: block.Id.ToString(), + arg2: recomputedHash.ToString()))); + } - // fill the "out" variable - validationExceptions = exceptions.ToArray(); + if (block.StorageContract.ByteCount != block.Bytes.Length) + { + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.StorageContract.ByteCount), + message: string.Format(format: "{0} length {1} does not match data length of {2} bytes", + arg0: nameof(block.StorageContract.ByteCount), + arg1: block.StorageContract.ByteCount, + arg2: block.Bytes.Length))); + } - return exceptions.Count == 0; + if (!block.StorageContract.Equals(other: block.StorageContract)) + { + exceptions.Add(item: new BrightChainValidationException( + element: nameof(block.StorageContract), + message: string.Format(format: "{0} on redundancy contract does not match StorageContract", + arg0: nameof(block.StorageContract)))); } + + // TODO: Validate signature + + // fill the "out" variable + validationExceptions = exceptions.ToArray(); + + return exceptions.Count == 0; + } + + public static bool PerformValidation(this ConstituentBlockListBlock cblBlock, + out IEnumerable validationExceptions) + { + var baseValidation = PerformValidation(block: cblBlock.AsBlock, + validationExceptions: out validationExceptions); + if (!baseValidation) + { + return baseValidation; + } + + var exceptions = new List(); + + // TODO: validate all data against SourceId + + // fill the "out" variable + validationExceptions = exceptions.ToArray(); + + return exceptions.Count == 0; } } diff --git a/src/BrightChain.Engine/Extensions/JsonDocumentExtensions.cs b/src/BrightChain.Engine/Extensions/JsonDocumentExtensions.cs old mode 100644 new mode 100755 index 87d300bd..df6bd3f5 --- a/src/BrightChain.Engine/Extensions/JsonDocumentExtensions.cs +++ b/src/BrightChain.Engine/Extensions/JsonDocumentExtensions.cs @@ -1,13 +1,13 @@ - +using System; +using System.Buffers; +using System.Text.Json; + namespace BrightChain.Engine.Extensions { - using System; - using System.Buffers; - using System.Text.Json; - public static class JsonDocumentExtensions { - #region https://stackoverflow.com/a/61047681/4009129 + #region https: //stackoverflow.com/a/61047681/4009129 + public static T ToObject(this JsonElement element, JsonSerializerOptions options = null) { var bufferWriter = new ArrayBufferWriter(); @@ -16,7 +16,8 @@ public static T ToObject(this JsonElement element, JsonSerializerOptions opti element.WriteTo(writer); } - return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, options); + return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, + options); } public static T ToObject(this JsonDocument document, JsonSerializerOptions options = null) @@ -37,7 +38,9 @@ public static object ToObject(this JsonElement element, Type returnType, JsonSer element.WriteTo(writer); } - return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, returnType, options); + return JsonSerializer.Deserialize(bufferWriter.WrittenSpan, + returnType, + options); } public static object ToObject(this JsonDocument document, Type returnType, JsonSerializerOptions options = null) @@ -47,8 +50,10 @@ public static object ToObject(this JsonDocument document, Type returnType, JsonS throw new ArgumentNullException(nameof(document)); } - return document.RootElement.ToObject(returnType, options); + return document.RootElement.ToObject(returnType, + options); } + #endregion } } diff --git a/src/BrightChain.Engine/Factories/HashJsonFactory.cs b/src/BrightChain.Engine/Factories/HashJsonFactory.cs old mode 100644 new mode 100755 index 0bbd2f3f..03ecd48f --- a/src/BrightChain.Engine/Factories/HashJsonFactory.cs +++ b/src/BrightChain.Engine/Factories/HashJsonFactory.cs @@ -1,158 +1,164 @@ -namespace BrightChain.Engine.Factories +using System; +using System.Globalization; +using System.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Factories; + +public class HashJsonFactory : JsonConverterFactory { - using System; - using System.Linq; - using System.Text.Json; - using System.Text.Json.Serialization; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - - public class HashJsonFactory : JsonConverterFactory + public static JsonSerializerOptions NewSerializerOptions() { - public static JsonSerializerOptions NewSerializerOptions() + return new JsonSerializerOptions { - return new JsonSerializerOptions - { - PropertyNamingPolicy = null, - AllowTrailingCommas = true, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - WriteIndented = false, - Converters = - { - new HashJsonFactory(), - }, - }; - } + PropertyNamingPolicy = null, + AllowTrailingCommas = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + WriteIndented = false, + Converters = {new HashJsonFactory()}, + }; + } + + private static byte[] StringToByteArray(string hex) + { + return Enumerable.Range(start: 0, + count: hex.Length) + .Where(predicate: x => x % 2 == 0) + .Select(selector: x => Convert.ToByte(value: hex.Substring(startIndex: x, + length: 2), + fromBase: 16)) + .ToArray(); + } - private static byte[] StringToByteArray(string hex) + public override bool CanConvert(Type typeToConvert) + { + return typeToConvert == typeof(DataHash) || typeToConvert == typeof(BlockHash); + } + + public override JsonConverter CreateConverter( + Type type, + JsonSerializerOptions options) + { + var isBlock = type == typeof(BlockHash); + if (type == typeof(DataHash) || isBlock) { - return Enumerable.Range(0, hex.Length) - .Where(x => x % 2 == 0) - .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) - .ToArray(); + return new DataHashConverter(options: options, + isBlock: isBlock); } - public override bool CanConvert(Type typeToConvert) + throw new Exception(); + } + + private class DataHashConverter : + JsonConverter + { + private bool isBlock; + + public DataHashConverter(JsonSerializerOptions options, bool isBlock) { - return typeToConvert == typeof(DataHash) || typeToConvert == typeof(BlockHash); + this.isBlock = isBlock; } - public override JsonConverter CreateConverter( - Type type, + public override DataHash Read( + ref Utf8JsonReader reader, + Type typeToConvert, JsonSerializerOptions options) { - var isBlock = type == typeof(BlockHash); - if (type == typeof(DataHash) || isBlock) + if (reader.TokenType != JsonTokenType.StartObject) { - return new DataHashConverter(options, isBlock); + throw new JsonException(); } - throw new Exception(); - } + DataHash dataHash = null; + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + return dataHash; + } - private class DataHashConverter : - JsonConverter - { - private bool isBlock; + if (reader.TokenType != JsonTokenType.PropertyName) + { + throw new JsonException(); + } - public DataHashConverter(JsonSerializerOptions options, bool isBlock) - { - this.isBlock = isBlock; - } + var firstPropertyName = reader.GetString(); + if (firstPropertyName == "s") + { + this.isBlock = true; + } + else if (firstPropertyName != "l") + { + throw new JsonException(); + } - public override DataHash Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) - { - if (reader.TokenType != JsonTokenType.StartObject) + reader.Read(); + + var dataLength = this.isBlock ? reader.GetInt32() : reader.GetInt64(); + + reader.Read(); + + if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException(); } - DataHash dataHash = null; - while (reader.Read()) + var secondPropertyName = reader.GetString(); + if (secondPropertyName != "h") { - if (reader.TokenType == JsonTokenType.EndObject) - { - return dataHash; - } - - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new JsonException(); - } - - var firstPropertyName = reader.GetString(); - if (firstPropertyName == "s") - { - this.isBlock = true; - } - else if (firstPropertyName != "l") - { - throw new JsonException(); - } - - reader.Read(); - - long dataLength = this.isBlock ? reader.GetInt32() : reader.GetInt64(); - - reader.Read(); - - if (reader.TokenType != JsonTokenType.PropertyName) - { - throw new JsonException(); - } - - var secondPropertyName = reader.GetString(); - if (secondPropertyName != "h") - { - throw new JsonException(); - } - - reader.Read(); - - string stringHash = reader.GetString(); - - if (this.isBlock) - { - dataHash = new BlockHash( - blockType: typeof(Block), - originalBlockSize: BlockSizeMap.BlockSize((int)dataLength), - providedHashBytes: StringToByteArray(stringHash), - computed: false); - } - else - { - dataHash = new DataHash( - providedHashBytes: StringToByteArray(stringHash), - sourceDataLength: dataLength, - computed: false); - } + throw new JsonException(); } - throw new JsonException(); - } + reader.Read(); - public override void Write( - Utf8JsonWriter writer, - DataHash dataHash, - JsonSerializerOptions options) - { - writer.WriteStartObject(); + var stringHash = reader.GetString(); - if (dataHash is BlockHash blockHash) + if (this.isBlock) { - writer.WriteNumber("s", BlockSizeMap.BlockSize(blockHash.BlockSize)); + dataHash = new BlockHash( + blockType: typeof(Block), + originalBlockSize: BlockSizeMap.BlockSize(blockSize: (int)dataLength), + providedHashBytes: StringToByteArray(hex: stringHash), + computed: false); } else { - writer.WriteNumber("l", dataHash.SourceDataLength); + dataHash = new DataHash( + providedHashBytes: StringToByteArray(hex: stringHash), + sourceDataLength: dataLength, + computed: false); } + } + + throw new JsonException(); + } + + public override void Write( + Utf8JsonWriter writer, + DataHash dataHash, + JsonSerializerOptions options) + { + writer.WriteStartObject(); - writer.WriteString("h", dataHash.ToString().Replace("-", string.Empty).ToLower(culture: System.Globalization.CultureInfo.InvariantCulture)); - writer.WriteEndObject(); + if (dataHash is BlockHash blockHash) + { + writer.WriteNumber(propertyName: "s", + value: BlockSizeMap.BlockSize(blockSize: blockHash.BlockSize)); } + else + { + writer.WriteNumber(propertyName: "l", + value: dataHash.SourceDataLength); + } + + writer.WriteString(propertyName: "h", + value: dataHash.ToString().Replace(oldValue: "-", + newValue: string.Empty).ToLower(culture: CultureInfo.InvariantCulture)); + writer.WriteEndObject(); } } } diff --git a/src/BrightChain.Engine/Faster/BlockSessionAddresses.cs b/src/BrightChain.Engine/Faster/BlockSessionAddresses.cs deleted file mode 100644 index 1c55e392..00000000 --- a/src/BrightChain.Engine/Faster/BlockSessionAddresses.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace BrightChain.Engine.Faster -{ - using System.Collections.Generic; - using BrightChain.Engine.Faster.Enumerations; - - public struct BlockSessionAddresses - { - public readonly Dictionary Addresses; - - public BlockSessionAddresses(Dictionary addresses) - { - this.Addresses = addresses; - } - } -} diff --git a/src/BrightChain.Engine/Faster/BlockSessionCheckpoint.cs b/src/BrightChain.Engine/Faster/BlockSessionCheckpoint.cs deleted file mode 100644 index 1d58c152..00000000 --- a/src/BrightChain.Engine/Faster/BlockSessionCheckpoint.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace BrightChain.Engine.Faster -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Faster.Enumerations; - - public struct BlockSessionCheckpoint - { - public readonly bool Success; - public readonly Dictionary CheckpointResult; - public readonly Dictionary CheckpointGuids; - - public BlockSessionCheckpoint(bool success, Dictionary results, Dictionary guids) - { - this.Success = success; - this.CheckpointResult = results; - this.CheckpointGuids = guids; - } - } -} diff --git a/src/BrightChain.Engine/Faster/BlockSessionContext.cs b/src/BrightChain.Engine/Faster/BlockSessionContext.cs deleted file mode 100644 index eb89d4b5..00000000 --- a/src/BrightChain.Engine/Faster/BlockSessionContext.cs +++ /dev/null @@ -1,158 +0,0 @@ -namespace BrightChain.Engine.Faster -{ - using System; - using System.Threading.Tasks; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.Functions; - using BrightChain.Engine.Faster.Indices; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - using Microsoft.Extensions.Logging; - - public class BlockSessionContext : IDisposable - { - private readonly ILogger logger; - - public readonly ClientSession BlockDataBlobSession; - - public readonly ClientSession SharedCacheSession; - - public BlockSessionContext( - ILogger logger, - ClientSession dataSession, - ClientSession cblIndicesSession) - { - this.logger = logger; - this.BlockDataBlobSession = dataSession; - this.SharedCacheSession = cblIndicesSession; - } - - public bool Contains(BlockHash blockHash) - { - var dataResultTuple = this.BlockDataBlobSession.Read(blockHash); - - return - dataResultTuple.status == Status.OK; - } - - public bool Drop(BlockHash blockHash, bool complete = true) - { - if (this.BlockDataBlobSession.Delete(blockHash) != Status.OK) - { - // TODO: rollback? - return false; - } - - // TODO: determine when/where & implement index deletions relevant to the block - - if (complete) - { - return this.CompletePending(waitForCommit: false); - } - - return true; - } - - private static string BlockMetadataIndexKey(BlockHash blockHash) - => string.Format("Metadata:{0}", blockHash.ToString()); - - public BrightenedBlock Get(BlockHash blockHash) - { - var dataResultTuple = this.BlockDataBlobSession.Read(blockHash); - - if (dataResultTuple.status != Status.OK) - { - throw new IndexOutOfRangeException(message: blockHash.ToString()); - } - - var result = this.SharedCacheSession.Read(BlockMetadataIndexKey(blockHash)); - if (result.status == Status.NOTFOUND) - { - throw new IndexOutOfRangeException(message: blockHash.ToString()); - } - else if (result.status != Status.OK) - { - throw new BrightChainException( - message: string.Format("metadata fetch error: {0}", result.status.ToString())); - } - - if (result.output is BlockMetadataIndexValue blockMetadata) - { - var block = blockMetadata.Block; - - block.StoredData = dataResultTuple.output; - - if (!block.Validate()) - { - throw new BrightChainValidationEnumerableException(block.ValidationExceptions, "Failed to reload block from store"); - } - - return block; - } - - throw new BrightChainException("Unexpected index result type for key"); - - } - - public void Upsert(BrightenedBlock block, bool completePending = false) - { - var resultStatus = this.SharedCacheSession.Upsert( - key: BlockMetadataIndexKey(block.Id), - desiredValue: new BlockMetadataIndexValue(block)); - - if (resultStatus != Status.OK) - { - throw new BrightChainException("Unable to store block"); - } - - resultStatus = this.BlockDataBlobSession.Upsert(block.Id, block.StoredData); - if (resultStatus != Status.OK) - { - throw new BrightChainException("Unable to store block"); - } - - if (completePending) - { - this.CompletePending(waitForCommit: false); - } - } - - public async Task WaitForCommitAsync() - { - await Task.WhenAll(new Task[] - { - this.BlockDataBlobSession.WaitForCommitAsync().AsTask(), - this.SharedCacheSession.WaitForCommitAsync().AsTask(), - }).ConfigureAwait(false); - } - - public bool CompletePending(bool waitForCommit) - { - var d = this.BlockDataBlobSession.CompletePending(wait: waitForCommit); - var c = this.SharedCacheSession.CompletePending(wait: waitForCommit); - - // broken out to prevent short circuit - return d && c; - } - - public async Task CompletePendingAsync(bool waitForCommit) - { - Task.WaitAll(new Task[] - { - this.BlockDataBlobSession.CompletePendingAsync(waitForCommit: waitForCommit).AsTask(), - this.SharedCacheSession.CompletePendingAsync(waitForCommit: waitForCommit).AsTask(), - }); - } - - public string SessionID => - string.Format("{0}-{1}", this.BlockDataBlobSession.ID, this.SharedCacheSession.ID); - - public void Dispose() - { - this.BlockDataBlobSession.Dispose(); - this.SharedCacheSession.Dispose(); - } - } -} diff --git a/src/BrightChain.Engine/Faster/BrightChainFasterCacheContext.cs b/src/BrightChain.Engine/Faster/BrightChainFasterCacheContext.cs deleted file mode 100644 index cbe5dff0..00000000 --- a/src/BrightChain.Engine/Faster/BrightChainFasterCacheContext.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace BrightChain.Engine.Faster -{ - /// - /// User context to measure latency and/or check read result. - /// - public struct BrightChainFasterCacheContext - { - public int type; - public long ticks; - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CBLIndex.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CBLIndex.cs deleted file mode 100644 index 67b20878..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CBLIndex.cs +++ /dev/null @@ -1,111 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.Indices; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - public partial class FasterBlockCacheManager - { - private static string CblIndexKey(DataHash sourceHash) - { - return string.Format("Source:{0}", sourceHash.ToString()); - } - - public override BrightHandle GetCbl(DataHash sourceHash) - { - using var sessionContext = this.NewFasterSessionContext; - { - var result = sessionContext.SharedCacheSession.Read(CblIndexKey(sourceHash)); - if (result.status == Status.NOTFOUND) - { - throw new IndexOutOfRangeException(message: sourceHash.ToString()); - } - else if (result.status != Status.OK) - { - throw new BrightChainException( - message: string.Format("cbl handle fetch error: {0}", result.status.ToString())); - } - - if (result.output is BrightHandleIndexValue brightHandle) - { - return brightHandle.BrightHandle; - } - - throw new BrightChainException("Unexpected index result type for key"); - } - } - - public override void SetCbl(BlockHash brightenedCblHash, DataHash identifiableSourceHash, BrightHandle brightHandle) - { - // technically the node can allow the CBL to be committed even if the store doesn't have the final block necessary to recreate it - // this would be allowed in some circumstances TBD. - // the parameter is provided as a means to check that. - if (!brightHandle.BrightenedCblHash.Equals(brightenedCblHash)) - { - throw new BrightChainException(nameof(brightenedCblHash)); - } - - if (!brightHandle.IdentifiableSourceHash.Equals(identifiableSourceHash)) - { - throw new BrightChainException(nameof(identifiableSourceHash)); - } - - using var sessionContext = this.NewFasterSessionContext; - { - sessionContext.SharedCacheSession.Upsert( - key: CblIndexKey(identifiableSourceHash), - desiredValue: new BrightHandleIndexValue(brightHandle).AsIndex); - - sessionContext.CompletePending(waitForCommit: false); - } - } - - private static string CorrelationIndexKey(Guid correlationId) - { - return string.Format("Correlation:{0}", correlationId.ToString()); - } - - public override void UpdateCblVersion(ConstituentBlockListBlock newCbl, ConstituentBlockListBlock oldCbl = null) - { - newCbl.CorrelationId = oldCbl.CorrelationId; - newCbl.PreviousVersionHash = oldCbl.SourceId; - - base.UpdateCblVersion(newCbl, oldCbl); - using var sessionContext = this.NewFasterSessionContext; - { - sessionContext.SharedCacheSession.Upsert( - key: CorrelationIndexKey(newCbl.CorrelationId), - desiredValue: new CBLDataHashIndexValue(newCbl.SourceId).AsIndex); - } - } - - public override BrightHandle GetCbl(Guid correlationId) - { - using var sessionContext = this.NewFasterSessionContext; - { - var key = CorrelationIndexKey(correlationId); - var result = sessionContext.SharedCacheSession.Read(key); - if (result.status == Status.NOTFOUND) - { - throw new IndexOutOfRangeException(message: correlationId.ToString()); - } - else if (result.status != Status.OK) - { - throw new BrightChainException( - message: string.Format("cbl correlation fetch error: {0}", result.status.ToString())); - } - - if (result.output is BrightHandleIndexValue brightHandle) - { - return brightHandle.BrightHandle; - } - - throw new BrightChainException("Unexpected index result type for key"); - } - } - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CoreFunctions.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CoreFunctions.cs deleted file mode 100644 index 843ae53f..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.CoreFunctions.cs +++ /dev/null @@ -1,119 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - - public partial class FasterBlockCacheManager - { - /// - /// Returns whether the cache manager has the given key and it is not expired. - /// - /// key to check the collection for. - /// boolean with whether key is present. - public override bool Contains(BlockHash key) - { - using var sessionContext = this.NewFasterSessionContext; - { - return sessionContext.Contains(key); - } - } - - /// - /// Removes a key from the cache and returns a boolean wither whether it was actually present. - /// - /// key to drop from the collection. - /// Skips the contains check for performance. - /// whether requested key was present and actually dropped. - public override bool Drop(BlockHash key, bool noCheckContains = true) - { - bool contains; - BrightenedBlock block = null; - try - { - block = this.Get(key); - contains = true; - } - catch (Exception _) - { - contains = false; - } - - if (!base.Drop(key, noCheckContains: true)) - { - return false; - } - - using var sessionContext = this.NewFasterSessionContext; - { - if (!sessionContext.Drop(blockHash: key, complete: true)) - { - return false; - } - } - - this.RemoveExpiration(block); - - return true; - } - - /// - /// Retrieves a block from the cache if it is present. - /// - /// key to retrieve. - /// returns requested block or throws. - public override BrightenedBlock Get(BlockHash blockHash) - { - using var sessionContext = this.NewFasterSessionContext; - { - return sessionContext.Get(blockHash); - } - } - - /// - /// Adds a key to the cache if it is not already present. - /// - /// block to palce in the cache. - public void Set(BrightenedBlock block) - { - base.Set(block); - block.SetCacheManager(this); - using var sessionContext = this.NewFasterSessionContext; - { - sessionContext.Upsert( - block: block, - completePending: false); - } - this.AddExpiration(block, noCheckContains: true); - } - - public override void SetAll(IEnumerable items) - { - BrightenedBlock[] blocks = (BrightenedBlock[])items; - - for (int i = 0; i < blocks.Length; i++) - { - this.Set(blocks[i]); - } - - using var sessionContext = this.NewFasterSessionContext; - { - sessionContext.CompletePending(waitForCommit: false); - } - } - - public async override void SetAllAsync(IAsyncEnumerable items) - { - await foreach (var block in items) - { - this.Set(block); - } - - using var sessionContext = this.NewFasterSessionContext; - { - await sessionContext.CompletePendingAsync(waitForCommit: false).ConfigureAwait(false); - } - } - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Events.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Events.cs deleted file mode 100644 index c70529eb..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Events.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - - public partial class FasterBlockCacheManager - { - /// - /// Fired whenever a block is added to the cache - /// - public override event ICacheManager.KeyAddedEventHandler KeyAdded; - - /// - /// Fired whenever a block is expired from the cache - /// - public override event ICacheManager.KeyExpiredEventHandler KeyExpired; - - /// - /// Fired whenever a block is removed from the collection - /// - public override event ICacheManager.KeyRemovedEventHandler KeyRemoved; - - /// - /// Fired whenever a block is requested from the cache but is not present. - /// - public override event ICacheManager.CacheMissEventHandler CacheMiss; - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.ExpirationIndex.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.ExpirationIndex.cs deleted file mode 100644 index 8c6dc5d5..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.ExpirationIndex.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using System.Linq; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.Indices; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - - public partial class FasterBlockCacheManager - { - public static string BlockExpirationIndexKey(long date) - { - return string.Format("Expiration:{0}", date); - } - - public override IEnumerable GetBlocksExpiringAt(long date) - { - using var sessionContext = this.NewFasterSessionContext; - { - var resultTuple = sessionContext.SharedCacheSession.Read(BlockExpirationIndexKey(date)); - if (resultTuple.status == FASTER.core.Status.OK) - { - if (resultTuple.output is null) - { - throw new BrightChainExceptionImpossible("Cache returned null value"); - } - else if (resultTuple.output is BlockExpirationIndexValue expirationIndex) - { - return expirationIndex.ExpiringHashes; - } - else - { - throw new BrightChainException("Unexpected index value type for key"); - } - } - else if (resultTuple.status == FASTER.core.Status.NOTFOUND) - { - return new BlockHash[] { }; - } - - throw new BrightChainException(resultTuple.status.ToString()); - } - } - - public override void AddExpiration(BrightenedBlock block, bool noCheckContains = false) - { - using var sessionContext = this.NewFasterSessionContext; - { - if (!noCheckContains && !sessionContext.Contains(block.Id)) - { - throw new IndexOutOfRangeException(block.Id.ToString()); - } - - var ticks = block.StorageContract.KeepUntilAtLeast.Ticks; - var expiring = (BlockHash[])this.GetBlocksExpiringAt(ticks); - if (!expiring.Contains(block.Id)) - { - var size = expiring.Count(); - Array.Resize(ref expiring, size + 1); - expiring[size] = block.Id; - } - - sessionContext.SharedCacheSession.Upsert( - key: BlockExpirationIndexKey(ticks), - desiredValue: new BlockExpirationIndexValue(expiring)); - } - } - - public override void RemoveExpiration(BrightenedBlock block) - { - var ticks = block.StorageContract.KeepUntilAtLeast.Ticks; - var expiring = new List(this.GetBlocksExpiringAt(ticks)); - expiring.Remove(block.Id); - - using var sessionContext = this.NewFasterSessionContext; - { - sessionContext.SharedCacheSession.Upsert( - key: BlockExpirationIndexKey(ticks), - desiredValue: new BlockExpirationIndexValue(expiring.ToArray())); - } - } - - public override void ExpireBlocks(long date) - { - using var sessionContext = this.NewFasterSessionContext; - { - - // checkpoint - foreach (var blockHash in this.GetBlocksExpiringAt(date)) - { - sessionContext.Drop(blockHash); - } - // checkpoint - } - } - - public override void ExpireBlocksThrough(long date) - { - // determine/lookup oldest block in cache - // expire all seconds between, inclusive, that time and specified time - } - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Helpers.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Helpers.cs deleted file mode 100644 index 061c7dc6..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Helpers.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using System.IO; - using BrightChain.Engine.Faster.Enumerations; - using FASTER.core; - - public partial class FasterBlockCacheManager - { - private static LogSettings NewLogSettings(Dictionary storeDevices, bool useReadCache) - { - return new LogSettings - { - LogDevice = storeDevices[CacheDeviceType.Log], - ObjectLogDevice = storeDevices[CacheDeviceType.Data], - ReadCacheSettings = useReadCache ? new ReadCacheSettings() : null, - }; - } - - private static CheckpointSettings NewCheckpointSettings(string cacheDir) - { - return new CheckpointSettings - { - CheckpointDir = cacheDir, - }; - } - - private DirectoryInfo EnsuredDirectory(string dir) - { - if (!Directory.Exists(dir)) - { - return Directory.CreateDirectory(dir); - } - - return new DirectoryInfo(dir); - } - - protected DirectoryInfo GetDiskCacheDirectory() - { - return Directory.CreateDirectory( - Path.Combine( - path1: this.baseDirectory.FullName, - path2: "BrightChain", - path3: this.DatabaseName)); - } - - protected string GetDevicePath(string nameSpace, out DirectoryInfo cacheDirectoryInfo) - { - cacheDirectoryInfo = this.GetDiskCacheDirectory(); - - return Path.Combine( - cacheDirectoryInfo.FullName, - string.Format( - provider: System.Globalization.CultureInfo.InvariantCulture, - format: "{0}-{1}.log", - this.DatabaseName, - nameSpace)); - } - - protected IDevice CreateLogDevice(string nameSpace) - { - var devicePath = this.GetDevicePath(nameSpace, out DirectoryInfo _); - - return Devices.CreateLogDevice( - logPath: devicePath); - } - - private - (Dictionary> DevicesByStoreType, - Dictionary StoresByStoreType) - InitFaster() - { - var cacheDir = this.GetDiskCacheDirectory().FullName; - var kvs = new Dictionary(); - var devices = new Dictionary>(); - foreach (CacheStoreType storeType in Enum.GetValues(enumType: typeof(CacheStoreType))) - { - var logDevicesByType = new Dictionary(); - foreach (CacheDeviceType deviceType in Enum.GetValues(enumType: typeof(CacheDeviceType))) - { - var device = this.CreateLogDevice(string.Format("{0}-{1}", storeType.ToString(), deviceType.ToString())); - logDevicesByType.Add(deviceType, device); - } - - devices.Add(storeType, logDevicesByType); - var newKv = this.newKVFuncs[storeType](logDevicesByType, this.useReadCache, cacheDir); - kvs.Add(storeType, newKv); - } - - return (devices, kvs); - } - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.SessionContext.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.SessionContext.cs deleted file mode 100644 index 186b0ba2..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.SessionContext.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using BrightChain.Engine.Faster; - using BrightChain.Engine.Faster.Functions; - using BrightChain.Engine.Faster.Indices; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - public partial class FasterBlockCacheManager - { - private BlockSessionContext NewFasterSessionContext => new BlockSessionContext( - logger: this.Logger, - dataSession: this.NewDataSession, - cblIndicesSession: this.NewCblIndicesSession); - - private ClientSession NewDataSession - => this.primaryDataKV - .For(functions: new BrightChainBlockHashAdvancedFunctions()) - .NewSession(); - - private ClientSession NewCblIndicesSession - => this.cblIndicesKV - .For(functions: new BrightChainIndicesAdvancedFunctions()) - .NewSession(); - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Transactable.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Transactable.cs deleted file mode 100644 index 68a99e73..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.Transactable.cs +++ /dev/null @@ -1,190 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster; - using BrightChain.Engine.Faster.Enumerations; - using FASTER.core; - - public partial class FasterBlockCacheManager - { - private readonly BlockSessionCheckpoint lastCheckpoint; - private readonly BlockSessionAddresses lastHead; - private readonly BlockSessionAddresses lastCommit; - - public BlockSessionCheckpoint TakeFullCheckpoint(CheckpointType checkpointType = CheckpointType.Snapshot) - { - return this.CheckpointFunc(FasterCheckpointOperation.Full, checkpointType); - } - - private async Task TakeFullCheckpointAsync(CheckpointType checkpointType = CheckpointType.Snapshot) - { - return await this.CheckpointFuncAsync(() => new Dictionary>() - { - { CacheStoreType.BlockData, this.primaryDataKV.TakeFullCheckpointAsync(checkpointType: checkpointType).AsTask() }, - { CacheStoreType.Indices, this.cblIndicesKV.TakeFullCheckpointAsync(checkpointType: checkpointType).AsTask() }, - }).ConfigureAwait(false); - } - - public BlockSessionCheckpoint TakeHybridCheckpoint(CheckpointType checkpointType) - { - return this.CheckpointFunc(FasterCheckpointOperation.Hybrid, checkpointType); - } - - public async Task TakeHybridCheckpointAsync(CheckpointType checkpointType = CheckpointType.Snapshot) - { - return await this.CheckpointFuncAsync(() => new Dictionary>() - { - { CacheStoreType.BlockData, this.primaryDataKV.TakeHybridLogCheckpointAsync(checkpointType: checkpointType).AsTask() }, - { CacheStoreType.Indices, this.cblIndicesKV.TakeHybridLogCheckpointAsync(checkpointType: checkpointType).AsTask() }, - }).ConfigureAwait(false); - } - - public BlockSessionCheckpoint TakeIndexCheckpoint() - { - return this.CheckpointFunc(FasterCheckpointOperation.Index); - } - - public async Task TakeIndexCheckPointAsync() - { - return await this.CheckpointFuncAsync(() => new Dictionary>() - { - { CacheStoreType.BlockData, this.primaryDataKV.TakeIndexCheckpointAsync().AsTask() }, - { CacheStoreType.Indices, this.cblIndicesKV.TakeIndexCheckpointAsync().AsTask() }, - }).ConfigureAwait(false); - } - - public BlockSessionCheckpoint CheckpointFunc(FasterCheckpointOperation operation, CheckpointType checkpointType = CheckpointType.Snapshot) - { - bool dataResult, expirationResult, cblResult, cblIndexResult; - Guid dataToken, expirationToken, cblToken, cblIndexsToken; - switch (operation) - { - case FasterCheckpointOperation.Full: - dataResult = this.primaryDataKV.TakeFullCheckpoint(token: out dataToken, checkpointType: checkpointType); - cblIndexResult = this.cblIndicesKV.TakeFullCheckpoint(token: out cblIndexsToken, checkpointType: checkpointType); - break; - case FasterCheckpointOperation.Hybrid: - dataResult = this.primaryDataKV.TakeHybridLogCheckpoint(out dataToken); - cblIndexResult = this.cblIndicesKV.TakeHybridLogCheckpoint(out cblIndexsToken); - break; - case FasterCheckpointOperation.Index: - dataResult = this.primaryDataKV.TakeIndexCheckpoint(out dataToken); - cblIndexResult = this.cblIndicesKV.TakeIndexCheckpoint(out cblIndexsToken); - break; - default: - throw new BrightChainExceptionImpossible("Unexpected type"); - } - - return new BlockSessionCheckpoint( - success: dataResult && cblIndexResult, - results: new Dictionary() - { - { CacheStoreType.BlockData, dataResult }, - { CacheStoreType.Indices, cblIndexResult }, - }, - guids: new Dictionary() - { - { CacheStoreType.BlockData, dataToken }, - { CacheStoreType.Indices, cblIndexsToken }, - }); - } - - public async Task CheckpointFuncAsync(Func>> func) - { - var taskDict = func(); - - await Task.WhenAll(taskDict.Values) - .ConfigureAwait(false); - - var resultDict = new Dictionary(); - var guidDict = new Dictionary(); - var allGood = true; - foreach (var task in taskDict) - { - var result = task.Value.Result; - resultDict.Add(task.Key, result.Item1); - guidDict.Add(task.Key, result.Item2); - - allGood = allGood && result.Item1; - } - - return new BlockSessionCheckpoint(allGood, resultDict, guidDict); - } - - public async Task CompleteCheckpointAsync() - { - await Task - .WhenAll(new Task[] - { - this.primaryDataKV.CompleteCheckpointAsync().AsTask(), - this.cblIndicesKV.CompleteCheckpointAsync().AsTask(), - }) - .ConfigureAwait(false); - } - - public BlockSessionAddresses NextSerials() - { - using var sessionContext = this.NewFasterSessionContext; - { - return new BlockSessionAddresses(addresses: new Dictionary - { - { - CacheStoreType.BlockData, - sessionContext.BlockDataBlobSession.NextSerialNo - }, - { - CacheStoreType.Indices, - sessionContext.SharedCacheSession.NextSerialNo - }, - }); - } - } - - public BlockSessionAddresses HeadAddresses() - { - return new BlockSessionAddresses(addresses: new Dictionary - { - { - CacheStoreType.BlockData, - this.primaryDataKV.Log.HeadAddress - }, - { - CacheStoreType.Indices, - this.cblIndicesKV.Log.HeadAddress - }, - }); - } - - public BlockSessionAddresses Compact(bool shiftBeginAddress = true) - { - using var sessionContext = this.NewFasterSessionContext; - { - return new BlockSessionAddresses(addresses: new Dictionary - { - { - CacheStoreType.BlockData, sessionContext.BlockDataBlobSession.Compact( - untilAddress: this.primaryDataKV.Log.HeadAddress, - shiftBeginAddress: shiftBeginAddress) - }, - { - CacheStoreType.Indices, sessionContext.SharedCacheSession.Compact( - untilAddress: this.cblIndicesKV.Log.HeadAddress, - shiftBeginAddress: shiftBeginAddress) - }, - }); - } - } - - public async void Recover() - { - Task.WaitAll(new Task[] - { - this.primaryDataKV.RecoverAsync().AsTask(), - this.cblIndicesKV.RecoverAsync().AsTask(), - }); - } - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.TypeHelpers.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.TypeHelpers.cs deleted file mode 100644 index a8b237ae..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.TypeHelpers.cs +++ /dev/null @@ -1,66 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Faster.Enumerations; - using BrightChain.Engine.Faster.Indices; - using BrightChain.Engine.Faster.Serializers; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - public partial class FasterBlockCacheManager - { - private readonly Dictionary, bool, string, FasterBase>> newKVFuncs = - new Dictionary, bool, string, FasterBase>>() - { - { - CacheStoreType.BlockData, - FasterBase (Dictionary storeDevices, bool useReadCache, string cacheDir) => - { - var blockDataSerializerSettings = new SerializerSettings - { - keySerializer = () => new FasterBlockHashSerializer(), - valueSerializer = () => new DataContractObjectSerializer(), - }; - - return new FasterKV( - size: HashTableBuckets, - logSettings: NewLogSettings(storeDevices, useReadCache), - checkpointSettings: NewCheckpointSettings(cacheDir), - serializerSettings: blockDataSerializerSettings, - comparer: BlockSizeMap.ZeroVectorHash(BlockSize.Micro)); // gets an arbitrary BlockHash object which has the IFasterEqualityComparer on the class. - } - }, - { - CacheStoreType.Indices, - FasterBase (Dictionary storeDevices, bool useReadCache, string cacheDir) => - { - var cblIndexSerializerSettings = new SerializerSettings - { - keySerializer = () => null, - valueSerializer = () => new FasterBrightChainIndexValueSerializer(), - }; - - return new FasterKV( - size: HashTableBuckets, - logSettings: NewLogSettings(storeDevices, useReadCache), - checkpointSettings: NewCheckpointSettings(cacheDir), - serializerSettings: cblIndexSerializerSettings, - comparer: null); - } - }, - }; - - protected FasterKV primaryDataKV => - (FasterKV)this.fasterStores[CacheStoreType.BlockData]; - - /// - /// Map of correlation GUIDs to latest CBL source hash associated with a correlation ID. - /// - protected FasterKV cblIndicesKV => - (FasterKV)this.fasterStores[CacheStoreType.Indices]; - } -} diff --git a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.cs b/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.cs deleted file mode 100644 index aa9e85b7..00000000 --- a/src/BrightChain.Engine/Faster/CacheManager/FasterBlockCacheManager.cs +++ /dev/null @@ -1,131 +0,0 @@ -namespace BrightChain.Engine.Faster.CacheManager -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.Enumerations; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Services.CacheManagers.Block; - using FASTER.core; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - - /// - /// Disk/Memory hybrid Block Cache Manager based on Microsoft FASTER KV. - /// - /// - /// The plan is to keep a couple separate caches of data in sync using the FasterKV checkpointing. - /// Hopefully errors where we need to put back or take out blocks that have already been altered on disk are rare. - /// The primary, Write Once*, Read Many cache: - /// - The Data cache contains the actual raw block data only. These blocks are not to be altered unless deleted through a revocation certificate or normal expiration. - /// The secondary, Multiple Write Multiple Read cache is a combined cache that serves as a shared index table - /// - The BlockMetadata cache contains block metadata that may be updated. - /// - BlockExpirationIndexValues contain a list of Block ID's expiring in any given second. - /// - CBLDataHashIndexValues contain the latest CBL source hash associated with a given correlation ID. - /// - BrightHandleIndexValues contain the CBL handles for a given source hash ID. - /// - CBLTagIndexValue contain the correlation IDs for a given tag. - /// - /// Sessions are what you issue a sequence of operations against. \ - /// You checkpoint the database periodically, which ensures some prefix of operations \ - /// on the session are persisted, i.e., can survive process failure. If you Upsert and try \ - /// to read back the data in the same session, it should be there. - /// - public partial class FasterBlockCacheManager : BrightenedBlockCacheManagerBase, IDisposable - { - /// - /// hash table size (number of 64-byte buckets). - /// - private const long HashTableBuckets = 1L << 20; - - /// - /// Directory where the block tree root will be placed. - /// - private readonly DirectoryInfo baseDirectory; - - /// - /// Whether we enable a read cache. - /// Updated from config. - /// - private readonly bool useReadCache = false; - - private readonly Dictionary> fasterDevices; - private readonly Dictionary fasterStores; - private List uncommittedBlocks; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the logging provider. - /// Instance of the configuration provider. - /// Database/directory name for the store. - /// Block containing key information for store. - /// Whether to delete device files on shutdown. - public FasterBlockCacheManager(ILogger logger, IConfiguration configuration, RootBlock rootBlock, bool testingSelfDestruct = false) - : base(logger, configuration, rootBlock, testingSelfDestruct) - { - var nodeOptions = configuration.GetSection("NodeOptions"); - if (nodeOptions is null) - { - throw new BrightChainException("'NodeOptions' config section must be defined, but is not"); - } - - var configOption = nodeOptions.GetSection("BasePath"); - var dir = configOption is not null && configOption.Value.Any() ? configOption.Value : Path.Join(Path.GetTempPath(), "brightchain"); - - this.baseDirectory = this.EnsuredDirectory(dir); - - var configuredDbName - = nodeOptions.GetSection("DatabaseName"); - - if (configuredDbName is null || !configuredDbName.Value.Any()) - { - //ConfigurationHelper.AddOrUpdateAppSetting("NodeOptions:DatabaseName", this.databaseName); - } - else - { - var expectedGuid = Guid.Parse(configuredDbName.Value); - if (expectedGuid != this.RootBlock.Guid) - { - throw new BrightChainException("Provided root block does not match configured root block guid"); - } - } - - var readCache = nodeOptions.GetSection("EnableReadCache"); - this.useReadCache = readCache is null || readCache.Value is null ? false : Convert.ToBoolean(readCache.Value); - - (this.fasterDevices, this.fasterStores) = this.InitFaster(); - this.lastHead = this.HeadAddresses(); - this.lastCommit = lastHead; - this.lastCheckpoint = this.TakeFullCheckpoint(); - this.uncommittedBlocks = new List(); - } - - /// - /// Gets the full path to the configuration file. - /// - public string ConfigurationFilePath - => this.ConfigFile; - - public void Dispose() - { - foreach (var entry in this.fasterDevices) - { - var faster = this.fasterStores[entry.Key]; - (faster as IDisposable).Dispose(); - entry.Value.Values.All(d => - { - d.Dispose(); - if (this.testingSelfDestruct) - { - File.Delete(d.FileName); - } - - return true; - }); - - } - } - } -} diff --git a/src/BrightChain.Engine/Faster/Enumerations/CacheDeviceType.cs b/src/BrightChain.Engine/Faster/Enumerations/CacheDeviceType.cs deleted file mode 100644 index df55574f..00000000 --- a/src/BrightChain.Engine/Faster/Enumerations/CacheDeviceType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BrightChain.Engine.Faster.Enumerations -{ - public enum CacheDeviceType - { - Log, - Data, - } -} diff --git a/src/BrightChain.Engine/Faster/Enumerations/CacheStoreType.cs b/src/BrightChain.Engine/Faster/Enumerations/CacheStoreType.cs deleted file mode 100644 index d3da71f2..00000000 --- a/src/BrightChain.Engine/Faster/Enumerations/CacheStoreType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace BrightChain.Engine.Faster.Enumerations -{ - public enum CacheStoreType - { - BlockData, - Indices, - } -} diff --git a/src/BrightChain.Engine/Faster/Enumerations/FasterCheckpointOperation.cs b/src/BrightChain.Engine/Faster/Enumerations/FasterCheckpointOperation.cs deleted file mode 100644 index 5d40d4da..00000000 --- a/src/BrightChain.Engine/Faster/Enumerations/FasterCheckpointOperation.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace BrightChain.Engine.Faster.Enumerations -{ - public enum FasterCheckpointOperation - { - Full, - Hybrid, - Index, - } -} diff --git a/src/BrightChain.Engine/Faster/Functions/BrightChainAdvancedFunctions.cs b/src/BrightChain.Engine/Faster/Functions/BrightChainAdvancedFunctions.cs deleted file mode 100644 index 0db6a8f5..00000000 --- a/src/BrightChain.Engine/Faster/Functions/BrightChainAdvancedFunctions.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace BrightChain.Engine.Faster.Functions -{ - using FASTER.core; - - public class BrightChainAdvancedFunctions : FunctionsBase - where Input : Value - where Output : Input, Value - { - public BrightChainAdvancedFunctions(bool locking = false) - : base(locking: locking) - { - } - - public override void ConcurrentReader(ref Key key, ref Input input, ref Value value, ref Output dst) - { - dst = (Output)value; - } - - public override bool ConcurrentWriter(ref Key key, ref Value src, ref Value dst) - { - dst = src; - return true; - } - - public override void SingleWriter(ref Key key, ref Value src, ref Value dst) - { - dst = src; - } - - public override void InitialUpdater(ref Key key, ref Input input, ref Value value, ref Output output) - { - value = input; - } - } -} diff --git a/src/BrightChain.Engine/Faster/Functions/BrightChainBlockHashAdvancedFunctions.cs b/src/BrightChain.Engine/Faster/Functions/BrightChainBlockHashAdvancedFunctions.cs deleted file mode 100644 index e0843d0f..00000000 --- a/src/BrightChain.Engine/Faster/Functions/BrightChainBlockHashAdvancedFunctions.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace BrightChain.Engine.Faster.Functions -{ - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - public class BrightChainBlockHashAdvancedFunctions : FunctionsBase - { - public BrightChainBlockHashAdvancedFunctions(bool locking = false) - : base(locking: locking) - { - } - - public override void ConcurrentReader(ref BlockHash key, ref BlockData input, ref BlockData value, ref BlockData dst) - { - dst = value; - } - - public override bool ConcurrentWriter(ref BlockHash key, ref BlockData src, ref BlockData dst) - { - dst = src; - return true; - } - - public override void SingleWriter(ref BlockHash key, ref BlockData src, ref BlockData dst) - { - dst = src; - } - - public override void InitialUpdater(ref BlockHash key, ref BlockData input, ref BlockData value, ref BlockData output) - { - value = input; - output = input; - } - } -} diff --git a/src/BrightChain.Engine/Faster/Functions/BrightChainIndicesAdvancedFunctions.cs b/src/BrightChain.Engine/Faster/Functions/BrightChainIndicesAdvancedFunctions.cs deleted file mode 100644 index dbbdaee5..00000000 --- a/src/BrightChain.Engine/Faster/Functions/BrightChainIndicesAdvancedFunctions.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace BrightChain.Engine.Faster.Functions -{ - using BrightChain.Engine.Faster.Indices; - using FASTER.core; - - public class BrightChainIndicesAdvancedFunctions : FunctionsBase - { - public BrightChainIndicesAdvancedFunctions(bool locking = false) - : base(locking: locking) - { - } - - public override void ConcurrentReader(ref string key, ref BrightChainIndexValue input, ref BrightChainIndexValue value, ref BrightChainIndexValue dst) - { - dst = value; - } - - public override bool ConcurrentWriter(ref string key, ref BrightChainIndexValue src, ref BrightChainIndexValue dst) - { - dst = src; - return true; - } - - public override void SingleWriter(ref string key, ref BrightChainIndexValue src, ref BrightChainIndexValue dst) - { - dst = src; - } - - public override void InitialUpdater(ref string key, ref BrightChainIndexValue input, ref BrightChainIndexValue value, ref BrightChainIndexValue output) - { - value = input; - output = input; - } - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/BlockExpirationIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/BlockExpirationIndexValue.cs deleted file mode 100644 index a1f58aca..00000000 --- a/src/BrightChain.Engine/Faster/Indices/BlockExpirationIndexValue.cs +++ /dev/null @@ -1,63 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using BrightChain.Engine.Faster.Serializers; - using BrightChain.Engine.Models.Hashes; - - public class BlockExpirationIndexValue : BrightChainIndexValue - { - public readonly IEnumerable ExpiringHashes; - - public BlockExpirationIndexValue(IEnumerable hashes) - : base(data: InternalSerialize(hashes)) - { - this.ExpiringHashes = hashes; - } - - public BlockExpirationIndexValue(ReadOnlyMemory data) - : base(data) - { - this.ExpiringHashes = InternalDeserialize(data).ExpiringHashes; - } - - private static ReadOnlyMemory InternalSerialize(IEnumerable data) - { - var serializer = new FasterBlockHashSerializer(); - var memory = new MemoryStream(); - - memory.Write(BitConverter.GetBytes(data.Count())); - serializer.BeginSerialize(memory); - foreach (var item in data) - { - var refItem = item; - serializer.Serialize(ref refItem); - } - - var retval = new ReadOnlyMemory(memory.ToArray()); - serializer.EndSerialize(); - return retval; - } - - private static BlockExpirationIndexValue InternalDeserialize(ReadOnlyMemory data) - { - var deserializer = new FasterBlockHashSerializer(); - MemoryStream s = new MemoryStream(data.ToArray()); - deserializer.BeginDeserialize(s); - - byte[] iBytes = new byte[sizeof(int)]; - s.Read(iBytes, 0, sizeof(int)); - var count = BitConverter.ToInt32(new ReadOnlySpan(array: iBytes)); - var hashes = new BlockHash[count]; - for (int i = 0; i < count; i++) - { - deserializer.Deserialize(out hashes[i]); - } - - deserializer.EndDeserialize(); - return new BlockExpirationIndexValue(hashes: hashes); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/BlockMetadataIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/BlockMetadataIndexValue.cs deleted file mode 100644 index e7a227fe..00000000 --- a/src/BrightChain.Engine/Faster/Indices/BlockMetadataIndexValue.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - using System.IO; - using BrightChain.Engine.Models.Blocks; - using FASTER.core; - - public class BlockMetadataIndexValue : BrightChainIndexValue - { - public readonly BrightenedBlock Block; - - public BlockMetadataIndexValue(BrightenedBlock block) - : base(data: InternalSerialize(block)) - { - this.Block = block; - } - - public BlockMetadataIndexValue(ReadOnlyMemory data) - : base(data) - { - this.Block = InternalDeserialize(data).Block; - } - - private static ReadOnlyMemory InternalSerialize(BrightenedBlock data) - { - var serializer = new DataContractObjectSerializer(); - var memory = new MemoryStream(); - serializer.BeginSerialize(memory); - serializer.Serialize(ref data); - var bytes = memory.ToArray(); - serializer.EndSerialize(); - - var retval = new ReadOnlyMemory(bytes); - return retval; - } - - private static BlockMetadataIndexValue InternalDeserialize(ReadOnlyMemory data) - { - var deserializer = new DataContractObjectSerializer(); - MemoryStream s = new MemoryStream(data.ToArray()); - deserializer.BeginDeserialize(s); - deserializer.Deserialize(out BrightenedBlock block); - deserializer.EndDeserialize(); - return new BlockMetadataIndexValue(block: block); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/BrightChainIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/BrightChainIndexValue.cs deleted file mode 100644 index b78d60e6..00000000 --- a/src/BrightChain.Engine/Faster/Indices/BrightChainIndexValue.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - - public abstract class BrightChainIndexValue - { - public readonly ReadOnlyMemory Data; - - public BrightChainIndexValue(ReadOnlyMemory data) - { - this.Data = data; - } - - public BrightChainIndexValue AsIndex => this; - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/BrightHandleIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/BrightHandleIndexValue.cs deleted file mode 100644 index f55118f5..00000000 --- a/src/BrightChain.Engine/Faster/Indices/BrightHandleIndexValue.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - using BrightChain.Engine.Models.Blocks.DataObjects; - - public class BrightHandleIndexValue : BrightChainIndexValue - { - public readonly BrightHandle BrightHandle; - - public BrightHandleIndexValue(BrightHandle brightHandle) - : base(data: new ReadOnlyMemory( - System.Text.Encoding.ASCII.GetBytes( - brightHandle.BrightChainAddress( - hostName: "hostname") - .ToString()))) - { - this.BrightHandle = brightHandle; - } - - public BrightHandleIndexValue(ReadOnlyMemory data) - : base(data) - { - var uriString = System.Text.Encoding.ASCII.GetString(data.ToArray()); - this.BrightHandle = new BrightHandle(new Uri(uriString)); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/CBLDataHashIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/CBLDataHashIndexValue.cs deleted file mode 100644 index 2a926363..00000000 --- a/src/BrightChain.Engine/Faster/Indices/CBLDataHashIndexValue.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - using System.IO; - using BrightChain.Engine.Models.Hashes; - using ProtoBuf; - - public class CBLDataHashIndexValue : BrightChainIndexValue - { - public readonly DataHash DataHash; - - public CBLDataHashIndexValue(DataHash dataHash) - : base(data: InternalSerialize(dataHash)) - { - this.DataHash = dataHash; - } - - public CBLDataHashIndexValue(ReadOnlyMemory data) - : base(data) - { - this.DataHash = InternalDeserialize(data); - } - - internal static ReadOnlyMemory InternalSerialize(T data) - { - MemoryStream s = new MemoryStream(); - Serializer.Serialize(s, data); - return new ReadOnlyMemory(s.ToArray()); - } - - internal static T InternalDeserialize(ReadOnlyMemory data) - { - MemoryStream s = new MemoryStream(data.ToArray()); - return Serializer.Deserialize(s); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Indices/CBLTagIndexValue.cs b/src/BrightChain.Engine/Faster/Indices/CBLTagIndexValue.cs deleted file mode 100644 index d8e2390b..00000000 --- a/src/BrightChain.Engine/Faster/Indices/CBLTagIndexValue.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace BrightChain.Engine.Faster.Indices -{ - using System; - using System.Collections.Generic; - using System.IO; - using ProtoBuf; - - public class CBLTagIndexValue : BrightChainIndexValue - { - public readonly IEnumerable CorrelationIds; - - public CBLTagIndexValue(IEnumerable guids) - : base(data: InternalSerialize(guids)) - { - this.CorrelationIds = guids; - } - - public CBLTagIndexValue(ReadOnlyMemory data) - : base(data) - { - this.CorrelationIds = InternalDeserialize(data); - } - - internal static ReadOnlyMemory InternalSerialize(IEnumerable data) - { - MemoryStream s = new MemoryStream(); - Serializer.Serialize(s, data); - return new ReadOnlyMemory(s.ToArray()); - } - - internal static IEnumerable InternalDeserialize(ReadOnlyMemory data) - { - MemoryStream s = new MemoryStream(data.ToArray()); - return Serializer.Deserialize>(s); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Serializers/FasterBlockHashSerializer.cs b/src/BrightChain.Engine/Faster/Serializers/FasterBlockHashSerializer.cs deleted file mode 100644 index b1fe1f73..00000000 --- a/src/BrightChain.Engine/Faster/Serializers/FasterBlockHashSerializer.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace BrightChain.Engine.Faster.Serializers -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - /// - /// Serializer for CacheKey - used if CacheKey is changed from struct to class - /// - public class FasterBlockHashSerializer - : BinaryObjectSerializer - { - - public FasterBlockHashSerializer() - { - } - - public override void Deserialize(out BlockHash obj) - { - var hashSize = this.reader.ReadInt32(); - var blockSizeString = this.reader.ReadString(); - var blockSize = (BlockSize)Enum.Parse(typeof(BlockSize), blockSizeString); - var blockBytes = this.reader.ReadBytes(hashSize); - var blockType = Type.GetType(this.reader.ReadString()); - var computed = this.reader.ReadBoolean(); - - obj = new BlockHash( - blockType: blockType, - originalBlockSize: blockSize, - providedHashBytes: blockBytes, - computed: computed); - } - - public override void Serialize(ref BlockHash obj) - { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - - this.writer.Write(BlockHash.HashSizeBytes); - this.writer.Write(obj.BlockSize.ToString()); - this.writer.Write(obj.HashBytes.ToArray()); - this.writer.Write(obj.BlockType.AssemblyQualifiedName); - this.writer.Write(obj.Computed); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Serializers/FasterBrightChainIndexValueSerializer.cs b/src/BrightChain.Engine/Faster/Serializers/FasterBrightChainIndexValueSerializer.cs deleted file mode 100644 index 80f3c775..00000000 --- a/src/BrightChain.Engine/Faster/Serializers/FasterBrightChainIndexValueSerializer.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace BrightChain.Engine.Faster.Serializers -{ - using System; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.Indices; - using FASTER.core; - - /// - /// Serializer for CacheKey - used if CacheKey is changed from struct to class - /// - public class FasterBrightChainIndexValueSerializer - : BinaryObjectSerializer - { - - public FasterBrightChainIndexValueSerializer() - { - } - - public override void Deserialize(out BrightChainIndexValue obj) - { - int length = this.reader.ReadInt32(); - Type type = Type.GetType(typeName: this.reader.ReadString()); - var data = this.reader.ReadBytes(length); - - if (type.Equals(typeof(BlockExpirationIndexValue))) - { - obj = new BlockExpirationIndexValue(new ReadOnlyMemory(data)); - } - else if (type.Equals(typeof(CBLDataHashIndexValue))) - { - obj = new CBLDataHashIndexValue(new ReadOnlyMemory(data)); - } - else if (type.Equals(typeof(CBLTagIndexValue))) - { - obj = new CBLTagIndexValue(new ReadOnlyMemory(data)); - } - else - { - throw new BrightChainException("Unexpected type"); - } - } - - public override void Serialize(ref BrightChainIndexValue obj) - { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - - this.writer.Write(obj.Data.Length); - this.writer.Write(obj.GetType().AssemblyQualifiedName); - this.writer.Write(obj.Data.ToArray()); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Serializers/FasterDataHashSerializer.cs b/src/BrightChain.Engine/Faster/Serializers/FasterDataHashSerializer.cs deleted file mode 100644 index 359ef31e..00000000 --- a/src/BrightChain.Engine/Faster/Serializers/FasterDataHashSerializer.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace BrightChain.Engine.Faster.Serializers -{ - using System; - using BrightChain.Engine.Models.Hashes; - using FASTER.core; - - /// - /// Serializer for CacheKey - used if CacheKey is changed from struct to class - /// - public class FasterDataHashSerializer - : BinaryObjectSerializer - { - - public FasterDataHashSerializer() - { - } - - public override void Deserialize(out DataHash obj) - { - var hashSize = this.reader.ReadInt32(); - var sourceLength = this.reader.ReadInt64(); - var dataBytes = this.reader.ReadBytes(hashSize); - var computed = this.reader.ReadBoolean(); - - obj = new DataHash( - providedHashBytes: dataBytes, - sourceDataLength: sourceLength, - computed: computed); - } - - public override void Serialize(ref DataHash obj) - { - if (obj is null) - { - throw new ArgumentNullException(nameof(obj)); - } - - this.writer.Write(BlockHash.HashSizeBytes); - this.writer.Write(obj.SourceDataLength); - this.writer.Write(obj.HashBytes.ToArray()); - this.writer.Write(obj.Computed); - } - } -} diff --git a/src/BrightChain.Engine/Faster/Serializers/FasterGuidSerializer.cs b/src/BrightChain.Engine/Faster/Serializers/FasterGuidSerializer.cs deleted file mode 100644 index 0f2087db..00000000 --- a/src/BrightChain.Engine/Faster/Serializers/FasterGuidSerializer.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace BrightChain.Engine.Faster.Serializers -{ - using System; - using FASTER.core; - /// - /// Serializer for CacheKey - used if CacheKey is changed from struct to class - /// - public class FasterGuidSerializer - : BinaryObjectSerializer - { - public FasterGuidSerializer() - { - } - - public override void Deserialize(out Guid obj) - { - obj = Guid.Parse(this.reader.ReadString()); - } - - public override void Serialize(ref Guid obj) - { - - this.writer.Write(obj.ToString()); - } - } -} diff --git a/src/BrightChain.Engine/GlobalSuppressions.cs b/src/BrightChain.Engine/GlobalSuppressions.cs old mode 100644 new mode 100755 index 684966db..a819ace8 --- a/src/BrightChain.Engine/GlobalSuppressions.cs +++ b/src/BrightChain.Engine/GlobalSuppressions.cs @@ -5,4 +5,9 @@ using System.Diagnostics.CodeAnalysis; -[assembly: SuppressMessage("Style", "IDE0003:Remove qualification", Justification = "", Scope = "member", Target = "~M:BrightChain.Engine.Services.BrightBlockService.CreateCblFromFile(System.String,System.DateTime,BrightChain.Engine.Enumerations.RedundancyContractType,System.Boolean,System.Boolean,System.Nullable{BrightChain.Engine.Enumerations.BlockSize})~BrightChain.Engine.Models.Blocks.Chains.ConstituentBlockListBlock")] +[assembly: SuppressMessage(category: "Style", + checkId: "IDE0003:Remove qualification", + Justification = "", + Scope = "member", + Target = + "~M:BrightChain.Engine.Services.BrightBlockService.CreateCblFromFile(System.String,System.DateTime,BrightChain.Engine.Enumerations.RedundancyContractType,System.Boolean,System.Boolean,System.Nullable{BrightChain.Engine.Enumerations.BlockSize})~BrightChain.Engine.Models.Blocks.Chains.ConstituentBlockListBlock")] diff --git a/src/BrightChain.Engine/Helpers/BinaryStringSerializer.cs b/src/BrightChain.Engine/Helpers/BinaryStringSerializer.cs old mode 100644 new mode 100755 index 4d43a2d7..f454d303 --- a/src/BrightChain.Engine/Helpers/BinaryStringSerializer.cs +++ b/src/BrightChain.Engine/Helpers/BinaryStringSerializer.cs @@ -1,33 +1,37 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.IO; - using System.Linq; - using FASTER.core; +using System; +using System.IO; +using System.Linq; +using FASTER.core; + +namespace BrightChain.Engine.Helpers; - public class BinaryStringSerializer : BinaryObjectSerializer +public class BinaryStringSerializer : BinaryObjectSerializer +{ + public override void Deserialize(out string obj) { - public override void Deserialize(out string obj) + var mem = new MemoryStream(); + var streamReader = new StreamReader(stream: this.reader.BaseStream); + var streamWriter = new StreamWriter(stream: mem); + int b; + while ((b = streamReader.Read()) > 0) { - var mem = new MemoryStream(); - var streamReader = new StreamReader(this.reader.BaseStream); - var streamWriter = new StreamWriter(mem); - int b; - while ((b = streamReader.Read()) > 0) - { - streamWriter.Write((byte)b); - } - - var memBuf = mem.ToArray(); - var origBytes = Convert.FromBase64CharArray(memBuf.Select(b => (char)b).ToArray(), 0, (int)mem.Length); - obj = new string(origBytes.Select(b => (char)b).ToArray()); + streamWriter.Write(value: (byte)b); } - public override void Serialize(ref string obj) - { - var stringArr = obj.ToCharArray().Select(c => (byte)c).ToArray(); - this.writer.Write(Convert.ToBase64String(stringArr, 0, stringArr.Length, Base64FormattingOptions.None)); - this.writer.Write(0); - } + var memBuf = mem.ToArray(); + var origBytes = Convert.FromBase64CharArray(inArray: memBuf.Select(selector: b => (char)b).ToArray(), + offset: 0, + length: (int)mem.Length); + obj = new string(value: origBytes.Select(selector: b => (char)b).ToArray()); + } + + public override void Serialize(ref string obj) + { + var stringArr = obj.ToCharArray().Select(selector: c => (byte)c).ToArray(); + this.writer.Write(value: Convert.ToBase64String(inArray: stringArr, + offset: 0, + length: stringArr.Length, + options: Base64FormattingOptions.None)); + this.writer.Write(value: 0); } } diff --git a/src/BrightChain.Engine/Helpers/BlockDataSerializer.cs b/src/BrightChain.Engine/Helpers/BlockDataSerializer.cs old mode 100644 new mode 100755 index 09786da1..3f47efcf --- a/src/BrightChain.Engine/Helpers/BlockDataSerializer.cs +++ b/src/BrightChain.Engine/Helpers/BlockDataSerializer.cs @@ -1,77 +1,82 @@ -namespace BrightChain.Engine.Helpers +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks.DataObjects; +using FASTER.core; + +namespace BrightChain.Engine.Helpers; + +public class BlockDataSerializer : BinaryObjectSerializer { - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks.DataObjects; - using FASTER.core; + private void DeserializePiBlock(out PiBlockData obj) + { + var offset = this.reader.ReadInt64(); + var size = this.reader.ReadInt32(); + obj = new PiBlockData(nOffset: offset, + blockSize: size); + } - public class BlockDataSerializer : BinaryObjectSerializer + private void SerializePiBlock(ref PiBlockData obj) { - private void DeserializePiBlock(out PiBlockData obj) - { - var offset = this.reader.ReadInt64(); - var size = this.reader.ReadInt32(); - obj = new PiBlockData(nOffset: offset, blockSize: size); - } + this.writer.Write(value: BlockDataType.Pi.ToString()); + this.writer.Write(value: obj.PiOffset); + this.writer.Write(value: obj.BlockSize); + } - private void SerializePiBlock(ref PiBlockData obj) - { - this.writer.Write(BlockDataType.Pi.ToString()); - this.writer.Write(obj.PiOffset); - this.writer.Write(obj.BlockSize); - } + private void DeserializeStoredBlock(out StoredBlockData obj) + { + var sizet = this.reader.ReadInt32(); + var bytes = new byte[sizet]; + this.reader.Read(buffer: bytes, + index: 0, + count: sizet); + obj = new StoredBlockData(data: new ReadOnlyMemory(array: bytes)); + } - private void DeserializeStoredBlock(out StoredBlockData obj) - { - var sizet = this.reader.ReadInt32(); - var bytes = new byte[sizet]; - this.reader.Read(bytes, 0, sizet); - obj = new StoredBlockData(new ReadOnlyMemory(bytes)); - } + private void SerializeStoredBlock(ref StoredBlockData obj) + { + this.writer.Write(value: BlockDataType.Stored.ToString()); + this.writer.Write(value: obj.Bytes.Length); + this.writer.BaseStream.Write(buffer: obj.Bytes.ToArray(), + offset: 0, + count: obj.Bytes.Length); + } + + public override void Deserialize(out BlockData obj) + { + var type = this.reader.ReadString(); + var storedBlockType = Enum.Parse( + enumType: typeof(BlockDataType), + value: type); - private void SerializeStoredBlock(ref StoredBlockData obj) + switch (storedBlockType) { - this.writer.Write(BlockDataType.Stored.ToString()); - this.writer.Write(obj.Bytes.Length); - this.writer.BaseStream.Write(obj.Bytes.ToArray(), 0, obj.Bytes.Length); + case BlockDataType.Stored: + this.DeserializeStoredBlock(obj: out var storedObj); + obj = storedObj; + return; + case BlockDataType.Pi: + this.DeserializePiBlock(obj: out var piObj); + obj = piObj; + return; + default: + throw new NotImplementedException(); } + } - public override void Deserialize(out BlockData obj) + public override void Serialize(ref BlockData obj) + { + if (obj is StoredBlockData storedObj) { - var type = this.reader.ReadString(); - var storedBlockType = Enum.Parse( - enumType: typeof(BlockDataType), - value: type); - - switch (storedBlockType) - { - case BlockDataType.Stored: - this.DeserializeStoredBlock(out StoredBlockData storedObj); - obj = storedObj; - return; - case BlockDataType.Pi: - this.DeserializePiBlock(out PiBlockData piObj); - obj = piObj; - return; - default: - throw new NotImplementedException(); - } + this.SerializeStoredBlock(obj: ref storedObj); + return; } - public override void Serialize(ref BlockData obj) + if (obj is PiBlockData piObj) { - if (obj is StoredBlockData storedObj) - { - this.SerializeStoredBlock(ref storedObj); - return; - } - else if (obj is PiBlockData piObj) - { - this.SerializePiBlock(ref piObj); - return; - } - - throw new NotImplementedException(); + this.SerializePiBlock(obj: ref piObj); + return; } + + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Helpers/BrightenedBlockStream.cs b/src/BrightChain.Engine/Helpers/BrightenedBlockStream.cs old mode 100644 new mode 100755 index 4b0ef6cf..1019a396 --- a/src/BrightChain.Engine/Helpers/BrightenedBlockStream.cs +++ b/src/BrightChain.Engine/Helpers/BrightenedBlockStream.cs @@ -1,66 +1,66 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.IO; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks; +using System; +using System.IO; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Services; - public class BrightenedBlockStream : Stream - { - private readonly Stream sourceStream; - private readonly Stream destinationStream; - private readonly BlockSize blockSize; +namespace BrightChain.Engine.Helpers; +public class BrightenedBlockStream : Stream +{ + private readonly BlockSize blockSize; + private readonly Stream destinationStream; + private readonly Stream sourceStream; - public BrightenedBlockStream(Stream sourceStream, BlockSize blockSize) - { - this.sourceStream = sourceStream; - this.blockSize = blockSize; - } - public long SourcePosition => - this.sourceStream.Position; + public BrightenedBlockStream(Stream sourceStream, BlockSize blockSize) + { + this.sourceStream = sourceStream; + this.blockSize = blockSize; + } - public override bool CanRead => - this.sourceStream.CanRead; + public long SourcePosition => + this.sourceStream.Position; - public override bool CanSeek => - this.sourceStream.CanSeek; + public override bool CanRead => + this.sourceStream.CanRead; - public override bool CanWrite => - this.sourceStream.CanWrite; + public override bool CanSeek => + this.sourceStream.CanSeek; - public long BlockLength => - (long)Math.Ceiling((double)this.sourceStream.Length / BlockSizeMap.BlockSize(this.blockSize)); + public override bool CanWrite => + this.sourceStream.CanWrite; - public override long Length => - this.BlockLength * BlockSizeMap.BlockSize(this.blockSize) * Services.BlockBrightenerService.TupleCount; + public long BlockLength => + (long)Math.Ceiling(a: (double)this.sourceStream.Length / BlockSizeMap.BlockSize(blockSize: this.blockSize)); - public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public override long Length => + this.BlockLength * BlockSizeMap.BlockSize(blockSize: this.blockSize) * BlockBrightenerService.TupleCount; - public override void Flush() - { - throw new NotImplementedException(); - } + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } + public override void Flush() + { + throw new NotImplementedException(); + } - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } + public override int Read(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } - public override void SetLength(long value) - { - throw new NotImplementedException(); - } + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Helpers/ConfigurationHelper.cs b/src/BrightChain.Engine/Helpers/ConfigurationHelper.cs deleted file mode 100644 index 291dbdd0..00000000 --- a/src/BrightChain.Engine/Helpers/ConfigurationHelper.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.IO; - using Microsoft.Extensions.Configuration; - - public static class ConfigurationHelper - { - /// - /// Gets a string containing the directory to look for configuration files in. - /// - public static string ConfigurationBaseDirectory - => AppDomain.CurrentDomain.BaseDirectory; - - /// - /// Gets a string containing the non-pathed configuration file name to look for within the base path. - /// - public static string ConfigurationFileName - => "brightChainSettings.json"; - - public static string FullyQualifiedConfigurationFileName - => Path.Combine( - path1: ConfigurationHelper.ConfigurationBaseDirectory, - path2: ConfigurationHelper.ConfigurationFileName); - - public static IConfiguration LoadConfiguration() - { - return new ConfigurationBuilder() - .SetBasePath(ConfigurationHelper.ConfigurationBaseDirectory) - .AddJsonFile( - path: ConfigurationHelper.ConfigurationFileName, - optional: false, - reloadOnChange: true) - .AddEnvironmentVariables() - .Build(); - } - } -} diff --git a/src/BrightChain.Engine/Helpers/Crc32.cs b/src/BrightChain.Engine/Helpers/Crc32.cs deleted file mode 100644 index 95481c05..00000000 --- a/src/BrightChain.Engine/Helpers/Crc32.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; - -namespace BrightChain.Engine.Helpers -{ - public class Crc32 - { - readonly uint[] table; - - public uint ComputeChecksum(byte[] bytes) - { - uint crc = 0xffffffff; - for (int i = 0; i < bytes.Length; ++i) - { - byte index = (byte)(((crc) & 0xff) ^ bytes[i]); - crc = (crc >> 8) ^ this.table[index]; - } - - return ~crc; - } - - public byte[] ComputeChecksumBytes(byte[] bytes) - { - return BitConverter.GetBytes(this.ComputeChecksum(bytes)); - } - - public static uint ComputeNewChecksum(byte[] bytes) - { - return (new Crc32()).ComputeChecksum(bytes); - } - - public Crc32() - { - uint poly = 0xedb88320; - this.table = new uint[256]; - uint temp = 0; - for (uint i = 0; i < this.table.Length; ++i) - { - temp = i; - for (int j = 8; j > 0; --j) - { - if ((temp & 1) == 1) - { - temp = (temp >> 1) ^ poly; - } - else - { - temp >>= 1; - } - } - - this.table[i] = temp; - } - } - } -} diff --git a/src/BrightChain.Engine/Helpers/Crc64.cs b/src/BrightChain.Engine/Helpers/Crc64.cs deleted file mode 100644 index 425a2cfe..00000000 --- a/src/BrightChain.Engine/Helpers/Crc64.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) Damien Guard. All rights reserved. -// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. -// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 -// Originally published at http://damieng.com/blog/2007/11/19/calculating-crc-64-in-c-and-net -// https://raw.githubusercontent.com/damieng/DamienGKit/master/CSharp/DamienG.Library/Security/Cryptography/Crc64.cs - -namespace DamienG.Security.Cryptography -{ - using System; - using System.Collections.Generic; - using System.Security.Cryptography; - - /// - /// Implements a 64-bit CRC hash algorithm for a given polynomial. - /// - /// - /// For ISO 3309 compliant 64-bit CRC's use Crc64Iso. - /// - public class Crc64 : HashAlgorithm - { - public const ulong DefaultSeed = 0x0; - - readonly ulong[] table; - - readonly ulong seed; - ulong hash; - - public Crc64(ulong polynomial) - : this(polynomial, DefaultSeed) - { - } - - public Crc64(ulong polynomial, ulong seed) - { - if (!BitConverter.IsLittleEndian) - { - throw new PlatformNotSupportedException("Not supported on Big Endian processors"); - } - - this.table = InitializeTable(polynomial); - this.seed = this.hash = seed; - } - - public override void Initialize() - { - this.hash = this.seed; - } - - protected override void HashCore(byte[] array, int ibStart, int cbSize) - { - this.hash = CalculateHash(this.hash, this.table, array, ibStart, cbSize); - } - - protected override byte[] HashFinal() - { - var hashBuffer = UInt64ToBigEndianBytes(this.hash); - this.HashValue = hashBuffer; - return hashBuffer; - } - - public override int HashSize => 64; - - protected static ulong CalculateHash(ulong seed, ulong[] table, IList buffer, int start, int size) - { - var hash = seed; - for (var i = start; i < start + size; i++) - { - unchecked - { - hash = (hash >> 8) ^ table[(buffer[i] ^ hash) & 0xff]; - } - } - - return hash; - } - - static byte[] UInt64ToBigEndianBytes(ulong value) - { - var result = BitConverter.GetBytes(value); - - if (BitConverter.IsLittleEndian) - { - Array.Reverse(result); - } - - return result; - } - - static ulong[] InitializeTable(ulong polynomial) - { - if (polynomial == Crc64Iso.Iso3309Polynomial && Crc64Iso.Table != null) - { - return Crc64Iso.Table; - } - - var createTable = CreateTable(polynomial); - - if (polynomial == Crc64Iso.Iso3309Polynomial) - { - Crc64Iso.Table = createTable; - } - - return createTable; - } - - protected static ulong[] CreateTable(ulong polynomial) - { - var createTable = new ulong[256]; - for (var i = 0; i < 256; ++i) - { - var entry = (ulong)i; - for (var j = 0; j < 8; ++j) - { - if ((entry & 1) == 1) - { - entry = (entry >> 1) ^ polynomial; - } - else - { - entry >>= 1; - } - } - - createTable[i] = entry; - } - return createTable; - } - } - - public class Crc64Iso : Crc64 - { - internal static ulong[] Table; - - public const ulong Iso3309Polynomial = 0xD800000000000000; - - public Crc64Iso() - : base(Iso3309Polynomial) - { - } - - public Crc64Iso(ulong seed) - : base(Iso3309Polynomial, seed) - { - } - - public static ulong Compute(byte[] buffer) - { - return Compute(DefaultSeed, buffer); - } - - public static ulong Compute(ulong seed, byte[] buffer) - { - if (Table == null) - { - Table = CreateTable(Iso3309Polynomial); - } - - return CalculateHash(seed, Table, buffer, 0, buffer.Length); - } - } -} diff --git a/src/BrightChain.Engine/Helpers/DebugStatusHelper.cs b/src/BrightChain.Engine/Helpers/DebugStatusHelper.cs deleted file mode 100644 index 2a4823d6..00000000 --- a/src/BrightChain.Engine/Helpers/DebugStatusHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace BrightChain.Engine.Helpers; - -public static class DebugStatusHelper -{ - public static bool IsDebugMode - { - get - { - #if DEBUG - return true; - #else - return false; - #endif - } - } -} diff --git a/src/BrightChain.Engine/Helpers/MemoryComparer.cs b/src/BrightChain.Engine/Helpers/MemoryComparer.cs deleted file mode 100644 index 349fbb56..00000000 --- a/src/BrightChain.Engine/Helpers/MemoryComparer.cs +++ /dev/null @@ -1,96 +0,0 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.Collections.Generic; - using System.Runtime.InteropServices; - - public class MemoryComparer : IEqualityComparer>, IComparer> - where T : IEquatable, IComparable - { - /// returns true if both arrays contain the exact same set of bytes. - public static bool Equals(Memory ar1, Memory ar2) - { - return 0 == Compare(ar1, ar2); - } - - /// Compares the contents of the byte arrays and returns the result. - public static int Compare(Memory ar1, Memory ar2) - { - if (ar1.IsEmpty) - { - return ar2.IsEmpty ? 0 : -1; - } - - if (ar2.IsEmpty) - { - return 1; - } - - int result = 0; - int i = 0, stop = Math.Min(ar1.Length, ar2.Length); - - for (; 0 == result && i < stop; i++) - { - T a = ar1.Slice(i).ToArray()[0]; - T b = ar2.Slice(i).ToArray()[0]; - result = a.CompareTo(b); - } - - if (result != 0) - { - return result; - } - - if (i == ar1.Length) - { - return i == ar2.Length ? 0 : -1; - } - - return 1; - } - - /// Returns a hash code the instance of the object - public static int GetHashCode(Memory memoryT) - { - var tArray = memoryT.ToArray(); - - var size = Marshal.SizeOf(tArray); - if (size == 0) - { - return 0; - } - - // Both managed and unmanaged buffers required. - var bytes = new byte[size]; - var ptr = Marshal.AllocHGlobal(size); - // Copy object byte-to-byte to unmanaged memory. - Marshal.StructureToPtr(tArray, ptr, false); - // Copy data from unmanaged memory to managed buffer. - Marshal.Copy(ptr, bytes, 0, size); - // Release unmanaged memory. - Marshal.FreeHGlobal(ptr); - - var crc32Instance = new Crc32(); - return (int)crc32Instance.ComputeChecksum(bytes); - } - - - /// Compares the contents of the byte arrays and returns the result. - int IComparer>.Compare(Memory x, Memory y) - { - return MemoryComparer.Compare(x, y); - } - - /// Returns true if the two objects are the same instance - bool IEqualityComparer>.Equals(Memory x, Memory y) - { - return 0 == MemoryComparer.Compare(x, y); - } - - /// Returns a hash code the instance of the object - int IEqualityComparer>.GetHashCode(Memory bytes) - { - return MemoryComparer.GetHashCode(bytes); - } - } -} diff --git a/src/BrightChain.Engine/Helpers/ProtoContractTestObject.cs b/src/BrightChain.Engine/Helpers/ProtoContractTestObject.cs old mode 100644 new mode 100755 index 6256828d..b4e6af90 --- a/src/BrightChain.Engine/Helpers/ProtoContractTestObject.cs +++ b/src/BrightChain.Engine/Helpers/ProtoContractTestObject.cs @@ -1,46 +1,46 @@ -namespace BrightChain.Engine.Helpers +using System; +using BrightChain.Engine.Interfaces; +using ProtoBuf; + +namespace BrightChain.Engine.Helpers; + +/// +/// test object for the Faster Cache. +/// +[ProtoContract] +public class ProtoContractTestObject : object, ITransactable, IComparable { - using System; - using BrightChain.Engine.Interfaces; - using ProtoBuf; - - /// - /// test object for the Faster Cache. - /// - [ProtoContract] - public class ProtoContractTestObject : object, ITransactable, IComparable + [ProtoMember(tag: 1)] public string id; + + public ProtoContractTestObject(string id) + { + this.id = id; + } + + public ProtoContractTestObject() + { + this.id = Guid.NewGuid().ToString(); + } + + public int CompareTo(ProtoContractTestObject other) + { + return string.Compare(strA: this.id, + strB: other.id, + comparisonType: StringComparison.Ordinal); + } + + public void Commit() + { + throw new NotImplementedException(); + } + + public void Rollback() + { + throw new NotImplementedException(); + } + + public void Dispose() { - [ProtoMember(1)] - public string id; - - public ProtoContractTestObject(string id) - { - this.id = id; - } - - public ProtoContractTestObject() - { - this.id = Guid.NewGuid().ToString(); - } - - public void Commit() - { - throw new NotImplementedException(); - } - - public void Rollback() - { - throw new NotImplementedException(); - } - - public void Dispose() - { - this.id = null; - } - - public int CompareTo(ProtoContractTestObject other) - { - return string.Compare(this.id, other.id, StringComparison.Ordinal); - } + this.id = null; } } diff --git a/src/BrightChain.Engine/Helpers/RandomDataHelper.cs b/src/BrightChain.Engine/Helpers/RandomDataHelper.cs index 1e62f6ee..ccb5c4c4 100644 --- a/src/BrightChain.Engine/Helpers/RandomDataHelper.cs +++ b/src/BrightChain.Engine/Helpers/RandomDataHelper.cs @@ -1,124 +1,134 @@ -namespace BrightChain.Engine.Helpers +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; + +namespace BrightChain.Engine.Helpers; + +public static class RandomDataHelper { - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Security.Cryptography; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - - public static class RandomDataHelper + public static byte[] RandomBytes(int length) { - public static byte[] RandomBytes(int length) + using (var rng = RandomNumberGenerator.Create()) // TODO: guarantee is CSPRNG { - using (var rng = RandomNumberGenerator.Create()) // TODO: guarantee is CSPRNG - { - var rnd = new byte[length]; - rng.GetBytes(rnd); - return rnd; - } + var rnd = new byte[length]; + rng.GetBytes(data: rnd); + return rnd; } + } + + public static ReadOnlyMemory RandomReadOnlyBytes(int length) + { + return new ReadOnlyMemory(array: RandomBytes(length: length).ToArray()); + } + + public static ReadOnlyMemory DataFiller(ReadOnlyMemory inputData, BlockSize blockSize) + { + var iBlockSize = BlockSizeMap.BlockSize(blockSize: blockSize); - public static ReadOnlyMemory RandomReadOnlyBytes(int length) + if (inputData.Length > iBlockSize) { - return new ReadOnlyMemory(RandomBytes(length: length).ToArray()); + throw new BrightChainException(message: "data length too long"); } - public static ReadOnlyMemory DataFiller(ReadOnlyMemory inputData, BlockSize blockSize) + if (inputData.Length == iBlockSize) { - var iBlockSize = BlockSizeMap.BlockSize(blockSize); + return inputData; + } - if (inputData.Length > iBlockSize) - { - throw new BrightChainException("data length too long"); - } - else if (inputData.Length == iBlockSize) - { - return inputData; - } + var bytes = new List(collection: inputData.ToArray()); + bytes.AddRange(collection: RandomBytes(length: iBlockSize - inputData.Length)); - var bytes = new List(inputData.ToArray()); - bytes.AddRange(RandomBytes(iBlockSize - inputData.Length)); + if (bytes.Count != iBlockSize) + { + throw new BrightChainException(message: "math error"); + } - if (bytes.Count != iBlockSize) - { - throw new BrightChainException("math error"); - } + return new ReadOnlyMemory(array: bytes.ToArray()); + } - return new ReadOnlyMemory(bytes.ToArray()); - } + public static FileInfo CreateRandomFile(string filePath, long totalBytes, out byte[] randomFileHash) + { + const int writeBufferSize = 1024 * 8; - public static FileInfo CreateRandomFile(string filePath, long totalBytes, out byte[] randomFileHash) + var bytesWritten = 0; + var bytesRemaining = totalBytes; + using (var sha = SHA256.Create()) { - const int writeBufferSize = 1024 * 8; - - var bytesWritten = 0; - var bytesRemaining = totalBytes; - using (SHA256 sha = SHA256.Create()) + using (var fileStream = File.OpenWrite(path: filePath)) { - using (FileStream fileStream = File.OpenWrite(filePath)) + while (bytesWritten < totalBytes) { - while (bytesWritten < totalBytes) + var finalBlock = bytesRemaining <= writeBufferSize; + var lengthToWrite = (int)(finalBlock ? bytesRemaining : writeBufferSize); + var data = RandomBytes(length: lengthToWrite); + if (lengthToWrite != data.Length) { - var finalBlock = bytesRemaining <= writeBufferSize; - var lengthToWrite = (int)(finalBlock ? bytesRemaining : writeBufferSize); - var data = RandomDataHelper.RandomBytes(lengthToWrite); - if (lengthToWrite != data.Length) - { - throw new BrightChainException(nameof(data.Length)); - } + throw new BrightChainException(message: nameof(data.Length)); + } - fileStream.Write(data, 0, data.Length); - bytesWritten += data.Length; - bytesRemaining -= data.Length; - if (finalBlock) + fileStream.Write(buffer: data, + offset: 0, + count: data.Length); + bytesWritten += data.Length; + bytesRemaining -= data.Length; + if (finalBlock) + { + if (bytesRemaining > 0) { - if (bytesRemaining > 0) - { - throw new BrightChainException(nameof(bytesRemaining)); - } - - sha.TransformFinalBlock(data, 0, data.Length); - randomFileHash = sha.Hash; - fileStream.Flush(); - fileStream.Close(); - FileInfo fileInfo = new FileInfo(filePath); - if ((totalBytes != bytesWritten) || - (bytesWritten != fileInfo.Length)) - { - throw new BrightChainException(nameof(bytesWritten)); - } - - return fileInfo; + throw new BrightChainException(message: nameof(bytesRemaining)); } - else + + sha.TransformFinalBlock(inputBuffer: data, + inputOffset: 0, + inputCount: data.Length); + randomFileHash = sha.Hash; + fileStream.Flush(); + fileStream.Close(); + var fileInfo = new FileInfo(fileName: filePath); + if (totalBytes != bytesWritten || + bytesWritten != fileInfo.Length) { - sha.TransformBlock(data, 0, lengthToWrite, null, 0); + throw new BrightChainException(message: nameof(bytesWritten)); } + + return fileInfo; } + + sha.TransformBlock(inputBuffer: data, + inputOffset: 0, + inputCount: lengthToWrite, + outputBuffer: null, + outputOffset: 0); } } - - randomFileHash = null; - return null; } - public static SourceFileInfo GenerateRandomFile(BlockSize blockSize, Func lengthFunc) - { - var fileName = Path.GetTempFileName(); - byte[] sourceFileHash; - var requestedLength = lengthFunc(blockSize); - var fileInfo = CreateRandomFile(fileName, requestedLength, out sourceFileHash); - var sourceInfo = new SourceFileInfo(fileInfo: fileInfo, blockSize: blockSize); - if (Utilities.HashToFormattedString(sourceFileHash) != Utilities.HashToFormattedString(sourceInfo.SourceId.HashBytes.ToArray())) - { - throw new BrightChainException(nameof(sourceFileHash)); - } + randomFileHash = null; + return null; + } - return sourceInfo; + public static SourceFileInfo GenerateRandomFile(BlockSize blockSize, Func lengthFunc) + { + var fileName = Path.GetTempFileName(); + byte[] sourceFileHash; + var requestedLength = lengthFunc(arg: blockSize); + var fileInfo = CreateRandomFile(filePath: fileName, + totalBytes: requestedLength, + randomFileHash: out sourceFileHash); + var sourceInfo = new SourceFileInfo(fileInfo: fileInfo, + blockSize: blockSize); + if (NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: sourceFileHash) != + NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: sourceInfo.SourceId.HashBytes.ToArray())) + { + throw new BrightChainException(message: nameof(sourceFileHash)); } + + return sourceInfo; } } diff --git a/src/BrightChain.Engine/Helpers/ReadOnlyMemoryComparer.cs b/src/BrightChain.Engine/Helpers/ReadOnlyMemoryComparer.cs deleted file mode 100644 index ff43f56e..00000000 --- a/src/BrightChain.Engine/Helpers/ReadOnlyMemoryComparer.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.Collections.Generic; - using System.Runtime.InteropServices; - - /// - /// Poor implementation of a 1:1 comparator on a ReadOnlyMemory - /// - /// - public sealed class ReadOnlyMemoryComparer : IEqualityComparer>, IComparer> - where T : IEquatable, IComparable - { - /// returns true if both arrays contain the exact same set of bytes. - public static bool Equals(ReadOnlyMemory ar1, ReadOnlyMemory ar2) - { - return 0 == Compare(ar1, ar2); - } - - /// Compares the contents of the byte arrays and returns the result. - public static int Compare(ReadOnlyMemory ar1, ReadOnlyMemory ar2) - { - if (ar1.IsEmpty) - { - return ar2.IsEmpty ? 0 : -1; - } - - if (ar2.IsEmpty) - { - return 1; - } - - int result = 0; - int i = 0, stop = Math.Min(ar1.Length, ar2.Length); - - for (; 0 == result && i < stop; i++) - { - T a = ar1.Slice(i).ToArray()[0]; - T b = ar2.Slice(i).ToArray()[0]; - result = a.CompareTo(b); - } - - if (result != 0) - { - return result; - } - - if (i == ar1.Length) - { - return i == ar2.Length ? 0 : -1; - } - - return 1; - } - - /// Returns a hash code the instance of the object - public static int GetHashCode(ReadOnlyMemory memoryT) - { - var tArray = memoryT.ToArray(); - - var size = Marshal.SizeOf(tArray); - if (size == 0) - { - return 0; - } - - // Both managed and unmanaged buffers required. - var bytes = new byte[size]; - var ptr = Marshal.AllocHGlobal(size); - // Copy object byte-to-byte to unmanaged memory. - Marshal.StructureToPtr(tArray, ptr, false); - // Copy data from unmanaged memory to managed buffer. - Marshal.Copy(ptr, bytes, 0, size); - // Release unmanaged memory. - Marshal.FreeHGlobal(ptr); - - var crc32Instance = new Crc32(); - return (int)crc32Instance.ComputeChecksum(bytes); - } - - - /// Compares the contents of the byte arrays and returns the result. - int IComparer>.Compare(ReadOnlyMemory x, ReadOnlyMemory y) - { - return ReadOnlyMemoryComparer.Compare(x, y); - } - - /// Returns true if the two objects are the same instance - bool IEqualityComparer>.Equals(ReadOnlyMemory x, ReadOnlyMemory y) - { - return 0 == ReadOnlyMemoryComparer.Compare(x, y); - } - - /// Returns a hash code the instance of the object - int IEqualityComparer>.GetHashCode(ReadOnlyMemory bytes) - { - return ReadOnlyMemoryComparer.GetHashCode(bytes); - } - } -} diff --git a/src/BrightChain.Engine/Helpers/Utilities.cs b/src/BrightChain.Engine/Helpers/Utilities.cs old mode 100644 new mode 100755 index f47d1e1e..57bb3ffc --- a/src/BrightChain.Engine/Helpers/Utilities.cs +++ b/src/BrightChain.Engine/Helpers/Utilities.cs @@ -1,81 +1,47 @@ -namespace BrightChain.Engine.Helpers -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; - public static class Utilities - { - public static Version GetAssemblyVersionForType(Type assemblyType = null) => - System.Reflection.Assembly.GetAssembly( - type: assemblyType is null ? typeof(Services.BrightBlockService) : assemblyType).GetName().Version; +namespace BrightChain.Engine.Helpers; - public static async IAsyncEnumerable ReadOnlyMemoryToAsyncEnumerable(ReadOnlyMemory source) - { - foreach (var b in source.ToArray()) - { - yield return b; - } - } - - public static async IAsyncEnumerable ParallelReadOnlyMemoryXORToAsyncEnumerable(ReadOnlyMemory sourceA, ReadOnlyMemory sourceB) +public static class Utilities +{ + public static ReadOnlyMemory ReadOnlyMemoryXOR(ReadOnlyMemory sourceA, ReadOnlyMemory sourceB) + { + if (sourceA.Length != sourceB.Length) { - if (sourceA.Length != sourceB.Length) - { - throw new BrightChainException(nameof(sourceB.Length)); - } - - var aArray = sourceA.ToArray(); - var bArray = sourceB.ToArray(); - for (int i = 0; i < aArray.Length; i++) - { - yield return (byte)(aArray[i] ^ bArray[i]); - } + throw new Exception(message: nameof(sourceB.Length)); } - public static ReadOnlyMemory ReadOnlyMemoryXOR(ReadOnlyMemory sourceA, ReadOnlyMemory sourceB) + var aArray = sourceA.ToArray(); + var bArray = sourceB.ToArray(); + var cArray = new byte[aArray.Length]; + for (var i = 0; i < aArray.Length; i++) { - if (sourceA.Length != sourceB.Length) - { - throw new BrightChainException(nameof(sourceB.Length)); - } - - var aArray = sourceA.ToArray(); - var bArray = sourceB.ToArray(); - var cArray = new byte[aArray.Length]; - for (int i = 0; i < aArray.Length; i++) - { - cArray[i] = (byte)(aArray[i] ^ bArray[i]); - } - - return new ReadOnlyMemory(cArray); + cArray[i] = (byte)(aArray[i] ^ bArray[i]); } - public static string HashToFormattedString(byte[] hashBytes) - { - return BitConverter.ToString(hashBytes) - .Replace("-", string.Empty) - .ToLower(culture: System.Globalization.CultureInfo.InvariantCulture); - } + return new ReadOnlyMemory(array: cArray); + } - /// - /// Generate a hash of an empty array to determine the block hash byte length - /// Used during testing. - /// - /// Block size to generate zero vector for. - /// Hash of the zero vector for the block. - public static void GenerateZeroVectorAndVerify(BlockSize blockSize, out BlockHash blockHash) + /// + /// Generate a hash of an empty array to determine the block hash byte length + /// Used during testing. + /// + /// Block size to generate zero vector for. + /// Hash of the zero vector for the block. + public static void GenerateZeroVectorAndVerify(BlockSize blockSize, out BlockHash blockHash) + { + var blockBytes = new byte[BlockSizeMap.BlockSize(blockSize: blockSize)]; + Array.Fill(array: blockBytes, + value: 0); + blockHash = new BlockHash(blockType: typeof(Block), + dataBytes: blockBytes); + if (blockHash.HashBytes.Length != BlockHash.HashSize / 8) { - var blockBytes = new byte[BlockSizeMap.BlockSize(blockSize)]; - Array.Fill(blockBytes, 0); - blockHash = new BlockHash(blockType: typeof(Block), dataBytes: blockBytes); - if (blockHash.HashBytes.Length != (BlockHash.HashSize / 8)) - { - throw new BrightChainException("BlockHash size mismatch."); - } + throw new BrightChainException(message: "BlockHash size mismatch."); } } } diff --git a/src/BrightChain.Engine/Interfaces/IBlock.cs b/src/BrightChain.Engine/Interfaces/IBlock.cs old mode 100644 new mode 100755 index 7be2cff2..f0282e84 --- a/src/BrightChain.Engine/Interfaces/IBlock.cs +++ b/src/BrightChain.Engine/Interfaces/IBlock.cs @@ -1,78 +1,77 @@ -namespace BrightChain.Engine.Interfaces -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Contracts; - using BrightChain.Engine.Models.Entities; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Models.Nodes; +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Contracts; +using BrightChain.Engine.Models.Entities; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Models.Nodes; + +namespace BrightChain.Engine.Interfaces; +/// +/// Basic description for a block. +/// +public interface IBlock : IDisposable, IComparable, IValidatable +{ /// - /// Basic description for a block. + /// Gets the block's SHA-256 hash. /// - public interface IBlock : IDisposable, IComparable, IValidatable - { - /// - /// Gets the block's SHA-256 hash. - /// - BlockHash Id { get; } + BlockHash Id { get; } - /// - /// Gets a BlockSize enum associated with it's data length. - /// - BlockSize BlockSize { get; } + /// + /// Gets a BlockSize enum associated with it's data length. + /// + BlockSize BlockSize { get; } - /// - /// Function to XOR this block's data with another. - /// - /// Block to XOR with. - /// Returns resultant block with its constituent blocks. - ReadOnlyMemory XOR(Block other); + /// + /// Gets the parameters of the storage contract for this block. + /// + StorageContract StorageContract { get; set; } - /// - /// Function to XOR this block's data with an array of others. - /// - /// - /// - ReadOnlyMemory XOR(IEnumerable others); + /// + /// Gets only the raw data for the block and none of the metadata. The hash is based only on this. + /// + BlockData StoredData { get; } - BlockSignature Sign(Agent user, string password); + /// + /// Gets the node that originated the block. + /// + BrightChainNode OriginatingNode { get; } - /// - /// Gets the parameters of the storage contract for this block. - /// - StorageContract StorageContract { get; set; } + /// + /// Gets the signature hash of the data by the committer. + /// + BlockSignature Signature { get; } - /// - /// Gets only the raw data for the block and none of the metadata. The hash is based only on this. - /// - BlockData StoredData { get; } + /// + /// Whether a signature hash is present + /// + bool Signed { get; } - /// - /// Gets the node that originated the block. - /// - BrightChainNode OriginatingNode { get; } + /// + /// Whether the signature hash has been compared against the data + /// + bool SignatureVerified { get; } - /// - /// Gets the signature hash of the data by the committer. - /// - BlockSignature Signature { get; } + string OriginalAssemblyTypeString { get; } - /// - /// Whether a signature hash is present - /// - bool Signed { get; } + string AssemblyVersion { get; } - /// - /// Whether the signature hash has been compared against the data - /// - bool SignatureVerified { get; } + /// + /// Function to XOR this block's data with another. + /// + /// Block to XOR with. + /// Returns resultant block with its constituent blocks. + ReadOnlyMemory XOR(Block other); - string OriginalAssemblyTypeString { get; } + /// + /// Function to XOR this block's data with an array of others. + /// + /// + /// + ReadOnlyMemory XOR(IEnumerable others); - string AssemblyVersion { get; } - } + BlockSignature Sign(Agent user, string password); } diff --git a/src/BrightChain.Engine/Interfaces/IBrightenedBlock.cs b/src/BrightChain.Engine/Interfaces/IBrightenedBlock.cs old mode 100644 new mode 100755 index 275f109e..a7295ac4 --- a/src/BrightChain.Engine/Interfaces/IBrightenedBlock.cs +++ b/src/BrightChain.Engine/Interfaces/IBrightenedBlock.cs @@ -1,30 +1,32 @@ -namespace BrightChain.Engine.Interfaces +using System; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Interfaces; + +/// +/// Basic members for a block that is to be transactable. +/// +public interface IBrightenedBlock : ITransactableBlock, ITransactable, IDisposable { - using System; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; + /// + /// Associated cache manager for this block + /// + ICacheManager CacheManager { get; } + + /// + /// Whether this block has been committed to the block store + /// + bool Committed { get; } + + /// + /// Whether this block should be allowed to be committed to the block store + /// + bool AllowCommit { get; } /// - /// Basic members for a block that is to be transactable. + /// Update the cache manager association for the block /// - public interface IBrightenedBlock : ITransactableBlock, ITransactable, IDisposable - { - /// - /// Associated cache manager for this block - /// - ICacheManager CacheManager { get; } - /// - /// Update the cache manager association for the block - /// - /// - void SetCacheManager(ICacheManager cacheManager); - /// - /// Whether this block has been committed to the block store - /// - bool Committed { get; } - /// - /// Whether this block should be allowed to be committed to the block store - /// - bool AllowCommit { get; } - } + /// + void SetCacheManager(ICacheManager cacheManager); } diff --git a/src/BrightChain.Engine/Interfaces/IBrightenedBlockCacheManager.cs b/src/BrightChain.Engine/Interfaces/IBrightenedBlockCacheManager.cs old mode 100644 new mode 100755 index f0b381a3..24b06dcc --- a/src/BrightChain.Engine/Interfaces/IBrightenedBlockCacheManager.cs +++ b/src/BrightChain.Engine/Interfaces/IBrightenedBlockCacheManager.cs @@ -1,38 +1,37 @@ -namespace BrightChain.Engine.Interfaces -{ - using System.Collections.Generic; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Models.Nodes; +using System.Collections.Generic; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Models.Nodes; + +namespace BrightChain.Engine.Interfaces; +/// +/// Basic guaranteed members of the cache system. +/// +public interface IBrightenedBlockCacheManager : ICacheManager +{ /// - /// Basic guaranteed members of the cache system. + /// Adds a key to the cache if it is not already present /// - public interface IBrightenedBlockCacheManager : ICacheManager - { - /// - /// Adds a key to the cache if it is not already present - /// - /// key to palce in the cache. - /// whether to allow duplicate to update metadata. - void Set(BrightenedBlock value, bool updateMetadataOnly = false); + /// key to palce in the cache. + /// whether to allow duplicate to update metadata. + void Set(BrightenedBlock value, bool updateMetadataOnly = false); - /// - /// Adds all keys to the cache if not already present - /// - /// key to palce in the cache - void SetAll(IEnumerable value); + /// + /// Adds all keys to the cache if not already present + /// + /// key to palce in the cache + void SetAll(IEnumerable value); - /// - /// Adds all keys to the cache if not already present - /// - /// key to palce in the cache - void SetAllAsync(IAsyncEnumerable value); + /// + /// Adds all keys to the cache if not already present + /// + /// key to palce in the cache + void SetAllAsync(IAsyncEnumerable value); - /// - /// Add a node that the cache manager should trust. - /// - /// Node submitting the block to the cache. - void Trust(BrightChainNode node); - } + /// + /// Add a node that the cache manager should trust. + /// + /// Node submitting the block to the cache. + void Trust(BrightChainNode node); } diff --git a/src/BrightChain.Engine/Interfaces/ICacheManager.cs b/src/BrightChain.Engine/Interfaces/ICacheManager.cs old mode 100644 new mode 100755 index 629725e5..2294d1d6 --- a/src/BrightChain.Engine/Interfaces/ICacheManager.cs +++ b/src/BrightChain.Engine/Interfaces/ICacheManager.cs @@ -1,56 +1,54 @@ -namespace BrightChain.Engine.Interfaces +using System; +using BrightChain.Engine.Models.Events; + +namespace BrightChain.Engine.Interfaces; + +/// +/// Basic guaranteed members of the cache system. Notably the system is heavily dependent on the BPlusTree caches which have transaction +/// support. +/// +/// +/// +public interface ICacheManager + where Tkey : IComparable { - using System; - using BrightChain.Engine.Models.Events; + delegate void CacheMissEventHandler(object sender, CacheEventArgs cacheEventArgs); + + delegate void KeyAddedEventHandler(object sender, CacheEventArgs cacheEventArgs); + + delegate void KeyExpiredEventHandler(object sender, CacheEventArgs cacheEventArgs); + + delegate void KeyRemovedEventHandler(object sender, CacheEventArgs cacheEventArgs); + + /// + /// Retrieves an object from the cache if it is present + /// + /// key to retrieve + /// returns requested block or throws + Tvalue Get(Tkey blockHash); + + /// + /// Adds a key to the cache if it is not already present + /// + /// key to palce in the cache + void Set(Tkey key, Tvalue value); + + /// + /// Returns whether the cache manager has the given key and it is not expired + /// + /// key to check the collection for + /// boolean with whether key is present + bool Contains(Tkey key); /// - /// Basic guaranteed members of the cache system. Notably the system is heavily dependent on the BPlusTree caches which have transaction support. /// - /// - /// - public interface ICacheManager - where Tkey : IComparable - { - /// - /// Retrieves an object from the cache if it is present - /// - /// key to retrieve - /// returns requested block or throws - Tvalue Get(Tkey blockHash); - - /// - /// Adds a key to the cache if it is not already present - /// - /// key to palce in the cache - void Set(Tkey key, Tvalue value); - - /// - /// - /// Returns whether the cache manager has the given key and it is not expired - /// - /// key to check the collection for - /// boolean with whether key is present - bool Contains(Tkey key); - - /// - /// - /// - /// - /// - /// - bool Drop(Tkey key, bool noCheckContains = false); - - delegate void KeyAddedEventHandler(object sender, CacheEventArgs cacheEventArgs); - - delegate void KeyExpiredEventHandler(object sender, CacheEventArgs cacheEventArgs); - - delegate void KeyRemovedEventHandler(object sender, CacheEventArgs cacheEventArgs); - - delegate void CacheMissEventHandler(object sender, CacheEventArgs cacheEventArgs); - - event KeyAddedEventHandler KeyAdded; - event KeyExpiredEventHandler KeyExpired; - event KeyRemovedEventHandler KeyRemoved; - event CacheMissEventHandler CacheMiss; - } + /// + /// + /// + bool Drop(Tkey key, bool noCheckContains = false); + + event KeyAddedEventHandler KeyAdded; + event KeyExpiredEventHandler KeyExpired; + event KeyRemovedEventHandler KeyRemoved; + event CacheMissEventHandler CacheMiss; } diff --git a/src/BrightChain.Engine/Interfaces/IDataHash.cs b/src/BrightChain.Engine/Interfaces/IDataHash.cs old mode 100644 new mode 100755 index d160300f..311c55cd --- a/src/BrightChain.Engine/Interfaces/IDataHash.cs +++ b/src/BrightChain.Engine/Interfaces/IDataHash.cs @@ -1,30 +1,29 @@ -namespace BrightChain.Engine.Interfaces -{ - using System; +using System; + +namespace BrightChain.Engine.Interfaces; +/// +/// Type box interface for data hash results. +/// +public interface IDataHash : IFormattable +{ /// - /// Type box interface for data hash results. + /// Size in bits of the hash. /// - public interface IDataHash : IFormattable - { - /// - /// Size in bits of the hash. - /// - const int HashSize = 0; + const int HashSize = 0; - /// - /// Gets the raw bytes of the hash value. - /// - ReadOnlyMemory HashBytes { get; } + /// + /// Gets the raw bytes of the hash value. + /// + ReadOnlyMemory HashBytes { get; } - /// - /// Gets a long containing the length of the source data the hash was computed on. - /// - public long SourceDataLength { get; } + /// + /// Gets a long containing the length of the source data the hash was computed on. + /// + public long SourceDataLength { get; } - /// - /// Gets a value indicating whether the hash value was computed from data or given from bytes. A computed hash is verified. - /// - bool Computed { get; } - } + /// + /// Gets a value indicating whether the hash value was computed from data or given from bytes. A computed hash is verified. + /// + bool Computed { get; } } diff --git a/src/BrightChain.Engine/Interfaces/IDataSignature.cs b/src/BrightChain.Engine/Interfaces/IDataSignature.cs old mode 100644 new mode 100755 index cf1c82a8..a6e69852 --- a/src/BrightChain.Engine/Interfaces/IDataSignature.cs +++ b/src/BrightChain.Engine/Interfaces/IDataSignature.cs @@ -1,12 +1,12 @@ using System; -namespace BrightChain.Engine.Interfaces +namespace BrightChain.Engine.Interfaces; + +public interface IDataSignature : IFormattable { - public interface IDataSignature : IFormattable - { - /// ` - /// raw bytes of the hash value - /// - ReadOnlyMemory SignatureHashBytes { get; } - } + /// + /// ` + /// raw bytes of the hash value + /// + ReadOnlyMemory SignatureHashBytes { get; } } diff --git a/src/BrightChain.Engine/Interfaces/ITransactable.cs b/src/BrightChain.Engine/Interfaces/ITransactable.cs old mode 100644 new mode 100755 index 77207c56..7a4544ba --- a/src/BrightChain.Engine/Interfaces/ITransactable.cs +++ b/src/BrightChain.Engine/Interfaces/ITransactable.cs @@ -1,6 +1,5 @@ -namespace BrightChain.Engine.Interfaces +namespace BrightChain.Engine.Interfaces; + +public interface ITransactable { - public interface ITransactable - { - } } diff --git a/src/BrightChain.Engine/Interfaces/ITransactableBlock.cs b/src/BrightChain.Engine/Interfaces/ITransactableBlock.cs old mode 100644 new mode 100755 index 530113bd..f7350dfc --- a/src/BrightChain.Engine/Interfaces/ITransactableBlock.cs +++ b/src/BrightChain.Engine/Interfaces/ITransactableBlock.cs @@ -1,27 +1,24 @@ using System; -using BrightChain.Engine.Enumerations; using BrightChain.Engine.Models.Blocks; using BrightChain.Engine.Models.Hashes; -namespace BrightChain.Engine.Interfaces +namespace BrightChain.Engine.Interfaces; + +/// +/// Basic members for a block that is to be transactable (currently tied to BPlus tree) +/// +public interface ITransactableBlock : IBlock, ITransactable, IDisposable { /// - /// Basic members for a block that is to be transactable (currently tied to BPlus tree) + /// Associated cache manager for this block + /// + ICacheManager CacheManager { get; } + + bool AllowCommit { get; } + + /// + /// Update the cache manager association for the block /// - public interface ITransactableBlock : IBlock, ITransactable, IDisposable - { - /// - /// Associated cache manager for this block - /// - ICacheManager CacheManager { get; } - /// - /// Update the cache manager association for the block - /// - /// - void SetCacheManager(ICacheManager cacheManager); - /// - /// Whether this block has been committed to the block store - /// - TransactionStatus State { get; } - } + /// + void SetCacheManager(ICacheManager cacheManager); } diff --git a/src/BrightChain.Engine/Interfaces/IValidatable.cs b/src/BrightChain.Engine/Interfaces/IValidatable.cs old mode 100644 new mode 100755 index 685204b2..82217125 --- a/src/BrightChain.Engine/Interfaces/IValidatable.cs +++ b/src/BrightChain.Engine/Interfaces/IValidatable.cs @@ -1,12 +1,11 @@ using System.Collections.Generic; using BrightChain.Engine.Exceptions; -namespace BrightChain.Engine.Interfaces +namespace BrightChain.Engine.Interfaces; + +public interface IValidatable { - public interface IValidatable - { - public IEnumerable ValidationExceptions { get; } + public IEnumerable ValidationExceptions { get; } - public bool Validate(); - } + public bool Validate(); } diff --git a/src/BrightChain.Engine/Models/Agents/BrightChainAgent.cs b/src/BrightChain.Engine/Models/Agents/BrightChainAgent.cs old mode 100644 new mode 100755 index bbf3b35e..ae995384 --- a/src/BrightChain.Engine/Models/Agents/BrightChainAgent.cs +++ b/src/BrightChain.Engine/Models/Agents/BrightChainAgent.cs @@ -1,23 +1,23 @@ -namespace BrightChain.Engine.Models.Agents -{ - using System; - using System.Security.Cryptography; - using BrightChain.Engine.Models.Keys; +using System; +using System.Security.Cryptography; +using BrightChain.Engine.Models.Keys; - public class BrightChainAgent - { - public Guid Id { get; } +namespace BrightChain.Engine.Models.Agents; - private BrightChainKey AgentKey { get; } +public class BrightChainAgent +{ + public Guid Id { get; } - public ECDiffieHellmanCngPublicKey PublicKey + private BrightChainKey AgentKey { get; } + + public ECDiffieHellmanCngPublicKey PublicKey + { + get { - get - { - var keyInfo = this.AgentKey.ExportSubjectPublicKeyInfo(); + var keyInfo = this.AgentKey.ExportSubjectPublicKeyInfo(); - return ECDiffieHellmanCngPublicKey.FromByteArray(keyInfo, CngKeyBlobFormat.EccPublicBlob) as ECDiffieHellmanCngPublicKey; - } + return ECDiffieHellmanCngPublicKey.FromByteArray(publicKeyBlob: keyInfo, + format: CngKeyBlobFormat.EccPublicBlob) as ECDiffieHellmanCngPublicKey; } } } diff --git a/src/BrightChain.Engine/Models/BlockSessionAddresses.cs b/src/BrightChain.Engine/Models/BlockSessionAddresses.cs new file mode 100755 index 00000000..f8295a4a --- /dev/null +++ b/src/BrightChain.Engine/Models/BlockSessionAddresses.cs @@ -0,0 +1,11 @@ +namespace BrightChain.Engine.Faster; + +public struct BlockSessionAddresses +{ + public readonly long Address; + + public BlockSessionAddresses(long address) + { + this.Address = address; + } +} diff --git a/src/BrightChain.Engine/Models/BlockSessionCheckpoint.cs b/src/BrightChain.Engine/Models/BlockSessionCheckpoint.cs new file mode 100755 index 00000000..7b2de6fc --- /dev/null +++ b/src/BrightChain.Engine/Models/BlockSessionCheckpoint.cs @@ -0,0 +1,17 @@ +using System; + +namespace BrightChain.Engine.Faster; + +public struct BlockSessionCheckpoint +{ + public readonly bool Success; + public readonly bool CheckpointResult; + public readonly Guid CheckpointGuids; + + public BlockSessionCheckpoint(bool success, bool result, Guid guid) + { + this.Success = success; + this.CheckpointResult = result; + this.CheckpointGuids = guid; + } +} diff --git a/src/BrightChain.Engine/Models/BlockSessionContext.cs b/src/BrightChain.Engine/Models/BlockSessionContext.cs new file mode 100755 index 00000000..72a04ca8 --- /dev/null +++ b/src/BrightChain.Engine/Models/BlockSessionContext.cs @@ -0,0 +1,166 @@ +using System; +using System.Threading.Tasks; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Functions; +using BrightChain.Engine.Faster.Indices; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; +using Microsoft.Extensions.Logging; + +namespace BrightChain.Engine.Faster; + +public class BlockSessionContext : IDisposable +{ + public readonly + ClientSession + BlockDataBlobSession; + + private readonly ILogger logger; + + public readonly + ClientSession SharedCacheSession; + + public BlockSessionContext( + ILogger logger, + ClientSession + dataSession, + ClientSession cblIndicesSession) + { + this.logger = logger; + this.BlockDataBlobSession = dataSession; + this.SharedCacheSession = cblIndicesSession; + } + + public string SessionID => + string.Format(format: "{0}-{1}", + arg0: this.BlockDataBlobSession.ID, + arg1: this.SharedCacheSession.ID); + + public void Dispose() + { + this.BlockDataBlobSession.Dispose(); + this.SharedCacheSession.Dispose(); + } + + public bool Contains(BlockHash blockHash) + { + var dataResultTuple = this.BlockDataBlobSession.Read(key: blockHash); + + return + dataResultTuple.status.Found; + } + + public bool Drop(BlockHash blockHash, bool complete = true) + { + if (!this.BlockDataBlobSession.Delete(key: blockHash).IsCompletedSuccessfully) + { + // TODO: rollback? + return false; + } + + // TODO: determine when/where & implement index deletions relevant to the block + + if (complete) + { + return this.CompletePending(waitForCommit: false); + } + + return true; + } + + private static string BlockMetadataIndexKey(BlockHash blockHash) + { + return string.Format(format: "Metadata:{0}", + arg0: blockHash.ToString()); + } + + public BrightenedBlock Get(BlockHash blockHash) + { + var dataResultTuple = this.BlockDataBlobSession.Read(key: blockHash); + + if (!dataResultTuple.status.Found) + { + throw new IndexOutOfRangeException(message: blockHash.ToString()); + } + + var result = this.SharedCacheSession.Read(key: BlockMetadataIndexKey(blockHash: blockHash)); + + if (result.status.IsFaulted) + { + throw new BrightChainException( + message: string.Format(format: "metadata fetch error: {0}", + arg0: result.status.ToString())); + } + + if (!result.status.Found) + { + throw new IndexOutOfRangeException(message: blockHash.ToString()); + } + + if (result.output is BlockMetadataIndexValue blockMetadata) + { + var block = blockMetadata.Block; + + block.StoredData = dataResultTuple.output; + + if (!block.Validate()) + { + throw new BrightChainValidationEnumerableException(exceptions: block.ValidationExceptions, + message: "Failed to reload block from store"); + } + + return block; + } + + throw new BrightChainException(message: "Unexpected index result type for key"); + } + + public void Upsert(BrightenedBlock block, bool completePending = false) + { + var resultStatus = this.SharedCacheSession.Upsert( + key: BlockMetadataIndexKey(blockHash: block.Id), + desiredValue: new BlockMetadataIndexValue(block: block)); + + if (!resultStatus.IsCompletedSuccessfully) + { + throw new BrightChainException(message: "Unable to store block"); + } + + resultStatus = this.BlockDataBlobSession.Upsert(key: block.Id, + desiredValue: block.StoredData); + if (!resultStatus.IsCompletedSuccessfully) + { + throw new BrightChainException(message: "Unable to store block"); + } + + if (completePending) + { + this.CompletePending(waitForCommit: false); + } + } + + public async Task WaitForCommitAsync() + { + await Task.WhenAll(this.BlockDataBlobSession.WaitForCommitAsync().AsTask(), + this.SharedCacheSession.WaitForCommitAsync().AsTask()).ConfigureAwait(continueOnCapturedContext: false); + } + + public bool CompletePending(bool waitForCommit) + { + var d = this.BlockDataBlobSession.CompletePending(wait: waitForCommit); + var c = this.SharedCacheSession.CompletePending(wait: waitForCommit); + + // broken out to prevent short circuit + return d && c; + } + + public async Task CompletePendingAsync(bool waitForCommit) + { + Task.WaitAll(this.BlockDataBlobSession.CompletePendingAsync(waitForCommit: waitForCommit).AsTask(), + this.SharedCacheSession.CompletePendingAsync(waitForCommit: waitForCommit).AsTask()); + } +} diff --git a/src/BrightChain.Engine/Models/Blocks/Block.cs b/src/BrightChain.Engine/Models/Blocks/Block.cs old mode 100644 new mode 100755 index 11149a4d..47b8c82d --- a/src/BrightChain.Engine/Models/Blocks/Block.cs +++ b/src/BrightChain.Engine/Models/Blocks/Block.cs @@ -1,421 +1,427 @@ -namespace BrightChain.Engine.Models.Blocks +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Extensions; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Contracts; +using BrightChain.Engine.Models.Entities; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Models.Nodes; +using BrightChain.Engine.Services.CacheManagers.Block; +using Ent; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks; + +using static EntCalc; + +/// +/// The block is the base unit persisted to disk. +/// +[DataContract] +[ProtoContract] +[ProtoInclude(tag: 1, + knownType: typeof(BrightenedBlock))] +[ProtoInclude(tag: 2, + knownType: typeof(RootBlock))] +[ProtoInclude(tag: 3, + knownType: typeof(RandomizerBlock))] +[ProtoInclude(tag: 4, + knownType: typeof(BrightenedBlock))] +[ProtoInclude(tag: 5, + knownType: typeof(ConstituentBlockListBlock))] +[ProtoInclude(tag: 6, + knownType: typeof(SuperConstituentBlockListBlock))] +[ProtoInclude(tag: 7, + knownType: typeof(ChainLinq<>))] +public abstract class Block : IBlock, IComparable, IComparable, IEquatable, IEquatable { - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using System.Runtime.Serialization; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Extensions; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Contracts; - using BrightChain.Engine.Models.Entities; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Models.Nodes; - using BrightChain.Engine.Services.CacheManagers.Block; - using Ent; - using ProtoBuf; - using static Ent.EntCalc; + public readonly Type OriginalType; /// - /// The block is the base unit persisted to disk. + /// Initializes a new instance of the class. + /// Construct a block from the given parameters and data. /// - [DataContract] - [ProtoContract] - [ProtoInclude(1, typeof(BrightenedBlock))] - [ProtoInclude(2, typeof(RootBlock))] - [ProtoInclude(3, typeof(RandomizerBlock))] - [ProtoInclude(4, typeof(BrightenedBlock))] - [ProtoInclude(5, typeof(ConstituentBlockListBlock))] - [ProtoInclude(6, typeof(SuperConstituentBlockListBlock))] - [ProtoInclude(7, typeof(ChainLinq<>))] - public abstract class Block : IBlock, IComparable, IComparable, IEquatable, IEquatable + /// + /// + public Block(BlockParams blockParams, ReadOnlyMemory data, IEnumerable constituentBlockHashes = null) { - [ProtoMember(1)] - public BlockHash Id { get; } + if (this is RootBlock) + { + // it is much easier to validate that we're the only rootblock at the TransactableBlock level where we know the cache manager + // TODO: there can only be one + this.BlockSize = blockParams.BlockSize; + } + else + { + var detectedBlockSize = BlockSizeMap.BlockSize(blockSize: data.Length); - [ProtoMember(2)] - public StorageContract StorageContract { get; set; } + if (blockParams.BlockSize != BlockSize.Unknown && detectedBlockSize != blockParams.BlockSize) + { + throw new BrightChainException(message: "Block size mismatch"); + } - /// - /// Gets the bytes associated with this block. - /// Notably, the StoredData is NOT part of the proto contract. - /// - public BlockData StoredData { get; internal set; } + this.BlockSize = detectedBlockSize; + } - public ReadOnlyMemory Bytes => this.StoredData.Bytes; + var assembly = Assembly.GetEntryAssembly(); + var versionAttribute = assembly.GetCustomAttribute(); + + this.StorageContract = new StorageContract( + RequestTime: blockParams.RequestTime, + KeepUntilAtLeast: blockParams.KeepUntilAtLeast, + ByteCount: data.Length, + PrivateEncrypted: blockParams.PrivateEncrypted, + redundancyContractType: blockParams.Redundancy); + this.StoredData = new StoredBlockData(data: data); + this.Id = new BlockHash(block: this); // must happen after data is in place + this.ConstituentBlocks = constituentBlockHashes is null ? new BlockHash[] { } : constituentBlockHashes; + this.OriginatingNode = null; + this.Signature = null; + this.SignatureVerified = false; + this.RevocationCertificates = new List(); + this.OriginalType = blockParams.OriginalType; + this.OriginalAssemblyTypeString = this.OriginalType.AssemblyQualifiedName; + this.AssemblyVersion = versionAttribute.InformationalVersion; + this.HashVerified = this.Validate(); // also fills in any validation errors in the array + } - public string Base58Data => this.StoredData.Base58Data; + public ReadOnlyMemory Bytes => this.StoredData.Bytes; - public string Base58Id => this.Id.Base58; + public string Base58Data => this.StoredData.Base58Data; - public byte ByteAt(int index) - { - return this.StoredData.Bytes.Slice(index).ToArray()[0]; - } + public string Base58Id => this.Id.Base58; - public BlockSize BlockSize { get; } + public bool HashVerified { get; } - public bool HashVerified { get; private set; } + /// + /// For private encrypted files, a special token encrypted with the original user's key will allow revocation + /// + [ProtoMember(tag: 8)] + public IEnumerable RevocationCertificates { get; internal set; } - /// - /// Gets a BlockSignature containing a signature of the block's hash and all other contents of metadata except signature. - /// - [ProtoMember(4)] - public BlockSignature Signature { get; internal set; } + /// + /// Gets a boolean whether the revocation list contains possible revocation tokens. + /// + public bool Revokable => this.RevocationCertificates.Count() > 0; - public bool Signed => (this.Signature is not null); + /// + /// Gets or sets a list of the blocks, in order, required to complete this block. Not persisted to disk. + /// Generally only used during construction of a chain + /// + public IEnumerable ConstituentBlocks { get; protected set; } - public bool SignatureVerified { get; internal set; } + public Block AsBlock => this; - [ProtoMember(5)] - public BrightChainNode OriginatingNode { get; internal set; } + public IBlock AsIBlock => this; - // TODO: Probably going to remove this from the stored attributes and only persist these on ChainLinqDataObjects? - [ProtoMember(6)] - public string OriginalAssemblyTypeString { get; internal set; } + public ulong Reads { get; } - public readonly Type OriginalType; + public IEnumerable Ratings { get; } - [ProtoMember(7)] - public string AssemblyVersion { get; internal set; } + public decimal Rating { get; } - /// - /// For private encrypted files, a special token encrypted with the original user's key will allow revocation - /// - [ProtoMember(8)] - public IEnumerable RevocationCertificates { get; internal set; } + /// + /// If Guid is set with valid LegalOrder, any delete calls should be prevented. Respond as denied or invisible according to + /// LegalHoldInvisible. + /// + public Guid? LegalHoldPreventDelete { get; } - /// - /// Gets a boolean whether the revocation list contains possible revocation tokens. - /// - public bool Revokable => this.RevocationCertificates.Count() > 0; + /// + /// If Guid is set with valid LegalOrder, any read accesses should be prevented. Respond as denied or invisible according to + /// LegalHoldInvisible. + /// + public Guid? LegalHoldPreventRead { get; } - /// - /// Gets or sets a list of the blocks, in order, required to complete this block. Not persisted to disk. - /// Generally only used during construction of a chain - /// - public IEnumerable ConstituentBlocks { get; protected set; } + /// + /// If Guid is set with valid LegalOrder, any read accesses should be logged to appropriate legal log. + /// + public Guid? LegalHoldLogRead { get; } - public Block AsBlock => this; + /// + /// If Guid is set with valid LegalOrder, any accesses should respond as if block does not exist. + /// + public Guid? LegalHoldInvisible { get; } - public IBlock AsIBlock => this; + /// + /// Gets an EntCalcResult. + /// Uses ENT Chi Square monte-carlo calculator/estimator. + /// + public EntCalcResult EntropyEstimate + { + get + { + var entCalc = new EntCalc(binmode: false); + new List(collection: this.Bytes.ToArray()).ForEach(action: b => entCalc.AddSample(buf: b, + Fold: false)); + var calculationResult = entCalc.EndCalculation(); + return calculationResult; + } + } - public ulong Reads { get; } + /// + /// Gets a uint with the CRC32 of the block's data. + /// + public uint Crc32 => + this.StoredData.Crc32; - public IEnumerable Ratings { get; } + public ulong Crc64 => + this.StoredData.Crc64; - public decimal Rating { get; } + /// + /// Gets a blockParams object from this block's attributes. + /// + public virtual BlockParams BlockParams => new( + blockSize: this.BlockSize, + requestTime: this.StorageContract.RequestTime, + keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, + redundancy: this.StorageContract.RedundancyContractType, + privateEncrypted: this.StorageContract.PrivateEncrypted, + originalType: this.OriginalType); - /// - /// If Guid is set with valid LegalOrder, any delete calls should be prevented. Respond as denied or invisible according to LegalHoldInvisible. - /// - public Guid? LegalHoldPreventDelete { get; } + [ProtoMember(tag: 1)] public BlockHash Id { get; } - /// - /// If Guid is set with valid LegalOrder, any read accesses should be prevented. Respond as denied or invisible according to LegalHoldInvisible. - /// - public Guid? LegalHoldPreventRead { get; } + [ProtoMember(tag: 2)] public StorageContract StorageContract { get; set; } - /// - /// If Guid is set with valid LegalOrder, any read accesses should be logged to appropriate legal log. - /// - public Guid? LegalHoldLogRead { get; } + /// + /// Gets the bytes associated with this block. + /// Notably, the StoredData is NOT part of the proto contract. + /// + public BlockData StoredData { get; internal set; } - /// - /// If Guid is set with valid LegalOrder, any accesses should respond as if block does not exist. - /// - public Guid? LegalHoldInvisible { get; } + public BlockSize BlockSize { get; } - public IEnumerable ValidationExceptions { get; private set; } + /// + /// Gets a BlockSignature containing a signature of the block's hash and all other contents of metadata except signature. + /// + [ProtoMember(tag: 4)] + public BlockSignature Signature { get; internal set; } - /// - /// Gets an EntCalcResult. - /// Uses ENT Chi Square monte-carlo calculator/estimator. - /// - public EntCalcResult EntropyEstimate - { - get - { - EntCalc entCalc = new EntCalc(false); - new List(this.Bytes.ToArray()).ForEach(b => entCalc.AddSample(b, false)); - EntCalc.EntCalcResult calculationResult = entCalc.EndCalculation(); - return calculationResult; - } - } + public bool Signed => this.Signature is not null; + + public bool SignatureVerified { get; internal set; } + + [ProtoMember(tag: 5)] public BrightChainNode OriginatingNode { get; internal set; } - /// - /// Gets a uint with the CRC32 of the block's data. - /// - public uint Crc32 => - this.StoredData.Crc32; - - public ulong Crc64 => - this.StoredData.Crc64; - - /// - /// Compares the data hashes only. - /// - /// - /// - /// - public static bool operator ==(Block a, Block b) + // TODO: Probably going to remove this from the stored attributes and only persist these on ChainLinqDataObjects? + [ProtoMember(tag: 6)] public string OriginalAssemblyTypeString { get; internal set; } + + [ProtoMember(tag: 7)] public string AssemblyVersion { get; internal set; } + + public IEnumerable ValidationExceptions { get; private set; } + + /// + /// XORs this block with another/randomizer block. + /// + /// + /// + public ReadOnlyMemory XOR(Block other) + { + if (other is IdentifiableBlock) { - return a.StoredData == b.StoredData; + throw new BrightChainException(message: "Unexpected Identifiable Block"); } - public static bool operator !=(Block a, Block b) + if (this.Bytes.Length != other.Bytes.Length) { - return a.StoredData != b.StoredData; + throw new BrightChainException(message: "BlockSize mismatch"); } - /// - /// Initializes a new instance of the class. - /// Construct a block from the given parameters and data. - /// - /// - /// - public Block(BlockParams blockParams, ReadOnlyMemory data, IEnumerable constituentBlockHashes = null) + return Utilities.ReadOnlyMemoryXOR(sourceA: this.Bytes, + sourceB: other.Bytes); + } + + /// + /// XORs this block with a list of other/randomizer blocks. + /// XOR will ignore the instance block in the block array. + /// + /// + /// + public ReadOnlyMemory XOR(IEnumerable others) + { + var blockSize = BlockSizeMap.Map[key: this.BlockSize]; + var xorData = this.Bytes.ToArray(); + + foreach (var b in others) { - if (this is RootBlock) + if (b.Id == this.Id) { - // it is much easier to validate that we're the only rootblock at the TransactableBlock level where we know the cache manager - // TODO: there can only be one - this.BlockSize = blockParams.BlockSize; + continue; } - else - { - var detectedBlockSize = BlockSizeMap.BlockSize(data.Length); - - if (blockParams.BlockSize != BlockSize.Unknown && detectedBlockSize != blockParams.BlockSize) - { - throw new BrightChainException("Block size mismatch"); - } - this.BlockSize = detectedBlockSize; + if (b is IdentifiableBlock) + { + throw new BrightChainException(message: "Unexpected Identifiable Block"); } - Assembly assembly = Assembly.GetEntryAssembly(); - AssemblyInformationalVersionAttribute versionAttribute = assembly.GetCustomAttribute(); - - this.StorageContract = new StorageContract( - RequestTime: blockParams.RequestTime, - KeepUntilAtLeast: blockParams.KeepUntilAtLeast, - ByteCount: data.Length, - PrivateEncrypted: blockParams.PrivateEncrypted, - redundancyContractType: blockParams.Redundancy); - this.StoredData = new StoredBlockData(data); - this.Id = new BlockHash(this); // must happen after data is in place - this.ConstituentBlocks = constituentBlockHashes is null ? new BlockHash[] { } : constituentBlockHashes; - this.OriginatingNode = null; - this.Signature = null; - this.SignatureVerified = false; - this.RevocationCertificates = new List(); - this.OriginalType = blockParams.OriginalType; - this.OriginalAssemblyTypeString = this.OriginalType.AssemblyQualifiedName; - this.AssemblyVersion = versionAttribute.InformationalVersion; - this.HashVerified = this.Validate(); // also fills in any validation errors in the array - } - - /// - /// XORs this block with another/randomizer block. - /// - /// - /// - public ReadOnlyMemory XOR(Block other) - { - if (other is IdentifiableBlock) + if (b.BlockSize != this.BlockSize) { - throw new BrightChainException("Unexpected Identifiable Block"); + throw new BrightChainException(message: "BlockSize mismatch"); } - if (this.Bytes.Length != other.Bytes.Length) + var xorWith = b.Bytes.ToArray(); + for (var i = 0; i < blockSize; i++) { - throw new BrightChainException("BlockSize mismatch"); + xorData[i] = (byte)(xorData[i] ^ xorWith[i]); } - - return Utilities.ReadOnlyMemoryXOR(this.Bytes, other.Bytes); } - /// - /// XORs this block with a list of other/randomizer blocks. - /// XOR will ignore the instance block in the block array. - /// - /// - /// - public ReadOnlyMemory XOR(IEnumerable others) - { - int blockSize = BlockSizeMap.Map[this.BlockSize]; - byte[] xorData = this.Bytes.ToArray(); + return new ReadOnlyMemory(array: xorData); + } - foreach (Block b in others) - { - if (b.Id == this.Id) - { - continue; - } - - if (b is IdentifiableBlock) - { - throw new BrightChainException("Unexpected Identifiable Block"); - } - - if (b.BlockSize != this.BlockSize) - { - throw new BrightChainException("BlockSize mismatch"); - } - - byte[] xorWith = b.Bytes.ToArray(); - for (int i = 0; i < blockSize; i++) - { - xorData[i] = (byte)(xorData[i] ^ xorWith[i]); - } - } + /// + /// Sign the block/metadata. + /// + /// + /// + /// + public BlockSignature Sign(Agent user, string password) + { + throw new NotImplementedException(); + this.SignatureVerified = true; + } - return new ReadOnlyMemory(xorData); - } + public bool Validate() + { + IEnumerable validationExceptions; + var result = this.PerformValidation(validationExceptions: out validationExceptions); + this.ValidationExceptions = validationExceptions; + return result; + } - /// - /// Returns a boolean indicating whether the assembly qualified type name was resolved. Optional type to compare against. - /// - /// - /// - /// - /// - public static bool ValidateType(out Type restoredType, string typeName, Type compareTo) - { - try - { - restoredType = Type.GetType(typeName); + public abstract void Dispose(); - if (restoredType is null) - { - return false; - } + public int CompareTo(IBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - return restoredType.Equals(compareTo); - } - catch (Exception _) - { - restoredType = null; - return false; - } - } + public int CompareTo(Block other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - public bool ValidateOriginalType() - { - return ValidateType( - restoredType: out _, - typeName: this.OriginalAssemblyTypeString, - compareTo: this.OriginalType); - } + public bool Equals(Block other) + { + return this.CompareTo(other: other) == 0; + } - public bool CompareOriginalType(Type compareTo) - { - return this.OriginalType.Equals(compareTo); - } + public bool Equals(IBlock other) + { + return this.CompareTo(other: other) == 0; + } - public bool CompareOriginalType(Block other) - { - return this.CompareOriginalType(other.OriginalType); - } + public byte ByteAt(int index) + { + return this.StoredData.Bytes.Slice(start: index).ToArray()[0]; + } - public bool ValidateCurrentTypeVsOriginal() - { - return this.GetType().Equals(this.OriginalType); - } + /// + /// Compares the data hashes only. + /// + /// + /// + /// + public static bool operator ==(Block a, Block b) + { + return a.StoredData == b.StoredData; + } - /// - /// Sign the block/metadata. - /// - /// - /// - /// - public BlockSignature Sign(Agent user, string password) - { - throw new NotImplementedException(); - this.SignatureVerified = true; - } + public static bool operator !=(Block a, Block b) + { + return a.StoredData != b.StoredData; + } - /// - /// Verifies the block's signature. - /// - /// - /// - /// Signature hash. If signature is not provided, pull from attributes. - /// - public bool VerifySignature(Agent user, string password, ReadOnlyMemory? signature = null) + /// + /// Returns a boolean indicating whether the assembly qualified type name was resolved. Optional type to compare against. + /// + /// + /// + /// + /// + public static bool ValidateType(out Type restoredType, string typeName, Type compareTo) + { + try { - throw new NotImplementedException(); - return false; - } + restoredType = Type.GetType(typeName: typeName); - public BrightenedBlock MakeTransactable(BrightenedBlockCacheManagerBase cacheManager, bool allowCommit) - { - var blockParams = new BrightenedBlockParams( - cacheManager: cacheManager, - allowCommit: allowCommit, - blockParams: this.BlockParams); - - return new BrightenedBlock( - blockParams: blockParams, - data: this.Bytes, - constituentBlockHashes: this.ConstituentBlocks); - } + if (restoredType is null) + { + return false; + } - /// - /// Gets a blockParams object from this block's attributes. - /// - public virtual BlockParams BlockParams => new BlockParams( - blockSize: this.BlockSize, - requestTime: this.StorageContract.RequestTime, - keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, - redundancy: this.StorageContract.RedundancyContractType, - privateEncrypted: this.StorageContract.PrivateEncrypted, - originalType: this.OriginalType); - - public bool Validate() + return restoredType.Equals(o: compareTo); + } + catch (Exception _) { - IEnumerable validationExceptions; - var result = this.PerformValidation(out validationExceptions); - this.ValidationExceptions = validationExceptions; - return result; + restoredType = null; + return false; } + } - public abstract void Dispose(); + public bool ValidateOriginalType() + { + return ValidateType( + restoredType: out _, + typeName: this.OriginalAssemblyTypeString, + compareTo: this.OriginalType); + } - public override int GetHashCode() - { - return (int)this.StoredData.Crc32; - } + public bool CompareOriginalType(Type compareTo) + { + return this.OriginalType.Equals(o: compareTo); + } - public int CompareTo(IBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public bool CompareOriginalType(Block other) + { + return this.CompareOriginalType(compareTo: other.OriginalType); + } - public int CompareTo(Block other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public bool ValidateCurrentTypeVsOriginal() + { + return this.GetType().Equals(o: this.OriginalType); + } - public override bool Equals(object obj) - { - return obj is Block blockObj ? this.Equals(blockObj) : false; - } + /// + /// Verifies the block's signature. + /// + /// + /// + /// Signature hash. If signature is not provided, pull from attributes. + /// + public bool VerifySignature(Agent user, string password, ReadOnlyMemory? signature = null) + { + throw new NotImplementedException(); + return false; + } - public bool Equals(IBlock other) - { - return this.CompareTo(other) == 0; - } + public BrightenedBlock MakeTransactable(BrightenedBlockCacheManagerBase cacheManager, bool allowCommit) + { + var blockParams = new BrightenedBlockParams( + cacheManager: cacheManager, + allowCommit: allowCommit, + blockParams: this.BlockParams); + + return new BrightenedBlock( + blockParams: blockParams, + data: this.Bytes, + constituentBlockHashes: this.ConstituentBlocks); + } - public bool Equals(Block other) - { - return this.CompareTo(other) == 0; - } + public override int GetHashCode() + { + return (int)this.StoredData.Crc32; + } + + public override bool Equals(object obj) + { + return obj is Block blockObj ? this.Equals(other: blockObj) : false; } } diff --git a/src/BrightChain.Engine/Models/Blocks/BlockRating.cs b/src/BrightChain.Engine/Models/Blocks/BlockRating.cs old mode 100644 new mode 100755 index 2b9d1ebc..f54794ef --- a/src/BrightChain.Engine/Models/Blocks/BlockRating.cs +++ b/src/BrightChain.Engine/Models/Blocks/BlockRating.cs @@ -1,18 +1,16 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Models.Hashes; +using System; +using BrightChain.Engine.Models.Hashes; - public record BlockRating - { - public readonly Guid Id; +namespace BrightChain.Engine.Models.Blocks; - public readonly BlockHash BlockId; +public record BlockRating +{ + public readonly Guid AgentId; - public readonly Guid AgentId; + public readonly decimal AgentReputationWeight; - public readonly decimal AgentReputationWeight; + public readonly BlockHash BlockId; + public readonly Guid Id; - public readonly decimal Rating; - } + public readonly decimal Rating; } diff --git a/src/BrightChain.Engine/Models/Blocks/BlockSignature.cs b/src/BrightChain.Engine/Models/Blocks/BlockSignature.cs old mode 100644 new mode 100755 index 4140bbe4..1af75e97 --- a/src/BrightChain.Engine/Models/Blocks/BlockSignature.cs +++ b/src/BrightChain.Engine/Models/Blocks/BlockSignature.cs @@ -1,40 +1,50 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Hashes; - using ProtoBuf; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks; - /// - /// Type box for the sha hashes. - /// - [ProtoContract] - public class BlockSignature : DataSignature, IDataSignature, IComparable +/// +/// Type box for the sha hashes. +/// +[ProtoContract] +public class BlockSignature : DataSignature, IDataSignature, IComparable +{ + public BlockSignature(IBlock block) + : base(dataBytes: block.StoredData.Bytes) { - public BlockSignature(IBlock block) - : base(block) - { - } + } - public BlockSignature(ReadOnlyMemory dataBytes) - : base(dataBytes) - { - } + public BlockSignature(ReadOnlyMemory dataBytes) + : base(dataBytes: dataBytes) + { + } - public BlockSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes) - : base(originalBlockSize, providedHashBytes) + public BlockSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes) + : base(providedHashBytes: providedHashBytes, + computed: false) + { + if (providedHashBytes.Length != BlockSizeMap.BlockSize(blockSize: originalBlockSize)) { + throw new BrightChainException(message: "hash size mismatch"); } + } - internal BlockSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes, bool computed = false) - : base(originalBlockSize, providedHashBytes, computed) + internal BlockSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes, bool computed = false) + : base(providedHashBytes: providedHashBytes, + computed: computed) + { + if (providedHashBytes.Length != BlockSizeMap.BlockSize(blockSize: originalBlockSize)) { + throw new BrightChainException(message: "hash size mismatch"); } + } - public int CompareTo(BlockSignature other) - { - throw new NotImplementedException(); - } + public int CompareTo(BlockSignature other) + { + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Blocks/BlockSizeMap.cs b/src/BrightChain.Engine/Models/Blocks/BlockSizeMap.cs old mode 100644 new mode 100755 index ffe5a8a5..b6a8943c --- a/src/BrightChain.Engine/Models/Blocks/BlockSizeMap.cs +++ b/src/BrightChain.Engine/Models/Blocks/BlockSizeMap.cs @@ -1,225 +1,219 @@ -namespace BrightChain.Engine.Models.Blocks +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Models.Blocks; + +/// +/// Map of the block size enumeration values to their actual sizes. +/// +public static class BlockSizeMap { - using System; - using System.Collections.Generic; - using System.Collections.Immutable; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Hashes; + /// + /// Smallest block size. Best for encryption keys, etc. + /// + public const int NanoSize = 128; + + /// + /// Best for extremely small payloads. 256 bytes. + /// + public const int MicroSize = 256; + + /// + /// Best for small payloads like messages. 512 bytes. + /// + public const int MessageSize = 512; + + /// + /// Best for small payloads larger than basic messages. 1024 bytes. 1K. + /// + public const int TinySize = 1024; + + /// + /// Best for small files. 4096 bytes. 4K. + /// + public const int SmallSize = 4 * 1024; + + /// + /// Medium block size. Best for small to moderately sized data. 1,048,576 bytes. 1M. + /// + public const int MediumSize = 1024 * 1024; + + /// + /// Large block size. Best for large data. 4,194.304 bytes. 4M. + /// + public const int LargeSize = 4 * 1024 * 1024; + + public static readonly ImmutableDictionary Map = new Dictionary + { + {Enumerations.BlockSize.Unknown, -1}, + {Enumerations.BlockSize.Nano, NanoSize}, + {Enumerations.BlockSize.Micro, MicroSize}, + {Enumerations.BlockSize.Message, MessageSize}, + {Enumerations.BlockSize.Tiny, TinySize}, + {Enumerations.BlockSize.Small, SmallSize}, + {Enumerations.BlockSize.Medium, MediumSize}, + {Enumerations.BlockSize.Large, LargeSize}, + }.ToImmutableDictionary(); + + public static readonly ImmutableDictionary HashesPerBlockMap = new Dictionary + { + {Enumerations.BlockSize.Unknown, -1}, + {Enumerations.BlockSize.Nano, NanoSize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Micro, MicroSize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Message, MessageSize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Tiny, TinySize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Small, SmallSize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Medium, MediumSize / DataHash.HashSizeBytes}, + {Enumerations.BlockSize.Large, LargeSize / DataHash.HashSizeBytes}, + }.ToImmutableDictionary(); /// - /// Map of the block size enumeration values to their actual sizes. + /// Map of Zero Vector Block generators by block size, created from known hashes. /// - public static class BlockSizeMap + public static readonly ImmutableDictionary ZeroVectorMap = new Dictionary { - /// - /// Smallest block size. Best for encryption keys, etc. - /// - public const int NanoSize = 128; - - /// - /// Best for extremely small payloads. 256 bytes. - /// - public const int MicroSize = 256; - - /// - /// Best for small payloads like messages. 512 bytes. - /// - public const int MessageSize = 512; - - /// - /// Best for small payloads larger than basic messages. 1024 bytes. 1K. - /// - public const int TinySize = 1024; - - /// - /// Best for small files. 4096 bytes. 4K. - /// - public const int SmallSize = 4 * 1024; - - /// - /// Medium block size. Best for small to moderately sized data. 1,048,576 bytes. 1M. - /// - public const int MediumSize = 1024 * 1024; - - /// - /// Large block size. Best for large data. 4,194.304 bytes. 4M. - /// - public const int LargeSize = 4 * 1024 * 1024; - - public static readonly ImmutableDictionary Map = new Dictionary() { - { Enumerations.BlockSize.Unknown, -1 }, - { Enumerations.BlockSize.Nano, NanoSize }, - { Enumerations.BlockSize.Micro, MicroSize }, - { Enumerations.BlockSize.Message, MessageSize }, - { Enumerations.BlockSize.Tiny, TinySize }, - { Enumerations.BlockSize.Small, SmallSize }, - { Enumerations.BlockSize.Medium, MediumSize }, - { Enumerations.BlockSize.Large, LargeSize }, - }.ToImmutableDictionary(); - - public static readonly ImmutableDictionary HashesPerBlockMap = new Dictionary() + Enumerations.BlockSize.Unknown, null // Impossible + }, { - { Enumerations.BlockSize.Unknown, -1 }, - { Enumerations.BlockSize.Nano, NanoSize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Micro, MicroSize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Message, MessageSize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Tiny, TinySize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Small, SmallSize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Medium, MediumSize / DataHash.HashSizeBytes }, - { Enumerations.BlockSize.Large, LargeSize / DataHash.HashSizeBytes }, - }.ToImmutableDictionary(); - - /// - /// Map of Zero Vector Block generators by block size, created from known hashes. - /// - public static readonly ImmutableDictionary ZeroVectorMap = new Dictionary() + Enumerations.BlockSize.Nano, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Nano, + providedHashBytes: Convert.FromHexString(s: "38723a2e5e8a17aa7950dc008209944e898f69a7bd10a23c839d341e935fd5ca"), + computed: true) + }, { - { - Enumerations.BlockSize.Unknown, - null // Impossible - }, - { - Enumerations.BlockSize.Nano, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Nano, - providedHashBytes: Convert.FromHexString("38723a2e5e8a17aa7950dc008209944e898f69a7bd10a23c839d341e935fd5ca"), - computed: true) - }, - { - Enumerations.BlockSize.Micro, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Micro, - providedHashBytes: Convert.FromHexString("5341e6b2646979a70e57653007a1f310169421ec9bdd9f1a5648f75ade005af1"), - computed: true) - }, - { - Enumerations.BlockSize.Tiny, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Tiny, - providedHashBytes: Convert.FromHexString("5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"), - computed: true) - }, - { - Enumerations.BlockSize.Small, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Small, - providedHashBytes: Convert.FromHexString("ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"), - computed: true) - }, - { - Enumerations.BlockSize.Message, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Message, - providedHashBytes: Convert.FromHexString("076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560"), - computed: true) - }, - { - Enumerations.BlockSize.Medium, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Medium, - providedHashBytes: Convert.FromHexString("30e14955ebf1352266dc2ff8067e68104607e750abb9d3b36582b8af909fcb58"), - computed: true) - }, - { - Enumerations.BlockSize.Large, - new BlockHash( - blockType: typeof(ZeroVectorBlock), - originalBlockSize: Enumerations.BlockSize.Large, - providedHashBytes: Convert.FromHexString("bb9f8df61474d25e71fa00722318cd387396ca1736605e1248821cc0de3d3af8"), - computed: true) - }, - }.ToImmutableDictionary(); - - /// - /// Map a block size enumeration to its actual size in bytes. - /// - /// - /// - public static int BlockSize(BlockSize blockSize) + Enumerations.BlockSize.Micro, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Micro, + providedHashBytes: Convert.FromHexString(s: "5341e6b2646979a70e57653007a1f310169421ec9bdd9f1a5648f75ade005af1"), + computed: true) + }, { - if (!Map.ContainsKey(blockSize)) - { - throw new KeyNotFoundException(nameof(blockSize)); - } - - return Map[blockSize]; - } - - public static bool LengthIsValid(int length) + Enumerations.BlockSize.Tiny, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Tiny, + providedHashBytes: Convert.FromHexString(s: "5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"), + computed: true) + }, { - foreach (var pair in Map) - { - if (pair.Value == length) - { - return true; - } - } + Enumerations.BlockSize.Small, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Small, + providedHashBytes: Convert.FromHexString(s: "ad7facb2586fc6e966c004d7d1d16b024f5805ff7cb47c7a85dabd8b48892ca7"), + computed: true) + }, + { + Enumerations.BlockSize.Message, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Message, + providedHashBytes: Convert.FromHexString(s: "076a27c79e5ace2a3d47f9dd2e83e4ff6ea8872b3c2218f66c92b89b55f36560"), + computed: true) + }, + { + Enumerations.BlockSize.Medium, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Medium, + providedHashBytes: Convert.FromHexString(s: "30e14955ebf1352266dc2ff8067e68104607e750abb9d3b36582b8af909fcb58"), + computed: true) + }, + { + Enumerations.BlockSize.Large, new BlockHash( + blockType: typeof(ZeroVectorBlock), + originalBlockSize: Enumerations.BlockSize.Large, + providedHashBytes: Convert.FromHexString(s: "bb9f8df61474d25e71fa00722318cd387396ca1736605e1248821cc0de3d3af8"), + computed: true) + }, + }.ToImmutableDictionary(); - return false; + /// + /// Map a block size enumeration to its actual size in bytes. + /// + /// + /// + public static int BlockSize(BlockSize blockSize) + { + if (!Map.ContainsKey(key: blockSize)) + { + throw new KeyNotFoundException(message: nameof(blockSize)); } - /// - /// Map a block size enumeration to the number of hashes it can contain. - /// - /// - /// - public static long HashesPerBlock(BlockSize blockSize, int exponent = 1) + return Map[key: blockSize]; + } + + public static bool LengthIsValid(int length) + { + foreach (var pair in Map) { - if (!HashesPerBlockMap.ContainsKey(blockSize)) + if (pair.Value == length) { - throw new KeyNotFoundException(nameof(blockSize)); + return true; } + } - var value = HashesPerBlockMap[blockSize]; - if (exponent <= 1) - { - return value; - } + return false; + } - return (long)Math.Pow(value, exponent); + /// + /// Map a block size enumeration to the number of hashes it can contain. + /// + /// + /// + public static long HashesPerBlock(BlockSize blockSize, int exponent = 1) + { + if (!HashesPerBlockMap.ContainsKey(key: blockSize)) + { + throw new KeyNotFoundException(message: nameof(blockSize)); } - /// - /// Map a block size in bytes back to its block size enumeration. - /// - /// - /// - public static BlockSize BlockSize(int blockSize) + var value = HashesPerBlockMap[key: blockSize]; + if (exponent <= 1) { - foreach (var pair in Map) - { - if (pair.Value == blockSize) - { - return pair.Key; - } - } - - throw new KeyNotFoundException(nameof(blockSize)); + return value; } - public static BlockHash ZeroVectorHash(BlockSize blockSize) + return (long)Math.Pow(x: value, + y: exponent); + } + + /// + /// Map a block size in bytes back to its block size enumeration. + /// + /// + /// + public static BlockSize BlockSize(int blockSize) + { + foreach (var pair in Map) { - BlockHash expectedVector; - var b = BlockSizeMap.ZeroVectorMap.TryGetValue(blockSize, out expectedVector); - if (!b) + if (pair.Value == blockSize) { - throw new BrightChainException(nameof(blockSize)); + return pair.Key; } - - return expectedVector; } - public static ZeroVectorBlock ZeroVectorBlock(BlockSize blockSize) + throw new KeyNotFoundException(message: nameof(blockSize)); + } + + public static BlockHash ZeroVectorHash(BlockSize blockSize) + { + BlockHash expectedVector; + var b = ZeroVectorMap.TryGetValue(key: blockSize, + value: out expectedVector); + if (!b) { - return new ZeroVectorBlock(blockSize); + throw new BrightChainException(message: nameof(blockSize)); } + + return expectedVector; + } + + public static ZeroVectorBlock ZeroVectorBlock(BlockSize blockSize) + { + return new ZeroVectorBlock(blockSize: blockSize); } } diff --git a/src/BrightChain.Engine/Models/Blocks/BrightMail.cs b/src/BrightChain.Engine/Models/Blocks/BrightMail.cs old mode 100644 new mode 100755 index bad400f0..0820848b --- a/src/BrightChain.Engine/Models/Blocks/BrightMail.cs +++ b/src/BrightChain.Engine/Models/Blocks/BrightMail.cs @@ -1,15 +1,14 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System.Collections.Generic; - using BrightChain.Engine.Models.Hashes; +using System.Collections.Generic; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Models.Blocks; - /// - /// TODO: This needs a total rethink/redo. Decide whether/where to store IEnumerable<(RecipientType, BrightChainAgent)> - /// - public record BrightMail : BrightMessage - { - private readonly IEnumerable Headers; - private readonly IEnumerable Attachments; - private readonly bool recipientBcc; - } +/// +/// TODO: This needs a total rethink/redo. Decide whether/where to store IEnumerable<(RecipientType, BrightChainAgent)> +/// +public record BrightMail : BrightMessage +{ + private readonly IEnumerable Attachments; + private readonly IEnumerable Headers; + private readonly bool recipientBcc; } diff --git a/src/BrightChain.Engine/Models/Blocks/BrightMessage.cs b/src/BrightChain.Engine/Models/Blocks/BrightMessage.cs old mode 100644 new mode 100755 index ae2ecfd8..bbb15761 --- a/src/BrightChain.Engine/Models/Blocks/BrightMessage.cs +++ b/src/BrightChain.Engine/Models/Blocks/BrightMessage.cs @@ -1,48 +1,47 @@ -namespace BrightChain.Engine.Models.Blocks +using System; +using BrightChain.Engine.Models.Entities; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Models.Blocks; + +public record BrightMessage : IDisposable { - using System; - using BrightChain.Engine.Models.Entities; - using BrightChain.Engine.Models.Hashes; + protected readonly BlockHash BlockHash; + protected readonly bool Deleted; + protected readonly Guid Id; + protected readonly DateTime? Read; + protected readonly Agent Recipient; + protected readonly Agent Sender; + protected readonly DateTime Sent; + protected readonly Guid Thread; + protected bool _disposedValue; + + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~BrightMail() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } - public record BrightMessage : IDisposable + public void Dispose() { - protected readonly Guid Id; - protected readonly Agent Sender; - protected readonly Agent Recipient; - protected readonly BlockHash BlockHash; - protected readonly DateTime Sent; - protected readonly DateTime? Read; - protected readonly bool Deleted; - protected readonly Guid Thread; - protected bool _disposedValue; + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + this.Dispose(disposing: true); + GC.SuppressFinalize(obj: this); + } - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) + { + if (!this._disposedValue) { - if (!_disposedValue) + if (disposing) { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } - - // TODO: free unmanaged resources (unmanaged objects) and override finalizer - // TODO: set large fields to null - _disposedValue = true; + // TODO: dispose managed state (managed objects) } - } - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources - // ~BrightMail() - // { - // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - // Dispose(disposing: false); - // } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + this._disposedValue = true; } } } diff --git a/src/BrightChain.Engine/Models/Blocks/BrightenedBlock.cs b/src/BrightChain.Engine/Models/Blocks/BrightenedBlock.cs old mode 100644 new mode 100755 index 086cadba..9234f2e2 --- a/src/BrightChain.Engine/Models/Blocks/BrightenedBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/BrightenedBlock.cs @@ -1,221 +1,163 @@ -using System.Linq; - -namespace BrightChain.Engine.Models.Blocks +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks; + +/// +/// Block that is able to be stored, rolled back, committed, or prevented from being stored. +/// +[ProtoContract] +public class BrightenedBlock : Block, IDisposable, ITransactable, ITransactableBlock, IComparable, + IComparable, IEquatable { - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using ProtoBuf; - /// - /// Block that is able to be stored, rolled back, committed, or prevented from being stored. + /// Boolean indicating whether our data has been disposed. /// - [ProtoContract] - public class BrightenedBlock : Block, IDisposable, ITransactable, ITransactableBlock, IComparable, IComparable, IEquatable + private bool disposedValue; + + public BrightenedBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data, + IEnumerable constituentBlockHashes = null) + : base( + blockParams: blockParams, + data: data, + constituentBlockHashes: constituentBlockHashes) { - public BrightenedBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data, IEnumerable constituentBlockHashes = null) - : base( - blockParams: blockParams, - data: data, - constituentBlockHashes: constituentBlockHashes) - { - this.CacheManager = blockParams.CacheManager; - this.State = !blockParams.AllowCommit ? TransactionStatus.DoNotWrite : TransactionStatus.Uncommitted; - this.disposedValue = false; - } - - /// - /// Initializes a new instance of the class. - /// For test methods. - /// - internal BrightenedBlock() - : base( - blockParams: new BlockParams( - blockSize: BlockSize.Message, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: RedundancyContractType.HeapAuto, - privateEncrypted: false, - originalType: typeof(BrightenedBlock)), - data: new ReadOnlyMemory() { }, - constituentBlockHashes: new List()) - { - } - - public BrightenedBlock AsTransactableBlock => this; + this.CacheManager = blockParams.CacheManager; + this.AllowCommit = blockParams.AllowCommit; + this.disposedValue = false; + } - /// - /// Gets a bool indicating whether the block's data has been loaded from the attached cache, or kept after persisting to cache. - /// - public bool DataInMemory { get; } + /// + /// Initializes a new instance of the class. + /// For test methods. + /// + internal BrightenedBlock() + : base( + blockParams: new BlockParams( + blockSize: BlockSize.Message, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.HeapAuto, + privateEncrypted: false, + originalType: typeof(BrightenedBlock)), + data: new ReadOnlyMemory(), + constituentBlockHashes: new List()) + { + } - /// - /// Boolean indicating whether our data has been disposed. - /// - private bool disposedValue; + public BrightenedBlock AsTransactableBlock => this; - public ICacheManager CacheManager { get; internal set; } + /// + /// Gets a bool indicating whether the block's data has been loaded from the attached cache, or kept after persisting to cache. + /// + public bool DataInMemory { get; } + + public override BrightenedBlockParams BlockParams => new( + cacheManager: this.CacheManager, + allowCommit: this.AllowCommit, + blockParams: new BlockParams( + blockSize: this.BlockSize, + requestTime: this.StorageContract.RequestTime, + keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, + redundancy: this.StorageContract.RedundancyContractType, + privateEncrypted: this.StorageContract.PrivateEncrypted, + originalType: Type.GetType(typeName: this.OriginalAssemblyTypeString))); + + public int CompareTo(BrightenedBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - public TransactionStatus State { get; private set; } + public int CompareTo(ITransactableBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - public bool AllowCommit - { - get - { - return new TransactionStatus[] - { - TransactionStatus.Uncommitted, - TransactionStatus.Committed, - TransactionStatus.DroppedCommitted, - TransactionStatus.WrittenUnconfirmed, - TransactionStatus.RolledBackRewrite, - }.Contains(this.State); - } - } + // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + // ~TransactableBlock() + // { + // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + // Dispose(disposing: false); + // } - public static bool operator ==(BrightenedBlock a, BrightenedBlock b) - { - return a.BlockSize == b.BlockSize && a.StoredData.Equals(b.StoredData); - } + /// + /// Dispose block data and memory contents. + /// + public override void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + this.Dispose(disposing: true); + GC.SuppressFinalize(obj: this); + } - public static bool operator !=(BrightenedBlock a, BrightenedBlock b) - { - return !a.Equals(b); - } + public ICacheManager CacheManager { get; internal set; } - public void SetCacheManager(ICacheManager cacheManager) - { - this.CacheManager = cacheManager; - } + public bool AllowCommit { get; internal set; } - /// - /// Commit the block to disk - /// - /// - /// - public void Commit() - { - switch (this.State) - { - case TransactionStatus.DoNotWrite: - case TransactionStatus.RolledBackDoNotWrite: - throw new BrightChainException("Block is not allowed to be committed"); - - case TransactionStatus.RolledBackRewrite: - case TransactionStatus.Uncommitted: - this.State = TransactionStatus.WrittenUnconfirmed; - throw new NotImplementedException(); - return; - - case TransactionStatus.WrittenUnconfirmed: - this.State = TransactionStatus.Committed; - throw new NotImplementedException(); - return; - - case TransactionStatus.Committed: - case TransactionStatus.DroppedCommitted: - return; - - default: - throw new BrightChainException(nameof(this.State)); - } - } + public void SetCacheManager(ICacheManager cacheManager) + { + this.CacheManager = cacheManager; + } - public void Rollback(bool rewrite = false) - { - switch (this.State) - { - case TransactionStatus.DoNotWrite: - case TransactionStatus.RolledBackDoNotWrite: - return; - - case TransactionStatus.RolledBackRewrite: - case TransactionStatus.Uncommitted: - case TransactionStatus.WrittenUnconfirmed: - this.State = rewrite ? TransactionStatus.RolledBackRewrite : TransactionStatus.RolledBackDoNotWrite; - throw new NotImplementedException(); - return; - - case TransactionStatus.DroppedCommitted: - case TransactionStatus.Committed: - throw new BrightChainException("Block already committed"); - - default: - throw new BrightChainException(nameof(this.State)); - } - } + public static bool operator ==(BrightenedBlock a, BrightenedBlock b) + { + return a.BlockSize == b.BlockSize && a.StoredData.Equals(other: b.StoredData); + } - public override BrightenedBlockParams BlockParams => new BrightenedBlockParams( - cacheManager: this.CacheManager, - allowCommit: State.Equals(TransactionStatus.DoNotWrite) ? false : true, - blockParams: new BlockParams( - blockSize: this.BlockSize, - requestTime: this.StorageContract.RequestTime, - keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, - redundancy: this.StorageContract.RedundancyContractType, - privateEncrypted: this.StorageContract.PrivateEncrypted, - originalType: Type.GetType(this.OriginalAssemblyTypeString))); - - public override bool Equals(object obj) - { - return obj is BrightenedBlock blockObj ? this.StoredData.Equals(blockObj.StoredData) : false; - } + public static bool operator !=(BrightenedBlock a, BrightenedBlock b) + { + return !a.Equals(other: b); + } - public override int GetHashCode() - { - return this.StoredData.GetHashCode(); - } + /// + /// Commit the block to disk + /// + /// + /// + public void Commit() + { + throw new NotImplementedException(); + } - public int CompareTo(BrightenedBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public void Rollback(bool rewrite = false) + { + throw new NotImplementedException(); + } - public int CompareTo(ITransactableBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public override bool Equals(object obj) + { + return obj is BrightenedBlock blockObj ? this.StoredData.Equals(other: blockObj.StoredData) : false; + } - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources - // ~TransactableBlock() - // { - // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - // Dispose(disposing: false); - // } - - /// - /// Dispose block data and memory contents. - /// - public override void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - this.Dispose(disposing: true); - GC.SuppressFinalize(this); - } + public override int GetHashCode() + { + return this.StoredData.GetHashCode(); + } - /// - /// Dispose block data and memory contents. - /// - /// - protected virtual void Dispose(bool disposing) + /// + /// Dispose block data and memory contents. + /// + /// + protected virtual void Dispose(bool disposing) + { + if (!this.disposedValue) { - if (!this.disposedValue) + if (disposing) { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } + // TODO: dispose managed state (managed objects) + } - this.Rollback(); + this.Rollback(); - // TODO: free unmanaged resources (unmanaged objects) and override finalizer - // TODO: set large fields to null - this.disposedValue = true; - } + // TODO: free unmanaged resources (unmanaged objects) and override finalizer + // TODO: set large fields to null + this.disposedValue = true; } } } diff --git a/src/BrightChain.Engine/Models/Blocks/BrokeredAnonymityIdentifier.cs b/src/BrightChain.Engine/Models/Blocks/BrokeredAnonymityIdentifier.cs old mode 100644 new mode 100755 index 4fd654de..74cc4970 --- a/src/BrightChain.Engine/Models/Blocks/BrokeredAnonymityIdentifier.cs +++ b/src/BrightChain.Engine/Models/Blocks/BrokeredAnonymityIdentifier.cs @@ -1,50 +1,49 @@ -namespace BrightChain.Engine.Models.Blocks +using System; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks; + +/// +/// Constitues really just the user's id- however the system will allow users to store data with registered identities or even anonymously +/// but we will store error correction (FEC) data that allows us to recover the original Id if all the pieces of it (once sharded) are +/// reconstructed. +/// Plan is to use Reed Solomon. +/// +[ProtoContract] +public class BrokeredAnonymityIdentifier : IComparable, IDisposable, IFormattable, + IEquatable { - using System; - using ProtoBuf; + /// + /// FEC data computed off the ID prior to any masking + /// + [ProtoMember(tag: 2)] public ReadOnlyMemory ChecksumRecovery; /// - /// Constitues really just the user's id- however the system will allow users to store data with registered identities or even anonymously - /// but we will store error correction (FEC) data that allows us to recover the original Id if all the pieces of it (once sharded) are reconstructed. - /// Plan is to use Reed Solomon. + /// Filled in with either the real Id, an alias of, or the the "anonymous" user (00000.. all zero). /// - [ProtoContract] - public class BrokeredAnonymityIdentifier : IComparable, IDisposable, IFormattable, IEquatable + [ProtoMember(tag: 1)] public ReadOnlyMemory Id; + + public BrokeredAnonymityIdentifier(ReadOnlyMemory originalId, ReadOnlyMemory requestedId) + { + } + + public int CompareTo(BrokeredAnonymityIdentifier other) + { + throw new NotImplementedException(); + } + + public void Dispose() + { + throw new NotImplementedException(); + } + + public bool Equals(BrokeredAnonymityIdentifier other) + { + throw new NotImplementedException(); + } + + public string ToString(string format, IFormatProvider formatProvider) { - /// - /// Filled in with either the real Id, an alias of, or the the "anonymous" user (00000.. all zero). - /// - [ProtoMember(1)] - public ReadOnlyMemory Id; - - /// - /// FEC data computed off the ID prior to any masking - /// - [ProtoMember(2)] - public ReadOnlyMemory ChecksumRecovery; - - public BrokeredAnonymityIdentifier(ReadOnlyMemory originalId, ReadOnlyMemory requestedId) - { - } - - public int CompareTo(BrokeredAnonymityIdentifier other) - { - throw new NotImplementedException(); - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public bool Equals(BrokeredAnonymityIdentifier other) - { - throw new NotImplementedException(); - } - - public string ToString(string format, IFormatProvider formatProvider) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/BrightChain.cs b/src/BrightChain.Engine/Models/Blocks/Chains/BrightChain.cs old mode 100644 new mode 100755 index ecc8b1e6..77b44cd3 --- a/src/BrightChain.Engine/Models/Blocks/Chains/BrightChain.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/BrightChain.cs @@ -1,159 +1,158 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services.CacheManagers.Block; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// Brightened data chain, can be composed of file-based CBLs or brightened ChainLinq based data blocks. +/// Although a BrightChain contains brightened data, the CBL block itself is not brightened. +/// TODO: improve memory usage. Don't keep full copy, do all on async enumeration? +/// +[ProtoContract] +public class BrightChain : ConstituentBlockListBlock, IEnumerable { - using System.Collections; - using System.Collections.Generic; - using System.Linq; - using global::BrightChain.Engine.Exceptions; - using global::BrightChain.Engine.Models.Blocks.DataObjects; - using global::BrightChain.Engine.Models.Hashes; - using global::BrightChain.Engine.Services.CacheManagers.Block; - using ProtoBuf; + private readonly IEnumerable _blocks; + private readonly int _count; + private readonly BrightenedBlock _head; + private readonly BrightenedBlock _tail; - /// - /// Brightened data chain, can be composed of file-based CBLs or brightened ChainLinq based data blocks. - /// Although a BrightChain contains brightened data, the CBL block itself is not brightened. - /// TODO: improve memory usage. Don't keep full copy, do all on async enumeration? - /// - [ProtoContract] - public class BrightChain : ConstituentBlockListBlock, IEnumerable + public BrightChain(ConstituentBlockListBlockParams blockParams, IEnumerable brightenedBlocks) + : base(blockParams: blockParams) { - private readonly IEnumerable _blocks; - private readonly BrightenedBlock _head; - private readonly BrightenedBlock _tail; - private readonly int _count; - - public BrightChain(ConstituentBlockListBlockParams blockParams, IEnumerable brightenedBlocks) - : base(blockParams) + if (!brightenedBlocks.Any()) { - if (!brightenedBlocks.Any()) - { - throw new BrightChainException(nameof(brightenedBlocks)); - } + throw new BrightChainException(message: nameof(brightenedBlocks)); + } - this._blocks = new List(brightenedBlocks); - this._head = brightenedBlocks.First(); - if (!this.VerifyHomogeneity( + this._blocks = new List(collection: brightenedBlocks); + this._head = brightenedBlocks.First(); + if (!this.VerifyHomogeneity( tail: out this._tail, blockCount: out this._count)) - { - throw new BrightChainException(nameof(brightenedBlocks)); - } + { + throw new BrightChainException(message: nameof(brightenedBlocks)); } + } - public BrightChain(ConstituentBlockListBlockParams blockParams, BrightenedBlockCacheManagerBase sourceCache) - : base(blockParams) + public BrightChain(ConstituentBlockListBlockParams blockParams, BrightenedBlockCacheManagerBase sourceCache) + : base(blockParams: blockParams) + { + if (!blockParams.ConstituentBlockHashes.Any()) { - if (!blockParams.ConstituentBlockHashes.Any()) - { - throw new BrightChainException("Can not create empty chain"); - } + throw new BrightChainException(message: "Can not create empty chain"); + } - var blocks = new List(); - int index = 0; - foreach (var blockHash in blockParams.ConstituentBlockHashes) + var blocks = new List(); + var index = 0; + foreach (var blockHash in blockParams.ConstituentBlockHashes) + { + var block = sourceCache.Get(blockHash: blockHash); + blocks.Add(item: block); + if (index++ == 0) { - var block = sourceCache.Get(blockHash); - blocks.Add(block); - if (index++ == 0) - { - this._head = block; - } + this._head = block; } + } - this._blocks = blocks; - if (!this.VerifyHomogeneity( + this._blocks = blocks; + if (!this.VerifyHomogeneity( tail: out this._tail, blockCount: out this._count)) - { - throw new BrightChainException(nameof(blocks)); - } - } - - public int Count() { - return this._count; + throw new BrightChainException(message: nameof(blocks)); } + } - public BrightenedBlock First() - { - return this._head; - } + public IEnumerator GetEnumerator() + { + return this._blocks.GetEnumerator(); + } - public bool VerifyHomogeneityAgainstBlock(BrightenedBlock block) - { - return - block.ValidateOriginalType() && - block.CompareOriginalType(this._head) && - block.GetType().Equals(this._head.GetType()) && - block.BlockSize.Equals(this._head.BlockSize); - } + IEnumerator IEnumerable.GetEnumerator() + { + return this._blocks.GetEnumerator(); + } - /// - /// Returns a Tuple of (BrightenedBlock, int) with the tail node and count. - /// Future planning that this verification process will walk the stack and get the counts/tail anyway, regardless of Async/eager loaded. - /// - /// - public bool VerifyHomogeneity(out BrightenedBlock tail, out int blockCount) - { - if (this._head is null) - { - throw new BrightChainExceptionImpossible("Head is null despite having present hashes"); - } + public int Count() + { + return this._count; + } - var allOk = true; - int count = 0; - BrightenedBlock movingTail = this._head; - foreach (var block in this._blocks) - { - count++; - movingTail = block; - allOk = allOk && this.VerifyHomogeneityAgainstBlock(block); - } + public BrightenedBlock First() + { + return this._head; + } - blockCount = count; - tail = movingTail; - return allOk; - } + public bool VerifyHomogeneityAgainstBlock(BrightenedBlock block) + { + return + block.ValidateOriginalType() && + block.CompareOriginalType(other: this._head) && + block.GetType().Equals(o: this._head.GetType()) && + block.BlockSize.Equals(obj: this._head.BlockSize); + } - public BrightenedBlock Last() + /// + /// Returns a Tuple of (BrightenedBlock, int) with the tail node and count. + /// Future planning that this verification process will walk the stack and get the counts/tail anyway, regardless of Async/eager loaded. + /// + /// + public bool VerifyHomogeneity(out BrightenedBlock tail, out int blockCount) + { + if (this._head is null) { - return this._tail; + throw new BrightChainExceptionImpossible(message: "Head is null despite having present hashes"); } - public IEnumerable All() + var allOk = true; + var count = 0; + var movingTail = this._head; + foreach (var block in this._blocks) { - return this._blocks; + count++; + movingTail = block; + allOk = allOk && this.VerifyHomogeneityAgainstBlock(block: block); } - public async IAsyncEnumerator AllAsyncEnumerable() - { - foreach (var block in this._blocks) - { - yield return block; - } - } + blockCount = count; + tail = movingTail; + return allOk; + } - public IEnumerable Ids() - { - return this._blocks.Select(b => b.Id); - } + public BrightenedBlock Last() + { + return this._tail; + } - public async IAsyncEnumerable IdsAsyncEnumerable() - { - foreach (var blockHash in this.Ids()) - { - yield return blockHash; - } - } + public IEnumerable All() + { + return this._blocks; + } - public IEnumerator GetEnumerator() + public async IAsyncEnumerator AllAsyncEnumerable() + { + foreach (var block in this._blocks) { - return this._blocks.GetEnumerator(); + yield return block; } + } - IEnumerator IEnumerable.GetEnumerator() + public IEnumerable Ids() + { + return this._blocks.Select(selector: b => b.Id); + } + + public async IAsyncEnumerable IdsAsyncEnumerable() + { + foreach (var blockHash in this.Ids()) { - return this._blocks.GetEnumerator(); + yield return blockHash; } } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/BrightChat.cs b/src/BrightChain.Engine/Models/Blocks/Chains/BrightChat.cs old mode 100644 new mode 100755 index ea4c13de..67ca0623 --- a/src/BrightChain.Engine/Models/Blocks/Chains/BrightChat.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/BrightChat.cs @@ -1,33 +1,34 @@ -namespace BrightChain.Engine.Models.Blocks.Chains -{ - using System; - using System.Collections.Generic; - using global::BrightChain.Engine.Enumerations; +using System; +using System.Collections.Generic; +using BrightChain.Engine.Models.Agents; + +namespace BrightChain.Engine.Models.Blocks.Chains; - public class BrightChat : ChainLinq +public class BrightChat : ChainLinq +{ + public BrightChat(string subject, string body, IEnumerable recipientAgents) + : base(blocks: NewChat(subject: subject, + body: body, + recipientAgents: recipientAgents)) { - public BrightChat(string subject, string body, IEnumerable recipientAgents) - : base(blocks: NewChat(subject: subject, body: body, recipientAgents: recipientAgents)) - { - } + } - public BrightChat(IEnumerable> messages) - : base(blocks: messages) - { - } + public BrightChat(IEnumerable> messages) + : base(blocks: messages) + { + } - public static IEnumerable> NewChat( - string subject, - string body, - IEnumerable recipientAgents) - { - throw new NotImplementedException(); - } + public DateTime DateCreated { get; } - public DateTime DateCreated { get; } + public IEnumerable Participants { get; } - public IEnumerable Participants { get; } + public IEnumerable Messages { get; } - public IEnumerable Messages { get; } + public static IEnumerable> NewChat( + string subject, + string body, + IEnumerable recipientAgents) + { + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/BrightMap.cs b/src/BrightChain.Engine/Models/Blocks/Chains/BrightMap.cs old mode 100644 new mode 100755 index 0f3ba24c..6bb3f7f2 --- a/src/BrightChain.Engine/Models/Blocks/Chains/BrightMap.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/BrightMap.cs @@ -1,133 +1,138 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Services.CacheManagers.Block; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// Represents a virtual map of all the contituent tuple-sets/blocks in a given source/reconstructed file. These cannot themselves be +/// committed to disk +/// The block datas may not actually be loaded in memory, but the appropriate blocks will be loaded (all non-local will be pulled into the +/// cache first) relative to their access offsets. +/// source file -> blockchainfilemap -> commit +/// pull blocks from pool -> blockchainfilemap -> read. +/// +public class BrightMap { - using System; - using System.Collections.Generic; - using System.Linq; - using global::BrightChain.Engine.Exceptions; - using global::BrightChain.Engine.Services.CacheManagers.Block; - - /// - /// Represents a virtual map of all the contituent tuple-sets/blocks in a given source/reconstructed file. These cannot themselves be committed to disk - /// The block datas may not actually be loaded in memory, but the appropriate blocks will be loaded (all non-local will be pulled into the cache first) relative to their access offsets. - /// source file -> blockchainfilemap -> commit - /// pull blocks from pool -> blockchainfilemap -> read. - /// - public class BrightMap + public BrightMap(ConstituentBlockListBlock cblBlock, IAsyncEnumerable tupleStripes = null) { - private IAsyncEnumerable TupleStripes { get; set; } + this.ConstituentBlockListBlock = cblBlock; + this.TupleStripes = tupleStripes; + } + + private BrightMap() + { + } - public ConstituentBlockListBlock ConstituentBlockListBlock { get; } + private IAsyncEnumerable TupleStripes { get; } - public static async IAsyncEnumerable> TakeIntoGroupsOf(IEnumerable list, int parts) + public ConstituentBlockListBlock ConstituentBlockListBlock { get; } + + public static async IAsyncEnumerable> TakeIntoGroupsOf(IEnumerable list, int parts) + { + var i = 0; + var items = new T[parts]; + foreach (var item in list) { - var i = 0; - T[] items = new T[parts]; - foreach (var item in list) + items[i++] = item; + + if (i == parts) { - items[i++] = item; - - if (i == parts) - { - yield return items; - i = 0; - items = new T[parts]; - } + yield return items; + i = 0; + items = new T[parts]; } - - Array.Resize(ref items, i); - yield return items; } - public static async IAsyncEnumerable> TakeIntoGroupsOf(IAsyncEnumerable list, int parts) + Array.Resize(array: ref items, + newSize: i); + yield return items; + } + + public static async IAsyncEnumerable> TakeIntoGroupsOf(IAsyncEnumerable list, int parts) + { + var i = 0; + var items = new T[parts]; + await foreach (var item in list) { - var i = 0; - T[] items = new T[parts]; - await foreach (var item in list) + items[i++] = item; + + if (i == parts) { - items[i++] = item; - - if (i == parts) - { - yield return items; - i = 0; - items = new T[parts]; - } + yield return items; + i = 0; + items = new T[parts]; } - - Array.Resize(ref items, i); - yield return items; } - public BrightMap(ConstituentBlockListBlock cblBlock, IAsyncEnumerable tupleStripes = null) + Array.Resize(array: ref items, + newSize: i); + yield return items; + } + + public async IAsyncEnumerable ReconstructTupleStripes(BrightenedBlockCacheManagerBase blockCacheManager) + { + var constituentBlocks = this.ConstituentBlockListBlock.ConstituentBlocks; + var constituentBlockCount = constituentBlocks.Count(); + if (constituentBlockCount == 0) { - this.ConstituentBlockListBlock = cblBlock; - this.TupleStripes = tupleStripes; + throw new BrightChainException(message: "No hashes in constituent block list"); } - private BrightMap() + if (constituentBlockCount % this.ConstituentBlockListBlock.TupleCount != 0) { + throw new BrightChainException(message: "CBL length is not a multiple of the tuple count"); } - public async IAsyncEnumerable ReconstructTupleStripes(BrightenedBlockCacheManagerBase blockCacheManager) + var tupleGroups = TakeIntoGroupsOf(list: constituentBlocks, + parts: this.ConstituentBlockListBlock.TupleCount); + await foreach (var tupleGroup in tupleGroups) { - var constituentBlocks = this.ConstituentBlockListBlock.ConstituentBlocks; - var constituentBlockCount = constituentBlocks.Count(); - if (constituentBlockCount == 0) + var blockList = new BrightenedBlock[this.ConstituentBlockListBlock.TupleCount]; + var i = 0; + foreach (var blockHash in tupleGroup) { - throw new BrightChainException("No hashes in constituent block list"); + blockList[i++] = blockCacheManager.Get(blockHash: blockHash); } - if ((constituentBlockCount % this.ConstituentBlockListBlock.TupleCount) != 0) + if (i == 0) { - throw new BrightChainException("CBL length is not a multiple of the tuple count"); + yield break; } - var tupleGroups = TakeIntoGroupsOf(constituentBlocks, this.ConstituentBlockListBlock.TupleCount); - await foreach (var tupleGroup in tupleGroups) - { - BrightenedBlock[] blockList = new BrightenedBlock[this.ConstituentBlockListBlock.TupleCount]; - var i = 0; - foreach (var blockHash in tupleGroup) - { - blockList[i++] = blockCacheManager.Get(blockHash); - } - - if (i == 0) - { - yield break; - } - - yield return new TupleStripe( - tupleCountMatch: this.ConstituentBlockListBlock.TupleCount, - blockSizeMatch: this.ConstituentBlockListBlock.BlockSize, - brightenedBlocks: blockList, - originalType: this.ConstituentBlockListBlock.OriginalType); - } + yield return new TupleStripe( + tupleCountMatch: this.ConstituentBlockListBlock.TupleCount, + blockSizeMatch: this.ConstituentBlockListBlock.BlockSize, + brightenedBlocks: blockList, + originalType: this.ConstituentBlockListBlock.OriginalType); } + } - public async IAsyncEnumerable ConsolidateTuplesToChainAsync(BrightenedBlockCacheManagerBase blockCacheManager) + public async IAsyncEnumerable ConsolidateTuplesToChainAsync(BrightenedBlockCacheManagerBase blockCacheManager) + { + await foreach (var tupleStripe in this.TupleStripes is null + ? this.ReconstructTupleStripes(blockCacheManager: blockCacheManager) + : this.TupleStripes) { - await foreach (TupleStripe tupleStripe in (this.TupleStripes is null) ? this.ReconstructTupleStripes(blockCacheManager) : this.TupleStripes) - { - yield return tupleStripe.Consolidate(); - } - - yield break; + yield return tupleStripe.Consolidate(); } + } - public static async IAsyncEnumerator ReadValidatedChainToBytes(IAsyncEnumerable source) + public static async IAsyncEnumerator ReadValidatedChainToBytes(IAsyncEnumerable source) + { + await foreach (var block in source) { - await foreach (var block in source) + if (!block.Validate()) + { + throw new BrightChainValidationEnumerableException(exceptions: block.ValidationExceptions, + message: block.Id.ToString()); + } + + foreach (var b in block.Bytes.ToArray()) { - if (!block.Validate()) - { - throw new BrightChainValidationEnumerableException(block.ValidationExceptions, block.Id.ToString()); - } - - foreach (byte b in block.Bytes.ToArray()) - { - yield return b; - } + yield return b; } } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinq.cs b/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinq.cs old mode 100644 new mode 100755 index 1e6c1eba..1c559077 --- a/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinq.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinq.cs @@ -1,167 +1,176 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Threading.Tasks; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// ChainLinq is the un-brightened/source array. ChainLinq helps build BrightChains. +/// +/// +[ProtoContract] +public class ChainLinq + where T : new() { - using System.Collections.Generic; - using System.Linq; - using System.Security.Cryptography; - using System.Threading.Tasks; - using global::BrightChain.Engine.Exceptions; - using global::BrightChain.Engine.Models.Blocks.DataObjects; - using global::BrightChain.Engine.Models.Hashes; - using global::BrightChain.Engine.Services; - using ProtoBuf; - - /// - /// ChainLinq is the un-brightened/source array. ChainLinq helps build BrightChains. - /// - /// - [ProtoContract] - public class ChainLinq - where T : new() + public ChainLinq(IEnumerable> blocks) { - public ChainLinq(IEnumerable> blocks) + if (!blocks.Any()) { - if (!blocks.Any()) - { - throw new BrightChainException(nameof(blocks)); - } - - SetNextLinks(blocks); - this.ObjectBlocks = blocks; + throw new BrightChainException(message: nameof(blocks)); } - public IEnumerable> ObjectBlocks { get; } - - public static IEnumerable> SetNextLinks(IEnumerable> blocks) - { - for (int i = blocks.Count() - 1; i >= 1; i--) - { - var block = blocks.ElementAt(i); - var previousBlock = blocks.ElementAt(i - 1); - previousBlock.Next = block.Id; - } + SetNextLinks(blocks: blocks); + this.ObjectBlocks = blocks; + } - return blocks; - } + public IEnumerable> ObjectBlocks { get; } - public static ChainLinq ForgeChainLinq(BlockParams blockParams, IEnumerable objects) + public static IEnumerable> SetNextLinks(IEnumerable> blocks) + { + for (var i = blocks.Count() - 1; i >= 1; i--) { - List> blocks = new List>(); - foreach (var o in objects) - { - blocks.Add(ChainLinqObjectBlock.MakeBlock( - blockParams: blockParams, - blockObject: o)); - } - - return new ChainLinq(blocks); + var block = blocks.ElementAt(index: i); + var previousBlock = blocks.ElementAt(index: i - 1); + previousBlock.Next = block.Id; } - public static async Task> ForgeChainLinqAsync(BlockParams blockParams, IAsyncEnumerable objects) - { - List> blocks = new List>(); - await foreach (var o in objects) - { - blocks.Add(ChainLinqObjectBlock.MakeBlock( - blockParams: blockParams, - blockObject: o)); - } - - return new ChainLinq(blocks); - } + return blocks; + } - public long Count() + public static ChainLinq ForgeChainLinq(BlockParams blockParams, IEnumerable objects) + { + var blocks = new List>(); + foreach (var o in objects) { - return this.ObjectBlocks.LongCount(); + blocks.Add(item: ChainLinqObjectBlock.MakeBlock( + blockParams: blockParams, + blockObject: o)); } - public ChainLinqObjectBlock First() - { - return this.ObjectBlocks.First(); - } + return new ChainLinq(blocks: blocks); + } - public ChainLinqObjectBlock Last() + public static async Task> ForgeChainLinqAsync(BlockParams blockParams, IAsyncEnumerable objects) + { + var blocks = new List>(); + await foreach (var o in objects) { - return this.ObjectBlocks.Last(); + blocks.Add(item: ChainLinqObjectBlock.MakeBlock( + blockParams: blockParams, + blockObject: o)); } - public IEnumerable All() - { - return this.ObjectBlocks.Select(b => b.BlockObject); - } + return new ChainLinq(blocks: blocks); + } - public async IAsyncEnumerable AllAsync() - { - foreach (var block in this.All()) - { - yield return block; - } - } + public long Count() + { + return this.ObjectBlocks.LongCount(); + } - public async IAsyncEnumerable> ObjectBlocksAsync() - { - foreach (var objectBlock in this.ObjectBlocks) - { - yield return objectBlock; - } - } + public ChainLinqObjectBlock First() + { + return this.ObjectBlocks.First(); + } - /// - /// Technically the "Id" field of the blocks, but as these are unbrightened source blocks, the Id will change and not be used. - /// Do NOT rely on the Id of these blocks for anything other than comparison of whether the contents have changed, prior to being brightened into a BrightChain. - /// - /// - public IEnumerable Hashes() + public ChainLinqObjectBlock Last() + { + return this.ObjectBlocks.Last(); + } + + public IEnumerable All() + { + return this.ObjectBlocks.Select(selector: b => b.BlockObject); + } + + public async IAsyncEnumerable AllAsync() + { + foreach (var block in this.All()) { - return this.ObjectBlocks.Select(b => b.Id); + yield return block; } + } - public async IAsyncEnumerable HashesAsync() + public async IAsyncEnumerable> ObjectBlocksAsync() + { + foreach (var objectBlock in this.ObjectBlocks) { - foreach (var blockHash in this.Hashes()) - { - yield return blockHash; - } + yield return objectBlock; } + } - public async Task BrightenAllAsync(BrightBlockService brightBlockService) + /// + /// Technically the "Id" field of the blocks, but as these are unbrightened source blocks, the Id will change and not be used. + /// Do NOT rely on the Id of these blocks for anything other than comparison of whether the contents have changed, prior to being + /// brightened into a BrightChain. + /// + /// + public IEnumerable Hashes() + { + return this.ObjectBlocks.Select(selector: b => b.Id); + } + + public async IAsyncEnumerable HashesAsync() + { + foreach (var blockHash in this.Hashes()) { - return await BrightenAllAsync(brightBlockService, this.ObjectBlocksAsync()) -.ConfigureAwait(false); + yield return blockHash; } + } - public static async Task BrightenAllAsync(BrightBlockService brightBlockService, IAsyncEnumerable> objectBlocks) + public async Task BrightenAllAsync(BrightBlockService brightBlockService) + { + return await BrightenAllAsync(brightBlockService: brightBlockService, + objectBlocks: this.ObjectBlocksAsync()) + .ConfigureAwait(continueOnCapturedContext: false); + } + + public static async Task BrightenAllAsync(BrightBlockService brightBlockService, + IAsyncEnumerable> objectBlocks) + { + using (var sha = SHA256.Create()) { - using (SHA256 sha = SHA256.Create()) + var received = 0; + var expected = await objectBlocks.CountAsync().ConfigureAwait(continueOnCapturedContext: false); + long bytesProcessed = 0; + await foreach (var block in objectBlocks) { - int received = 0; - var expected = await objectBlocks.CountAsync().ConfigureAwait(false); - long bytesProcessed = 0; - await foreach (var block in objectBlocks) + var blockLength = block.Bytes.Length; + bytesProcessed += blockLength; + if (++received == expected) { - var blockLength = block.Bytes.Length; - bytesProcessed += blockLength; - if (++received == expected) - { - sha.TransformFinalBlock(block.Bytes.ToArray(), 0, blockLength); - } - else - { - sha.TransformBlock(block.Bytes.ToArray(), 0, blockLength, null, 0); - } + sha.TransformFinalBlock(inputBuffer: block.Bytes.ToArray(), + inputOffset: 0, + inputCount: blockLength); } + else + { + sha.TransformBlock(inputBuffer: block.Bytes.ToArray(), + inputOffset: 0, + inputCount: blockLength, + outputBuffer: null, + outputOffset: 0); + } + } - var brightBlocks = brightBlockService + var brightBlocks = brightBlockService .BrightenBlocksAsyncEnumerable( identifiableBlocks: objectBlocks); - return await brightBlockService.ForgeChainAsync( + return await brightBlockService.ForgeChainAsync( sourceId: new DataHash( providedHashBytes: sha.Hash, sourceDataLength: bytesProcessed, computed: true), brightenedBlocks: brightBlocks) - .ConfigureAwait(false); - } + .ConfigureAwait(continueOnCapturedContext: false); } } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinqObjectBlock.cs b/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinqObjectBlock.cs old mode 100644 new mode 100755 index 6c3d8fa6..dff9cf5e --- a/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinqObjectBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/ChainLinqObjectBlock.cs @@ -1,137 +1,140 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System; +using System.IO; +using System.Linq; +using System.Text; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// Data container for serialization of objects into BrightChain. +/// +/// +[ProtoContract] +public class ChainLinqObjectBlock + : IdentifiableBlock + where T : new() { - using System; - using System.Buffers; - using System.IO; - using System.Linq; - using System.Text; - using global::BrightChain.Engine.Enumerations; - using global::BrightChain.Engine.Exceptions; - using global::BrightChain.Engine.Helpers; - using global::BrightChain.Engine.Models.Blocks.DataObjects; - using global::BrightChain.Engine.Models.Hashes; - using ProtoBuf; + public readonly T BlockObject; + + [ProtoMember(tag: 50)] public int ObjectDataLength; /// - /// Data container for serialization of objects into BrightChain. + /// Initializes a new instance of the class. + /// TODO: are we using this? /// - /// - [ProtoContract] - public class ChainLinqObjectBlock - : IdentifiableBlock - where T : new() + /// Desired block parameters. + /// Object serialized into this block. + /// Id of next block in chain. + public ChainLinqObjectBlock(BlockParams blockParams, T blockObject, BlockHash? next = null) + : base( + blockParams: blockParams, + data: RandomDataHelper.DataFiller( + inputData: ObjectToByteArray( + objectData: blockObject, + blockSize: blockParams.BlockSize, + totalLength: out var totalLength), + blockSize: blockParams.BlockSize)) { - /// - /// Convert an object to a Byte Array. - /// - public static ReadOnlyMemory ObjectToByteArray(T objectData, BlockSize blockSize, out int totalLength) + this.BlockObject = blockObject; + this.ObjectDataLength = totalLength; + this.Next = next; + if (!this.ValidateOriginalType() || !this.ValidateCurrentTypeVsOriginal()) { - if (objectData == null) - { - totalLength = -1; - return default; - } - - var memoryStream = new MemoryStream(); - Serializer.Serialize(destination: memoryStream, instance: objectData); - var finalBytes = Encoding.UTF8.GetBytes(chars: memoryStream.ToArray().Select(c => (char)c).ToArray()); - if (finalBytes.Length >= BlockSizeMap.BlockSize(blockSize)) - { - throw new Exception("Serialized data is too long for block. Use a larger block size."); - } - - totalLength = finalBytes.Length; - - return Helpers.RandomDataHelper.DataFiller( - inputData: new ReadOnlyMemory(finalBytes), - blockSize: blockSize); + throw new BrightChainException(message: "Original type mismatch."); } + } - public static T ByteArrayToObject(Type t, byte[] byteArray, int originalDataLength) - { - if (byteArray == null || !byteArray.Any()) - { - return default; - } + internal ChainLinqObjectBlock(BlockParams blockParams, ReadOnlyMemory data) + : base(blockParams: blockParams, + data: data) + { + this.BlockObject = ByteArrayToObject(byteArray: data.ToArray(), + originalDataLength: this.ObjectDataLength); + } - if (originalDataLength > 0 && originalDataLength < byteArray.Length) - { - Array.Resize(ref byteArray, originalDataLength); - } + /// + /// Gets or sets the hash of the next CBL in this CBL Chain. + /// + [ProtoMember(tag: 51)] + public BlockHash Next { get; set; } - return (T)Serializer.Deserialize(type: t, new MemoryStream(byteArray)); + /// + /// Convert an object to a Byte Array. + /// + public static ReadOnlyMemory ObjectToByteArray(T objectData, BlockSize blockSize, out int totalLength) + { + if (objectData == null) + { + totalLength = -1; + return default; } - /// - /// Convert a byte array to an Object of T. - /// - public static T ByteArrayToObject(byte[] byteArray, int originalDataLength) + var memoryStream = new MemoryStream(); + Serializer.Serialize(destination: memoryStream, + instance: objectData); + var finalBytes = Encoding.UTF8.GetBytes(chars: memoryStream.ToArray().Select(selector: c => (char)c).ToArray()); + if (finalBytes.Length >= BlockSizeMap.BlockSize(blockSize: blockSize)) { - if (byteArray == null || !byteArray.Any()) - { - return default; - } + throw new Exception(message: "Serialized data is too long for block. Use a larger block size."); + } - if (originalDataLength > 0 && originalDataLength < byteArray.Length) - { - Array.Resize(ref byteArray, originalDataLength); - } + totalLength = finalBytes.Length; - return Serializer.Deserialize(new MemoryStream(byteArray)); - } + return RandomDataHelper.DataFiller( + inputData: new ReadOnlyMemory(array: finalBytes), + blockSize: blockSize); + } - /// - /// Initializes a new instance of the class. - /// TODO: are we using this? - /// - /// Desired block parameters. - /// Object serialized into this block. - /// Id of next block in chain. - public ChainLinqObjectBlock(BlockParams blockParams, T blockObject, BlockHash? next = null) - : base( - blockParams: blockParams, - data: RandomDataHelper.DataFiller( - inputData: ObjectToByteArray( - objectData: blockObject, - blockSize: blockParams.BlockSize, - totalLength: out int totalLength), - blockSize: blockParams.BlockSize)) + public static T ByteArrayToObject(Type t, byte[] byteArray, int originalDataLength) + { + if (byteArray == null || !byteArray.Any()) { - this.BlockObject = blockObject; - this.ObjectDataLength = totalLength; - this.Next = next; - if (!this.ValidateOriginalType() || !this.ValidateCurrentTypeVsOriginal()) - { - throw new BrightChainException("Original type mismatch."); - } + return default; } - internal ChainLinqObjectBlock(BlockParams blockParams, ReadOnlyMemory data) - : base(blockParams: blockParams, data: data) + if (originalDataLength > 0 && originalDataLength < byteArray.Length) { - this.BlockObject = ByteArrayToObject(data.ToArray(), this.ObjectDataLength); + Array.Resize(array: ref byteArray, + newSize: originalDataLength); } - public override void Dispose() + return (T)Serializer.Deserialize(type: t, + source: new MemoryStream(buffer: byteArray)); + } + + /// + /// Convert a byte array to an Object of T. + /// + public static T ByteArrayToObject(byte[] byteArray, int originalDataLength) + { + if (byteArray == null || !byteArray.Any()) { + return default; } - public static ChainLinqObjectBlock MakeBlock(BlockParams blockParams, T blockObject, BlockHash next = null) + if (originalDataLength > 0 && originalDataLength < byteArray.Length) { - return new ChainLinqObjectBlock( - blockParams: blockParams, - blockObject: blockObject); + Array.Resize(array: ref byteArray, + newSize: originalDataLength); } - public readonly T BlockObject; + return Serializer.Deserialize(source: new MemoryStream(buffer: byteArray)); + } - [ProtoMember(50)] - public int ObjectDataLength; + public override void Dispose() + { + } - /// - /// Gets or sets the hash of the next CBL in this CBL Chain. - /// - [ProtoMember(51)] - public BlockHash Next { get; set; } + public static ChainLinqObjectBlock MakeBlock(BlockParams blockParams, T blockObject, BlockHash next = null) + { + return new ChainLinqObjectBlock( + blockParams: blockParams, + blockObject: blockObject); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/ConstituentBlockListBlock.cs b/src/BrightChain.Engine/Models/Blocks/Chains/ConstituentBlockListBlock.cs old mode 100644 new mode 100755 index 7a72a43f..9c8106fb --- a/src/BrightChain.Engine/Models/Blocks/Chains/ConstituentBlockListBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/ConstituentBlockListBlock.cs @@ -1,176 +1,174 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Blocks.Tags; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// A block which describes the hashes of all of the blocks needed to reconstitute a resultant block. +/// TODO: Ensure that the resultant list doesn't exceed a block, split into two lists, make a new top block, etc. +/// TODO: Ensure that the hash of the source file +/// TODO: Validate constituent blocks can recompose into that data (break up by tuple size), validate all blocks are same length +/// +[ProtoContract] +public class ConstituentBlockListBlock : IdentifiableBlock, IBlock, IDisposable, IValidatable { - using System; - using System.Collections.Generic; - using System.Linq; - using global::BrightChain.Engine.Exceptions; - using global::BrightChain.Engine.Interfaces; - using global::BrightChain.Engine.Models.Blocks.DataObjects; - using global::BrightChain.Engine.Models.Blocks.Tags; - using global::BrightChain.Engine.Models.Hashes; - using global::BrightChain.Engine.Services; - using ProtoBuf; + /// + /// Initializes a new instance of the class. + /// + /// + public ConstituentBlockListBlock(ConstituentBlockListBlockParams blockParams) + : base( + blockParams: blockParams, + data: RandomDataHelper.DataFiller( + inputData: blockParams.ConstituentBlockHashes + .SelectMany(selector: b => b.HashBytes.ToArray()) + .ToArray(), + blockSize: blockParams.BlockSize)) + { + // TODO : if finalBlockHash is null, reconstitute and compute- or accept the validation result's hash essentially? + this.SourceId = blockParams.SourceId; + this.TotalLength = blockParams.TotalLength; + this.ConstituentBlocks = blockParams.ConstituentBlockHashes; + this.Previous = blockParams.Previous; + this.Next = blockParams.Next; + this.TupleCount = BlockBrightenerService.TupleCount; + this.CorrelationId = blockParams.CorrelationId; + this.PreviousVersionHash = blockParams.PreviousVersionHash; + } + + /// + /// Gets a CBLBlockParams object with the parameters of this block. + /// + public override ConstituentBlockListBlockParams BlockParams => new( + blockParams: new BlockParams( + blockSize: this.BlockSize, + requestTime: this.StorageContract.RequestTime, + keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, + redundancy: this.StorageContract.RedundancyContractType, + privateEncrypted: this.StorageContract.PrivateEncrypted, + originalType: this.OriginalType), + sourceId: this.SourceId, + segmentId: this.SegmentId, + totalLength: this.TotalLength, + constituentBlockHashes: this.ConstituentBlocks, + previous: this.Previous, + next: this.Next, + correlationId: this.CorrelationId, + previousVersionHash: this.PreviousVersionHash); + + /// + /// Gets or sets the hash of the sum bytes of the file when assembled in order. + /// + [ProtoMember(tag: 60)] + public DataHash SourceId { get; set; } + + /// + /// Gets or sets the total length of bytes in the user data section. + /// + [ProtoMember(tag: 61)] + public long TotalLength { get; set; } + + /// + /// Gets or sets an int with the TupleCount at the time of creation. + /// + [ProtoMember(tag: 62)] + public int TupleCount { get; set; } + + /// + /// Gets or sets the hash of the sum bytes of the segment of the file contained in this CBL when assembled in order. + /// If the segment does not fill the the final block, the hash does not include the remainder of the data. + /// + [ProtoMember(tag: 63)] + public SegmentHash SegmentId { get; set; } + + /// + /// Gets or sets the BlockHash of the previous CBL in this CBL Chain. + /// + [ProtoMember(tag: 64)] + public BlockHash Previous { get; set; } + + /// + /// Gets or sets the hash of the next CBL in this CBL Chain. + /// + [ProtoMember(tag: 65)] + public BlockHash Next { get; set; } + + [ProtoMember(tag: 69)] public IEnumerable Tags { get; internal set; } /// - /// A block which describes the hashes of all of the blocks needed to reconstitute a resultant block. - /// TODO: Ensure that the resultant list doesn't exceed a block, split into two lists, make a new top block, etc. - /// TODO: Ensure that the hash of the source file - /// TODO: Validate constituent blocks can recompose into that data (break up by tuple size), validate all blocks are same length + /// Gets or sets the BrightChainID of the block's creator. /// - [ProtoContract] - public class ConstituentBlockListBlock : IdentifiableBlock, IBlock, IDisposable, IValidatable + [ProtoMember(tag: 66)] + public BrokeredAnonymityIdentifier CreatorId { get; set; } + + [ProtoMember(tag: 67)] public Guid CorrelationId { get; set; } + + [ProtoMember(tag: 68)] public DataHash PreviousVersionHash { get; set; } + + /// + /// Gets an array of the bytes of the constituent block hashes for writing to disk. + /// + public ReadOnlyMemory ConstituentBlockHashesBytes => new( + array: this.ConstituentBlocks + .SelectMany(selector: b => + b.HashBytes.ToArray()) + .ToArray()); + + /// + /// Gets a value indicating the computed cost of storing this contract. + /// + [ProtoMember(tag: 67)] + public double TotalCost { get; set; } + + /// + /// Gets an int representing the computed capacity of this block in terms of number of BlockHashes. + /// + public int MaximumHashesPerBlock => + (int)Math.Floor(d: (double)(BlockHash.HashSize / 8) / BlockSizeMap.BlockSize(blockSize: this.BlockSize)); + + /// + /// Perform validation of this CBL and its underlying data. + /// + /// A boolean indicating whether validation succeeded. + public new bool Validate() { - /// - /// Initializes a new instance of the class. - /// - /// - public ConstituentBlockListBlock(ConstituentBlockListBlockParams blockParams) - : base( - blockParams: blockParams, - data: Helpers.RandomDataHelper.DataFiller( - inputData: blockParams.ConstituentBlockHashes - .SelectMany(b => b.HashBytes.ToArray()) - .ToArray(), - blockSize: blockParams.BlockSize)) + if (!base.Validate()) { - // TODO : if finalBlockHash is null, reconstitute and compute- or accept the validation result's hash essentially? - this.SourceId = blockParams.SourceId; - this.TotalLength = blockParams.TotalLength; - this.ConstituentBlocks = blockParams.ConstituentBlockHashes; - this.Previous = blockParams.Previous; - this.Next = blockParams.Next; - this.TupleCount = BlockBrightenerService.TupleCount; - this.CorrelationId = blockParams.CorrelationId; - this.PreviousVersionHash = blockParams.PreviousVersionHash; + return false; } - /// - /// Gets a CBLBlockParams object with the parameters of this block. - /// - public override ConstituentBlockListBlockParams BlockParams => new ConstituentBlockListBlockParams( - blockParams: new BlockParams( - blockSize: this.BlockSize, - requestTime: this.StorageContract.RequestTime, - keepUntilAtLeast: this.StorageContract.KeepUntilAtLeast, - redundancy: this.StorageContract.RedundancyContractType, - privateEncrypted: this.StorageContract.PrivateEncrypted, - originalType: this.OriginalType), - sourceId: this.SourceId, - segmentId: this.SegmentId, - totalLength: this.TotalLength, - constituentBlockHashes: this.ConstituentBlocks, - previous: this.Previous, - next: this.Next, - correlationId: this.CorrelationId, - previousVersionHash: this.PreviousVersionHash); - - /// - /// Gets or sets the hash of the sum bytes of the file when assembled in order. - /// - [ProtoMember(60)] - public DataHash SourceId { get; set; } - - /// - /// Gets or sets the total length of bytes in the user data section. - /// - [ProtoMember(61)] - public long TotalLength { get; set; } - - /// - /// Gets or sets an int with the TupleCount at the time of creation. - /// - [ProtoMember(62)] - public int TupleCount { get; set; } - - /// - /// Gets or sets the hash of the sum bytes of the segment of the file contained in this CBL when assembled in order. - /// If the segment does not fill the the final block, the hash does not include the remainder of the data. - /// - [ProtoMember(63)] - public SegmentHash SegmentId { get; set; } - - /// - /// Gets or sets the BlockHash of the previous CBL in this CBL Chain. - /// - [ProtoMember(64)] - public BlockHash Previous { get; set; } - - /// - /// Gets or sets the hash of the next CBL in this CBL Chain. - /// - [ProtoMember(65)] - public BlockHash Next { get; set; } - - [ProtoMember(69)] - public IEnumerable Tags { get; internal set; } - - /// - /// Gets or sets the BrightChainID of the block's creator. - /// - [ProtoMember(66)] - public BrokeredAnonymityIdentifier CreatorId { get; set; } - - [ProtoMember(67)] - public Guid CorrelationId { get; set; } - - [ProtoMember(68)] - public DataHash PreviousVersionHash { get; set; } - - /// - /// Gets an array of the bytes of the constituent block hashes for writing to disk. - /// - public ReadOnlyMemory ConstituentBlockHashesBytes => new ReadOnlyMemory( - this.ConstituentBlocks - .SelectMany(b => - b.HashBytes.ToArray()) - .ToArray()); - - /// - /// Gets a value indicating the computed cost of storing this contract. - /// - [ProtoMember(67)] - public double TotalCost { get; set; } - - /// - /// Gets an int representing the computed capacity of this block in terms of number of BlockHashes. - /// - public int MaximumHashesPerBlock => - (int)Math.Floor((double)(BlockHash.HashSize / 8) / BlockSizeMap.BlockSize(this.BlockSize)); - - /// - /// Generate a BlockMap from the list of constituent blocks. - /// - /// BlockChainFileMap with TupleStripes of the chain. - public BrightMap CreateBrightMap() - { - return new BrightMap(this); - } + var validationExceptions = new List(collection: this.ValidationExceptions); - /// - /// Perform validation of this CBL and its underlying data. - /// - /// A boolean indicating whether validation succeeded. - public new bool Validate() + if (!(this.Previous is null)) { - if (!base.Validate()) + if (!(this.Previous is ConstituentBlockListBlock)) { - return false; + validationExceptions.Add(item: new BrightChainValidationException( + element: nameof(this.Previous), + message: "Previous object must be a CBL.")); } + } - var validationExceptions = new List(this.ValidationExceptions); - - if (!(this.Previous is null)) - { - if (!(this.Previous is ConstituentBlockListBlock)) - { - validationExceptions.Add(new BrightChainValidationException( - element: nameof(this.Previous), - message: "Previous object must be a CBL.")); - } - } + // TODO: perform additional validation as described above + return true; + } - // TODO: perform additional validation as described above - return true; - } + /// + /// Generate a BlockMap from the list of constituent blocks. + /// + /// BlockChainFileMap with TupleStripes of the chain. + public BrightMap CreateBrightMap() + { + return new BrightMap(cblBlock: this); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/SuperConstituentBlockListBlock.cs b/src/BrightChain.Engine/Models/Blocks/Chains/SuperConstituentBlockListBlock.cs old mode 100644 new mode 100755 index e2b9421e..299da1b2 --- a/src/BrightChain.Engine/Models/Blocks/Chains/SuperConstituentBlockListBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/SuperConstituentBlockListBlock.cs @@ -1,30 +1,29 @@ -namespace BrightChain.Engine.Models.Blocks.Chains -{ - using System; - using global::BrightChain.Engine.Interfaces; - using global::BrightChain.Engine.Models.Blocks.DataObjects; - using ProtoBuf; +using System; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.DataObjects; +using ProtoBuf; - /// - /// A block which describes the hashes of all of the CBL blocks needed to reconstitute a resultant block. - /// TODO: Ensure that the resultant list doesn't exceed a block, split into two lists, make a new top block, etc. - /// TODO: Ensure that the hash of the source file - /// TODO: Validate constituent blocks can recompose into that data (break up by tuple size), validate all blocks are same length - /// - [ProtoContract] - public class SuperConstituentBlockListBlock : ConstituentBlockListBlock, IBlock, IDisposable, IValidatable - { - public SuperConstituentBlockListBlock(ConstituentBlockListBlockParams blockParams) +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// A block which describes the hashes of all of the CBL blocks needed to reconstitute a resultant block. +/// TODO: Ensure that the resultant list doesn't exceed a block, split into two lists, make a new top block, etc. +/// TODO: Ensure that the hash of the source file +/// TODO: Validate constituent blocks can recompose into that data (break up by tuple size), validate all blocks are same length +/// +[ProtoContract] +public class SuperConstituentBlockListBlock : ConstituentBlockListBlock, IBlock, IDisposable, IValidatable +{ + public SuperConstituentBlockListBlock(ConstituentBlockListBlockParams blockParams) : base( - blockParams: blockParams) - { - // TODO : if finalBlockHash is null, reconstitute and compute- or accept the validation result's hash essentially? - } + blockParams: blockParams) + { + // TODO : if finalBlockHash is null, reconstitute and compute- or accept the validation result's hash essentially? + } - public new bool Validate() - { - // TODO: perform additional validation as described above - return base.Validate(); - } + public new bool Validate() + { + // TODO: perform additional validation as described above + return base.Validate(); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Chains/TupleStripe.cs b/src/BrightChain.Engine/Models/Blocks/Chains/TupleStripe.cs old mode 100644 new mode 100755 index 05957a32..c4cfb00e --- a/src/BrightChain.Engine/Models/Blocks/Chains/TupleStripe.cs +++ b/src/BrightChain.Engine/Models/Blocks/Chains/TupleStripe.cs @@ -1,59 +1,61 @@ -namespace BrightChain.Engine.Models.Blocks.Chains +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; + +namespace BrightChain.Engine.Models.Blocks.Chains; + +/// +/// A tuple stripe is a representation of the blocks used only to Recover a source block. +/// In each row, only the last block is expected to be the non-randomizer block, but order doesn't matter within a stripe. +/// +public struct TupleStripe { - using System; - using System.Collections.Generic; - using System.Linq; - using global::BrightChain.Engine.Enumerations; - using global::BrightChain.Engine.Exceptions; + public readonly IEnumerable Blocks; - /// - /// A tuple stripe is a representation of the blocks used only to Recover a source block. - /// In each row, only the last block is expected to be the non-randomizer block, but order doesn't matter within a stripe. - /// - public struct TupleStripe - { - public readonly IEnumerable Blocks; + public readonly BlockSize BlockSize; - public readonly BlockSize BlockSize; + public readonly Type OriginalType; - public readonly Type OriginalType; - - public static void ValidateRandomizers(int tupleCountMatch, BlockSize blockSizeMatch, IEnumerable blocks) + public static void ValidateRandomizers(int tupleCountMatch, BlockSize blockSizeMatch, IEnumerable blocks) + { + if (tupleCountMatch != blocks.Count()) { - if (tupleCountMatch != blocks.Count()) - { - throw new BrightChainException("Block length mismatch"); - } + throw new BrightChainException(message: "Block length mismatch"); + } - foreach (BrightenedBlock block in blocks) + foreach (var block in blocks) + { + if (blockSizeMatch != block.BlockSize) { - if (blockSizeMatch != block.BlockSize) - { - throw new BrightChainException("block size mismatch"); - } + throw new BrightChainException(message: "block size mismatch"); } } + } - public TupleStripe(int tupleCountMatch, BlockSize blockSizeMatch, Type originalType, IEnumerable brightenedBlocks) - { - ValidateRandomizers(tupleCountMatch, blockSizeMatch, brightenedBlocks); + public TupleStripe(int tupleCountMatch, BlockSize blockSizeMatch, Type originalType, IEnumerable brightenedBlocks) + { + ValidateRandomizers(tupleCountMatch: tupleCountMatch, + blockSizeMatch: blockSizeMatch, + blocks: brightenedBlocks); - this.Blocks = brightenedBlocks; - this.BlockSize = blockSizeMatch; - this.OriginalType = originalType; - } + this.Blocks = brightenedBlocks; + this.BlockSize = blockSizeMatch; + this.OriginalType = originalType; + } - /// - /// XOR's the stripe's blocks back into an Identifiable Block. - /// - /// - public IdentifiableBlock Consolidate() - { - Block firstBlock = this.Blocks.First(); - // the XOR will never XOR with the same block as that would yield all zeroes. It will be skipped. - var identifiable = new IdentifiableBlock(firstBlock.BlockParams, firstBlock.XOR(this.Blocks)); - return identifiable; - //return (IdentifiableBlock)Convert.ChangeType(identifiable, identifiable.OriginalType); - } + /// + /// XOR's the stripe's blocks back into an Identifiable Block. + /// + /// + public IdentifiableBlock Consolidate() + { + Block firstBlock = this.Blocks.First(); + // the XOR will never XOR with the same block as that would yield all zeroes. It will be skipped. + var identifiable = new IdentifiableBlock(blockParams: firstBlock.BlockParams, + data: firstBlock.XOR(others: this.Blocks)); + return identifiable; + //return (IdentifiableBlock)Convert.ChangeType(identifiable, identifiable.OriginalType); } } diff --git a/src/BrightChain.Engine/Models/Blocks/CleartextBlock.cs b/src/BrightChain.Engine/Models/Blocks/CleartextBlock.cs old mode 100644 new mode 100755 index 39a5363a..1ab5e89f --- a/src/BrightChain.Engine/Models/Blocks/CleartextBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/CleartextBlock.cs @@ -1,13 +1,13 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Models.Blocks.DataObjects; +using System; +using BrightChain.Engine.Models.Blocks.DataObjects; + +namespace BrightChain.Engine.Models.Blocks; - public class CleartextBlock : IdentifiableBlock +public class CleartextBlock : IdentifiableBlock +{ + public CleartextBlock(BlockParams blockParams, ReadOnlyMemory cleartextData) + : base(blockParams: blockParams, + data: cleartextData) { - public CleartextBlock(BlockParams blockParams, ReadOnlyMemory cleartextData) - : base(blockParams, cleartextData) - { - } } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockData.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockData.cs old mode 100644 new mode 100755 index a6be47ef..0ef27274 --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockData.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockData.cs @@ -1,80 +1,77 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using FASTER.core; +using SimpleBase; + +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +public abstract class BlockData : IComparable, IEquatable, IEqualityComparer, + IFasterEqualityComparer { - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using FASTER.core; + public virtual ReadOnlyMemory Bytes => throw new NotImplementedException(); + + public IEnumerable SHA256 => + System.Security.Cryptography.SHA256.Create().ComputeHash(buffer: this.Bytes.ToArray()); + + public uint Crc32 => + NeuralFabric.Helpers.Crc32.ComputeChecksum(bytes: this.Bytes.ToArray()); + + public ulong Crc64 => + NeuralFabric.Helpers.Crc64.ComputeChecksum(bytes: this.Bytes.ToArray()); + + public string Base64SHA256 => + Base58.Bitcoin.Encode(bytes: new ReadOnlySpan(array: (byte[])this.SHA256)); + + public string Base58Crc64 => + Base58.Bitcoin.Encode(bytes: BitConverter.GetBytes(value: this.Crc64)); + + public string Base58Data => + Base58.Bitcoin.Encode(bytes: this.Bytes.ToArray()); + + public int CompareTo(BlockData other) + { + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: this.Bytes, + ar2: other.Bytes); + } + + public bool Equals(BlockData x, BlockData y) + { + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: x.Bytes, + ar2: y.Bytes) == 0; + } + + public int GetHashCode([DisallowNull] BlockData obj) + { + return (int)this.Crc32; + } + + public bool Equals(BlockData other) + { + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: this.Bytes, + ar2: other.Bytes) == 0; + } + + public long GetHashCode64(ref BlockData k) + { + return (long)this.Crc64; + } + + public bool Equals(ref BlockData k1, ref BlockData k2) + { + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: k1.Bytes, + ar2: k2.Bytes) == 0; + } + + public static bool operator ==(BlockData a, BlockData b) + { + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: a.Bytes, + ar2: b.Bytes) == 0; + } - public abstract class BlockData : IComparable, IEquatable, IEqualityComparer, IFasterEqualityComparer + public static bool operator !=(BlockData a, BlockData b) { - public virtual ReadOnlyMemory Bytes - { - get - { - throw new NotImplementedException(); - } - } - - public BlockData() - { - } - - public IEnumerable SHA256 => - System.Security.Cryptography.SHA256.Create().ComputeHash(this.Bytes.ToArray()); - - public uint Crc32 => - Helpers.Crc32.ComputeNewChecksum(this.Bytes.ToArray()); - - public ulong Crc64 => - DamienG.Security.Cryptography.Crc64Iso.Compute(this.Bytes.ToArray()); - - public string Base64SHA256 => - SimpleBase.Base58.Bitcoin.Encode(new ReadOnlySpan((byte[])this.SHA256)); - - public static bool operator ==(BlockData a, BlockData b) - { - return Helpers.ReadOnlyMemoryComparer.Compare(a.Bytes, b.Bytes) == 0; - } - - public string Base58Crc64 => - SimpleBase.Base58.Bitcoin.Encode(BitConverter.GetBytes(this.Crc64)); - - public static bool operator !=(BlockData a, BlockData b) - { - return Helpers.ReadOnlyMemoryComparer.Compare(a.Bytes, b.Bytes) != 0; - } - - public string Base58Data => - SimpleBase.Base58.Bitcoin.Encode(this.Bytes.ToArray()); - - public int CompareTo(BlockData other) - { - return Helpers.ReadOnlyMemoryComparer.Compare(this.Bytes, other.Bytes); - } - - public bool Equals(BlockData other) - { - return Helpers.ReadOnlyMemoryComparer.Compare(this.Bytes, other.Bytes) == 0; - } - - public bool Equals(BlockData x, BlockData y) - { - return Helpers.ReadOnlyMemoryComparer.Compare(x.Bytes, y.Bytes) == 0; - } - - public int GetHashCode([DisallowNull] BlockData obj) - { - return (int)this.Crc32; - } - - public long GetHashCode64(ref BlockData k) - { - return (long)this.Crc64; - } - - public bool Equals(ref BlockData k1, ref BlockData k2) - { - return Helpers.ReadOnlyMemoryComparer.Compare(k1.Bytes, k2.Bytes) == 0; - } + return NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: a.Bytes, + ar2: b.Bytes) != 0; } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockParams.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockParams.cs old mode 100644 new mode 100755 index cc99ea1f..9f8d8adc --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockParams.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/BlockParams.cs @@ -1,50 +1,52 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; + +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +/// +/// Simple data object for passing block parameters +/// +public class BlockParams { - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - - /// - /// Simple data object for passing block parameters - /// - public class BlockParams - { - public readonly BlockSize BlockSize; + public readonly BlockSize BlockSize; - public readonly DateTime RequestTime; + public readonly DateTime KeepUntilAtLeast; - public readonly DateTime KeepUntilAtLeast; + public readonly Type OriginalType; - public readonly RedundancyContractType Redundancy; + public readonly bool PrivateEncrypted; - public readonly bool PrivateEncrypted; + public readonly RedundancyContractType Redundancy; - public readonly Type OriginalType; + public readonly DateTime RequestTime; - public BlockParams(BlockSize blockSize, DateTime requestTime, DateTime keepUntilAtLeast, RedundancyContractType redundancy, bool privateEncrypted, Type originalType) - { - this.BlockSize = blockSize; - this.RequestTime = requestTime; - this.KeepUntilAtLeast = keepUntilAtLeast; - this.Redundancy = redundancy; - this.PrivateEncrypted = privateEncrypted; - this.OriginalType = originalType; - } + public BlockParams(BlockSize blockSize, DateTime requestTime, DateTime keepUntilAtLeast, RedundancyContractType redundancy, + bool privateEncrypted, Type originalType) + { + this.BlockSize = blockSize; + this.RequestTime = requestTime; + this.KeepUntilAtLeast = keepUntilAtLeast; + this.Redundancy = redundancy; + this.PrivateEncrypted = privateEncrypted; + this.OriginalType = originalType; + } - public BlockParams Merge(BlockParams otherBlockParams) + public BlockParams Merge(BlockParams otherBlockParams) + { + if (otherBlockParams.BlockSize != this.BlockSize) { - if (otherBlockParams.BlockSize != this.BlockSize) - { - throw new BrightChainException("BlockSize mismatch"); - } - - return new BlockParams( - blockSize: this.BlockSize, - requestTime: this.RequestTime > otherBlockParams.RequestTime ? this.RequestTime : otherBlockParams.RequestTime, - keepUntilAtLeast: (otherBlockParams.KeepUntilAtLeast > this.KeepUntilAtLeast) ? otherBlockParams.KeepUntilAtLeast : this.KeepUntilAtLeast, - redundancy: (otherBlockParams.Redundancy > this.Redundancy) ? otherBlockParams.Redundancy : this.Redundancy, - privateEncrypted: this.PrivateEncrypted || otherBlockParams.PrivateEncrypted, - originalType: this.OriginalType); + throw new BrightChainException(message: "BlockSize mismatch"); } + + return new BlockParams( + blockSize: this.BlockSize, + requestTime: this.RequestTime > otherBlockParams.RequestTime ? this.RequestTime : otherBlockParams.RequestTime, + keepUntilAtLeast: otherBlockParams.KeepUntilAtLeast > this.KeepUntilAtLeast + ? otherBlockParams.KeepUntilAtLeast + : this.KeepUntilAtLeast, + redundancy: otherBlockParams.Redundancy > this.Redundancy ? otherBlockParams.Redundancy : this.Redundancy, + privateEncrypted: this.PrivateEncrypted || otherBlockParams.PrivateEncrypted, + originalType: this.OriginalType); } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightHandle.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightHandle.cs old mode 100644 new mode 100755 index 0c4806e9..ac30d38d --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightHandle.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightHandle.cs @@ -1,80 +1,81 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Hashes; - using ProtoBuf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Helpers; +using NeuralFabric.Models.Hashes; +using ProtoBuf; - [ProtoContract] - public struct BrightHandle - { - [ProtoMember(1)] - public readonly BlockSize BlockSize; +namespace BrightChain.Engine.Models.Blocks.DataObjects; - [ProtoMember(2)] - public readonly IEnumerable> BlockHashByteArrays; +[ProtoContract] +public struct BrightHandle +{ + [ProtoMember(tag: 1)] public readonly BlockSize BlockSize; - [ProtoMember(3)] - public readonly Type OriginalType; + [ProtoMember(tag: 2)] public readonly IEnumerable> BlockHashByteArrays; - [ProtoMember(4)] - public readonly BlockHash BrightenedCblHash; + [ProtoMember(tag: 3)] public readonly Type OriginalType; - [ProtoMember(5)] - public readonly DataHash IdentifiableSourceHash; + [ProtoMember(tag: 4)] public readonly BlockHash BrightenedCblHash; - public BrightHandle(BlockSize blockSize, IEnumerable blockHashes, Type originalType, BlockHash brightenedCblHash = null, DataHash identifiableSourceHash = null) - { - this.BlockSize = blockSize; - this.BlockHashByteArrays = blockHashes.Select(h => h.HashBytes); - this.OriginalType = originalType; - this.BrightenedCblHash = brightenedCblHash; - this.IdentifiableSourceHash = identifiableSourceHash; - } + [ProtoMember(tag: 5)] public readonly DataHash IdentifiableSourceHash; - public BrightHandle(Uri brightChainAddress) - { - throw new NotImplementedException(); - } + public BrightHandle(BlockSize blockSize, IEnumerable blockHashes, Type originalType, BlockHash brightenedCblHash = null, + DataHash identifiableSourceHash = null) + { + this.BlockSize = blockSize; + this.BlockHashByteArrays = blockHashes.Select(selector: h => h.HashBytes); + this.OriginalType = originalType; + this.BrightenedCblHash = brightenedCblHash; + this.IdentifiableSourceHash = identifiableSourceHash; + } - public int TupleCount => this.BlockHashByteArrays.Count(); + public BrightHandle(Uri brightChainAddress) + { + throw new NotImplementedException(); + } + + public int TupleCount => this.BlockHashByteArrays.Count(); - public IEnumerable BlockHashes + public IEnumerable BlockHashes + { + get { - get - { - var blockSize = this.BlockSize; - return this.BlockHashByteArrays.Select(r => new BlockHash( - typeof(BrightenedBlock), - originalBlockSize: blockSize, - providedHashBytes: r, - computed: true)); - } + var blockSize = this.BlockSize; + return this.BlockHashByteArrays.Select(selector: r => new BlockHash( + blockType: typeof(BrightenedBlock), + originalBlockSize: blockSize, + providedHashBytes: r, + computed: true)); } + } - public IEnumerable HashStrings => this.BlockHashByteArrays - .Select(r => Helpers.Utilities.HashToFormattedString(r.ToArray())); + public IEnumerable HashStrings => this.BlockHashByteArrays + .Select(selector: r => Utilities.HashToFormattedString(hashBytes: r.ToArray())); - public Uri BrightChainAddress(string hostName, string endpoint = "chains") - { - UriBuilder uriBuilder = new UriBuilder( - schemeName: "https", - hostName: hostName); - - uriBuilder.Path = string.Format("/{0}/{1}", endpoint, this.BlockSize.ToString()); + public Uri BrightChainAddress(string hostName, string endpoint = "chains") + { + var uriBuilder = new UriBuilder( + schemeName: "https", + hostName: hostName); - var query = HttpUtility.ParseQueryString(uriBuilder.Query); - query.Add("t", this.OriginalType.AssemblyQualifiedName); - foreach (var s in this.HashStrings) - { - query.Add(name: null, value: s); - } + uriBuilder.Path = string.Format(format: "/{0}/{1}", + arg0: endpoint, + arg1: this.BlockSize.ToString()); - uriBuilder.Query = query.ToString(); - return uriBuilder.Uri; + var query = HttpUtility.ParseQueryString(query: uriBuilder.Query); + query.Add(name: "t", + value: this.OriginalType.AssemblyQualifiedName); + foreach (var s in this.HashStrings) + { + query.Add(name: null, + value: s); } + + uriBuilder.Query = query.ToString(); + return uriBuilder.Uri; } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightenedBlockParams.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightenedBlockParams.cs old mode 100644 new mode 100755 index bb89bab1..f7913816 --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightenedBlockParams.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/BrightenedBlockParams.cs @@ -1,39 +1,38 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +public class BrightenedBlockParams : BlockParams { - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Hashes; + public ICacheManager CacheManager; - public class BrightenedBlockParams : BlockParams + public BrightenedBlockParams(ICacheManager cacheManager, bool allowCommit, BlockParams blockParams) + : base( + blockSize: blockParams.BlockSize, + requestTime: blockParams.RequestTime, + keepUntilAtLeast: blockParams.KeepUntilAtLeast, + redundancy: blockParams.Redundancy, + privateEncrypted: blockParams.PrivateEncrypted, + originalType: blockParams.OriginalType) { - public ICacheManager CacheManager; + this.CacheManager = cacheManager; + this.AllowCommit = allowCommit; + } - public bool AllowCommit { get; } + public bool AllowCommit { get; } - public BrightenedBlockParams(ICacheManager cacheManager, bool allowCommit, BlockParams blockParams) - : base( - blockSize: blockParams.BlockSize, - requestTime: blockParams.RequestTime, - keepUntilAtLeast: blockParams.KeepUntilAtLeast, - redundancy: blockParams.Redundancy, - privateEncrypted: blockParams.PrivateEncrypted, - originalType: blockParams.OriginalType) + public BrightenedBlockParams Merge(BrightenedBlockParams otherBlockParams) + { + if (otherBlockParams.BlockSize != this.BlockSize) { - this.CacheManager = cacheManager; - this.AllowCommit = allowCommit; + throw new BrightChainException(message: "BlockSize mismatch"); } - public BrightenedBlockParams Merge(BrightenedBlockParams otherBlockParams) - { - if (otherBlockParams.BlockSize != this.BlockSize) - { - throw new BrightChainException("BlockSize mismatch"); - } - - return new BrightenedBlockParams( - cacheManager: this.CacheManager, - allowCommit: this.AllowCommit && otherBlockParams.AllowCommit, - blockParams: this.Merge(otherBlockParams)); - } + return new BrightenedBlockParams( + cacheManager: this.CacheManager, + allowCommit: this.AllowCommit && otherBlockParams.AllowCommit, + blockParams: this.Merge(otherBlockParams: otherBlockParams)); } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/ConstituentBlockListBlockParams.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/ConstituentBlockListBlockParams.cs old mode 100644 new mode 100755 index d1db8e4f..534bcefb --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/ConstituentBlockListBlockParams.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/ConstituentBlockListBlockParams.cs @@ -1,70 +1,71 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Hashes; +using System; +using System.Collections.Generic; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Models.Hashes; - public class ConstituentBlockListBlockParams : BlockParams - { - public readonly DataHash SourceId; +namespace BrightChain.Engine.Models.Blocks.DataObjects; - public readonly long TotalLength; +public class ConstituentBlockListBlockParams : BlockParams +{ + public readonly IEnumerable ConstituentBlockHashes; - public readonly IEnumerable ConstituentBlockHashes; + public readonly Guid CorrelationId; - /// - /// Hash of the sum bytes of the segment of the file contained in this CBL when assembled in order. - /// - public SegmentHash SegmentId; + public readonly BlockHash Next; - public readonly BlockHash Previous = null; + public readonly BlockHash Previous; - public readonly BlockHash Next = null; + public readonly DataHash PreviousVersionHash; + public readonly DataHash SourceId; - public readonly Guid CorrelationId; + public readonly long TotalLength; - public readonly DataHash PreviousVersionHash = null; + /// + /// Hash of the sum bytes of the segment of the file contained in this CBL when assembled in order. + /// + public SegmentHash SegmentId; - public ConstituentBlockListBlockParams(BlockParams blockParams, DataHash sourceId, SegmentHash segmentId, long totalLength, IEnumerable constituentBlockHashes, BlockHash previous = null, BlockHash next = null, Guid? correlationId = null, DataHash previousVersionHash = null) - : base( - blockSize: blockParams.BlockSize, - requestTime: blockParams.RequestTime, - keepUntilAtLeast: blockParams.KeepUntilAtLeast, - redundancy: blockParams.Redundancy, - privateEncrypted: blockParams.PrivateEncrypted, - originalType: blockParams.OriginalType) - { - this.SourceId = sourceId; - this.TotalLength = totalLength; - this.ConstituentBlockHashes = constituentBlockHashes; - this.SegmentId = segmentId; - this.Previous = previous; - this.Next = next; - this.CorrelationId = correlationId.HasValue ? correlationId.Value : Guid.NewGuid(); - this.PreviousVersionHash = previousVersionHash; - } + public ConstituentBlockListBlockParams(BlockParams blockParams, DataHash sourceId, SegmentHash segmentId, long totalLength, + IEnumerable constituentBlockHashes, BlockHash previous = null, BlockHash next = null, Guid? correlationId = null, + DataHash previousVersionHash = null) + : base( + blockSize: blockParams.BlockSize, + requestTime: blockParams.RequestTime, + keepUntilAtLeast: blockParams.KeepUntilAtLeast, + redundancy: blockParams.Redundancy, + privateEncrypted: blockParams.PrivateEncrypted, + originalType: blockParams.OriginalType) + { + this.SourceId = sourceId; + this.TotalLength = totalLength; + this.ConstituentBlockHashes = constituentBlockHashes; + this.SegmentId = segmentId; + this.Previous = previous; + this.Next = next; + this.CorrelationId = correlationId.HasValue ? correlationId.Value : Guid.NewGuid(); + this.PreviousVersionHash = previousVersionHash; + } - public ConstituentBlockListBlockParams Merge(ConstituentBlockListBlockParams otherBlockParams) + public ConstituentBlockListBlockParams Merge(ConstituentBlockListBlockParams otherBlockParams) + { + if (otherBlockParams.BlockSize != this.BlockSize) { - if (otherBlockParams.BlockSize != this.BlockSize) - { - throw new BrightChainException("BlockSize mismatch"); - } + throw new BrightChainException(message: "BlockSize mismatch"); + } - var newConstituentBlocks = new List(this.ConstituentBlockHashes); - newConstituentBlocks.AddRange(otherBlockParams.ConstituentBlockHashes); + var newConstituentBlocks = new List(collection: this.ConstituentBlockHashes); + newConstituentBlocks.AddRange(collection: otherBlockParams.ConstituentBlockHashes); - return new ConstituentBlockListBlockParams( - blockParams: this.Merge(otherBlockParams), - sourceId: this.SourceId, - segmentId: this.SegmentId, - totalLength: this.TotalLength > otherBlockParams.TotalLength ? this.TotalLength : otherBlockParams.TotalLength, - constituentBlockHashes: newConstituentBlocks, - previous: this.Previous, - next: this.Next, - correlationId: this.CorrelationId, - previousVersionHash: this.PreviousVersionHash); - } + return new ConstituentBlockListBlockParams( + blockParams: this.Merge(otherBlockParams: otherBlockParams), + sourceId: this.SourceId, + segmentId: this.SegmentId, + totalLength: this.TotalLength > otherBlockParams.TotalLength ? this.TotalLength : otherBlockParams.TotalLength, + constituentBlockHashes: newConstituentBlocks, + previous: this.Previous, + next: this.Next, + correlationId: this.CorrelationId, + previousVersionHash: this.PreviousVersionHash); } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/IdentifiableBlocksInfo.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/IdentifiableBlocksInfo.cs old mode 100644 new mode 100755 index 0a79bdd0..9bdfff85 --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/IdentifiableBlocksInfo.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/IdentifiableBlocksInfo.cs @@ -1,35 +1,35 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Exceptions; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +public struct IdentifiableBlocksInfo { - using System.Collections.Generic; - using System.Linq; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Hashes; + public readonly DataHash SourceId; + public readonly int BytesPerBlock; + public readonly long TotalBlocksExpected; + public readonly long TotalBlockedBytes; + public readonly long HashesPerBlock; + public readonly int CblsExpected; + public readonly long BytesPerCbl; - public struct IdentifiableBlocksInfo + public IdentifiableBlocksInfo(IEnumerable blocks) { - public readonly DataHash SourceId; - public readonly int BytesPerBlock; - public readonly long TotalBlocksExpected; - public readonly long TotalBlockedBytes; - public readonly long HashesPerBlock; - public readonly int CblsExpected; - public readonly long BytesPerCbl; - - public IdentifiableBlocksInfo(IEnumerable blocks) + var first = blocks.First(); + this.SourceId = new DataHash(dataBytes: blocks.SelectMany(selector: b => b.Bytes.ToArray())); + this.BytesPerBlock = BlockSizeMap.BlockSize(blockSize: first.BlockSize); + var length = this.BytesPerBlock * blocks.Count(); + this.TotalBlocksExpected = (length / this.BytesPerBlock) + (length % this.BytesPerBlock > 0 ? 1 : 0); + this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; + this.HashesPerBlock = BlockSizeMap.HashesPerBlock(blockSize: first.BlockSize); + this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + + (this.TotalBlocksExpected % this.HashesPerBlock > 0 ? 1 : 0); + this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; + if (this.CblsExpected > this.HashesPerBlock) { - var first = blocks.First(); - this.SourceId = new DataHash(blocks.SelectMany(b => b.Bytes.ToArray())); - this.BytesPerBlock = BlockSizeMap.BlockSize(first.BlockSize); - var length = this.BytesPerBlock * blocks.Count(); - this.TotalBlocksExpected = length / this.BytesPerBlock + ((length % this.BytesPerBlock) > 0 ? 1 : 0); - this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; - this.HashesPerBlock = BlockSizeMap.HashesPerBlock(first.BlockSize); - this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + ((this.TotalBlocksExpected % this.HashesPerBlock) > 0 ? 1 : 0); - this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; - if (this.CblsExpected > this.HashesPerBlock) - { - throw new BrightChainException(nameof(this.CblsExpected)); - } + throw new BrightChainException(message: nameof(this.CblsExpected)); } } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/PiBlockData.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/PiBlockData.cs old mode 100644 new mode 100755 index 03dae91a..0a5fab35 --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/PiBlockData.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/PiBlockData.cs @@ -1,29 +1,21 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects -{ - using System; - using System.Linq; - using BBP; +using System; +using System.Linq; +using BBP; - public class PiBlockData : BlockData - { - public readonly long PiOffset; - public readonly int BlockSize; +namespace BrightChain.Engine.Models.Blocks.DataObjects; - public PiBlockData(long nOffset, int blockSize) - { - this.PiOffset = nOffset; - this.BlockSize = blockSize; - } +public class PiBlockData : BlockData +{ + public readonly int BlockSize; + public readonly long PiOffset; - public override ReadOnlyMemory Bytes - { - get - { - PiDigit pd = new PiDigit(nOffset: this.PiOffset); - return new ReadOnlyMemory(pd.PiBytes( - n: this.PiOffset, - count: this.BlockSize).ToArray()); - } - } + public PiBlockData(long nOffset, int blockSize) + { + this.PiOffset = nOffset; + this.BlockSize = blockSize; } + + public override ReadOnlyMemory Bytes => new ReadOnlyMemory(array: BBPCalculator.PiBytes( + offsetInHexDigitChars: this.PiOffset, + count: this.BlockSize).ToArray()); } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/SourceFileInfo.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/SourceFileInfo.cs old mode 100644 new mode 100755 index e9fe5df8..33b2131b --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/SourceFileInfo.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/SourceFileInfo.cs @@ -1,51 +1,54 @@ using System.IO; using BrightChain.Engine.Enumerations; using BrightChain.Engine.Exceptions; -using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Models.Hashes; -namespace BrightChain.Engine.Models.Blocks.DataObjects +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +public struct SourceFileInfo { - public struct SourceFileInfo - { - public readonly FileInfo FileInfo; - public readonly DataHash SourceId; - public int BytesPerBlock; - public long TotalBlocksExpected; - public readonly long TotalBlockedBytes; - public readonly long HashesPerBlock; - public readonly int CblsExpected; - public readonly long BytesPerCbl; + public readonly FileInfo FileInfo; + public readonly DataHash SourceId; + public int BytesPerBlock; + public long TotalBlocksExpected; + public readonly long TotalBlockedBytes; + public readonly long HashesPerBlock; + public readonly int CblsExpected; + public readonly long BytesPerCbl; - public SourceFileInfo(string fileName, BlockSize blockSize) + public SourceFileInfo(string fileName, BlockSize blockSize) + { + this.FileInfo = new FileInfo(fileName: fileName); + this.SourceId = new DataHash(fileInfo: this.FileInfo); + this.BytesPerBlock = BlockSizeMap.BlockSize(blockSize: blockSize); + this.TotalBlocksExpected = + (int)(this.FileInfo.Length / this.BytesPerBlock) + (this.FileInfo.Length % this.BytesPerBlock > 0 ? 1 : 0); + this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; + this.HashesPerBlock = BlockSizeMap.HashesPerBlock(blockSize: blockSize); + this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + + (this.TotalBlocksExpected % this.HashesPerBlock > 0 ? 1 : 0); + this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; + if (this.CblsExpected > this.HashesPerBlock) { - this.FileInfo = new FileInfo(fileName); - this.SourceId = new DataHash(fileInfo: this.FileInfo); - this.BytesPerBlock = BlockSizeMap.BlockSize(blockSize); - this.TotalBlocksExpected = (int)(this.FileInfo.Length / this.BytesPerBlock) + ((this.FileInfo.Length % this.BytesPerBlock) > 0 ? 1 : 0); - this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; - this.HashesPerBlock = BlockSizeMap.HashesPerBlock(blockSize); - this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + ((this.TotalBlocksExpected % this.HashesPerBlock) > 0 ? 1 : 0); - this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; - if (this.CblsExpected > this.HashesPerBlock) - { - throw new BrightChainException(nameof(this.CblsExpected)); - } + throw new BrightChainException(message: nameof(this.CblsExpected)); } + } - public SourceFileInfo(FileInfo fileInfo, BlockSize blockSize) + public SourceFileInfo(FileInfo fileInfo, BlockSize blockSize) + { + this.FileInfo = fileInfo; + this.SourceId = new DataHash(fileInfo: this.FileInfo); + this.BytesPerBlock = BlockSizeMap.BlockSize(blockSize: blockSize); + this.TotalBlocksExpected = + (int)(this.FileInfo.Length / this.BytesPerBlock) + (this.FileInfo.Length % this.BytesPerBlock > 0 ? 1 : 0); + this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; + this.HashesPerBlock = BlockSizeMap.HashesPerBlock(blockSize: blockSize); + this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + + (this.TotalBlocksExpected % this.HashesPerBlock > 0 ? 1 : 0); + this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; + if (this.CblsExpected > this.HashesPerBlock) { - this.FileInfo = fileInfo; - this.SourceId = new DataHash(fileInfo: this.FileInfo); - this.BytesPerBlock = BlockSizeMap.BlockSize(blockSize); - this.TotalBlocksExpected = (int)(this.FileInfo.Length / this.BytesPerBlock) + ((this.FileInfo.Length % this.BytesPerBlock) > 0 ? 1 : 0); - this.TotalBlockedBytes = this.TotalBlocksExpected * this.BytesPerBlock; - this.HashesPerBlock = BlockSizeMap.HashesPerBlock(blockSize); - this.CblsExpected = (int)(this.TotalBlocksExpected / this.HashesPerBlock) + ((this.TotalBlocksExpected % this.HashesPerBlock) > 0 ? 1 : 0); - this.BytesPerCbl = this.HashesPerBlock * this.BytesPerBlock; - if (this.CblsExpected > this.HashesPerBlock) - { - throw new BrightChainException(nameof(this.CblsExpected)); - } + throw new BrightChainException(message: nameof(this.CblsExpected)); } } } diff --git a/src/BrightChain.Engine/Models/Blocks/DataObjects/StoredBlockData.cs b/src/BrightChain.Engine/Models/Blocks/DataObjects/StoredBlockData.cs old mode 100644 new mode 100755 index fbf4b682..f5f4f7e6 --- a/src/BrightChain.Engine/Models/Blocks/DataObjects/StoredBlockData.cs +++ b/src/BrightChain.Engine/Models/Blocks/DataObjects/StoredBlockData.cs @@ -1,43 +1,39 @@ -namespace BrightChain.Engine.Models.Blocks.DataObjects +using System; +using Microsoft.Toolkit.HighPerformance.Buffers; + +namespace BrightChain.Engine.Models.Blocks.DataObjects; + +public class StoredBlockData : BlockData, IDisposable { - using System; - using Microsoft.Toolkit.HighPerformance.Buffers; + private readonly MemoryOwner StoredBytes; + private bool _disposedValue; - public class StoredBlockData : BlockData, IDisposable + public StoredBlockData(ReadOnlyMemory data) { - private readonly MemoryOwner StoredBytes; - private bool _disposedValue; + this.StoredBytes = MemoryOwner.Allocate(size: data.Length, + mode: AllocationMode.Default); + data.Span.CopyTo(destination: this.StoredBytes.Span); + } - public override ReadOnlyMemory Bytes - { - get - => new ReadOnlyMemory(this.StoredBytes.Span.ToArray()); - } + public override ReadOnlyMemory Bytes => new(array: this.StoredBytes.Span.ToArray()); - public StoredBlockData(ReadOnlyMemory data) - { - this.StoredBytes = MemoryOwner.Allocate(size: data.Length, mode: AllocationMode.Default); - data.Span.CopyTo(destination: this.StoredBytes.Span); - } + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + this.Dispose(disposing: true); + GC.SuppressFinalize(obj: this); + } - protected virtual void Dispose(bool disposing) + protected virtual void Dispose(bool disposing) + { + if (!this._disposedValue) { - if (!_disposedValue) + if (disposing) { - if (disposing) - { - this.StoredBytes.Dispose(); - } - - _disposedValue = true; + this.StoredBytes.Dispose(); } - } - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); + this._disposedValue = true; } } } diff --git a/src/BrightChain.Engine/Models/Blocks/EncryptedBlock.cs b/src/BrightChain.Engine/Models/Blocks/EncryptedBlock.cs old mode 100644 new mode 100755 index b39dd9de..ebd6c70d --- a/src/BrightChain.Engine/Models/Blocks/EncryptedBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/EncryptedBlock.cs @@ -1,17 +1,17 @@ -namespace BrightChain.Engine.Models.Blocks +using System; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Entities; + +namespace BrightChain.Engine.Models.Blocks; + +public class EncryptedBlock : IdentifiableBlock { - using System; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Entities; + public readonly Agent RecipientAgent; - public class EncryptedBlock : IdentifiableBlock + public EncryptedBlock(BlockParams blockParams, Agent recipientAgent, ReadOnlyMemory encryptedData) + : base(blockParams: blockParams, + data: encryptedData) { - public readonly Agent RecipientAgent; - - public EncryptedBlock(BlockParams blockParams, Agent recipientAgent, ReadOnlyMemory encryptedData) - : base(blockParams, encryptedData) - { - this.RecipientAgent = recipientAgent; - } + this.RecipientAgent = recipientAgent; } } diff --git a/src/BrightChain.Engine/Models/Blocks/IdentifiableBlock.cs b/src/BrightChain.Engine/Models/Blocks/IdentifiableBlock.cs old mode 100644 new mode 100755 index b2fad076..9450ad3f --- a/src/BrightChain.Engine/Models/Blocks/IdentifiableBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/IdentifiableBlock.cs @@ -1,35 +1,34 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using global::BrightChain.Engine.Extensions; - using global::BrightChain.Engine.Interfaces; - using global::BrightChain.Engine.Models.Blocks.DataObjects; +using System; +using BrightChain.Engine.Extensions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.DataObjects; + +namespace BrightChain.Engine.Models.Blocks; - /// - /// User data that must be whitened with the block whitener before being persisted. These blocks must never be stored directly. - /// - public class IdentifiableBlock - : Block, IComparable, IComparable, IComparable +/// +/// User data that must be whitened with the block whitener before being persisted. These blocks must never be stored directly. +/// +public class IdentifiableBlock + : Block, IComparable, IComparable, IComparable +{ + public IdentifiableBlock(BlockParams blockParams, ReadOnlyMemory data) + : base( + blockParams: blockParams, + data: data) { - public IdentifiableBlock(BlockParams blockParams, ReadOnlyMemory data) - : base( - blockParams: blockParams, - data: data) - { - } + } - public int CompareTo(IdentifiableBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public int CompareTo(IdentifiableBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - public override void Dispose() - { - } + public override void Dispose() + { + } - public new bool Validate() - { - return this.PerformValidation(out _); - } + public new bool Validate() + { + return this.PerformValidation(validationExceptions: out _); } } diff --git a/src/BrightChain.Engine/Models/Blocks/Keys/BrightChainKeyBlock.cs b/src/BrightChain.Engine/Models/Blocks/Keys/BrightChainKeyBlock.cs old mode 100644 new mode 100755 index 0dd54c09..6510f0a6 --- a/src/BrightChain.Engine/Models/Blocks/Keys/BrightChainKeyBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/Keys/BrightChainKeyBlock.cs @@ -1,9 +1,8 @@ -namespace BrightChain.Engine.Models.Blocks.Keys -{ - using ProtoBuf; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks.Keys; - [ProtoContract] - public class BrightChainKeyBlock : BrightenedBlock - { - } +[ProtoContract] +public class BrightChainKeyBlock : BrightenedBlock +{ } diff --git a/src/BrightChain.Engine/Models/Blocks/RandomizerBlock.cs b/src/BrightChain.Engine/Models/Blocks/RandomizerBlock.cs old mode 100644 new mode 100755 index 399681a2..a2160678 --- a/src/BrightChain.Engine/Models/Blocks/RandomizerBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/RandomizerBlock.cs @@ -1,51 +1,50 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Services.CacheManagers.Block; - using ProtoBuf; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Services.CacheManagers.Block; +using ProtoBuf; - /// - /// Input blocks to the whitener service that consist of purely CSPRNG data of the specified block size - /// - [ProtoContract] - public class RandomizerBlock : BrightenedBlock, IComparable - { - public RandomizerBlock(BrightenedBlockCacheManagerBase destinationCache, BlockSize blockSize, DateTime keepUntilAtLeast, RedundancyContractType redundancyContractType, DateTime? requestTime = null) - : base( - blockParams: new BrightenedBlockParams( - cacheManager: destinationCache, - allowCommit: true, - blockParams: new BlockParams( - blockSize: blockSize, - requestTime: requestTime.GetValueOrDefault(DateTime.Now), - keepUntilAtLeast: keepUntilAtLeast, - redundancy: redundancyContractType, - privateEncrypted: false, // randomizers are never "private encrypted" - originalType: typeof(RandomizerBlock))), - data: RandomDataHelper.RandomReadOnlyBytes(BlockSizeMap.BlockSize(blockSize))) - { - this.OriginalAssemblyTypeString = typeof(RandomizerBlock).AssemblyQualifiedName; - } +namespace BrightChain.Engine.Models.Blocks; - public RandomizerBlock(BrightenedBlockParams blockParams) - : base( - blockParams: blockParams, - data: RandomDataHelper.RandomReadOnlyBytes(BlockSizeMap.BlockSize(blockParams.BlockSize))) - { - this.OriginalAssemblyTypeString = typeof(RandomizerBlock).AssemblyQualifiedName; - } +/// +/// Input blocks to the whitener service that consist of purely CSPRNG data of the specified block size +/// +[ProtoContract] +public class RandomizerBlock : BrightenedBlock, IComparable +{ + public RandomizerBlock(BrightenedBlockCacheManagerBase destinationCache, BlockSize blockSize, DateTime keepUntilAtLeast, + RedundancyContractType redundancyContractType, DateTime? requestTime = null) + : base( + blockParams: new BrightenedBlockParams( + cacheManager: destinationCache, + allowCommit: true, + blockParams: new BlockParams( + blockSize: blockSize, + requestTime: requestTime.GetValueOrDefault(defaultValue: DateTime.Now), + keepUntilAtLeast: keepUntilAtLeast, + redundancy: redundancyContractType, + privateEncrypted: false, // randomizers are never "private encrypted" + originalType: typeof(RandomizerBlock))), + data: RandomDataHelper.RandomReadOnlyBytes(length: BlockSizeMap.BlockSize(blockSize: blockSize))) + { + this.OriginalAssemblyTypeString = typeof(RandomizerBlock).AssemblyQualifiedName; + } - public int CompareTo(RandomizerBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public RandomizerBlock(BrightenedBlockParams blockParams) + : base( + blockParams: blockParams, + data: RandomDataHelper.RandomReadOnlyBytes(length: BlockSizeMap.BlockSize(blockSize: blockParams.BlockSize))) + { + this.OriginalAssemblyTypeString = typeof(RandomizerBlock).AssemblyQualifiedName; + } - public override void Dispose() - { + public int CompareTo(RandomizerBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - } + public override void Dispose() + { } } diff --git a/src/BrightChain.Engine/Models/Blocks/RestorableBlock.cs b/src/BrightChain.Engine/Models/Blocks/RestorableBlock.cs old mode 100644 new mode 100755 index f4fe66a9..c5c92c8c --- a/src/BrightChain.Engine/Models/Blocks/RestorableBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/RestorableBlock.cs @@ -1,32 +1,32 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Models.Blocks.DataObjects; - using ProtoBuf; +using System; +using BrightChain.Engine.Models.Blocks.DataObjects; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Blocks; - [ProtoContract] - public class RestorableBlock : Block +[ProtoContract] +public class RestorableBlock : Block +{ + public RestorableBlock(BlockParams blockParams, ReadOnlyMemory data) + : base(blockParams: blockParams, + data: data) { - public RestorableBlock(BlockParams blockParams, ReadOnlyMemory data) - : base(blockParams: blockParams, data: data) - { - } + } - public RestorableBlock(Block block) - : base( - blockParams: new BlockParams( - blockSize: block.BlockSize, - requestTime: block.StorageContract.RequestTime, - keepUntilAtLeast: block.StorageContract.KeepUntilAtLeast, - redundancy: block.StorageContract.RedundancyContractType, - privateEncrypted: block.StorageContract.PrivateEncrypted, - originalType: block.OriginalType), - data: block.Bytes) - { - } + public RestorableBlock(Block block) + : base( + blockParams: new BlockParams( + blockSize: block.BlockSize, + requestTime: block.StorageContract.RequestTime, + keepUntilAtLeast: block.StorageContract.KeepUntilAtLeast, + redundancy: block.StorageContract.RedundancyContractType, + privateEncrypted: block.StorageContract.PrivateEncrypted, + originalType: block.OriginalType), + data: block.Bytes) + { + } - public override void Dispose() - { - } + public override void Dispose() + { } } diff --git a/src/BrightChain.Engine/Models/Blocks/RootBlock.cs b/src/BrightChain.Engine/Models/Blocks/RootBlock.cs old mode 100644 new mode 100755 index accd6363..07eba7a5 --- a/src/BrightChain.Engine/Models/Blocks/RootBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/RootBlock.cs @@ -1,37 +1,37 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks.DataObjects; - using ProtoBuf; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.DataObjects; +using ProtoBuf; - /// - /// The root block is the key / control node for the cache. Everything gets signed from here. - /// There can only be one. - /// - [ProtoContract] - public class RootBlock : BrightenedBlock, IBlock, IComparable - { - public RootBlock(Guid databaseGuid, BlockSize blockSize = BlockSize.Large) - : base( - blockParams: new BrightenedBlockParams( - cacheManager: null, - allowCommit: false, - blockParams: new BlockParams( - blockSize: blockSize, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: RedundancyContractType.HeapHighPriority, - privateEncrypted: false, - originalType: typeof(RootBlock))), - data: Helpers.RandomDataHelper.DataFiller(default(ReadOnlyMemory), blockSize)) - { - this.Guid = databaseGuid; - this.OriginalAssemblyTypeString = typeof(RootBlock).AssemblyQualifiedName; - } +namespace BrightChain.Engine.Models.Blocks; - [ProtoMember(30)] - public Guid Guid { get; set; } +/// +/// The root block is the key / control node for the cache. Everything gets signed from here. +/// There can only be one. +/// +[ProtoContract] +public class RootBlock : BrightenedBlock, IBlock, IComparable +{ + public RootBlock(Guid databaseGuid, BlockSize blockSize = BlockSize.Large) + : base( + blockParams: new BrightenedBlockParams( + cacheManager: null, + allowCommit: false, + blockParams: new BlockParams( + blockSize: blockSize, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.HeapHighPriority, + privateEncrypted: false, + originalType: typeof(RootBlock))), + data: RandomDataHelper.DataFiller(inputData: default, + blockSize: blockSize)) + { + this.Guid = databaseGuid; + this.OriginalAssemblyTypeString = typeof(RootBlock).AssemblyQualifiedName; } + + [ProtoMember(tag: 30)] public Guid Guid { get; set; } } diff --git a/src/BrightChain.Engine/Models/Blocks/Tags/BrightTag.cs b/src/BrightChain.Engine/Models/Blocks/Tags/BrightTag.cs old mode 100644 new mode 100755 index 914d7c88..6243c08a --- a/src/BrightChain.Engine/Models/Blocks/Tags/BrightTag.cs +++ b/src/BrightChain.Engine/Models/Blocks/Tags/BrightTag.cs @@ -1,47 +1,87 @@ using System; +using System.Linq; using BrightChain.Engine.Enumerations; -namespace BrightChain.Engine.Models.Blocks.Tags +namespace BrightChain.Engine.Models.Blocks.Tags; + +/// +/// Tag string. +/// +public struct BrightTag : IFormattable { - public struct BrightTag : IFormattable + /// + /// Tag id. + /// + public readonly Guid Id; + + /// + /// Tag string. + /// + public readonly string Tag; + + /// + /// Tag type. + /// + public readonly BrightTagType Type; + + /// + /// Initializes a new instance of the struct. + /// Create a new tag. + /// + /// + /// + public BrightTag(string tag, BrightTagType type = BrightTagType.UserAssigned) + { + this.Id = Guid.NewGuid(); + this.Tag = tag; + this.Type = type; + } + + /// + /// Gets tag bytes. + /// + public ReadOnlyMemory Bytes => + new(array: this.Tag.Select(selector: c => (byte)c).ToArray()); + + /// + /// Gets create a unique identifier from the type and tag. + /// + public string UniqueIdentifier => $"{this.Type.ToString()}:{this.Tag}"; + + /// + /// Gets the unique identifier as bytes. + /// + public ReadOnlyMemory IdentifierBytes => new(array: this.UniqueIdentifier.Select(selector: c => (byte)c).ToArray()); + + /// + /// Gets the CRC32 of the tag bytes. + /// + public uint Crc32 => + NeuralFabric.Helpers.Crc32.ComputeChecksum(bytes: this.Bytes.ToArray()); + + /// + /// Gets the CRC64 of the tag bytes. + /// + public ulong Crc64 => + NeuralFabric.Helpers.Crc64.ComputeChecksum(bytes: this.Bytes.ToArray()); + + /// + /// Tag to string is just the tag. + /// + /// + /// + /// + public string ToString(string _, IFormatProvider formatProvider) + { + return this.Tag.ToString(provider: formatProvider); + } + + /// + /// Tag to string is just the tag. + /// + /// Tag string. + public override string ToString() { - public readonly Guid Id; - public readonly string Tag; - public readonly BrightTagType Type; - - public BrightTag(string tag, BrightTagType type = BrightTagType.UserAssigned) - { - this.Id = Guid.NewGuid(); - this.Tag = tag; - this.Type = type; - } - - private string uniqueIdentifier => - string.Format( - format: "{0}:{1}", - this.Type.ToString(), - this.Tag); - - public ReadOnlyMemory Bytes => - System.Text.Encoding.ASCII.GetBytes(this.Tag); - - public ReadOnlyMemory IdentifierBytes => - System.Text.Encoding.ASCII.GetBytes(this.uniqueIdentifier); - - public uint Crc32 => - Helpers.Crc32.ComputeNewChecksum(this.Bytes.ToArray()); - - public ulong Crc64 => - DamienG.Security.Cryptography.Crc64Iso.Compute(this.Bytes.ToArray()); - - public string ToString(string _, IFormatProvider formatProvider) - { - return this.Tag.ToString(provider: formatProvider); - } - - public string ToString() - { - return this.Tag.ToString(); - } + return this.Tag; } } diff --git a/src/BrightChain.Engine/Models/Blocks/ZeroVectorBlock.cs b/src/BrightChain.Engine/Models/Blocks/ZeroVectorBlock.cs old mode 100644 new mode 100755 index a835a195..0229cc56 --- a/src/BrightChain.Engine/Models/Blocks/ZeroVectorBlock.cs +++ b/src/BrightChain.Engine/Models/Blocks/ZeroVectorBlock.cs @@ -1,52 +1,51 @@ -namespace BrightChain.Engine.Models.Blocks -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks.DataObjects; - using ProtoBuf; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks.DataObjects; +using ProtoBuf; - /// - /// Input blocks to the whitener service that consist of purely CSPRNG data of the specified block size - /// - [ProtoContract] - public class ZeroVectorBlock : Block, IComparable - { - public static ReadOnlyMemory NewZeroVectorBlockData(BlockSize blockSize) - { - var zeroBytes = new byte[BlockSizeMap.BlockSize(blockSize)]; - Array.Fill(array: zeroBytes, value: 0); - return new ReadOnlyMemory(zeroBytes); - } +namespace BrightChain.Engine.Models.Blocks; - public ZeroVectorBlock(BlockParams blockParams) - : base( - blockParams: blockParams, - data: NewZeroVectorBlockData(blockParams.BlockSize)) - { - this.OriginalAssemblyTypeString = typeof(ZeroVectorBlock).AssemblyQualifiedName; - } +/// +/// Input blocks to the whitener service that consist of purely CSPRNG data of the specified block size +/// +[ProtoContract] +public class ZeroVectorBlock : Block, IComparable +{ + public ZeroVectorBlock(BlockParams blockParams) + : base( + blockParams: blockParams, + data: NewZeroVectorBlockData(blockSize: blockParams.BlockSize)) + { + this.OriginalAssemblyTypeString = typeof(ZeroVectorBlock).AssemblyQualifiedName; + } - public ZeroVectorBlock(BlockSize blockSize) - : base( - blockParams: new BlockParams( - blockSize: blockSize, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: RedundancyContractType.Unknown, - privateEncrypted: false, - originalType: typeof(ZeroVectorBlock)), - data: NewZeroVectorBlockData(blockSize)) - { - } + public ZeroVectorBlock(BlockSize blockSize) + : base( + blockParams: new BlockParams( + blockSize: blockSize, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.Unknown, + privateEncrypted: false, + originalType: typeof(ZeroVectorBlock)), + data: NewZeroVectorBlockData(blockSize: blockSize)) + { + } - public int CompareTo(ZeroVectorBlock other) - { - return this.StoredData.CompareTo(other.StoredData); - } + public int CompareTo(ZeroVectorBlock other) + { + return this.StoredData.CompareTo(other: other.StoredData); + } - public override void Dispose() - { + public static ReadOnlyMemory NewZeroVectorBlockData(BlockSize blockSize) + { + var zeroBytes = new byte[BlockSizeMap.BlockSize(blockSize: blockSize)]; + Array.Fill(array: zeroBytes, + value: 0); + return new ReadOnlyMemory(array: zeroBytes); + } - } + public override void Dispose() + { } } diff --git a/src/BrightChain.Engine/Models/BrightChainConfiguration.cs b/src/BrightChain.Engine/Models/BrightChainConfiguration.cs old mode 100644 new mode 100755 index 4cb791a1..563bdff0 --- a/src/BrightChain.Engine/Models/BrightChainConfiguration.cs +++ b/src/BrightChain.Engine/Models/BrightChainConfiguration.cs @@ -1,13 +1,13 @@ -namespace BrightChain.Engine.Models -{ - using System.Collections.Generic; - using Microsoft.Extensions.Configuration; +using System.Collections.Generic; +using Microsoft.Extensions.Configuration; + +namespace BrightChain.Engine.Models; - public class BrightChainConfiguration : ConfigurationSection +public class BrightChainConfiguration : ConfigurationSection +{ + public BrightChainConfiguration() + : base(root: new ConfigurationRoot(providers: new List()), + path: string.Empty) { - public BrightChainConfiguration() - : base(root: new ConfigurationRoot(new List() { }), path: string.Empty) - { - } } } diff --git a/src/BrightChain.Engine/Models/BrightChainFasterCacheContext.cs b/src/BrightChain.Engine/Models/BrightChainFasterCacheContext.cs new file mode 100755 index 00000000..9cae2a6f --- /dev/null +++ b/src/BrightChain.Engine/Models/BrightChainFasterCacheContext.cs @@ -0,0 +1,10 @@ +namespace BrightChain.Engine.Faster; + +/// +/// User context to measure latency and/or check read result. +/// +public struct BrightChainFasterCacheContext +{ + public int type; + public long ticks; +} diff --git a/src/BrightChain.Engine/Models/BrightenedBlockTransaction.cs b/src/BrightChain.Engine/Models/BrightenedBlockTransaction.cs new file mode 100755 index 00000000..d586b12e --- /dev/null +++ b/src/BrightChain.Engine/Models/BrightenedBlockTransaction.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services.CacheManagers.Block; + +namespace BrightChain.Engine.Models; + +public class BrightenedBlockTransaction +{ + private readonly BrightenedBlockCacheManagerBase CacheManager; + + public readonly Queue UncomittedBlockQueue; + + /// + /// Blocks that are in-memory either pending write to the cache or confirmation of no-rollback required. + /// + private readonly Dictionary UncommittedBlocksByHash; + + /// + /// Hashes of concomitted blocks grouped by transactions status. + /// + private readonly Dictionary> UncommittedHashesByStatus; + + private int BlockAddDrop = 0; + private int BlockAdditions = 0; + private int BlockDrops = 0; + + private int BlockReads = 0; + private int BlockUpdates = 0; + private int CommittedBlocks = 0; + private int RolledBackBlocks = 0; + private TransactionStatus TransactionState; + + public BrightenedBlockTransaction(BrightenedBlockCacheManagerBase cacheManager) + { + this.Id = Guid.NewGuid(); + this.CacheManager = cacheManager; + this.TransactionState = TransactionStatus.Uncommitted; + this.UncommittedBlocksByHash = new Dictionary(); + this.UncommittedHashesByStatus = new Dictionary>(); + this.UncomittedBlockQueue = new Queue(); + } + + public Guid Id { get; } + + public IEnumerable UncommittedBlocks => this.UncommittedBlocksByHash.Values; + + public BlockHash NextBlockHash => this.UncomittedBlockQueue.Dequeue(); + + public BrightenedBlock NextBlock => this.UncommittedBlocksByHash[key: this.NextBlockHash]; + + public BlockHash PeekNextBlockHash => this.UncomittedBlockQueue.Peek(); + + public BrightenedBlock PeekNextBlock => this.UncommittedBlocksByHash[key: this.PeekNextBlockHash]; + + public IEnumerable UncommittedBlocksByStatus(TransactionStatus transactionStatus) + { + return this.CacheManager.Get(keys: this.UncommittedHashesByStatus[key: transactionStatus].ToArray()); + } + + public void DropTransactionBlock(BlockHash blockHash) + { + var currentStatus = this.GetBlockStatus(blockHash: blockHash); + + if (!this.UncomittedBlockQueue.Contains(value: blockHash)) + { + this.UncomittedBlockQueue.Append(element: blockHash); + } + + if (currentStatus.HasValue && currentStatus.Value != TransactionStatus.Uncommitted) + { + throw new BrightChainException(message: "Unexpected state"); + } + + this.SetBlockStatus(blockHash: blockHash, + newStatus: TransactionStatus.DroppedUncommitted); + } + + private TransactionStatus? GetBlockStatus(BlockHash blockHash) + { + foreach (TransactionStatus status in Enum.GetValues(enumType: typeof(TransactionStatus))) + { + var hashesByStatusList = this.UncommittedHashesByStatus[key: status]; + if (hashesByStatusList.Contains(item: blockHash)) + { + return status; + } + } + + return null; + } + + private void SetBlockStatus(BlockHash blockHash, TransactionStatus newStatus) + { + var updated = this.UncomittedBlockQueue.Contains(value: blockHash); + foreach (TransactionStatus status in Enum.GetValues(enumType: typeof(TransactionStatus))) + { + var hashesByStatusList = this.UncommittedHashesByStatus[key: newStatus]; + if (status == newStatus) + { + if (!hashesByStatusList.Contains(item: blockHash)) + { + hashesByStatusList.Add(item: blockHash); + } + } + else if (updated) + { + if (hashesByStatusList.Contains(item: blockHash)) + { + hashesByStatusList.Remove(item: blockHash); + } + } + } + } + + public bool AddUpdateMemoryBlock(BrightenedBlock block) + { + var updated = this.UncomittedBlockQueue.Contains(value: block.Id); + + if (!updated) + { + this.UncomittedBlockQueue.Append(element: block.Id); + } + + this.UncommittedBlocksByHash[key: block.Id] = block; + this.SetBlockStatus(blockHash: block.Id, + newStatus: TransactionStatus.Uncommitted); + + return updated; + } + + public BrightenedBlock CacheFetchToMemory(BlockHash blockHash) + { + var cacheHit = this.CacheManager.Contains(key: blockHash); + if (!cacheHit) + { + throw new BrightChainException(message: "Cache Miss"); + } + + var cacheBlock = this.CacheManager.Get(blockHash: blockHash); + this.AddUpdateMemoryBlock(block: cacheBlock); + + return cacheBlock; + } + + public BrightenedBlock TransactionBlock(BlockHash blockHash) + { + if (!this.UncommittedBlocksByHash.ContainsKey(key: blockHash)) + { + throw new BrightChainException(message: "Hash not found"); + } + + return this.UncommittedBlocksByHash[key: blockHash]; + } + + public bool Commit() + { + throw new NotImplementedException(); + } + + public bool Rollback() + { + throw new NotImplementedException(); + } +} diff --git a/src/BrightChain.Engine/Models/Contracts/RevocationCertificate.cs b/src/BrightChain.Engine/Models/Contracts/RevocationCertificate.cs old mode 100644 new mode 100755 index 47351c60..57915c79 --- a/src/BrightChain.Engine/Models/Contracts/RevocationCertificate.cs +++ b/src/BrightChain.Engine/Models/Contracts/RevocationCertificate.cs @@ -1,29 +1,30 @@ -namespace BrightChain.Engine.Models.Contracts +using System; +using BrightChain.Engine.Models.Blocks; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Contracts; + +/// +/// Type box for the revocation certificates/tokens to delete private/encrypted blocks. +/// +[ProtoContract] +public class RevocationCertificate : DataSignature, IComparable { - using System; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - using ProtoBuf; + public RevocationCertificate(BrightenedBlock block) + : base(dataBytes: block.StoredData.Bytes) + { + } /// - /// Type box for the revocation certificates/tokens to delete private/encrypted blocks. + /// Compares this RevocationCertificate to another for equality. /// - [ProtoContract] - public class RevocationCertificate : DataSignature, IComparable + /// Other RevocationCertificate instance to compare to. + /// + /// integer representing -1, 0, or 1 for <, =, and >, respectively. + /// + public int CompareTo(RevocationCertificate other) { - public RevocationCertificate(BrightenedBlock block) - : base(block) - { - } - - /// - /// Compares this RevocationCertificate to another for equality. - /// - /// Other RevocationCertificate instance to compare to. - /// integer representing -1, 0, or 1 for <, =, and >, respectively. - public int CompareTo(RevocationCertificate other) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Contracts/StorageContract.cs b/src/BrightChain.Engine/Models/Contracts/StorageContract.cs old mode 100644 new mode 100755 index 4aa39fa2..c612cb36 --- a/src/BrightChain.Engine/Models/Contracts/StorageContract.cs +++ b/src/BrightChain.Engine/Models/Contracts/StorageContract.cs @@ -1,93 +1,93 @@ -namespace BrightChain.Engine.Models.Contracts +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Units; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Contracts; + +/// +/// Contract for the minimum amount of time required to store a given block. +/// +[ProtoContract] +public struct StorageContract { - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Units; - using ProtoBuf; + /// + /// Gets the Date/Time the block was received by the network. + /// + [ProtoMember(tag: 1)] + public DateTime RequestTime { get; internal set; } /// - /// Contract for the minimum amount of time required to store a given block. + /// Gets the Minimum date the block will be preserved until. /// - [ProtoContract] - public struct StorageContract + [ProtoMember(tag: 2)] + public DateTime KeepUntilAtLeast { get; internal set; } + + /// + /// Gets the Number of bytes stored in this block. + /// + [ProtoMember(tag: 3)] + public int ByteCount { get; internal set; } + + /// + /// Gets a value indicating whether the data is being stored for public use. + /// Factors into cost and other matters later on. + /// + [ProtoMember(tag: 4)] + public bool PrivateEncrypted { get; internal set; } + + /// + /// Gets the contracted durability requirements. + /// + [ProtoMember(tag: 5)] + public RedundancyContractType RedundancyContractType { get; internal set; } + + public StorageContract(DateTime RequestTime, DateTime KeepUntilAtLeast, int ByteCount, bool PrivateEncrypted, + RedundancyContractType redundancyContractType) + { + this.RequestTime = RequestTime; + this.KeepUntilAtLeast = KeepUntilAtLeast; + this.ByteCount = ByteCount; + this.PrivateEncrypted = PrivateEncrypted; + this.RedundancyContractType = redundancyContractType; + } + + public static bool operator ==(StorageContract a, StorageContract b) + { + return a.RequestTime == b.RequestTime && + a.KeepUntilAtLeast == b.KeepUntilAtLeast && + a.ByteCount == b.ByteCount && + a.PrivateEncrypted == b.PrivateEncrypted && + a.RedundancyContractType == b.RedundancyContractType; + } + + public static bool operator !=(StorageContract a, StorageContract b) + { + return !(a == b); + } + + public double Duration => this.KeepUntilAtLeast.Subtract(value: this.RequestTime).TotalSeconds; + + public ByteStorageDuration ByteStorageDuration => new( + byteCount: this.ByteCount, + durationSeconds: (ulong)this.Duration); + + public readonly bool DoNotStore => this.KeepUntilAtLeast.Equals(value: DateTime.MinValue); + + public readonly bool NonExpiring => this.KeepUntilAtLeast.Equals(value: DateTime.MaxValue); + + public bool Equals(StorageContract other) + { + return this == other; + } + + public override bool Equals(object other) + { + return other is StorageContract storageContract && storageContract == this; + } + + public override int GetHashCode() { - /// - /// Gets the Date/Time the block was received by the network. - /// - [ProtoMember(1)] - public DateTime RequestTime { get; internal set; } - - /// - /// Gets the Minimum date the block will be preserved until. - /// - [ProtoMember(2)] - public DateTime KeepUntilAtLeast { get; internal set; } - - /// - /// Gets the Number of bytes stored in this block. - /// - [ProtoMember(3)] - public int ByteCount { get; internal set; } - - /// - /// Gets a value indicating whether the data is being stored for public use. - /// Factors into cost and other matters later on. - /// - [ProtoMember(4)] - public bool PrivateEncrypted { get; internal set; } - - /// - /// Gets the contracted durability requirements. - /// - [ProtoMember(5)] - public RedundancyContractType RedundancyContractType { get; internal set; } - - public StorageContract(DateTime RequestTime, DateTime KeepUntilAtLeast, int ByteCount, bool PrivateEncrypted, RedundancyContractType redundancyContractType) - { - this.RequestTime = RequestTime; - this.KeepUntilAtLeast = KeepUntilAtLeast; - this.ByteCount = ByteCount; - this.PrivateEncrypted = PrivateEncrypted; - this.RedundancyContractType = redundancyContractType; - } - - public static bool operator ==(StorageContract a, StorageContract b) - { - return a.RequestTime == b.RequestTime && - a.KeepUntilAtLeast == b.KeepUntilAtLeast && - a.ByteCount == b.ByteCount && - a.PrivateEncrypted == b.PrivateEncrypted && - a.RedundancyContractType == b.RedundancyContractType; - } - - public static bool operator !=(StorageContract a, StorageContract b) - { - return !(a == b); - } - - public double Duration => this.KeepUntilAtLeast.Subtract(this.RequestTime).TotalSeconds; - - public ByteStorageDuration ByteStorageDuration => new ByteStorageDuration( - byteCount: this.ByteCount, - durationSeconds: (ulong)this.Duration); - - public readonly bool DoNotStore => this.KeepUntilAtLeast.Equals(DateTime.MinValue); - - public readonly bool NonExpiring => this.KeepUntilAtLeast.Equals(DateTime.MaxValue); - - public bool Equals(StorageContract other) - { - return this == other; - } - - public override bool Equals(object other) - { - return other is StorageContract storageContract && storageContract == this; - } - - public override int GetHashCode() - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Entities/Agent.cs b/src/BrightChain.Engine/Models/Entities/Agent.cs old mode 100644 new mode 100755 index 53ee9d52..08541297 --- a/src/BrightChain.Engine/Models/Entities/Agent.cs +++ b/src/BrightChain.Engine/Models/Entities/Agent.cs @@ -1,25 +1,24 @@ -namespace BrightChain.Engine.Models.Entities -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Keys; +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Keys; + +namespace BrightChain.Engine.Models.Entities; - /// - /// A user in the BrightChain network. - /// Likely to change. - /// - public class Agent - { - public Guid Id { get; } +/// +/// A user in the BrightChain network. +/// Likely to change. +/// +public class Agent +{ + public Guid Id { get; } - public BrightChainKey Key { get; } + public BrightChainKey Key { get; } - public Block[] PublicBlocks { get; } + public Block[] PublicBlocks { get; } - public Block[] PrivateBlocks { get; } + public Block[] PrivateBlocks { get; } - public Dictionary<(string, BrightMailBoxType, BrightMessageType), IEnumerable> Mailbox { get; } - } + public Dictionary<(string, BrightMailBoxType, BrightMessageType), IEnumerable> Mailbox { get; } } diff --git a/src/BrightChain.Engine/Models/Events/BlockEventArgs.cs b/src/BrightChain.Engine/Models/Events/BlockEventArgs.cs old mode 100644 new mode 100755 index 0c912806..df980815 --- a/src/BrightChain.Engine/Models/Events/BlockEventArgs.cs +++ b/src/BrightChain.Engine/Models/Events/BlockEventArgs.cs @@ -1,13 +1,12 @@ using System; using BrightChain.Engine.Models.Blocks; -namespace BrightChain.Engine.Models.Events +namespace BrightChain.Engine.Models.Events; + +/// +/// Any action related to a block will have these event args +/// +public class BlockEventArgs : EventArgs { - /// - /// Any action related to a block will have these event args - /// - public class BlockEventArgs : EventArgs - { - public readonly Block Block; - } + public readonly Block Block; } diff --git a/src/BrightChain.Engine/Models/Events/CacheEventArgs.cs b/src/BrightChain.Engine/Models/Events/CacheEventArgs.cs old mode 100644 new mode 100755 index a4e2d6c5..6e7397e9 --- a/src/BrightChain.Engine/Models/Events/CacheEventArgs.cs +++ b/src/BrightChain.Engine/Models/Events/CacheEventArgs.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; -namespace BrightChain.Engine.Models.Events +namespace BrightChain.Engine.Models.Events; + +/// +/// Any cache event will have these args +/// +/// +/// +public class CacheEventArgs : EventArgs { - /// - /// Any cache event will have these args - /// - /// - /// - public class CacheEventArgs : EventArgs - { - public KeyValuePair KeyValue; - } + public KeyValuePair KeyValue; } diff --git a/src/BrightChain.Engine/Models/Hashes/BlockHash.cs b/src/BrightChain.Engine/Models/Hashes/BlockHash.cs old mode 100644 new mode 100755 index 3fd32de2..089cf7b9 --- a/src/BrightChain.Engine/Models/Hashes/BlockHash.cs +++ b/src/BrightChain.Engine/Models/Hashes/BlockHash.cs @@ -1,165 +1,180 @@ -namespace BrightChain.Engine.Models.Hashes +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using FASTER.core; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Models.Hashes; + +/// +/// Type box for the sha hashes. +/// +[ProtoContract] +public class BlockHash : DataHash, IDataHash, IComparable, IEquatable, IFasterEqualityComparer { - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using DamienG.Security.Cryptography; - using FASTER.core; - using ProtoBuf; + /// + /// Size in bits of the hash. + /// + public new const int HashSize = 256; /// - /// Type box for the sha hashes. + /// Initializes a new instance of the class. /// - [ProtoContract] - public class BlockHash : DataHash, IDataHash, IComparable, IEquatable, IFasterEqualityComparer + /// Source block to compute data hash from. + public BlockHash(Block block) + : base(dataBytes: block.Bytes) { - /// - /// Size in bits of the hash. - /// - public new const int HashSize = 256; - - /// - /// Initializes a new instance of the class. - /// - /// Source block to compute data hash from. - public BlockHash(Block block) - : base(dataBytes: block.Bytes) + if (block is not RootBlock) { - if (block is not RootBlock) + var detectedSize = BlockSizeMap.BlockSize(blockSize: block.Bytes.Length); + if (detectedSize != block.BlockSize) { - var detectedSize = BlockSizeMap.BlockSize(block.Bytes.Length); - if (detectedSize != block.BlockSize) - { - throw new BrightChainValidationException( - element: nameof(detectedSize), - message: "Detected block size did not match specified block size"); - } - - this.BlockSize = block.BlockSize; - this.BlockType = block.GetType(); + throw new BrightChainValidationException( + element: nameof(detectedSize), + message: "Detected block size did not match specified block size"); } - } - /// - /// Initializes a new instance of the class. - /// - /// Block type of the underlying block. - /// Block size of the block the hash was computed from. - /// Hash bytes to accept as the hash. - /// A boolean value indicating whether the source bytes were computed internally or externally (false). - public BlockHash(Type blockType, BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes, bool computed) - : base(providedHashBytes: providedHashBytes, sourceDataLength: BlockSizeMap.BlockSize(originalBlockSize), computed: computed) - { - if (!typeof(Block).IsAssignableFrom(blockType)) - { - throw new BrightChainException("Block Type must be Block or descendant."); - } - - this.BlockType = blockType; - this.BlockSize = originalBlockSize; + this.BlockSize = block.BlockSize; + this.BlockType = block.GetType(); } + } - /// - /// Initializes a new instance of the class. - /// - /// Block type of the underlying block. - /// Data to compute hash from. - public BlockHash(Type blockType, ReadOnlyMemory dataBytes) - : base(dataBytes) + /// + /// Initializes a new instance of the class. + /// + /// Block type of the underlying block. + /// Block size of the block the hash was computed from. + /// Hash bytes to accept as the hash. + /// A boolean value indicating whether the source bytes were computed internally or externally (false). + public BlockHash(Type blockType, BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes, bool computed) + : base(providedHashBytes: providedHashBytes, + sourceDataLength: BlockSizeMap.BlockSize(blockSize: originalBlockSize), + computed: computed) + { + if (!typeof(Block).IsAssignableFrom(c: blockType)) { - this.BlockSize = BlockSizeMap.BlockSize(dataBytes.Length); - this.BlockType = blockType; + throw new BrightChainException(message: "Block Type must be Block or descendant."); } - /// - /// Gets a value indicating the block type of the underlying block. - /// - [ProtoMember(20)] - public Type BlockType { get; } + this.BlockType = blockType; + this.BlockSize = originalBlockSize; + } - /// - /// Gets a BlockSize enum of the source block. - /// - [ProtoMember(21)] - public BlockSize BlockSize { get; } + /// + /// Initializes a new instance of the class. + /// + /// Block type of the underlying block. + /// Data to compute hash from. + public BlockHash(Type blockType, ReadOnlyMemory dataBytes) + : base(dataBytes: dataBytes) + { + this.BlockSize = BlockSizeMap.BlockSize(blockSize: dataBytes.Length); + this.BlockType = blockType; + } - public string Base58 => - SimpleBase.Base58.Bitcoin.Encode(this.HashBytes.ToArray()); + /// + /// Gets a value indicating the block type of the underlying block. + /// + [ProtoMember(tag: 20)] + public Type BlockType { get; } - public uint Crc32 => - Helpers.Crc32.ComputeNewChecksum(this.HashBytes.ToArray()); + /// + /// Gets a BlockSize enum of the source block. + /// + [ProtoMember(tag: 21)] + public BlockSize BlockSize { get; } - public ulong Crc64 => - DamienG.Security.Cryptography.Crc64Iso.Compute(this.HashBytes.ToArray()); + public string Base58 => + SimpleBase.Base58.Bitcoin.Encode(bytes: this.HashBytes.ToArray()); - public string Base58Crc64 => - SimpleBase.Base58.Bitcoin.Encode(BitConverter.GetBytes(this.Crc64)); + public uint Crc32 => + NeuralFabric.Helpers.Crc32.ComputeChecksum(bytes: this.HashBytes.ToArray()); - public static bool operator ==(BlockHash a, BlockHash b) - { - return a.SourceDataLength == b.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(a.HashBytes, b.HashBytes) == 0; - } + public ulong Crc64 => + NeuralFabric.Helpers.Crc64.ComputeChecksum(bytes: this.HashBytes.ToArray()); - public static bool operator ==(ReadOnlyMemory a, BlockHash b) - { - return a.Length == b.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(b.HashBytes, a) == 0; - } + public string Base58Crc64 => + SimpleBase.Base58.Bitcoin.Encode(bytes: BitConverter.GetBytes(value: this.Crc64)); - public static bool operator !=(ReadOnlyMemory b, BlockHash a) - { - return !(b == a); - } + /// + /// Compares the raw bytes of the hash. + /// + /// Other BlockHash to compare bytes with. + /// Returns a standard comparison result, -1, 0, 1 for less than, equal, greater than. + public int CompareTo(BlockHash other) + { + return other.SourceDataLength == this.SourceDataLength ? NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare( + ar1: this.HashBytes, + ar2: other.HashBytes) : + other.SourceDataLength > this.SourceDataLength ? -1 : 1; + } - public static bool operator !=(BlockHash a, BlockHash b) - { - return !a.Equals(b); - } + /// + /// Returns a boolean whether the two objects contain the same series of bytes. + /// + /// Other BlockHash to compare bytes with. + /// Returns the standard comparison result, -1, 0, 1 for less than, equal, greater than. + public bool Equals(BlockHash other) + { + return other.SourceDataLength == this.SourceDataLength && NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare( + ar1: this.HashBytes, + ar2: other.HashBytes) == 0; + } - /// - /// Compares the raw bytes of the hash with a BlockHash classed as a plain object. - /// - /// Should be of BlockHash type. - /// Returns a boolean indicating whether the bytes are the same in both objects. - public override bool Equals(object obj) - { - return obj is BlockHash blockHash ? blockHash.SourceDataLength == this.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, blockHash.HashBytes) == 0 : false; - } + public long GetHashCode64(ref BlockHash k) + { + return (long)NeuralFabric.Helpers.Crc64.ComputeChecksum(bytes: this.HashBytes.ToArray()); + } - /// - /// Compares the raw bytes of the hash. - /// - /// Other BlockHash to compare bytes with. - /// Returns a standard comparison result, -1, 0, 1 for less than, equal, greater than. - public int CompareTo(BlockHash other) - { - return other.SourceDataLength == this.SourceDataLength ? Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) : other.SourceDataLength > this.SourceDataLength ? -1 : 1; - } + public bool Equals(ref BlockHash k1, ref BlockHash k2) + { + return !(k2 is null) + ? k2.SourceDataLength == k1.SourceDataLength && NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: k1.HashBytes, + ar2: k2.HashBytes) == 0 + : false; + } - /// - /// Returns a boolean whether the two objects contain the same series of bytes. - /// - /// Other BlockHash to compare bytes with. - /// Returns the standard comparison result, -1, 0, 1 for less than, equal, greater than. - public bool Equals(BlockHash other) - { - return other.SourceDataLength == this.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) == 0; - } + public static bool operator ==(BlockHash a, BlockHash b) + { + return a.SourceDataLength == b.SourceDataLength && NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: a.HashBytes, + ar2: b.HashBytes) == 0; + } - public override int GetHashCode() - { - return (int)Helpers.Crc32.ComputeNewChecksum(this.HashBytes.ToArray()); - } + public static bool operator ==(ReadOnlyMemory a, BlockHash b) + { + return a.Length == b.SourceDataLength && NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare(ar1: b.HashBytes, + ar2: a) == 0; + } - public long GetHashCode64(ref BlockHash k) - { - return (long)Crc64Iso.Compute(this.HashBytes.ToArray()); - } + public static bool operator !=(ReadOnlyMemory b, BlockHash a) + { + return !(b == a); + } - public bool Equals(ref BlockHash k1, ref BlockHash k2) - { - return !(k2 is null) ? k2.SourceDataLength == k1.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(k1.HashBytes, k2.HashBytes) == 0 : false; - } + public static bool operator !=(BlockHash a, BlockHash b) + { + return !a.Equals(other: b); + } + + /// + /// Compares the raw bytes of the hash with a BlockHash classed as a plain object. + /// + /// Should be of BlockHash type. + /// Returns a boolean indicating whether the bytes are the same in both objects. + public override bool Equals(object obj) + { + return obj is BlockHash blockHash + ? blockHash.SourceDataLength == this.SourceDataLength && NeuralFabric.Helpers.ReadOnlyMemoryComparer.Compare( + ar1: this.HashBytes, + ar2: blockHash.HashBytes) == 0 + : false; + } + + public override int GetHashCode() + { + return (int)NeuralFabric.Helpers.Crc32.ComputeChecksum(bytes: this.HashBytes.ToArray()); } } diff --git a/src/BrightChain.Engine/Models/Hashes/DataHash.cs b/src/BrightChain.Engine/Models/Hashes/DataHash.cs deleted file mode 100644 index 683b85b4..00000000 --- a/src/BrightChain.Engine/Models/Hashes/DataHash.cs +++ /dev/null @@ -1,218 +0,0 @@ - -namespace BrightChain.Engine.Models.Hashes -{ - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Security.Cryptography; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Interfaces; - using DamienG.Security.Cryptography; - using FASTER.core; - using ProtoBuf; - - /// - /// Type box for the sha hashes. - /// - [ProtoContract] - [ProtoInclude(1, typeof(BlockHash))] - public class DataHash : IDataHash, IComparable, IEquatable, IFasterEqualityComparer - { - /// - /// Size in bits of the hash. - /// - public const int HashSize = 256; - - /// - /// Size in bytes of the hash. - /// - public const int HashSizeBytes = HashSize / 8; - - /// - /// Initializes a new instance of the class. - /// - /// Data to compute hash from. - public DataHash(ReadOnlyMemory dataBytes) - { - using (SHA256 mySHA256 = SHA256.Create()) - { - this.HashBytes = mySHA256.ComputeHash(dataBytes.ToArray()); - } - - this.Computed = true; - this.SourceDataLength = dataBytes.Length; - } - - /// - /// Initializes a new instance of the class. - /// - /// Data to compute hash from. - public DataHash(IEnumerable dataBytes) - { - using (SHA256 mySHA256 = SHA256.Create()) - { - this.HashBytes = mySHA256.ComputeHash((byte[])dataBytes); - } - - this.Computed = true; - this.SourceDataLength = dataBytes.Count(); - } - - public DataHash(Stream stream) - { - using (var sha = SHA256.Create()) - { - var streamStart = stream.Position; - sha.ComputeHash(stream); - var streamLength = stream.Position - streamStart; - this.HashBytes = sha.Hash; - this.SourceDataLength = streamLength; - this.Computed = true; - } - } - - public DataHash(FileInfo fileInfo) - { - using (Stream stream = File.OpenRead(fileInfo.FullName)) - { - using (var sha = SHA256.Create()) - { - var streamStart = stream.Position; - sha.ComputeHash(stream); - var streamLength = stream.Position - streamStart; - this.HashBytes = sha.Hash; - this.SourceDataLength = streamLength; - this.Computed = true; - } - - if (this.SourceDataLength != fileInfo.Length) - { - throw new BrightChainException(nameof(this.SourceDataLength)); - } - } - } - - /// - /// Initializes a new instance of the class. - /// - /// Hash bytes to accept as the hash. - /// A boolean value indicating whether the source bytes were computed internally or externally (false). - /// A long indicating the length of the source data. - public DataHash(ReadOnlyMemory providedHashBytes, long sourceDataLength, bool computed) - { - this.HashBytes = providedHashBytes; - this.Computed = computed; - this.SourceDataLength = sourceDataLength; - } - - /// - /// Gets a ReadOnlyMemory containing the raw hash result bytes. - /// - [ProtoMember(1)] - public ReadOnlyMemory HashBytes { get; } - - /// - /// Gets a long containing the length of the source data the hash was computed on. - /// - [ProtoMember(2)] - public long SourceDataLength { get; } - - /// - /// Gets a value indicating whether trusted code calculated this hash. - /// - [ProtoMember(3)] - public bool Computed { get; } - - public static bool operator ==(DataHash a, DataHash b) - { - return a.SourceDataLength == b.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(a.HashBytes, b.HashBytes) == 0; - } - - public static bool operator ==(ReadOnlyMemory b, DataHash a) - { - return a.SourceDataLength == b.Length && Helpers.ReadOnlyMemoryComparer.Compare(a.HashBytes, b) == 0; - } - - public static bool operator !=(ReadOnlyMemory b, DataHash a) - { - return !(b == a); - } - - public static bool operator !=(DataHash a, DataHash b) - { - return !(b == a); - } - - /// - /// Returns a formatted hash string as a series of lowercase hexadecimal characters. - /// - /// Ignored. - /// Ignored also. - /// Returns a formatted hash string. - public string ToString(string _, IFormatProvider __) - { - return Helpers.Utilities.HashToFormattedString(this.HashBytes.ToArray()); - } - - /// - /// Returns a formatted hash string as a series of lowercase hexadecimal characters. - /// - /// Returns a formatted hash string. - public new string ToString() - { - return Helpers.Utilities.HashToFormattedString(this.HashBytes.ToArray()); - } - - /// - /// Compares the raw bytes of the hash with a DataHash classed as a plain object. - /// - /// Should be of DataHash type. - /// Returns a boolean indicating whether the bytes are the same in both objects. - public override bool Equals(object obj) - { - return obj is IDataHash iDataHash ? iDataHash.SourceDataLength == this.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, iDataHash.HashBytes) == 0 : false; - } - - /// - /// Computes and returns the hash code for the HashBytes in this object. - /// - /// Returns the hash code for the HashBytes in this object. - public override int GetHashCode() - { - return (int)Crc32.ComputeNewChecksum(this.HashBytes.ToArray()); - } - - /// - /// Compares the raw bytes of the hash. - /// - /// Other DataHash to compare bytes with. - /// Returns a standard comparison result, -1, 0, 1 for less than, equal, greater than. - /// TODO: verify -1/1 correctness - public int CompareTo(DataHash other) - { - return other.SourceDataLength == this.SourceDataLength ? Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) : (other.SourceDataLength > this.SourceDataLength ? -1 : 1); - } - - /// - /// Returns a boolean whether the two objects contain the same series of bytes. - /// - /// Other DataHash to compare bytes with. - /// Returns the standard comparison result, -1, 0, 1 for less than, equal, greater than. - public bool Equals(DataHash other) - { - return !(other is null) ? other.SourceDataLength == this.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) == 0 : false; - } - - public long GetHashCode64(ref DataHash k) - { - return (long)Crc64Iso.Compute(k.HashBytes.ToArray()); - } - - public bool Equals(ref DataHash k1, ref DataHash k2) - { - return !(k2 is null) ? k2.SourceDataLength == k1.SourceDataLength && Helpers.ReadOnlyMemoryComparer.Compare(k1.HashBytes, k2.HashBytes) == 0 : false; - } - } -} diff --git a/src/BrightChain.Engine/Models/Hashes/DataSignature.cs b/src/BrightChain.Engine/Models/Hashes/DataSignature.cs deleted file mode 100644 index bf8c159f..00000000 --- a/src/BrightChain.Engine/Models/Hashes/DataSignature.cs +++ /dev/null @@ -1,113 +0,0 @@ -namespace BrightChain.Engine.Models.Hashes -{ - using System; - using System.Security.Cryptography; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Contracts; - using ProtoBuf; - - /// - /// Type box for the sha hashes of signatures. - /// - [ProtoContract] - [ProtoInclude(1, typeof(BlockSignature))] - [ProtoInclude(2, typeof(RevocationCertificate))] - public class DataSignature : IDataSignature, IComparable - { - /// - /// Size in bits of the hash. - /// - public const int SignatureHashSize = 256; - - /// - /// Size in bytes of the hash. - /// - public const int SignatureHashSizeBytes = SignatureHashSize / 8; - - [ProtoMember(1)] - public ReadOnlyMemory SignatureHashBytes { get; protected set; } - - [ProtoMember(2)] - public bool Computed { get; } - - public DataSignature(IBlock block) - { - using (SHA256 mySHA256 = SHA256.Create()) - { - throw new NotImplementedException(); - } - - this.Computed = true; - } - - public DataSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes) - { - this.SignatureHashBytes = providedHashBytes; - this.Computed = false; - } - - internal DataSignature(BlockSize originalBlockSize, ReadOnlyMemory providedHashBytes, bool computed = false) - { - this.SignatureHashBytes = providedHashBytes; - this.Computed = computed; - } - - public DataSignature(ReadOnlyMemory dataBytes) - { - using (SHA256 mySHA256 = SHA256.Create()) - { - throw new NotImplementedException(); - } - - this.Computed = true; - } - - public static bool operator ==(DataSignature a, DataSignature b) - { - return ReadOnlyMemoryComparer.Compare(a.SignatureHashBytes, b.SignatureHashBytes) == 0; - } - - public static bool operator ==(ReadOnlyMemory b, DataSignature a) - { - return ReadOnlyMemoryComparer.Compare(a.SignatureHashBytes, b) == 0; - } - - public static bool operator !=(ReadOnlyMemory b, DataSignature a) - { - return !(b == a); - } - - public static bool operator !=(DataSignature a, DataSignature b) - { - return !a.Equals(b); - } - - public string ToString(string format, IFormatProvider _) - { - return BitConverter.ToString(this.SignatureHashBytes.ToArray()).Replace("-", string.Empty).ToLower(culture: System.Globalization.CultureInfo.InvariantCulture); - } - - public new string ToString() - { - return BitConverter.ToString(this.SignatureHashBytes.ToArray()).Replace("-", string.Empty).ToLower(culture: System.Globalization.CultureInfo.InvariantCulture); - } - - public override bool Equals(object obj) - { - return obj is DataSignature ? ReadOnlyMemoryComparer.Compare(this.SignatureHashBytes, (obj as DataSignature).SignatureHashBytes) == 0 : false; - } - - public override int GetHashCode() - { - return this.SignatureHashBytes.GetHashCode(); - } - - public int CompareTo(DataSignature other) - { - return ReadOnlyMemoryComparer.Compare(this.SignatureHashBytes, other.SignatureHashBytes); - } - } -} diff --git a/src/BrightChain.Engine/Models/Hashes/GuidId.cs b/src/BrightChain.Engine/Models/Hashes/GuidId.cs deleted file mode 100644 index 7f5020e5..00000000 --- a/src/BrightChain.Engine/Models/Hashes/GuidId.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace BrightChain.Engine.Models.Hashes -{ - /// - /// Notably a Guid is not a hash, but this is a convenient container.. maybe a refactor. - /// - public class GuidId : DataHash - { - /// - /// Size in bits of the hash. - /// - public const int HashSize = 128; - - /// - /// Size in bytes of the hash. - /// - public const int HashSizeBytes = HashSize / 8; - - public readonly Guid Guid; - - public GuidId(Guid guid, long sourceDataLength) - : base(providedHashBytes: guid.ToByteArray(), sourceDataLength: sourceDataLength, computed: false) - { - this.Guid = guid; - } - } -} diff --git a/src/BrightChain.Engine/Models/Hashes/SegmentHash.cs b/src/BrightChain.Engine/Models/Hashes/SegmentHash.cs index 8f3f6829..87d35767 100644 --- a/src/BrightChain.Engine/Models/Hashes/SegmentHash.cs +++ b/src/BrightChain.Engine/Models/Hashes/SegmentHash.cs @@ -1,59 +1,66 @@ -namespace BrightChain.Engine.Models.Hashes +using System; +using NeuralFabric.Helpers; +using NeuralFabric.Interfaces; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Models.Hashes; + +/// +/// Type box for the sha hashes. +/// +public class SegmentHash : DataHash, IDataHash, IComparable, IEquatable { - using System; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Interfaces; + /// + /// Size in bits of the hash. + /// + public new const int HashSize = 256; /// - /// Type box for the sha hashes. + /// Initializes a new instance of the class. /// - public class SegmentHash : DataHash, IDataHash, IComparable, IEquatable + /// Hash bytes to accept as the hash. + /// Long indicating the length of the source the hash was computed from. + /// A boolean value indicating whether the source bytes were computed internally or externally (false). + public SegmentHash(ReadOnlyMemory providedHashBytes, long sourceDataLength, bool computed) + : base(providedHashBytes: providedHashBytes, + sourceDataLength: sourceDataLength, + computed: computed) { - /// - /// Size in bits of the hash. - /// - public new const int HashSize = 256; - - /// - /// Initializes a new instance of the class. - /// - /// Hash bytes to accept as the hash. - /// Long indicating the length of the source the hash was computed from. - /// A boolean value indicating whether the source bytes were computed internally or externally (false). - public SegmentHash(ReadOnlyMemory providedHashBytes, long sourceDataLength, bool computed) - : base(providedHashBytes: providedHashBytes, sourceDataLength: sourceDataLength, computed: computed) - { - } + } - /// - /// Initializes a new instance of the class. - /// - /// Block type of the underlying block. - /// Data to compute hash from. - public SegmentHash(ReadOnlyMemory dataBytes) - : base(dataBytes) - { - } + /// + /// Initializes a new instance of the class. + /// + /// Block type of the underlying block. + /// Data to compute hash from. + public SegmentHash(ReadOnlyMemory dataBytes) + : base(dataBytes: dataBytes) + { + } - /// - /// Compares the raw bytes of the hash. - /// - /// Other BlockHash to compare bytes with. - /// Returns a standard comparison result, -1, 0, 1 for less than, equal, greater than. - /// TODO: verify -1/1 correctness - public int CompareTo(SegmentHash other) - { - return other.SourceDataLength == this.SourceDataLength ? ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) : (this.SourceDataLength > other.SourceDataLength ? -1 : 1); - } + /// + /// Compares the raw bytes of the hash. + /// + /// Other BlockHash to compare bytes with. + /// Returns a standard comparison result, -1, 0, 1 for less than, equal, greater than. + /// TODO: verify -1/1 correctness + public int CompareTo(SegmentHash other) + { + return other.SourceDataLength == this.SourceDataLength ? ReadOnlyMemoryComparer.Compare(ar1: this.HashBytes, + ar2: other.HashBytes) : + this.SourceDataLength > other.SourceDataLength ? -1 : 1; + } - /// - /// Returns a boolean whether the two objects contain the same series of bytes. - /// - /// Other BlockHash to compare bytes with. - /// Returns the standard comparison result, -1, 0, 1 for less than, equal, greater than. - public bool Equals(SegmentHash other) - { - return !(other is null) ? other.SourceDataLength == this.SourceDataLength && ReadOnlyMemoryComparer.Compare(this.HashBytes, other.HashBytes) == 0 : false; - } + /// + /// Returns a boolean whether the two objects contain the same series of bytes. + /// + /// Other BlockHash to compare bytes with. + /// Returns the standard comparison result, -1, 0, 1 for less than, equal, greater than. + public bool Equals(SegmentHash other) + { + return !(other is null) + ? other.SourceDataLength == this.SourceDataLength && ReadOnlyMemoryComparer.Compare(ar1: this.HashBytes, + ar2: other.HashBytes) == 0 + : false; } } diff --git a/src/BrightChain.Engine/Models/Keys/BrightChainKey.cs b/src/BrightChain.Engine/Models/Keys/BrightChainKey.cs old mode 100644 new mode 100755 index 217581c1..4662c597 --- a/src/BrightChain.Engine/Models/Keys/BrightChainKey.cs +++ b/src/BrightChain.Engine/Models/Keys/BrightChainKey.cs @@ -1,17 +1,17 @@ -namespace BrightChain.Engine.Models.Keys -{ - using System.Security.Cryptography; +using System; +using System.Security.Cryptography; + +namespace BrightChain.Engine.Models.Keys; - public class BrightChainKey : ECDsa +public class BrightChainKey : ECDsa +{ + public override byte[] SignHash(byte[] hash) { - public override byte[] SignHash(byte[] hash) - { - throw new System.NotImplementedException(); - } + throw new NotImplementedException(); + } - public override bool VerifyHash(byte[] hash, byte[] signature) - { - throw new System.NotImplementedException(); - } + public override bool VerifyHash(byte[] hash, byte[] signature) + { + throw new NotImplementedException(); } } diff --git a/src/BrightChain.Engine/Models/Nodes/BrightChainNode.cs b/src/BrightChain.Engine/Models/Nodes/BrightChainNode.cs old mode 100644 new mode 100755 index e2ba774f..1303be92 --- a/src/BrightChain.Engine/Models/Nodes/BrightChainNode.cs +++ b/src/BrightChain.Engine/Models/Nodes/BrightChainNode.cs @@ -1,41 +1,40 @@ -namespace BrightChain.Engine.Models.Nodes -{ - using System.Security.Cryptography; - using BrightChain.Engine.Models.Agents; - using BrightChain.Engine.Models.Hashes; - using Microsoft.Extensions.Configuration; +using System.Security.Cryptography; +using BrightChain.Engine.Models.Agents; +using BrightChain.Engine.Models.Hashes; +using Microsoft.Extensions.Configuration; + +namespace BrightChain.Engine.Models.Nodes; +/// +/// Representation of a bright chain participartory node. +/// +public class BrightChainNode +{ /// - /// Representation of a bright chain participartory node. + /// Initializes a new instance of the class. /// - public class BrightChainNode + public BrightChainNode(IConfiguration configuration) { - /// - /// Initializes a new instance of the class. - /// - public BrightChainNode(IConfiguration configuration) - { - } + } - /// - /// Gets the Id of the Node. - /// The Id of a Node is tied to its key once the block is accepted. - /// Duplicate Ids should not be accepted. - /// This will be used in TrustedNode lists. - /// - public BlockHash Id { get; } + /// + /// Gets the Id of the Node. + /// The Id of a Node is tied to its key once the block is accepted. + /// Duplicate Ids should not be accepted. + /// This will be used in TrustedNode lists. + /// + public BlockHash Id { get; } - /// - /// Gets the node agent's public key. Shortcut. - /// - public ECDiffieHellmanCngPublicKey PublicKey => - this.NodeAgent.PublicKey; + /// + /// Gets the node agent's public key. Shortcut. + /// + public ECDiffieHellmanCngPublicKey PublicKey => + this.NodeAgent.PublicKey; - /// - /// Entity with keys to perform actions on behalf of the node. - /// - public BrightChainAgent NodeAgent { get; } + /// + /// Entity with keys to perform actions on behalf of the node. + /// + public BrightChainAgent NodeAgent { get; } - public BrightChainNodeInfo NodeInfo { get; } - } + public BrightChainNodeInfo NodeInfo { get; } } diff --git a/src/BrightChain.Engine/Models/Nodes/BrightChainNodeInfo.cs b/src/BrightChain.Engine/Models/Nodes/BrightChainNodeInfo.cs old mode 100644 new mode 100755 index 70854529..68bab5ba --- a/src/BrightChain.Engine/Models/Nodes/BrightChainNodeInfo.cs +++ b/src/BrightChain.Engine/Models/Nodes/BrightChainNodeInfo.cs @@ -4,71 +4,12 @@ using BrightChain.Engine.Enumerations; /// - /// Data Object Model containing node statistics and features. + /// Data Object Model containing node statistics and features. /// - public struct BrightChainNodeInfo + public record BrightChainNodeInfo(List OfferedFeatures, List ConsumedFeatures, + List SupportedReadBlockSizes, List SupportedWriteBlockSizes, List QuorumAdjustments, ulong LastUptime, + ulong UnannouncedDisconnections, ulong FlapSeconds, ulong SuccessfulValidations, ulong MissedValidations, ulong RejectedValidations, + ulong IncorrectValidations) { - /// - /// List of features this node offers to the BrightChain network. - /// - public readonly List OfferedFeatures; - - /// - /// List of features this node consumes from the BrightChain network. - /// Anything not declared at construction cannot be consumed. It will be be broadcasted out about your node. - /// - public readonly List ConsumedFeatures; - - /// - /// List of block sizes this node supports for reading. The list may include no longer supported write sizes. - /// - public readonly List SupportedReadBlockSizes; - - /// - /// List of block sizes this node supports for writing. - /// - public readonly List SupportedWriteBlockSizes; - - /// - /// Reserved concept property to indicate either positive or negative adjustments to the public info/statistics about this node. - /// All entries must be signed and match quorum in order to participate. - /// - public readonly List QuorumAdjustments; - - /// - /// Last time the node came online. - /// - public readonly ulong LastUptime; - - /// - /// Numbers of unannounced disconnections without indicating stored block fate. - /// - public readonly ulong UnannouncedDisconnections; - - /// - /// Number of seconds total downtime during unnannounced disconnection events. - /// Avg flap duration = flapSeconds / unannouncedDisconnections. - /// - public readonly ulong FlapSeconds = 0; - - /// - /// Number of corroborated validations performed for the network. - /// - public readonly ulong SuccessfulValidations; - - /// - /// Number of validation requests from the network that were not accepted/performed/compelted. - /// - public readonly ulong MissedValidations; - - /// - /// Number of validation requests from the network that were rejected and not performed. - /// - public readonly ulong RejectedValidations; - - /// - /// Number of validation requests from the network that were accepted and yielded a contested result. In the event of a disagreement between the initial two, a third node will vote majority. - /// - public readonly ulong IncorrectValidations; } } diff --git a/src/BrightChain.Engine/Models/Units/ByteStorageDuration.cs b/src/BrightChain.Engine/Models/Units/ByteStorageDuration.cs old mode 100644 new mode 100755 index 120e526a..571d2751 --- a/src/BrightChain.Engine/Models/Units/ByteStorageDuration.cs +++ b/src/BrightChain.Engine/Models/Units/ByteStorageDuration.cs @@ -1,19 +1,18 @@ -namespace BrightChain.Engine.Models.Units +namespace BrightChain.Engine.Models.Units; + +/// +/// Struct to house the fields for the StorageDurationContract +/// +public struct ByteStorageDuration { - /// - /// Struct to house the fields for the StorageDurationContract - /// - public struct ByteStorageDuration - { - readonly int ByteCount; - readonly ulong DurationSeconds; - readonly double TotalCost; + private readonly int ByteCount; + private readonly ulong DurationSeconds; + private readonly double TotalCost; - public ByteStorageDuration(int byteCount, ulong durationSeconds) - { - this.ByteCount = byteCount; - this.DurationSeconds = durationSeconds; - this.TotalCost = ((ulong)byteCount) * durationSeconds; - } + public ByteStorageDuration(int byteCount, ulong durationSeconds) + { + this.ByteCount = byteCount; + this.DurationSeconds = durationSeconds; + this.TotalCost = (ulong)byteCount * durationSeconds; } } diff --git a/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDuration.cs b/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDuration.cs old mode 100644 new mode 100755 index ac28cb30..08580b19 --- a/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDuration.cs +++ b/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDuration.cs @@ -1,20 +1,20 @@ using BrightChain.Engine.Enumerations; -namespace BrightChain.Engine.Models.Units + +namespace BrightChain.Engine.Models.Units; + +/// +/// Struct to house the fields for the RedundancyContract. Per block. +/// +public struct ByteStorageRedundancyDuration { - /// - /// Struct to house the fields for the RedundancyContract. Per block. - /// - public struct ByteStorageRedundancyDuration - { - readonly int ByteCount; - readonly ulong DurationSeconds; - readonly RedundancyContractType Redundancy; + private readonly int ByteCount; + private readonly ulong DurationSeconds; + private readonly RedundancyContractType Redundancy; - public ByteStorageRedundancyDuration(int byteCount, ulong durationSeconds, RedundancyContractType redundancy) - { - this.ByteCount = byteCount; - this.DurationSeconds = durationSeconds; - this.Redundancy = redundancy; - } + public ByteStorageRedundancyDuration(int byteCount, ulong durationSeconds, RedundancyContractType redundancy) + { + this.ByteCount = byteCount; + this.DurationSeconds = durationSeconds; + this.Redundancy = redundancy; } } diff --git a/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDurationCostMap.cs b/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDurationCostMap.cs old mode 100644 new mode 100755 index 5a406704..dc3bdc66 --- a/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDurationCostMap.cs +++ b/src/BrightChain.Engine/Models/Units/ByteStorageRedundancyDurationCostMap.cs @@ -1,48 +1,49 @@ using System.Collections.Generic; using BrightChain.Engine.Enumerations; -namespace BrightChain.Engine.Models.Units +namespace BrightChain.Engine.Models.Units; + +/// +/// Map of the block sizes to their (to be determined) costs, which may end up even being calculation functions. +/// +public static class ByteStorageRedundancyDurationCostMap { - /// - /// Map of the block sizes to their (to be determined) costs, which may end up even being calculation functions. - /// - public static class ByteStorageRedundancyDurationCostMap + public static readonly Dictionary SizeMap = new() { - public static readonly Dictionary SizeMap = new Dictionary { - { global::BrightChain.Engine.Enumerations.BlockSize.Micro, 0 }, // 256B - { global::BrightChain.Engine.Enumerations.BlockSize.Message, 0 }, // 512B - { global::BrightChain.Engine.Enumerations.BlockSize.Tiny, 0 }, // 1K - { global::BrightChain.Engine.Enumerations.BlockSize.Small, 0 }, // 4K - { global::BrightChain.Engine.Enumerations.BlockSize.Medium, 0 }, // 1M - { global::BrightChain.Engine.Enumerations.BlockSize.Large, 0 }, // 4M - }; + {BlockSize.Micro, 0}, // 256B + {BlockSize.Message, 0}, // 512B + {BlockSize.Tiny, 0}, // 1K + {BlockSize.Small, 0}, // 4K + {BlockSize.Medium, 0}, // 1M + {BlockSize.Large, 0}, // 4M + }; - public static readonly Dictionary RedundancyMap = new Dictionary { - {RedundancyContractType.LocalNone, 0 }, - {RedundancyContractType.LocalMirror, 0 }, - {RedundancyContractType.HeapAuto, 0 }, - {RedundancyContractType.HeapLowPriority, 0 }, - {RedundancyContractType.HeapHighPriority, 0 }, - }; + public static readonly Dictionary RedundancyMap = new() + { + {RedundancyContractType.LocalNone, 0}, + {RedundancyContractType.LocalMirror, 0}, + {RedundancyContractType.HeapAuto, 0}, + {RedundancyContractType.HeapLowPriority, 0}, + {RedundancyContractType.HeapHighPriority, 0}, + }; - /// - /// Map a block size back to its cost - /// - /// - /// - public static double Cost(BlockSize blockSize, RedundancyContractType redundancy) + /// + /// Map a block size back to its cost + /// + /// + /// + public static double Cost(BlockSize blockSize, RedundancyContractType redundancy) + { + if (!SizeMap.ContainsKey(key: blockSize)) { - if (!ByteStorageRedundancyDurationCostMap.SizeMap.ContainsKey(blockSize)) - { - throw new KeyNotFoundException(message: nameof(blockSize)); - } - - if (!ByteStorageRedundancyDurationCostMap.RedundancyMap.ContainsKey(redundancy)) - { - throw new KeyNotFoundException(message: nameof(redundancy)); - } + throw new KeyNotFoundException(message: nameof(blockSize)); + } - return ByteStorageRedundancyDurationCostMap.SizeMap[blockSize] * ByteStorageRedundancyDurationCostMap.RedundancyMap[redundancy]; + if (!RedundancyMap.ContainsKey(key: redundancy)) + { + throw new KeyNotFoundException(message: nameof(redundancy)); } + + return SizeMap[key: blockSize] * RedundancyMap[key: redundancy]; } } diff --git a/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Galois.cs b/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Galois.cs new file mode 100644 index 00000000..a9f19de1 --- /dev/null +++ b/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Galois.cs @@ -0,0 +1,305 @@ +using System; +using System.Collections.Generic; +using Spectre.Cli.Exceptions; + +namespace BrightChain.Engine.Quorum.BackblazeReedSolomon; + +/// +/// 8-bit Galois Field +/// +/// This class implements multiplication, division, addition, +/// subtraction, and exponentiation. +/// +/// The multiplication operation is in the inner loop of +/// erasure coding, so it's been optimized. Having the +/// class be "final" helps a little, and having the EXP_TABLE +/// repeat the data, so there's no need to bound the sum +/// of two logarithms to 255 helps a lot. +/// +public sealed class Galois +{ + /// + /// The number of elements in the field. + /// + public const byte FIELD_SIZE = 0xFF; + + /// + /// The polynomial used to generate the logarithm table. + /// + /// There are a number of polynomials that work to generate + /// a Galois field of 256 elements. The choice is arbitrary, + /// and we just use the first one. + /// + /// The possibilities are: 29, 43, 45, 77, 95, 99, 101, 105, + /// 113, 135, 141, 169, 195, 207, 231, and 245. + /// + public const byte GENERATING_POLYNOMIAL = 29; + + /// + /// Mapping from members of the Galois Field to their + /// integer logarithms. The entry for 0 is meaningless + /// because there is no log of 0. + /// + /// This array is shorts, not bytes, so that they can + /// be used directly to index arrays without casting. + /// The values (except the non-value at index 0) are + /// all really bytes, so they range from 0 to 255. + /// + /// This table was generated by java_tables.py, and the + /// unit tests check it against the Java implementation. + /// + public static readonly short[] LOG_TABLE = + { + -1, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, + 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, + 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, + 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, + 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, + 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, + 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, + 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, + 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, + 234, 168, 80, 88, 175, + }; + + /// + /// Inverse of the logarithm table. Maps integer logarithms + /// to members of the field. There is no entry for 255 + /// because the highest log is 254. + /// + /// This table was generated by java_tables.py. + /// + public static readonly short[] EXP_TABLE = + { + 1, 2, 4, 8, 16, 32, 64, -128, 29, 58, 116, -24, -51, -121, 19, 38, 76, -104, 45, 90, -76, 117, -22, -55, -113, 3, 6, 12, 24, 48, 96, + -64, -99, 39, 78, -100, 37, 74, -108, 53, 106, -44, -75, 119, -18, -63, -97, 35, 70, -116, 5, 10, 20, 40, 80, -96, 93, -70, 105, + -46, -71, 111, -34, -95, 95, -66, 97, -62, -103, 47, 94, -68, 101, -54, -119, 15, 30, 60, 120, -16, -3, -25, -45, -69, 107, -42, + -79, 127, -2, -31, -33, -93, 91, -74, 113, -30, -39, -81, 67, -122, 17, 34, 68, -120, 13, 26, 52, 104, -48, -67, 103, -50, -127, 31, + 62, 124, -8, -19, -57, -109, 59, 118, -20, -59, -105, 51, 102, -52, -123, 23, 46, 92, -72, 109, -38, -87, 79, -98, 33, 66, -124, 21, + 42, 84, -88, 77, -102, 41, 82, -92, 85, -86, 73, -110, 57, 114, -28, -43, -73, 115, -26, -47, -65, 99, -58, -111, 63, 126, -4, -27, + -41, -77, 123, -10, -15, -1, -29, -37, -85, 75, -106, 49, 98, -60, -107, 55, 110, -36, -91, 87, -82, 65, -126, 25, 50, 100, -56, + -115, 7, 14, 28, 56, 112, -32, -35, -89, 83, -90, 81, -94, 89, -78, 121, -14, -7, -17, -61, -101, 43, 86, -84, 69, -118, 9, 18, 36, + 72, -112, 61, 122, -12, -11, -9, -13, -5, -21, -53, -117, 11, 22, 44, 88, -80, 125, -6, -23, -49, -125, 27, 54, 108, -40, -83, 71, + -114, + /* Repeat the table a second time, so multiply() + * does not have to check bounds. */ + 1, 2, 4, 8, 16, 32, 64, -128, 29, 58, 116, -24, -51, -121, 19, 38, 76, -104, 45, 90, -76, 117, -22, -55, -113, 3, 6, 12, 24, 48, 96, + -64, -99, 39, 78, -100, 37, 74, -108, 53, 106, -44, -75, 119, -18, -63, -97, 35, 70, -116, 5, 10, 20, 40, 80, -96, 93, -70, 105, + -46, -71, 111, -34, -95, 95, -66, 97, -62, -103, 47, 94, -68, 101, -54, -119, 15, 30, 60, 120, -16, -3, -25, -45, -69, 107, -42, + -79, 127, -2, -31, -33, -93, 91, -74, 113, -30, -39, -81, 67, -122, 17, 34, 68, -120, 13, 26, 52, 104, -48, -67, 103, -50, -127, 31, + 62, 124, -8, -19, -57, -109, 59, 118, -20, -59, -105, 51, 102, -52, -123, 23, 46, 92, -72, 109, -38, -87, 79, -98, 33, 66, -124, 21, + 42, 84, -88, 77, -102, 41, 82, -92, 85, -86, 73, -110, 57, 114, -28, -43, -73, 115, -26, -47, -65, 99, -58, -111, 63, 126, -4, -27, + -41, -77, 123, -10, -15, -1, -29, -37, -85, 75, -106, 49, 98, -60, -107, 55, 110, -36, -91, 87, -82, 65, -126, 25, 50, 100, -56, + -115, 7, 14, 28, 56, 112, -32, -35, -89, 83, -90, 81, -94, 89, -78, 121, -14, -7, -17, -61, -101, 43, 86, -84, 69, -118, 9, 18, 36, + 72, -112, 61, 122, -12, -11, -9, -13, -5, -21, -53, -117, 11, 22, 44, 88, -80, 125, -6, -23, -49, -125, 27, 54, 108, -40, -83, 71, + -114, + }; + + /// + /// A multiplication table for the Galois field. + /// + /// Using this table is an alternative to using the multiply() method, + /// which uses log/exp table lookups. + /// + public static short[,] MULTIPLICATION_TABLE = generateMultiplicationTable(); + + /// + /// Adds two elements of the field. If you're in an inner loop, + /// you should inline this function: it's just XOR. + /// + public static byte add(byte a, byte b) + { + return (byte)(a ^ b); + } + + /// + /// Inverse of addition. If you're in an inner loop, + /// you should inline this function: it's just XOR. + /// + /// + /// + /// + public static byte subtract(byte a, byte b) + { + return (byte)(a ^ b); + } + + /// + /// Multiplies two elements of the field. + /// + /// + /// + /// + public static short multiply(byte a, byte b) + { + if (a == 0 || b == 0) + { + return 0; + } + + int logA = LOG_TABLE[a & 0xFF]; + int logB = LOG_TABLE[b & 0xFF]; + var logResult = logA + logB; + return EXP_TABLE[logResult]; + } + + /// + /// Inverse of multiplication. + /// + /// + /// + /// + /// + public static short divide(sbyte a, sbyte b) + { + if (a == 0) + { + return 0; + } + + if (b == 0) + { + throw new ArgumentOutOfRangeException(paramName: "Argument 'divisor' is 0"); + } + + int logA = LOG_TABLE[a & 0xFF]; + int logB = LOG_TABLE[b & 0xFF]; + var logResult = logA - logB; + if (logResult < 0) + { + logResult += 255; + } + + return EXP_TABLE[logResult]; + } + + /// + /// Computes a**n. + /// + /// The result will be the same as multiplying a times itself n times. + /// + /// A member of the field. + /// A plain-old integer. + /// The result of multiplying a by itself n times. + public static short exp(byte a, int n) + { + if (n == 0) + { + return 1; + } + + if (a == 0) + { + return 0; + } + + int logA = LOG_TABLE[a & 0xFF]; + var logResult = logA * n; + while (logResult >= 255) + { + logResult -= 255; + } + + return EXP_TABLE[logResult]; + } + + /// + /// Generates a logarithm table given a starting polynomial. + /// + /// + /// + /// + public static short[] generateLogTable(int polynomial) + { + var result = new short[FIELD_SIZE]; + for (var i = 0; i < FIELD_SIZE; i++) + { + result[i] = -1; // -1 means "not set" + } + + var b = 1; + for (var log = 0; log < FIELD_SIZE - 1; log++) + { + if (result[b] != -1) + { + throw new Exception(message: "BUG: duplicate logarithm (bad polynomial?)"); + } + + result[b] = (short)log; + b = b << 1; + if (b >= FIELD_SIZE) + { + b = (b - FIELD_SIZE) ^ polynomial; + } + } + + return result; + } + + /// + /// Generates the inverse log table. + /// + /// + /// + public static short[] generateExpTable(short[] logTable) + { + var result = new short[(FIELD_SIZE * 2) - 2]; + for (byte i = 1; i < FIELD_SIZE; i++) + { + int log = logTable[i]; + result[log] = i; + result[log + FIELD_SIZE - 1] = i; + } + + return result; + } + + /// + /// Generates a multiplication table as an array of byte arrays. + /// + /// To get the result of multiplying a and b: + /// + /// MULTIPLICATION_TABLE[a][b] + /// + public static short[,] generateMultiplicationTable() + { + var result = new short[256, 256]; + for (byte a = 0; a < FIELD_SIZE; a++) + { + for (byte b = 0; b < FIELD_SIZE; b++) + { + result[a, b] = multiply( + a: a, + b: b); + } + } + + return result; + } + + /// + /// Returns a list of all polynomials that can be used to generate + /// the field. + /// + /// This is never used in the code; it's just here for completeness. + /// + /// + public static int[] allPossiblePolynomials() + { + var result = new List(); + for (byte i = 0; i < FIELD_SIZE; i++) + { + try + { + generateLogTable(polynomial: i); + result.Add(item: i); + } + catch (RuntimeException e) + { + // this one didn't work + } + } + + return result.ToArray(); + } +} diff --git a/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Matrix.cs b/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Matrix.cs new file mode 100644 index 00000000..5bb7b417 --- /dev/null +++ b/src/BrightChain.Engine/Quorum/BackblazeReedSolomon/Matrix.cs @@ -0,0 +1,482 @@ +using System; +using System.Text; + +namespace BrightChain.Engine.Quorum.BackblazeReedSolomon; + +/// +/// A matrix over the 8-bit Galois field. +/// This class is not performance-critical, so the implementations +/// are simple and straightforward. +/// +public class Matrix +{ + /// + /// The number of columns in the matrix. + /// + private readonly int columns; + + /// + /// The data in the matrix, in row major form. + /// To get element (r, c): data[r][c] + /// Because this this is computer science, and not math, + /// the indices for both the row and column start at 0. + /// + private readonly int[][] data; + + /// + /// The number of rows in the matrix. + /// + private readonly int rows; + + + /// + /// Initializes a new instance of the class full of zeroes. + /// + /// The number of rows in the matrix. + /// The number of columns in the matrix. + public Matrix(int initRows, int initColumns) + { + this.rows = initRows; + this.columns = initColumns; + this.data = new int [this.rows][]; + for (var r = 0; r < this.rows; r++) + { + this.data[r] = new int[this.columns]; + } + } + + /// + /// Initializes a new instance of the class with the given row-major data + /// + /// + /// + public Matrix(byte[][] initData) + { + this.rows = initData.Length; + this.columns = initData[0].Length; + this.data = new int[this.rows][]; + for (var r = 0; r < this.rows; r++) + { + if (initData[r].Length != this.columns) + { + throw new ArgumentException(message: "Not all rows have the same number of columns"); + } + + this.data[r] = new int[this.columns]; + for (var c = 0; c < this.columns; c++) + { + this.data[r][c] = initData[r][c]; + } + } + } + + /// + /// Returns an identity matrix of the given size. + /// + /// + /// + public static Matrix identity(int size) + { + var result = new Matrix( + initRows: size, + initColumns: size); + for (var i = 0; i < size; i++) + { + result.set( + r: i, + c: i, + value: 1); + } + + return result; + } + + /// + /// Returns a human-readable string of the matrix contents. + /// Example: [[1, 2], [3, 4]] + /// + /// string. + public override string ToString() + { + var result = new StringBuilder(); + result.Append(value: '['); + for (var r = 0; r < this.rows; r++) + { + if (r != 0) + { + result.Append(value: ", "); + } + + result.Append(value: '['); + for (var c = 0; c < this.columns; c++) + { + if (c != 0) + { + result.Append(value: ", "); + } + + result.Append(value: this.data[r][c] & 0xFF); + } + + result.Append(value: ']'); + } + + result.Append(value: ']'); + return result.ToString(); + } + + + /// + /// Returns a human-readable string of the matrix contents. + /// Example: + /// 00 01 02 + /// 03 04 05 + /// 06 07 08 + /// 09 0a 0b + /// + /// + public string toBigString() + { + var result = new StringBuilder(); + for (var r = 0; r < this.rows; r++) + { + for (var c = 0; c < this.columns; c++) + { + var value = this.get( + r: r, + c: c); + if (value < 0) + { + value += 256; + } + + result.Append(value: string.Format( + format: "%02x ", + arg0: value)); + } + + result.Append(value: "\n"); + } + + return result.ToString(); + } + + /// + /// Returns the number of columns in this matrix. + /// + /// + public int getColumns() + { + return this.columns; + } + + /// + /// Returns the number of rows in this matrix. + /// + /// + public int getRows() + { + return this.rows; + } + + /// + /// Returns the value at row r, column c. + /// + /// + /// + /// + /// + public int get(int r, int c) + { + if (r < 0 || this.rows <= r) + { + throw new ArgumentOutOfRangeException(paramName: "Row index out of range: " + r); + } + + if (c < 0 || this.columns <= c) + { + throw new ArgumentOutOfRangeException(paramName: "Column index out of range: " + c); + } + + return this.data[r][c]; + } + + /// + /// Sets the value at row r, column c. + /// + /// + /// + /// + /// + public void set(int r, int c, int value) + { + if (r < 0 || this.rows <= r) + { + throw new ArgumentOutOfRangeException(paramName: "Row index out of range: " + r); + } + + if (c < 0 || this.columns <= c) + { + throw new ArgumentOutOfRangeException(paramName: "Column index out of range: " + c); + } + + this.data[r][c] = value; + } + + /// + /// Returns true iff this matrix is identical to the other. + /// + /// + /// + public bool equals(object other) + { + if (!(other is Matrix)) + { + return false; + } + + for (var r = 0; r < this.rows; r++) + { + if (!Equals(objA: this.data[r], + objB: ((Matrix)other).data[r])) + { + return false; + } + } + + return true; + } + + /// + /// Multiplies this matrix (the one on the left) by another + /// matrix (the one on the right). + /// + /// + /// + /// + public Matrix times(Matrix right) + { + if (this.getColumns() != right.getRows()) + { + throw new ArgumentOutOfRangeException( + paramName: "Columns on left (" + this.getColumns() + ") " + + "is different than rows on right (" + right.getRows() + ")"); + } + + var result = new Matrix(initRows: this.getRows(), + initColumns: right.getColumns()); + for (var r = 0; r < this.getRows(); r++) + { + for (var c = 0; c < right.getColumns(); c++) + { + var value = 0; + for (var i = 0; i < this.getColumns(); i++) + { + value ^= Galois.multiply( + a: (byte) this.get( + r: r, + c: i), + b: (byte) right.get( + r: i, + c: c)); + } + + result.set( + r: r, + c: c, + value: value); + } + } + + return result; + } + + /** + * Returns the concatenation of this matrix and the matrix on the right. + */ + public Matrix augment(Matrix right) + { + if (this.rows != right.rows) + { + throw new ArgumentOutOfRangeException(paramName: "Matrices don't have the same number of rows"); + } + + var result = new Matrix(initRows: this.rows, + initColumns: this.columns + right.columns); + for (var r = 0; r < this.rows; r++) + { + for (var c = 0; c < this.columns; c++) + { + result.data[r][c] = this.data[r][c]; + } + + for (var c = 0; c < right.columns; c++) + { + result.data[r][this.columns + c] = right.data[r][c]; + } + } + + return result; + } + + /** + * Returns a part of this matrix. + */ + public Matrix submatrix(int rmin, int cmin, int rmax, int cmax) + { + var result = new Matrix(initRows: rmax - rmin, + initColumns: cmax - cmin); + for (var r = rmin; r < rmax; r++) + { + for (var c = cmin; c < cmax; c++) + { + result.data[r - rmin][c - cmin] = this.data[r][c]; + } + } + + return result; + } + + /** + * Returns one row of the matrix as a byte array. + */ + public int[] getRow(int row) + { + var result = new int[this.columns]; + for (var c = 0; c < this.columns; c++) + { + result[c] = this.get( + r: row, + c: c); + } + + return result; + } + + /** + * Exchanges two rows in the matrix. + */ + public void swapRows(int r1, int r2) + { + if (r1 < 0 || this.rows <= r1 || r2 < 0 || this.rows <= r2) + { + throw new ArgumentOutOfRangeException(paramName: "Row index out of range"); + } + + var tmp = this.data[r1]; + this.data[r1] = this.data[r2]; + this.data[r2] = tmp; + } + + /// + /// Returns the inverse of this matrix. + /// @throws IllegalArgumentException when the matrix is singular and + /// doesn't have an inverse. + /// + public Matrix invert() + { + // Sanity check. + if (this.rows != this.columns) + { + throw new ArgumentOutOfRangeException(paramName: "Only square matrices can be inverted"); + } + + // Create a working matrix by augmenting this one with + // an identity matrix on the right. + var work = this.augment(right: identity(size: this.rows)); + + // Do Gaussian elimination to transform the left half into + // an identity matrix. + work.gaussianElimination(); + + // The right half is now the inverse. + return work.submatrix( + rmin: 0, + cmin: this.rows, + rmax: this.columns, + cmax: this.columns * 2); + } + + /// + /// Does the work of matrix inversion. + /// Assumes that this is an r by 2r matrix. + /// + private void gaussianElimination() + { + // Clear out the part below the main diagonal and scale the main + // diagonal to be 1. + for (var r = 0; r < this.rows; r++) + { + // If the element on the diagonal is 0, find a row below + // that has a non-zero and swap them. + if (this.data[r][r] == 0) + { + for (var rowBelow = r + 1; rowBelow < this.rows; rowBelow++) + { + if (this.data[rowBelow][r] != 0) + { + this.swapRows( + r1: r, + r2: rowBelow); + break; + } + } + } + + // If we couldn't find one, the matrix is singular. + if (this.data[r][r] == 0) + { + throw new ArgumentOutOfRangeException(paramName: "Matrix is singular"); + } + + // Scale to 1. + if (this.data[r][r] != 1) + { + var scale = Galois.divide( + a: 1, + b: (sbyte) this.data[r][r]); + for (var c = 0; c < this.columns; c++) + { + this.data[r][c] = Galois.multiply( + a: (byte) this.data[r][c], + b: (byte) scale); + } + } + + // Make everything below the 1 be a 0 by subtracting + // a multiple of it. (Subtraction and addition are + // both exclusive or in the Galois field.) + for (var rowBelow = r + 1; rowBelow < this.rows; rowBelow++) + { + if (this.data[rowBelow][r] != 0) + { + var scale = this.data[rowBelow][r]; + for (var c = 0; c < this.columns; c++) + { + this.data[rowBelow][c] ^= Galois.multiply( + a: (byte) scale, + b: (byte) this.data[r][c]); + } + } + } + } + + // Now clear the part above the main diagonal. + for (var d = 0; d < this.rows; d++) + { + for (var rowAbove = 0; rowAbove < d; rowAbove++) + { + if (this.data[rowAbove][d] != 0) + { + var scale = this.data[rowAbove][d]; + for (var c = 0; c < this.columns; c++) + { + this.data[rowAbove][c] ^= Galois.multiply( + a: (byte) scale, + b: (byte) this.data[d][c]); + } + } + } + } + } +} diff --git a/src/BrightChain.Engine/Quorum/Services/CacheManagers/QuorumCacheManager.cs b/src/BrightChain.Engine/Quorum/Services/CacheManagers/QuorumCacheManager.cs new file mode 100644 index 00000000..30fc9d4b --- /dev/null +++ b/src/BrightChain.Engine/Quorum/Services/CacheManagers/QuorumCacheManager.cs @@ -0,0 +1,93 @@ +using System; +using BrightChain.Engine.Interfaces; +using FASTER.core; + +namespace BrightChain.Engine.Services.CacheManagers.Quorum; + +/// +/// +/// +/// +/// +/// +/// +public class QuorumCacheManager + : ICacheManager, IDisposable + where Tkey : IComparable + where TkeySerializer : BinaryObjectSerializer, new() + where TvalueSerializer : BinaryObjectSerializer, new() +{ + /// + /// KeyAdded event + /// + public event ICacheManager.KeyAddedEventHandler KeyAdded; + + /// + /// KeyExpired event + /// + public event ICacheManager.KeyExpiredEventHandler KeyExpired; + + /// + /// KeyRemoved event + /// + public event ICacheManager.KeyRemovedEventHandler KeyRemoved; + + /// + /// Cache miss event + /// + public event ICacheManager.CacheMissEventHandler CacheMiss; + + /// + /// Get data from the quorum + /// + /// + /// + /// + public Tvalue Get(Tkey blockHash) + { + throw new NotImplementedException(); + } + + /// + /// Set quorum data + /// + /// + /// + /// + public void Set(Tkey key, Tvalue value) + { + throw new NotImplementedException(); + } + + /// + /// Whether the quorum contains the key + /// + /// + /// + /// + public bool Contains(Tkey key) + { + throw new NotImplementedException(); + } + + /// + /// Drop the key if it exists + /// + /// + /// + /// + /// + public bool Drop(Tkey key, bool noCheckContains = false) + { + throw new NotImplementedException(); + } + + /// + /// Standard dispose pattern + /// + /// + public void Dispose() + { + throw new NotImplementedException(); + } +} diff --git a/src/BrightChain.Engine/Quorum/Services/ConfidentialQuorum.cs b/src/BrightChain.Engine/Quorum/Services/ConfidentialQuorum.cs new file mode 100644 index 00000000..a981401c --- /dev/null +++ b/src/BrightChain.Engine/Quorum/Services/ConfidentialQuorum.cs @@ -0,0 +1,6 @@ +namespace BrightChain.Engine.Quorum.Services; + +public class ConfidentialQuorum +{ + +} diff --git a/src/BrightChain.Engine/README.txt b/src/BrightChain.Engine/README.txt old mode 100644 new mode 100755 diff --git a/src/BrightChain.Engine/Roslyn/Compiler.cs b/src/BrightChain.Engine/Roslyn/Compiler.cs old mode 100644 new mode 100755 index 6c72bb6f..f4f09823 --- a/src/BrightChain.Engine/Roslyn/Compiler.cs +++ b/src/BrightChain.Engine/Roslyn/Compiler.cs @@ -6,82 +6,88 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; -namespace BrightChain.Engine.Roslyn +namespace BrightChain.Engine.Roslyn; + +public class Compiler { - public class Compiler - { - private static readonly IEnumerable DefaultNamespaces = - new[] - { - "System", - "System.IO", - "System.Net", - "System.Linq", - "System.Text", - "System.Text.RegularExpressions", - "System.Collections.Generic", - }; + private static readonly IEnumerable DefaultNamespaces = + new[] + { + "System", "System.IO", "System.Net", "System.Linq", "System.Text", "System.Text.RegularExpressions", + "System.Collections.Generic", + }; - private static readonly string runtimePath = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\{0}.dll"; + private static readonly string runtimePath = + @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.1\{0}.dll"; - private static readonly IEnumerable DefaultReferences = - new[] - { - MetadataReference.CreateFromFile(string.Format(runtimePath, "mscorlib")), - MetadataReference.CreateFromFile(string.Format(runtimePath, "System")), - MetadataReference.CreateFromFile(string.Format(runtimePath, "System.Core")) - }; + private static readonly IEnumerable DefaultReferences = + new[] + { + MetadataReference.CreateFromFile(path: string.Format(format: runtimePath, + arg0: "mscorlib")), + MetadataReference.CreateFromFile(path: string.Format(format: runtimePath, + arg0: "System")), + MetadataReference.CreateFromFile(path: string.Format(format: runtimePath, + arg0: "System.Core")), + }; - private static readonly CSharpCompilationOptions DefaultCompilationOptions = - new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) - .WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release) - .WithUsings(DefaultNamespaces); + private static readonly CSharpCompilationOptions DefaultCompilationOptions = + new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary) + .WithOverflowChecks(enabled: true).WithOptimizationLevel(value: OptimizationLevel.Release) + .WithUsings(usings: DefaultNamespaces); - public static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null) - { - var stringText = SourceText.From(text, Encoding.UTF8); - return SyntaxFactory.ParseSyntaxTree(stringText, options, filename); - } + public static SyntaxTree Parse(string text, string filename = "", CSharpParseOptions options = null) + { + var stringText = SourceText.From(text: text, + encoding: Encoding.UTF8); + return SyntaxFactory.ParseSyntaxTree(text: stringText, + options: options, + path: filename); + } - static void Main(string[] args) - { - var fileToCompile = @"C:\Users\DesktopHome\Documents\Visual Studio 2013\Projects\ConsoleForEverything\SignalR_Everything\Program.cs"; - var source = File.ReadAllText(fileToCompile); - var parsedSyntaxTree = Parse(source, "", CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp5)); + private static void Main(string[] args) + { + var fileToCompile = + @"C:\Users\DesktopHome\Documents\Visual Studio 2013\Projects\ConsoleForEverything\SignalR_Everything\Program.cs"; + var source = File.ReadAllText(path: fileToCompile); + var parsedSyntaxTree = Parse(text: source, + filename: "", + options: CSharpParseOptions.Default.WithLanguageVersion(version: LanguageVersion.CSharp5)); - //var syntaxTree = CSharpSyntaxTree.ParseText(source); + //var syntaxTree = CSharpSyntaxTree.ParseText(source); - //CSharpCompilation compilation = CSharpCompilation.Create( - // "assemblyName", - // new[] { syntaxTree }, - // new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, - // new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + //CSharpCompilation compilation = CSharpCompilation.Create( + // "assemblyName", + // new[] { syntaxTree }, + // new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, + // new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - var compilation - = CSharpCompilation.Create( - "Test.dll", - new SyntaxTree[] { parsedSyntaxTree }, - DefaultReferences, - DefaultCompilationOptions); - try + var compilation + = CSharpCompilation.Create( + assemblyName: "Test.dll", + syntaxTrees: new[] {parsedSyntaxTree}, + references: DefaultReferences, + options: DefaultCompilationOptions); + try + { + using (var dllStream = new MemoryStream()) + using (var pdbStream = new MemoryStream()) { - using (var dllStream = new MemoryStream()) - using (var pdbStream = new MemoryStream()) + var emitResult = compilation.Emit(peStream: dllStream, + pdbStream: pdbStream); + Console.WriteLine(value: emitResult.Success ? "Sucess!!" : "Failed"); + if (!emitResult.Success) { - var emitResult = compilation.Emit(dllStream, pdbStream); - Console.WriteLine(emitResult.Success ? "Sucess!!" : "Failed"); - if (!emitResult.Success) - { - // emitResult.Diagnostics - } + // emitResult.Diagnostics } } - catch (Exception ex) - { - Console.WriteLine(ex); - } - Console.Read(); } + catch (Exception ex) + { + Console.WriteLine(value: ex); + } + + Console.Read(); } } diff --git a/src/BrightChain.Engine/Services/BlockBrightenerService.cs b/src/BrightChain.Engine/Services/BlockBrightenerService.cs old mode 100644 new mode 100755 index cc3c60ab..71cc01aa --- a/src/BrightChain.Engine/Services/BlockBrightenerService.cs +++ b/src/BrightChain.Engine/Services/BlockBrightenerService.cs @@ -1,77 +1,78 @@ -namespace BrightChain.Engine.Services -{ - using System.Linq; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Services.CacheManagers.Block; +using System.Linq; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Services.CacheManagers.Block; + +namespace BrightChain.Engine.Services; +/// +/// This tiny little class is actually the lynchpin of the owner free filesystem. +/// It is responsible for XORing blocks with random data blocks in order to correlate +/// the user data with random data and other user blocks. +/// +public class BlockBrightenerService +{ /// - /// This tiny little class is actually the lynchpin of the owner free filesystem. - /// It is responsible for XORing blocks with random data blocks in order to correlate - /// the user data with random data and other user blocks. + /// This value that determines how many blocks get XOR'd with a given input block. + /// TupleCount-1. Setting TupleCount = 5 will XOR input with 4 randomizers. /// - public class BlockBrightenerService - { - /// - /// This value that determines how many blocks get XOR'd with a given input block. - /// TupleCount-1. Setting TupleCount = 5 will XOR input with 4 randomizers. - /// - public const byte TupleCount = 5; + public const byte TupleCount = 5; - private readonly BrightenedBlockCacheManagerBase resultCache; + private readonly BrightenedBlockCacheManagerBase resultCache; - public BlockBrightenerService(BrightenedBlockCacheManagerBase resultCache) - { - this.resultCache = resultCache; - } + public BlockBrightenerService(BrightenedBlockCacheManagerBase resultCache) + { + this.resultCache = resultCache; + } - /// - /// Brightening is the process of XORing to correlate the data with block of random data and make it appear more random or "white" as white light is broad multi-spectrum light. - /// - /// - /// - public BrightenedBlock Brighten(IdentifiableBlock identifiableBlock, out BrightenedBlock[] randomizersUsed, out TupleStripe brightenedStripe) + /// + /// Brightening is the process of XORing to correlate the data with block of random data and make it appear more random or "white" as white + /// light is broad multi-spectrum light. + /// + /// + /// + public BrightenedBlock Brighten(IdentifiableBlock identifiableBlock, out BrightenedBlock[] randomizersUsed, + out TupleStripe brightenedStripe) + { + // the incoming block should be a raw disk block and is never used again + var stripeBlocks = new BrightenedBlock[TupleCount]; + randomizersUsed = new BrightenedBlock[TupleCount - 1]; + for (var i = 0; i < randomizersUsed.Length; i++) { - // the incoming block should be a raw disk block and is never used again - var stripeBlocks = new BrightenedBlock[TupleCount]; - randomizersUsed = new BrightenedBlock[TupleCount - 1]; - for (int i = 0; i < randomizersUsed.Length; i++) - { - // TODO: select or generate pre-generated random blocks (determine mixing) - // for now just generate on demand, but these can be pre-seeded, and - // technically any block in cache we haven't already used within a chain can be used. - // it is imperative we never commit a non-brightened block to cache. - // TODO: add a mixing ratio and re-use blocks as appropriately as possible - randomizersUsed[i] = new RandomizerBlock( - destinationCache: this.resultCache, - blockSize: identifiableBlock.BlockSize, - keepUntilAtLeast: identifiableBlock.StorageContract.KeepUntilAtLeast, - redundancyContractType: identifiableBlock.StorageContract.RedundancyContractType, - requestTime: identifiableBlock.StorageContract.RequestTime); + // TODO: select or generate pre-generated random blocks (determine mixing) + // for now just generate on demand, but these can be pre-seeded, and + // technically any block in cache we haven't already used within a chain can be used. + // it is imperative we never commit a non-brightened block to cache. + // TODO: add a mixing ratio and re-use blocks as appropriately as possible + randomizersUsed[i] = new RandomizerBlock( + destinationCache: this.resultCache, + blockSize: identifiableBlock.BlockSize, + keepUntilAtLeast: identifiableBlock.StorageContract.KeepUntilAtLeast, + redundancyContractType: identifiableBlock.StorageContract.RedundancyContractType, + requestTime: identifiableBlock.StorageContract.RequestTime); - stripeBlocks[i] = randomizersUsed[i]; + stripeBlocks[i] = randomizersUsed[i]; - this.resultCache.Set(randomizersUsed[i]); - } + this.resultCache.Set(value: randomizersUsed[i]); + } - var brightBlock = new BrightenedBlock( - blockParams: new BrightenedBlockParams( - cacheManager: this.resultCache, - allowCommit: true, - blockParams: identifiableBlock.BlockParams), - data: identifiableBlock.XOR(randomizersUsed), - constituentBlockHashes: randomizersUsed.Select(b => b.Id).ToArray()); + var brightBlock = new BrightenedBlock( + blockParams: new BrightenedBlockParams( + cacheManager: this.resultCache, + allowCommit: true, + blockParams: identifiableBlock.BlockParams), + data: identifiableBlock.XOR(others: randomizersUsed), + constituentBlockHashes: randomizersUsed.Select(selector: b => b.Id).ToArray()); - stripeBlocks[TupleCount - 1] = brightBlock; + stripeBlocks[TupleCount - 1] = brightBlock; - brightenedStripe = new TupleStripe( - tupleCountMatch: TupleCount, - blockSizeMatch: identifiableBlock.BlockSize, - brightenedBlocks: stripeBlocks, - originalType: identifiableBlock.OriginalType); + brightenedStripe = new TupleStripe( + tupleCountMatch: TupleCount, + blockSizeMatch: identifiableBlock.BlockSize, + brightenedBlocks: stripeBlocks, + originalType: identifiableBlock.OriginalType); - return brightBlock; - } + return brightBlock; } } diff --git a/src/BrightChain.Engine/Services/BrightBlockService.cs b/src/BrightChain.Engine/Services/BrightBlockService.cs old mode 100644 new mode 100755 index 9af8b894..54aac19f --- a/src/BrightChain.Engine/Services/BrightBlockService.cs +++ b/src/BrightChain.Engine/Services/BrightBlockService.cs @@ -2,722 +2,764 @@ // Copyright (c) BrightChain. All rights reserved. // -namespace BrightChain.Engine.Services -{ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Threading.Tasks; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.CacheManager; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Contracts; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Models.Nodes; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NeuralFabric.Helpers; +using NeuralFabric.Models.Hashes; +using Utilities = NeuralFabric.Helpers.Utilities; + +namespace BrightChain.Engine.Services; + #nullable enable - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Security.Cryptography; - using System.Threading.Tasks; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster.CacheManager; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Contracts; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Models.Nodes; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; + +/// +/// Core service for BrightChain used by the webservice to retrieve and store blocks. +/// TODO: Eventually needs to contain blockhash indices for things like expiration (grouped by ulong expiration second), +/// lists by block type, etc. +/// +public class BrightBlockService : IDisposable +{ + public readonly Version AssemblyVersion; + private readonly BlockBrightenerService blockBrightener; + private readonly FasterBlockCacheManager blockFasterCache; + private readonly BrightChainNode brightChainNodeAuthority; + private readonly IConfiguration configuration; + private readonly ILogger logger; + + private readonly MemoryDictionaryBlockCacheManager randomizerBlockMemoryCache; /// - /// Core service for BrightChain used by the webservice to retrieve and store blocks. - /// TODO: Eventually needs to contain blockhash indices for things like expiration (grouped by ulong expiration second), - /// lists by block type, etc. + /// Initializes a new instance of the class. /// - public class BrightBlockService : IDisposable + /// Instance of the logging provider. + public BrightBlockService(ILoggerFactory logger, IConfiguration configuration) { - private readonly ILogger logger; - private readonly IConfiguration configuration; + this.logger = logger.CreateLogger(categoryName: nameof(BrightBlockService)); + if (this.logger is null) + { + throw new BrightChainException(message: "CreateLogger failed"); + } - private readonly MemoryDictionaryBlockCacheManager randomizerBlockMemoryCache; - private readonly FasterBlockCacheManager blockFasterCache; - private readonly BlockBrightenerService blockBrightener; - private readonly BrightChainNode brightChainNodeAuthority; + this.logger.LogInformation(message: string.Format(format: "<{0}>: logging initialized", + arg0: nameof(BrightBlockService))); - public readonly Version AssemblyVersion; + this.configuration = configuration; - /// - /// Initializes a new instance of the class. - /// - /// Instance of the logging provider. - public BrightBlockService(ILoggerFactory logger, IConfiguration configuration) + var nodeOptions = configuration.GetSection(key: "NodeOptions"); + if (nodeOptions is null || !nodeOptions.Exists()) { - this.logger = logger.CreateLogger(nameof(BrightBlockService)); - if (this.logger is null) - { - throw new BrightChainException("CreateLogger failed"); - } + this.configuration = ConfigurationHelper.LoadConfiguration(); + nodeOptions = this.configuration.GetSection(key: "NodeOptions"); + } - this.logger.LogInformation(string.Format("<{0}>: logging initialized", nameof(BrightBlockService))); + if (nodeOptions is null || !nodeOptions.Exists()) + { + throw new BrightChainException(message: "'NodeOptions' config section must be defined, but is not"); + } - this.configuration = configuration; + var configuredDbName + = nodeOptions.GetSection(key: "DatabaseName"); - var nodeOptions = configuration.GetSection("NodeOptions"); - if (nodeOptions is null || !nodeOptions.Exists()) - { - this.configuration = ConfigurationHelper.LoadConfiguration(); - nodeOptions = this.configuration.GetSection("NodeOptions"); - } + var dbNameConfigured = configuredDbName is not null && configuredDbName.Value.Any(); + var serviceUnifiedStoreGuid = dbNameConfigured ? Guid.Parse(input: configuredDbName.Value) : Guid.NewGuid(); - if (nodeOptions is null || !nodeOptions.Exists()) - { - throw new BrightChainException(string.Format(format: "'NodeOptions' config section must be defined, but is not")); - } + if (!dbNameConfigured) + { + //global::BrightChain.Engine.Helpers.ConfigurationHelper.AddOrUpdateAppSetting("NodeOptions:DatabaseName", Utilities.HashToFormattedString(serviceUnifiedStoreGuid.ToByteArray())); + } - var configuredDbName - = nodeOptions.GetSection("DatabaseName"); + var rootBlock = new RootBlock( + databaseGuid: serviceUnifiedStoreGuid); + + this.blockFasterCache = new FasterBlockCacheManager( + logger: this.logger, + configuration: this.configuration, + rootBlock: rootBlock, + testingSelfDestruct: false); + + this.randomizerBlockMemoryCache = new MemoryDictionaryBlockCacheManager( + logger: this.logger, + configuration: this.configuration, + rootBlock: rootBlock); + + this.logger.LogInformation(message: string.Format(format: "<{0}>: caches initialized", + arg0: nameof(BrightBlockService))); + this.blockBrightener = new BlockBrightenerService( + resultCache: this.blockFasterCache); + this.brightChainNodeAuthority = new BrightChainNode(configuration: this.configuration); + this.AssemblyVersion = Utilities.GetAssemblyVersionForType(assemblyType: typeof(BrightBlockService)); + } - var dbNameConfigured = configuredDbName is not null && configuredDbName.Value.Any(); - Guid serviceUnifiedStoreGuid = dbNameConfigured ? Guid.Parse(configuredDbName.Value) : Guid.NewGuid(); + public RootBlock RootBlock => this.blockFasterCache.RootBlock; - if (!dbNameConfigured) + public void Dispose() + { + throw new NotImplementedException(); + } + + /// + /// Creates a descriptor block for a given input file, found on disk. + /// TODO: Break this up into a block-stream. + /// + /// + /// + /// + /// Resultant CBL block. + public async IAsyncEnumerable StreamCreatedBrightenedBlocksFromFileAsync(SourceFileInfo sourceInfo, + BlockParams blockParams, BlockSize? blockSize = null) + { + if (!blockSize.HasValue) + { + blockSize = blockParams.BlockSize; + if (blockSize.Value == BlockSize.Unknown) { - //global::BrightChain.Engine.Helpers.ConfigurationHelper.AddOrUpdateAppSetting("NodeOptions:DatabaseName", Utilities.HashToFormattedString(serviceUnifiedStoreGuid.ToByteArray())); + // decide best block size if null + throw new NotImplementedException(); } + } - var rootBlock = new RootBlock( - databaseGuid: serviceUnifiedStoreGuid); - - this.blockFasterCache = new FasterBlockCacheManager( - logger: this.logger, - configuration: this.configuration, - rootBlock: rootBlock, - testingSelfDestruct: false); - - this.randomizerBlockMemoryCache = new MemoryDictionaryBlockCacheManager( - logger: this.logger, - configuration: this.configuration, - rootBlock: rootBlock); - - this.logger.LogInformation(string.Format("<{0}>: caches initialized", nameof(BrightBlockService))); - this.blockBrightener = new BlockBrightenerService( - resultCache: this.blockFasterCache); - this.brightChainNodeAuthority = new BrightChainNode(this.configuration); - this.AssemblyVersion = Utilities.GetAssemblyVersionForType(); + var iBlockSize = BlockSizeMap.BlockSize(blockSize: blockSize.Value); + var maximumStorage = BlockSizeMap.HashesPerBlock(blockSize: blockSize.Value, + exponent: 2) * iBlockSize; + if (sourceInfo.FileInfo.Length > maximumStorage) + { + throw new BrightChainException(message: "File exceeds storage for this block size"); } - public RootBlock RootBlock => this.blockFasterCache.RootBlock; + if (blockParams.PrivateEncrypted) + { + throw new NotImplementedException(); + } /// - /// Creates a descriptor block for a given input file, found on disk. - /// TODO: Break this up into a block-stream. + /// The outer code already knows the SHA256 of the file in order to build all the CBL params, but serves as a check against that at all points. /// - /// - /// - /// - /// Resultant CBL block. - public async IAsyncEnumerable StreamCreatedBrightenedBlocksFromFileAsync(SourceFileInfo sourceInfo, BlockParams blockParams, BlockSize? blockSize = null) + using (var fileHasher = SHA256.Create()) { - if (!blockSize.HasValue) + using (var inFile = File.OpenRead(path: sourceInfo.FileInfo.FullName)) { - blockSize = blockParams.BlockSize; - if (blockSize.Value == BlockSize.Unknown) + var bytesRemaining = sourceInfo.FileInfo.Length; + var blocksRemaining = Math.Max(val1: 1, + val2: (int)Math.Ceiling(a: bytesRemaining / iBlockSize)); + while (bytesRemaining > 0) { - // decide best block size if null - throw new NotImplementedException(); - } - } - - var iBlockSize = BlockSizeMap.BlockSize(blockSize.Value); - var maximumStorage = BlockSizeMap.HashesPerBlock(blockSize.Value, 2) * iBlockSize; - if (sourceInfo.FileInfo.Length > maximumStorage) - { - throw new BrightChainException("File exceeds storage for this block size"); - } - - if (blockParams.PrivateEncrypted) - { - throw new NotImplementedException(); - } + var finalBlock = bytesRemaining <= iBlockSize; + var bytesToRead = finalBlock ? (int)bytesRemaining : iBlockSize; + var buffer = new byte[bytesToRead]; + var bytesRead = inFile.Read(buffer: buffer, + offset: 0, + count: bytesToRead); + bytesRemaining -= bytesRead; + + if (bytesRead < bytesToRead) + { + throw new BrightChainException(message: "Unexpected EOF"); + } - /// - /// The outer code already knows the SHA256 of the file in order to build all the CBL params, but serves as a check against that at all points. - /// - using (SHA256 fileHasher = SHA256.Create()) - { - using (FileStream inFile = File.OpenRead(sourceInfo.FileInfo.FullName)) - { - var bytesRemaining = sourceInfo.FileInfo.Length; - var blocksRemaining = Math.Max(1, (int)Math.Ceiling((double)(bytesRemaining / iBlockSize))); - while (bytesRemaining > 0) + if (bytesRead > iBlockSize) { - var finalBlock = bytesRemaining <= iBlockSize; - var bytesToRead = finalBlock ? (int)bytesRemaining : iBlockSize; - byte[] buffer = new byte[bytesToRead]; - int bytesRead = inFile.Read(buffer, 0, bytesToRead); - bytesRemaining -= bytesRead; + throw new BrightChainExceptionImpossible(message: nameof(bytesRead)); + } - if (bytesRead < bytesToRead) - { - throw new BrightChainException("Unexpected EOF"); - } - else if (bytesRead > iBlockSize) + if (finalBlock) + { + if (bytesRemaining != 0) { - throw new BrightChainExceptionImpossible(nameof(bytesRead)); + throw new BrightChainException(message: nameof(bytesRemaining)); } - else if (finalBlock) - { - if (bytesRemaining != 0) - { - throw new BrightChainException(nameof(bytesRemaining)); - } - fileHasher.TransformFinalBlock(buffer, 0, bytesToRead); // notably only takes the last bytes of the file not counting filler. + fileHasher.TransformFinalBlock(inputBuffer: buffer, + inputOffset: 0, + inputCount: bytesToRead); // notably only takes the last bytes of the file not counting filler. - // fill in the rest of the block with random data - buffer = Helpers.RandomDataHelper.DataFiller( - inputData: new ReadOnlyMemory(buffer), - blockSize: blockSize.Value).ToArray(); - } - else + // fill in the rest of the block with random data + buffer = RandomDataHelper.DataFiller( + inputData: new ReadOnlyMemory(array: buffer), + blockSize: blockSize.Value).ToArray(); + } + else + { + var bytesHashed = fileHasher.TransformBlock(inputBuffer: buffer, + inputOffset: 0, + inputCount: bytesRead, + outputBuffer: null, + outputOffset: 0); + if (bytesHashed != iBlockSize || bytesRead != bytesHashed) { - var bytesHashed = fileHasher.TransformBlock(buffer, 0, bytesRead, null, 0); - if (bytesHashed != iBlockSize || bytesRead != bytesHashed) - { - throw new BrightChainException("Unexpected transform mismatch"); - } + throw new BrightChainException(message: "Unexpected transform mismatch"); } + } - var brightenedBlock = this.blockBrightener.Brighten( - identifiableBlock: new IdentifiableBlock( - blockParams: blockParams, - data: buffer), - randomizersUsed: out _, - brightenedStripe: out _); + var brightenedBlock = this.blockBrightener.Brighten( + identifiableBlock: new IdentifiableBlock( + blockParams: blockParams, + data: buffer), + randomizersUsed: out _, + brightenedStripe: out _); - yield return brightenedBlock; - } // end while + yield return brightenedBlock; + } // end while - if (new DataHash( + if (new DataHash( providedHashBytes: fileHasher.Hash, sourceDataLength: sourceInfo.FileInfo.Length, computed: true) != sourceInfo.SourceId) - { - throw new BrightChainException("Hash mismatch against known hash"); - } - } // end using + { + throw new BrightChainException(message: "Hash mismatch against known hash"); + } } // end using - } + } // end using + } - /// - /// TODO: refactor out the core into a streaming CBL maker with a file stream wrapper. Then we can have a functionm that just takes the data. - /// - /// - /// - /// - public async Task> MakeCBLChainFromParamsAsync(string fileName, BlockParams blockParams) + /// + /// TODO: refactor out the core into a streaming CBL maker with a file stream wrapper. Then we can have a functionm that just takes the + /// data. + /// + /// + /// + /// + public async Task> MakeCBLChainFromParamsAsync(string fileName, BlockParams blockParams) + { + var sourceInfo = new SourceFileInfo( + fileName: fileName, + blockSize: blockParams.BlockSize); + var blockHashesUsedThisSegment = new List(); + var brightenedBlocksThisSegment = new List(); + var sourceBytesRemaining = sourceInfo.FileInfo.Length; + var totalBytesRemaining = sourceInfo.TotalBlockedBytes; + var cblsExpected = sourceInfo.CblsExpected; + var cblsEmitted = new Models.Blocks.Chains.BrightChain[cblsExpected]; + var cblIdx = 0; + var blocksRemaining = sourceInfo.TotalBlocksExpected; + + var blockCountThisSegment = 0; + var sourceByteCountThisSegment = 0; + var brightenedBlocksConsumed = 0; + + using (var segmentHasher = SHA256.Create()) { - var sourceInfo = new SourceFileInfo( - fileName: fileName, - blockSize: blockParams.BlockSize); - var blockHashesUsedThisSegment = new List(); - var brightenedBlocksThisSegment = new List(); - var sourceBytesRemaining = sourceInfo.FileInfo.Length; - var totalBytesRemaining = sourceInfo.TotalBlockedBytes; - var cblsExpected = sourceInfo.CblsExpected; - var cblsEmitted = new BrightChain[cblsExpected]; - var cblIdx = 0; - var blocksRemaining = sourceInfo.TotalBlocksExpected; - - var blockCountThisSegment = 0; - var sourceByteCountThisSegment = 0; - var brightenedBlocksConsumed = 0; - - using (SHA256 segmentHasher = SHA256.Create()) - { - // last block is always full of random data - await foreach (BrightenedBlock brightenedBlock in this.StreamCreatedBrightenedBlocksFromFileAsync(sourceInfo: sourceInfo, blockParams: blockParams)) + // last block is always full of random data + await foreach (var brightenedBlock in this.StreamCreatedBrightenedBlocksFromFileAsync(sourceInfo: sourceInfo, + blockParams: blockParams)) + { + brightenedBlocksThisSegment.Add(item: brightenedBlock); + this.blockFasterCache.Set(block: brightenedBlock); + sourceByteCountThisSegment += (int)(sourceBytesRemaining < sourceInfo.BytesPerBlock + ? sourceBytesRemaining + : brightenedBlock.Bytes.Length); + blockHashesUsedThisSegment.Add(item: brightenedBlock.Id); + blockHashesUsedThisSegment.AddRange(collection: brightenedBlock.ConstituentBlocks); + var cblFullAfterThisBlock = ++blockCountThisSegment == sourceInfo.HashesPerBlock; + var sourceConsumed = totalBytesRemaining <= sourceInfo.BytesPerBlock; + blocksRemaining--; + brightenedBlocksConsumed++; + if (cblFullAfterThisBlock || sourceConsumed || blocksRemaining == 0) { - brightenedBlocksThisSegment.Add(brightenedBlock); - this.blockFasterCache.Set(brightenedBlock); - sourceByteCountThisSegment += (int)(sourceBytesRemaining < sourceInfo.BytesPerBlock ? sourceBytesRemaining : brightenedBlock.Bytes.Length); - blockHashesUsedThisSegment.Add(brightenedBlock.Id); - blockHashesUsedThisSegment.AddRange(brightenedBlock.ConstituentBlocks); - var cblFullAfterThisBlock = ++blockCountThisSegment == sourceInfo.HashesPerBlock; - var sourceConsumed = totalBytesRemaining <= sourceInfo.BytesPerBlock; - blocksRemaining--; - brightenedBlocksConsumed++; - if (cblFullAfterThisBlock || sourceConsumed || (blocksRemaining == 0)) - { - var sourceBytesThisBlock = sourceBytesRemaining > sourceInfo.BytesPerBlock ? sourceInfo.BytesPerBlock : sourceBytesRemaining; - - segmentHasher.TransformFinalBlock(brightenedBlock.Bytes.ToArray(), 0, (int)sourceBytesThisBlock); - - var cblParams = new ConstituentBlockListBlockParams( - blockParams: new BrightenedBlockParams( - cacheManager: this.blockFasterCache, - allowCommit: true, - blockParams: blockParams), - sourceId: sourceInfo.SourceId, - segmentId: new SegmentHash( - providedHashBytes: segmentHasher.Hash, - sourceDataLength: sourceByteCountThisSegment, - computed: true), - totalLength: sourceBytesRemaining > sourceInfo.BytesPerCbl ? sourceInfo.BytesPerCbl : sourceBytesRemaining, - constituentBlockHashes: blockHashesUsedThisSegment.ToArray(), - previous: cblIdx > 0 ? cblsEmitted[cblIdx - 1].Id : null, - next: null, - correlationId: null, - previousVersionHash: null); - - var cbl = new BrightChain( - blockParams: cblParams, - brightenedBlocks: brightenedBlocksThisSegment); - - // update the next pointer of the previous block - if (cblIdx > 0) - { - cblsEmitted[cblIdx].Next = cbl.Id; - } + var sourceBytesThisBlock = + sourceBytesRemaining > sourceInfo.BytesPerBlock ? sourceInfo.BytesPerBlock : sourceBytesRemaining; - cblsEmitted[cblIdx++] = cbl; + segmentHasher.TransformFinalBlock(inputBuffer: brightenedBlock.Bytes.ToArray(), + inputOffset: 0, + inputCount: (int)sourceBytesThisBlock); - segmentHasher.Initialize(); - blockHashesUsedThisSegment.Clear(); - brightenedBlocksThisSegment.Clear(); - blockCountThisSegment = 0; - sourceByteCountThisSegment = 0; - } - else + var cblParams = new ConstituentBlockListBlockParams( + blockParams: new BrightenedBlockParams( + cacheManager: this.blockFasterCache, + allowCommit: true, + blockParams: blockParams), + sourceId: sourceInfo.SourceId, + segmentId: new SegmentHash( + providedHashBytes: segmentHasher.Hash, + sourceDataLength: sourceByteCountThisSegment, + computed: true), + totalLength: sourceBytesRemaining > sourceInfo.BytesPerCbl ? sourceInfo.BytesPerCbl : sourceBytesRemaining, + constituentBlockHashes: blockHashesUsedThisSegment.ToArray(), + previous: cblIdx > 0 ? cblsEmitted[cblIdx - 1].Id : null, + next: null, + correlationId: null, + previousVersionHash: null); + + var cbl = new Models.Blocks.Chains.BrightChain( + blockParams: cblParams, + brightenedBlocks: brightenedBlocksThisSegment); + + // update the next pointer of the previous block + if (cblIdx > 0) { - segmentHasher.TransformBlock( - inputBuffer: brightenedBlock.Bytes.ToArray(), - inputOffset: 0, - inputCount: sourceInfo.BytesPerBlock, - outputBuffer: null, - outputOffset: 0); + cblsEmitted[cblIdx].Next = cbl.Id; } - } - } - if (brightenedBlocksConsumed != sourceInfo.TotalBlocksExpected) - { - throw new BrightChainException(nameof(brightenedBlocksConsumed)); - } + cblsEmitted[cblIdx++] = cbl; - return cblsEmitted; + segmentHasher.Initialize(); + blockHashesUsedThisSegment.Clear(); + brightenedBlocksThisSegment.Clear(); + blockCountThisSegment = 0; + sourceByteCountThisSegment = 0; + } + else + { + segmentHasher.TransformBlock( + inputBuffer: brightenedBlock.Bytes.ToArray(), + inputOffset: 0, + inputCount: sourceInfo.BytesPerBlock, + outputBuffer: null, + outputOffset: 0); + } + } } - public async Task MakeSuperCBLFromCBLChainAsync(BlockParams blockParams, IEnumerable chainedCbls, DataHash sourceId) + if (brightenedBlocksConsumed != sourceInfo.TotalBlocksExpected) { - var hashBytes = chainedCbls - .SelectMany(c => c.Id.HashBytes.ToArray()) - .ToArray(); + throw new BrightChainException(message: nameof(brightenedBlocksConsumed)); + } - var constituentHashes = chainedCbls.Select(c => c.Id); + return cblsEmitted; + } - var sCbl = new SuperConstituentBlockListBlock( - blockParams: new ConstituentBlockListBlockParams( - blockParams: new BrightenedBlockParams( - cacheManager: this.blockFasterCache, - allowCommit: true, - blockParams: blockParams), - sourceId: sourceId, - segmentId: new SegmentHash(hashBytes), - totalLength: hashBytes.Length, - constituentBlockHashes: constituentHashes, - previous: null, - next: null)); - - return new BrightChain( - blockParams: sCbl.BlockParams, - sourceCache: this.blockFasterCache); - } + public async Task MakeSuperCBLFromCBLChainAsync(BlockParams blockParams, + IEnumerable chainedCbls, DataHash sourceId) + { + var hashBytes = chainedCbls + .SelectMany(selector: c => c.Id.HashBytes.ToArray()) + .ToArray(); - public async Task MakeCblOrSuperCblFromFileAsync(string fileName, BlockParams blockParams) - { - var firstPass = await this.MakeCBLChainFromParamsAsync( + var constituentHashes = chainedCbls.Select(selector: c => c.Id); + + var sCbl = new SuperConstituentBlockListBlock( + blockParams: new ConstituentBlockListBlockParams( + blockParams: new BrightenedBlockParams( + cacheManager: this.blockFasterCache, + allowCommit: true, + blockParams: blockParams), + sourceId: sourceId, + segmentId: new SegmentHash(dataBytes: hashBytes), + totalLength: hashBytes.Length, + constituentBlockHashes: constituentHashes, + previous: null, + next: null)); + + return new Models.Blocks.Chains.BrightChain( + blockParams: sCbl.BlockParams, + sourceCache: this.blockFasterCache); + } + + public async Task MakeCblOrSuperCblFromFileAsync(string fileName, BlockParams blockParams) + { + var firstPass = await this.MakeCBLChainFromParamsAsync( fileName: fileName, blockParams: blockParams) - .ConfigureAwait(false); + .ConfigureAwait(continueOnCapturedContext: false); - var count = firstPass.Count(); + var count = firstPass.Count(); - if (count == 0) - { - throw new BrightChainException("No blocks returned"); - } + if (count == 0) + { + throw new BrightChainException(message: "No blocks returned"); + } - var loneCbl = firstPass.ElementAt(0); + var loneCbl = firstPass.ElementAt(index: 0); - if (count == 1) - { - return loneCbl; - } - else if (count > BlockSizeMap.HashesPerBlock(blockParams.BlockSize)) - { - throw new NotImplementedException("Uber-CBLs not yet implemented"); - } + if (count == 1) + { + return loneCbl; + } + + if (count > BlockSizeMap.HashesPerBlock(blockSize: blockParams.BlockSize)) + { + throw new NotImplementedException(message: "Uber-CBLs not yet implemented"); + } - // TODO: figure out where/when to commit the firstPass blocks + // TODO: figure out where/when to commit the firstPass blocks - return await - this.MakeSuperCBLFromCBLChainAsync( + return await + this.MakeSuperCBLFromCBLChainAsync( blockParams: blockParams, chainedCbls: firstPass, sourceId: loneCbl.SourceId) - .ConfigureAwait(false); - } + .ConfigureAwait(continueOnCapturedContext: false); + } - public static Dictionary GetCBLBlocksFromCacheAsDictionary(BrightenedBlockCacheManagerBase blockCacheManager, ConstituentBlockListBlock block) + public static Dictionary GetCBLBlocksFromCacheAsDictionary(BrightenedBlockCacheManagerBase blockCacheManager, + ConstituentBlockListBlock block) + { + var blocks = new Dictionary(); + foreach (var blockHash in block.ConstituentBlocks) { - Dictionary blocks = new Dictionary(); - foreach (var blockHash in block.ConstituentBlocks) - { - blocks.Add(blockHash, blockCacheManager.Get(blockHash)); - } - - return blocks; + blocks.Add(key: blockHash, + value: blockCacheManager.Get(blockHash: blockHash)); } - public async Task RestoreStreamFromCBLAsync(ConstituentBlockListBlock constituentBlockListBlock, Stream? destination = null) - { - if (destination is null) - { - destination = new MemoryStream(); - } - - if (constituentBlockListBlock.TotalLength > long.MaxValue) - { - throw new NotImplementedException(); - } + return blocks; + } - if (constituentBlockListBlock is SuperConstituentBlockListBlock superConstituentBlockListBlock) - { - throw new NotImplementedException(); - } + public async Task RestoreStreamFromCBLAsync(ConstituentBlockListBlock constituentBlockListBlock, Stream? destination = null) + { + if (destination is null) + { + destination = new MemoryStream(); + } - long bytesWritten = 0; - using (SHA256 sha = SHA256.Create()) - { - var iBlockSize = BlockSizeMap.BlockSize(constituentBlockListBlock.BlockSize); - StreamWriter streamWriter = new StreamWriter(destination); - var cacheManager = this.blockFasterCache.AsBlockCacheManager; - var blockMap = constituentBlockListBlock.CreateBrightMap(); - await foreach (Block block in blockMap.ConsolidateTuplesToChainAsync(cacheManager)) - { - var bytesLeft = constituentBlockListBlock.TotalLength - bytesWritten; - var lastBlock = bytesLeft <= iBlockSize; - var length = lastBlock ? bytesLeft : iBlockSize; - if (lastBlock) - { - sha.TransformFinalBlock(block.Bytes.ToArray(), 0, (int)length); - } - else - { - sha.TransformBlock(block.Bytes.ToArray(), 0, (int)length, null, 0); - } + if (constituentBlockListBlock.TotalLength > long.MaxValue) + { + throw new NotImplementedException(); + } - await destination.WriteAsync(buffer: block.Bytes.ToArray(), offset: 0, count: (int)length) - .ConfigureAwait(false); - bytesWritten += length; - } + if (constituentBlockListBlock is SuperConstituentBlockListBlock superConstituentBlockListBlock) + { + throw new NotImplementedException(); + } - if (bytesWritten == 0) + long bytesWritten = 0; + using (var sha = SHA256.Create()) + { + var iBlockSize = BlockSizeMap.BlockSize(blockSize: constituentBlockListBlock.BlockSize); + var streamWriter = new StreamWriter(stream: destination); + var cacheManager = this.blockFasterCache.AsBlockCacheManager; + var blockMap = constituentBlockListBlock.CreateBrightMap(); + await foreach (var block in blockMap.ConsolidateTuplesToChainAsync(blockCacheManager: cacheManager)) + { + var bytesLeft = constituentBlockListBlock.TotalLength - bytesWritten; + var lastBlock = bytesLeft <= iBlockSize; + var length = lastBlock ? bytesLeft : iBlockSize; + if (lastBlock) { - throw new BrightChainException(nameof(bytesWritten)); + sha.TransformFinalBlock(inputBuffer: block.Bytes.ToArray(), + inputOffset: 0, + inputCount: (int)length); } - - var finalHash = new DataHash( - providedHashBytes: sha.Hash, - sourceDataLength: bytesWritten, - computed: true); - - if (!finalHash.Equals(constituentBlockListBlock.SourceId)) + else { - throw new BrightChainException(nameof(finalHash)); + sha.TransformBlock(inputBuffer: block.Bytes.ToArray(), + inputOffset: 0, + inputCount: (int)length, + outputBuffer: null, + outputOffset: 0); } - await destination - .FlushAsync() - .ConfigureAwait(false); - - destination.Seek(0, SeekOrigin.Begin); - - return destination; + await destination.WriteAsync(buffer: block.Bytes.ToArray(), + offset: 0, + count: (int)length) + .ConfigureAwait(continueOnCapturedContext: false); + bytesWritten += length; } - } - /// - /// Given a CBL Block, produce a temporary file on disk containing the reconstitued bytes. - /// - /// The CBL Block containing the list/order of blocks needed to rebuild the file. - /// Returns a Restored file object containing the path and hash for the resulting file as written, for verification. - public async Task RestoreFileFromCBLAsync(ConstituentBlockListBlock constituentBlockListBlock) - { - if (constituentBlockListBlock.TotalLength > long.MaxValue) + if (bytesWritten == 0) { - throw new NotImplementedException(); + throw new BrightChainException(message: nameof(bytesWritten)); } - if (constituentBlockListBlock is SuperConstituentBlockListBlock superConstituentBlockListBlock) + var finalHash = new DataHash( + providedHashBytes: sha.Hash, + sourceDataLength: bytesWritten, + computed: true); + + if (!finalHash.Equals(other: constituentBlockListBlock.SourceId)) { - throw new NotImplementedException(); + throw new BrightChainException(message: nameof(finalHash)); } - string tempFilename = Path.GetTempFileName(); - - using (Stream destination = File.OpenWrite(tempFilename)) - { - using (await this - .RestoreStreamFromCBLAsync(constituentBlockListBlock, destination) - .ConfigureAwait(false)) - { - destination.Close(); - destination.Dispose(); - } + await destination + .FlushAsync() + .ConfigureAwait(continueOnCapturedContext: false); - var restoredSourceInfo = new SourceFileInfo( - fileName: tempFilename, - blockSize: constituentBlockListBlock.BlockSize); + destination.Seek(offset: 0, + origin: SeekOrigin.Begin); - if (restoredSourceInfo.FileInfo.Length != constituentBlockListBlock.TotalLength) - { - throw new BrightChainException(nameof(restoredSourceInfo.FileInfo.Length)); - } - - if (!restoredSourceInfo.SourceId.Equals(constituentBlockListBlock.SourceId)) - { - throw new BrightChainException(nameof(restoredSourceInfo.SourceId)); - } - - return restoredSourceInfo; - } + return destination; } + } - public async Task FindBlockByIdAsync(BlockHash id) + /// + /// Given a CBL Block, produce a temporary file on disk containing the reconstitued bytes. + /// + /// The CBL Block containing the list/order of blocks needed to rebuild the file. + /// Returns a Restored file object containing the path and hash for the resulting file as written, for verification. + public async Task RestoreFileFromCBLAsync(ConstituentBlockListBlock constituentBlockListBlock) + { + if (constituentBlockListBlock.TotalLength > long.MaxValue) { - if (this.blockFasterCache.Contains(id)) - { - return this.blockFasterCache.Get(id); - } - - // TODO: look to other nodes - throw new KeyNotFoundException(id.ToString()); + throw new NotImplementedException(); } - public async IAsyncEnumerable FindBlocksByIdAsync(IAsyncEnumerable blockIdSource) + if (constituentBlockListBlock is SuperConstituentBlockListBlock superConstituentBlockListBlock) { - await foreach (var id in blockIdSource) - { - var block = await this.FindBlockByIdAsync(id) - .ConfigureAwait(false); - - if (block is Block && block.Validate()) - { - yield return block; - } - } + throw new NotImplementedException(); } - public async Task FindBlockByIdAsync(BlockHash id, bool useAsBlock) - where T : class + var tempFilename = Path.GetTempFileName(); + + using (Stream destination = File.OpenWrite(path: tempFilename)) { - var retrievedBlock = await this.FindBlockByIdAsync(id) - .ConfigureAwait(false); - var block = useAsBlock ? retrievedBlock.AsBlock as T : retrievedBlock as T; - if (block is null) + using (await this + .RestoreStreamFromCBLAsync(constituentBlockListBlock: constituentBlockListBlock, + destination: destination) + .ConfigureAwait(continueOnCapturedContext: false)) { - throw new BrightChainException("Unable to cast from unrelated type"); + destination.Close(); + destination.Dispose(); } - return block; - } + var restoredSourceInfo = new SourceFileInfo( + fileName: tempFilename, + blockSize: constituentBlockListBlock.BlockSize); - public async Task DropBlockByIdAsync(BlockHash id, RevocationCertificate? ownershipToken = null) - { - var block = await this.FindBlockByIdAsync(id: id) - .ConfigureAwait(false); - - // verify pernmission/ownership/date, etc - // can't drop unless expired or invalid - if (block is Block && true) + if (restoredSourceInfo.FileInfo.Length != constituentBlockListBlock.TotalLength) { - throw new BrightChainException("Permission denied!"); + throw new BrightChainException(message: nameof(restoredSourceInfo.FileInfo.Length)); } - if (this.blockFasterCache.Contains(id)) + if (!restoredSourceInfo.SourceId.Equals(other: constituentBlockListBlock.SourceId)) { - this.blockFasterCache.Drop(id); + throw new BrightChainException(message: nameof(restoredSourceInfo.SourceId)); } - // TODO: broadcast - return block; + return restoredSourceInfo; } + } - public async IAsyncEnumerable<(BlockHash, Block)> DropBlocksByIdAsync(IAsyncEnumerable idSource, RevocationCertificate? ownershipToken = null) + public async Task FindBlockByIdAsync(BlockHash id) + { + if (this.blockFasterCache.Contains(key: id)) { - await foreach (var id in idSource) - { - var dropped = await this.DropBlockByIdAsync(id, ownershipToken) - .ConfigureAwait(false); - - yield return (id, dropped); - } + return this.blockFasterCache.Get(blockHash: id); } - public async Task StoreBlockAsync(BrightenedBlock block) + // TODO: look to other nodes + throw new KeyNotFoundException(message: id.ToString()); + } + + public async IAsyncEnumerable FindBlocksByIdAsync(IAsyncEnumerable blockIdSource) + { + await foreach (var id in blockIdSource) { - if (!block.Validate()) + var block = await this.FindBlockByIdAsync(id: id) + .ConfigureAwait(continueOnCapturedContext: false); + + if (block is Block && block.Validate()) { - throw new BrightChainValidationEnumerableException( - exceptions: block.ValidationExceptions, - message: "Can not store invalid block"); + yield return block; } - - this.blockFasterCache.Set(block); - - return block; } + } - public async IAsyncEnumerable<(Block, IEnumerable)> StoreBlocksAsync(IAsyncEnumerable blockSource) + public async Task FindBlockByIdAsync(BlockHash id, bool useAsBlock) + where T : class + { + var retrievedBlock = await this.FindBlockByIdAsync(id: id) + .ConfigureAwait(continueOnCapturedContext: false); + var block = useAsBlock ? retrievedBlock.AsBlock as T : retrievedBlock as T; + if (block is null) { - await foreach (var block in blockSource) - { - (Block, IEnumerable) response; - try - { - var storedBlock = await this.StoreBlockAsync(block) - .ConfigureAwait(false); - - response = (block, new BrightChainValidationException[] { }); - } - catch (BrightChainValidationEnumerableException brightChainValidation) - { - response = (block, brightChainValidation.Exceptions); - } - - yield return response; - } + throw new BrightChainException(message: "Unable to cast from unrelated type"); } - public async IAsyncEnumerable BrightenBlocksAsyncEnumerable(IAsyncEnumerable identifiableBlocks) - { - await foreach (var identifiableBlock in identifiableBlocks) - { - var brightenedBlock = this.blockBrightener.Brighten( - identifiableBlock: identifiableBlock, - randomizersUsed: out _, - brightenedStripe: out _); + return block; + } - brightenedBlock.MakeTransactable( - cacheManager: this.blockFasterCache, - allowCommit: true); + public async Task DropBlockByIdAsync(BlockHash id, RevocationCertificate? ownershipToken = null) + { + var block = await this.FindBlockByIdAsync(id: id) + .ConfigureAwait(continueOnCapturedContext: false); - yield return brightenedBlock; - } + // verify pernmission/ownership/date, etc + // can't drop unless expired or invalid + if (block is Block && true) + { + throw new BrightChainException(message: "Permission denied!"); } - /// - /// Given a collection of brightened blocks either as part of a file or ChainLinq, assemble them into a CBL. - /// - /// - /// - public async Task ForgeChainAsync(DataHash sourceId, IAsyncEnumerable brightenedBlocks) + if (this.blockFasterCache.Contains(key: id)) { - var hashes = new List(); - var awaitedBlocks = new List(); + this.blockFasterCache.Drop(key: id); + } - await foreach (var block in brightenedBlocks) - { - hashes.Add(block.Id); - awaitedBlocks.Add(block); - } + // TODO: broadcast + return block; + } - var segmentBytes = hashes.SelectMany(h => h.HashBytes.ToArray()).ToArray(); - - var firstBlock = awaitedBlocks.First(); - - return new BrightChain( - blockParams: new ConstituentBlockListBlockParams( - blockParams: new BrightenedBlockParams( - cacheManager: this.blockFasterCache, - allowCommit: true, - blockParams: firstBlock.BlockParams), - sourceId: sourceId, - segmentId: new SegmentHash( - dataBytes: new ReadOnlyMemory(segmentBytes)), - totalLength: BlockSizeMap.BlockSize(firstBlock.BlockSize) * awaitedBlocks.Count, - constituentBlockHashes: hashes, - previous: null, - next: null, - correlationId: null, - previousVersionHash: null), - brightenedBlocks: awaitedBlocks); + public async IAsyncEnumerable<(BlockHash, Block)> DropBlocksByIdAsync(IAsyncEnumerable idSource, + RevocationCertificate? ownershipToken = null) + { + await foreach (var id in idSource) + { + var dropped = await this.DropBlockByIdAsync(id: id, + ownershipToken: ownershipToken) + .ConfigureAwait(continueOnCapturedContext: false); + + yield return (id, dropped); } + } - public BrightHandle CblToBrightHandle(ConstituentBlockListBlock cblBlock, BrightenedBlock brightenedCbl, TupleStripe cblStripe) + public async Task StoreBlockAsync(BrightenedBlock block) + { + if (!block.Validate()) { - return new BrightHandle( - blockSize: brightenedCbl.BlockSize, - blockHashes: cblStripe.Blocks - .Select(b => b.Id) - .ToArray(), - originalType: cblStripe.OriginalType, - brightenedCblHash: brightenedCbl.Id, - identifiableSourceHash: cblBlock.SourceId); + throw new BrightChainValidationEnumerableException( + exceptions: block.ValidationExceptions, + message: "Can not store invalid block"); } - public BrightHandle BrightenCbl(ConstituentBlockListBlock cblBlock, bool persist, out BrightenedBlock brightenedCbl) + this.blockFasterCache.Set(block: block); + + return block; + } + + public async IAsyncEnumerable<(Block, IEnumerable)> StoreBlocksAsync( + IAsyncEnumerable blockSource) + { + await foreach (var block in blockSource) { - // TODO: update indices - // TODO: CBLs may be a server option to disable - // CBL should itself be brightened before entering the cache! - brightenedCbl = this.blockBrightener.Brighten( - identifiableBlock: cblBlock, - randomizersUsed: out _, - brightenedStripe: out TupleStripe cblStripe); - - var handle = new BrightHandle( - blockSize: cblBlock.BlockSize, - blockHashes: cblStripe.Blocks - .Select(b => b.Id) - .ToArray(), - originalType: cblStripe.OriginalType, - brightenedCblHash: brightenedCbl.Id, - identifiableSourceHash: cblBlock.SourceId); - - if (persist) + (Block, IEnumerable) response; + try { - this.blockFasterCache.Set(brightenedCbl); - this.blockFasterCache.SetCbl( - brightenedCblHash: brightenedCbl.Id, - identifiableSourceHash: cblBlock.SourceId, - brightHandle: handle); + var storedBlock = await this.StoreBlockAsync(block: block) + .ConfigureAwait(continueOnCapturedContext: false); + + response = (block, new BrightChainValidationException[] { }); + } + catch (BrightChainValidationEnumerableException brightChainValidation) + { + response = (block, brightChainValidation.Exceptions); } - return handle; + yield return response; } + } - public BrightHandle FindSourceById(DataHash requestedHash) + public async IAsyncEnumerable BrightenBlocksAsyncEnumerable(IAsyncEnumerable identifiableBlocks) + { + await foreach (var identifiableBlock in identifiableBlocks) { - return this.blockFasterCache.GetCbl(requestedHash); - } + var brightenedBlock = this.blockBrightener.Brighten( + identifiableBlock: identifiableBlock, + randomizersUsed: out _, + brightenedStripe: out _); - public TupleStripe BrightHandleToTupleStripe(BrightHandle brightHandle) - { - return new TupleStripe( - tupleCountMatch: brightHandle.BlockHashByteArrays.Count(), - blockSizeMatch: brightHandle.BlockSize, - originalType: brightHandle.OriginalType, - brightenedBlocks: this.blockFasterCache.Get(brightHandle.BlockHashes)); + brightenedBlock.MakeTransactable( + cacheManager: this.blockFasterCache, + allowCommit: true); + + yield return brightenedBlock; } + } + + /// + /// Given a collection of brightened blocks either as part of a file or ChainLinq, assemble them into a CBL. + /// + /// + /// + public async Task ForgeChainAsync(DataHash sourceId, + IAsyncEnumerable brightenedBlocks) + { + var hashes = new List(); + var awaitedBlocks = new List(); - public IdentifiableBlock BrightHandleToIdentifiableBlock(BrightHandle brightHandle) + await foreach (var block in brightenedBlocks) { - return this.BrightHandleToTupleStripe(brightHandle) - .Consolidate(); + hashes.Add(item: block.Id); + awaitedBlocks.Add(item: block); } - public void Dispose() + var segmentBytes = hashes.SelectMany(selector: h => h.HashBytes.ToArray()).ToArray(); + + var firstBlock = awaitedBlocks.First(); + + return new Models.Blocks.Chains.BrightChain( + blockParams: new ConstituentBlockListBlockParams( + blockParams: new BrightenedBlockParams( + cacheManager: this.blockFasterCache, + allowCommit: true, + blockParams: firstBlock.BlockParams), + sourceId: sourceId, + segmentId: new SegmentHash( + dataBytes: new ReadOnlyMemory(array: segmentBytes)), + totalLength: BlockSizeMap.BlockSize(blockSize: firstBlock.BlockSize) * awaitedBlocks.Count, + constituentBlockHashes: hashes, + previous: null, + next: null, + correlationId: null, + previousVersionHash: null), + brightenedBlocks: awaitedBlocks); + } + + public BrightHandle CblToBrightHandle(ConstituentBlockListBlock cblBlock, BrightenedBlock brightenedCbl, TupleStripe cblStripe) + { + return new BrightHandle( + blockSize: brightenedCbl.BlockSize, + blockHashes: cblStripe.Blocks + .Select(selector: b => b.Id) + .ToArray(), + originalType: cblStripe.OriginalType, + brightenedCblHash: brightenedCbl.Id, + identifiableSourceHash: cblBlock.SourceId); + } + + public BrightHandle BrightenCbl(ConstituentBlockListBlock cblBlock, bool persist, out BrightenedBlock brightenedCbl) + { + // TODO: update indices + // TODO: CBLs may be a server option to disable + // CBL should itself be brightened before entering the cache! + brightenedCbl = this.blockBrightener.Brighten( + identifiableBlock: cblBlock, + randomizersUsed: out _, + brightenedStripe: out var cblStripe); + + var handle = new BrightHandle( + blockSize: cblBlock.BlockSize, + blockHashes: cblStripe.Blocks + .Select(selector: b => b.Id) + .ToArray(), + originalType: cblStripe.OriginalType, + brightenedCblHash: brightenedCbl.Id, + identifiableSourceHash: cblBlock.SourceId); + + if (persist) { - throw new NotImplementedException(); + this.blockFasterCache.Set(block: brightenedCbl); + this.blockFasterCache.SetCbl( + brightenedCblHash: brightenedCbl.Id, + identifiableSourceHash: cblBlock.SourceId, + brightHandle: handle); } + + return handle; + } + + public BrightHandle FindSourceById(DataHash requestedHash) + { + return this.blockFasterCache.GetCbl(sourceHash: requestedHash); + } + + public TupleStripe BrightHandleToTupleStripe(BrightHandle brightHandle) + { + return new TupleStripe( + tupleCountMatch: brightHandle.BlockHashByteArrays.Count(), + blockSizeMatch: brightHandle.BlockSize, + originalType: brightHandle.OriginalType, + brightenedBlocks: this.blockFasterCache.Get(keys: brightHandle.BlockHashes)); + } + + public IdentifiableBlock BrightHandleToIdentifiableBlock(BrightHandle brightHandle) + { + return this.BrightHandleToTupleStripe(brightHandle: brightHandle) + .Consolidate(); } } diff --git a/src/BrightChain.Engine/Services/BrightChainKeyService.cs b/src/BrightChain.Engine/Services/BrightChainKeyService.cs old mode 100644 new mode 100755 index 1c17cb03..57b39d72 --- a/src/BrightChain.Engine/Services/BrightChainKeyService.cs +++ b/src/BrightChain.Engine/Services/BrightChainKeyService.cs @@ -1,121 +1,111 @@ -namespace BrightChain.Engine.Services +using System; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Cryptography; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.IdentityModel.Tokens; +using Org.BouncyCastle.Asn1.Sec; +using Org.BouncyCastle.Math; + +namespace BrightChain.Engine.Services; + +/// +/// Loads keys from blocks, stores keys to blocks. +/// +public static class BrightChainKeyService { - using System; - using System.IdentityModel.Tokens.Jwt; - using System.Linq; - using System.Security.Cryptography; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.IdentityModel.Tokens; - using Org.BouncyCastle.Asn1.Sec; - - /// - /// Loads keys from blocks, stores keys to blocks. - /// - public static class BrightChainKeyService + public const string CurveKeyName = "secp256r1"; + public const string Issuer = "BrightChain"; + + public static ECDsa LoadPrivateKeyFromBlock(BrightenedBlockCacheManagerBase blockCacheManager, BlockHash id) { - public const string CurveKeyName = "secp256r1"; - public const string Issuer = "BrightChain"; + var brightChainKeyBlock = blockCacheManager.Get(blockHash: id); + // get data from block + throw new NotImplementedException(); + } - public static ECDsa LoadPrivateKeyFromBlock(BrightenedBlockCacheManagerBase blockCacheManager, BlockHash id) - { - var brightChainKeyBlock = blockCacheManager.Get(id); - // get data from block - throw new NotImplementedException(); - } + public static ECDsa LoadPrivateKey(string hexKeyString) + { + return LoadPrivateKey(key: FromHexString(hex: hexKeyString)); + } - public static ECDsa LoadPrivateKey(string hexKeyString) + public static ECDsa LoadPrivateKey(byte[] key) + { + var privKeyInt = new BigInteger(sign: +1, + bytes: key); + var parameters = SecNamedCurves.GetByName(name: CurveKeyName); + var ecPoint = parameters.G.Multiply(b: privKeyInt); + var privKeyX = ecPoint.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned(); + var privKeyY = ecPoint.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned(); + + return ECDsa.Create(parameters: new ECParameters { - return LoadPrivateKey(FromHexString(hexKeyString)); - } + Curve = ECCurve.NamedCurves.nistP256, D = privKeyInt.ToByteArrayUnsigned(), Q = new ECPoint {X = privKeyX, Y = privKeyY}, + }); + } - public static ECDsa LoadPrivateKey(byte[] key) - { - var privKeyInt = new Org.BouncyCastle.Math.BigInteger(+1, key); - var parameters = SecNamedCurves.GetByName(CurveKeyName); - var ecPoint = parameters.G.Multiply(privKeyInt); - var privKeyX = ecPoint.Normalize().XCoord.ToBigInteger().ToByteArrayUnsigned(); - var privKeyY = ecPoint.Normalize().YCoord.ToBigInteger().ToByteArrayUnsigned(); + public static ECDsa LoadPublicKey(string hexKeyString) + { + return LoadPublicKey(key: FromHexString(hex: hexKeyString)); + } - return ECDsa.Create(new ECParameters - { - Curve = ECCurve.NamedCurves.nistP256, - D = privKeyInt.ToByteArrayUnsigned(), - Q = new ECPoint - { - X = privKeyX, - Y = privKeyY, - }, - }); - } + public static ECDsa LoadPublicKey(byte[] key) + { + var pubKeyX = key.Skip(count: 1).Take(count: 32).ToArray(); + var pubKeyY = key.Skip(count: 33).ToArray(); - public static ECDsa LoadPublicKey(string hexKeyString) + return ECDsa.Create(parameters: new ECParameters { - return LoadPublicKey(FromHexString(hexKeyString)); - } + Curve = ECCurve.NamedCurves.nistP256, Q = new ECPoint {X = pubKeyX, Y = pubKeyY}, + }); + } - public static ECDsa LoadPublicKey(byte[] key) - { - var pubKeyX = key.Skip(1).Take(32).ToArray(); - var pubKeyY = key.Skip(33).ToArray(); + public static string CreateSignedJwt(ECDsa eCDsa, string audience) + { + var now = DateTime.UtcNow; + var tokenHandler = new JwtSecurityTokenHandler(); + + var jwtToken = tokenHandler.CreateJwtSecurityToken( + issuer: Issuer, + audience: audience, + subject: null, + notBefore: now, + expires: now.AddMinutes(value: 30), + issuedAt: now, + signingCredentials: new SigningCredentials( + key: new ECDsaSecurityKey(ecdsa: eCDsa), + algorithm: SecurityAlgorithms.EcdsaSha256)); + + return tokenHandler.WriteToken(token: jwtToken); + } - return ECDsa.Create(new ECParameters + public static bool VerifySignedJwt(ECDsa eCDsa, string token, string audience) + { + var tokenHandler = new JwtSecurityTokenHandler(); + + var claimsPrincipal = tokenHandler.ValidateToken( + token: token, + validationParameters: new TokenValidationParameters { - Curve = ECCurve.NamedCurves.nistP256, - Q = new ECPoint - { - X = pubKeyX, - Y = pubKeyY, - }, - }); - } + ValidIssuer = Issuer, ValidAudience = audience, IssuerSigningKey = new ECDsaSecurityKey(ecdsa: eCDsa), + }, + validatedToken: out var parsedToken); - public static string CreateSignedJwt(ECDsa eCDsa, string audience) - { - var now = DateTime.UtcNow; - var tokenHandler = new JwtSecurityTokenHandler(); - - var jwtToken = tokenHandler.CreateJwtSecurityToken( - issuer: Issuer, - audience: audience, - subject: null, - notBefore: now, - expires: now.AddMinutes(30), - issuedAt: now, - signingCredentials: new SigningCredentials( - key: new ECDsaSecurityKey(eCDsa), - algorithm: SecurityAlgorithms.EcdsaSha256)); - - return tokenHandler.WriteToken(jwtToken); - } + return claimsPrincipal.Identity.IsAuthenticated; + } - public static bool VerifySignedJwt(ECDsa eCDsa, string token, string audience) + private static byte[] FromHexString(string hex) + { + var numberChars = hex.Length; + var hexAsBytes = new byte[numberChars / 2]; + for (var i = 0; i < numberChars; i += 2) { - var tokenHandler = new JwtSecurityTokenHandler(); - - var claimsPrincipal = tokenHandler.ValidateToken( - token: token, - validationParameters: new TokenValidationParameters - { - ValidIssuer = Issuer, - ValidAudience = audience, - IssuerSigningKey = new ECDsaSecurityKey(eCDsa), - }, - validatedToken: out var parsedToken); - - return claimsPrincipal.Identity.IsAuthenticated; + hexAsBytes[i / 2] = Convert.ToByte(value: hex.Substring(startIndex: i, + length: 2), + fromBase: 16); } - private static byte[] FromHexString(string hex) - { - var numberChars = hex.Length; - var hexAsBytes = new byte[numberChars / 2]; - for (var i = 0; i < numberChars; i += 2) - { - hexAsBytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); - } - - return hexAsBytes; - } + return hexAsBytes; } } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CBLIndex.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CBLIndex.cs old mode 100644 new mode 100755 index d025656d..5a9a68f4 --- a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CBLIndex.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CBLIndex.cs @@ -1,34 +1,34 @@ -namespace BrightChain.Engine.Services.CacheManagers.Block -{ - using System; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; +using System; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using NeuralFabric.Models.Hashes; - /// - /// Block Cache Manager. - /// - public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager - { - public abstract BrightHandle GetCbl(DataHash sourceHash); +namespace BrightChain.Engine.Services.CacheManagers.Block; - public abstract void SetCbl(BlockHash cblHash, DataHash dataHash, BrightHandle brightHandle); +/// +/// Block Cache Manager. +/// +public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager +{ + public abstract BrightHandle GetCbl(DataHash sourceHash); - public virtual void UpdateCblVersion(ConstituentBlockListBlock newCbl, ConstituentBlockListBlock oldCbl = null) - { - if (oldCbl is not null && oldCbl.CorrelationId != newCbl.CorrelationId) - { - throw new BrightChainException(nameof(newCbl.CorrelationId)); - } + public abstract void SetCbl(BlockHash cblHash, DataHash dataHash, BrightHandle brightHandle); - if (oldCbl is not null && newCbl.StorageContract.RequestTime.CompareTo(oldCbl.StorageContract.RequestTime) < 0) - { - throw new BrightChainException("New CBL must be newer than old CBL"); - } + public virtual void UpdateCblVersion(ConstituentBlockListBlock newCbl, ConstituentBlockListBlock oldCbl = null) + { + if (oldCbl is not null && oldCbl.CorrelationId != newCbl.CorrelationId) + { + throw new BrightChainException(message: nameof(newCbl.CorrelationId)); } - public abstract BrightHandle GetCbl(Guid correlationID); + if (oldCbl is not null && newCbl.StorageContract.RequestTime.CompareTo(value: oldCbl.StorageContract.RequestTime) < 0) + { + throw new BrightChainException(message: "New CBL must be newer than old CBL"); + } } + + public abstract BrightHandle GetCbl(Guid correlationID); } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CoreFunctions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CoreFunctions.cs old mode 100644 new mode 100755 index 1e292ab5..497e54bd --- a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CoreFunctions.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.CoreFunctions.cs @@ -1,231 +1,204 @@ -namespace BrightChain.Engine.Services.CacheManagers.Block +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Models.Nodes; + +namespace BrightChain.Engine.Services.CacheManagers.Block; + +/// +/// Block Cache Manager. +/// +public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager { - using System; - using System.Collections.Generic; - using System.Linq; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Models.Nodes; + /// + /// Returns whether the cache manager has the given key and it is not expired + /// + /// key to check the collection for + /// boolean with whether key is present + public abstract bool Contains(BlockHash key); /// - /// Block Cache Manager. + /// Removes a key from the cache and returns a boolean wither whether it was actually present. /// - public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager + /// Key to drop from the collection. + /// Skips the contains check for performance. + /// Whether requested key was present and actually dropped. + public virtual bool Drop(BlockHash key, bool noCheckContains = true) { - /// - /// Returns whether the cache manager has the given key and it is not expired - /// - /// key to check the collection for - /// boolean with whether key is present - public abstract bool Contains(BlockHash key); - - /// - /// Removes a key from the cache and returns a boolean wither whether it was actually present. - /// - /// Key to drop from the collection. - /// Skips the contains check for performance. - /// Whether requested key was present and actually dropped. - public virtual bool Drop(BlockHash key, bool noCheckContains = true) + if (this.ActiveTransaction is null) { - if (!noCheckContains && !this.Contains(key)) - { - return false; - } + throw new BrightChainException(message: "Must be in transaction"); + } - return true; + if (!noCheckContains && !this.Contains(key: key)) + { + return false; } - /// - /// Retrieves a block from the cache if it is present. - /// - /// key to retrieve. - /// returns requested block or throws. - public abstract BrightenedBlock Get(BlockHash blockHash); + this.ActiveTransaction.DropTransactionBlock(blockHash: key); + + return true; + } - private void AddUpdateMemoryBlock(BrightenedBlock block) + /// + /// Retrieves a block from the cache if it is present. + /// + /// key to retrieve. + /// returns requested block or throws. + public abstract BrightenedBlock Get(BlockHash blockHash); + + /// + /// Adds a key to the cache if it is not already present. + /// + /// block to palce in the cache. + /// whether to allow duplicate and update the block metadata. + public virtual void Set(BrightenedBlock value, bool updateMetadataOnly = false) + { + if (this.ActiveTransaction is null) { - var memoryHit = this.UncomittedBlocksByHash.ContainsKey(block.Id); - var oldBlock = memoryHit ? this.UncomittedBlocksByHash[block.Id] : null; - this.UncomittedBlocksByHash[block.Id] = block; - this.UncommittedHashesByStatus[block.State].Add(block.Id); - - if (!memoryHit) - { - return; - } - - var memoryHashesByStatusList = this.UncommittedHashesByStatus[oldBlock!.State]; - if (memoryHashesByStatusList.Contains(block.Id)) - { - memoryHashesByStatusList.Remove(block.Id); - } + throw new BrightChainException(message: "Must be in transaction"); } - private BrightenedBlock CacheFetchToMemory(BlockHash blockHash) + if (value is null) { - var cacheHit = this.Contains(key: blockHash); - if (!cacheHit) - { - throw new BrightChainException(message: "Cache Miss"); - } - - var cacheBlock = this.Get(blockHash: blockHash); - this.AddUpdateMemoryBlock(block: cacheBlock); + throw new BrightChainException(message: "Can not store null block"); + } - return cacheBlock; + if (!value.Validate()) + { + throw new BrightChainValidationEnumerableException( + exceptions: value.ValidationExceptions, + message: "Can not store invalid block"); } - public virtual IEnumerable Get(IEnumerable keys) + if (this.Contains(key: value.Id) && !updateMetadataOnly) { - var blocks = new List(); - foreach (var key in keys) - { - BrightenedBlock blockData; - if (this.UncomittedBlocksByHash.ContainsKey(key)) - { - blockData = this.UncomittedBlocksByHash[key]; - this.UncommittedHashesByStatus[blockData.State].Add(key); - } - else - { - blockData = this.Get(blockHash: key); - } - - blocks.Add(blockData); - } - - return blocks; + throw new BrightChainException(message: "Key already exists in fasterkv"); } - public virtual async IAsyncEnumerable Get(IAsyncEnumerable keys) + this.ActiveTransaction.AddUpdateMemoryBlock(block: value); + } + + public virtual void Set(BlockHash key, BrightenedBlock value) + { + if (this.ActiveTransaction is null) { - await foreach (var key in keys) - { - yield return this.Get(key); - } + throw new BrightChainException(message: "Must be in transaction"); } - /// - /// Adds a key to the cache if it is not already present. - /// - /// block to palce in the cache. - /// whether to allow duplicate and update the block metadata. - public virtual void Set(BrightenedBlock value, bool updateMetadataOnly = false) + if (value.Id != key) { - if (value is null) - { - throw new BrightChainException("Can not store null block"); - } - - if (!value.Validate()) - { - throw new BrightChainValidationEnumerableException( - value.ValidationExceptions, - "Can not store invalid block"); - } - - if (this.Contains(value.Id) && !updateMetadataOnly) - { - throw new BrightChainException("Key already exists in fasterkv"); - } - - if (this.UncomittedBlocksByHash.ContainsKey(value.Id) && !updateMetadataOnly) - { - throw new BrightChainException("Key already exists uncommitted blocks"); - } - - AddUpdateMemoryBlock(block: value); - - // TODO: place into transaction + throw new BrightChainException(message: "Can not store transactable block with different key"); } - public void ExtendStorage(BrightenedBlock block, DateTime keepUntilAtLeast, RedundancyContractType redundancy = RedundancyContractType.Unknown) + this.Set( + value: value, + updateMetadataOnly: false); + } + + public virtual void SetAll(IEnumerable items) + { + foreach (var item in items) { - // duplicate block with extended attributes - var newBlock = new BrightenedBlock( - blockParams: new BrightenedBlockParams( - cacheManager: block.CacheManager, - allowCommit: block.AllowCommit, - blockParams: new BlockParams( - blockSize: block.BlockSize, - requestTime: block.StorageContract.RequestTime, - keepUntilAtLeast: keepUntilAtLeast, - redundancy: redundancy == RedundancyContractType.Unknown ? block.StorageContract.RedundancyContractType : redundancy, - privateEncrypted: block.StorageContract.PrivateEncrypted, - originalType: block.OriginalType)), - data: block.Bytes, - constituentBlockHashes: block.ConstituentBlocks); - - this.RemoveExpiration(block); - this.AddExpiration(newBlock); this.Set( - value: block, + value: item, updateMetadataOnly: false); } + } - public virtual void Set(BlockHash key, BrightenedBlock value) + public virtual async void SetAllAsync(IAsyncEnumerable items) + { + await foreach (var item in items) { - if (value.Id != key) - { - throw new BrightChainException("Can not store transactable block with different key"); - } - this.Set( - value: value, + value: item, updateMetadataOnly: false); } + } - public virtual void SetAll(IEnumerable items) + /// + /// Add a node that the cache manager should trust. + /// + /// Node submitting the block to the cache. + public void Trust(BrightChainNode node) + { + this.trustedNodes.Add(item: node); + } + + public virtual IEnumerable Get(IEnumerable keys) + { + if (this.ActiveTransaction is null) { - foreach (var item in items) - { - this.Set( - value: item, - updateMetadataOnly: false); - } + throw new BrightChainException(message: "Must be in transaction"); } - public async virtual void SetAllAsync(IAsyncEnumerable items) + var blocks = new List(); + foreach (var key in keys) { - await foreach (var item in items) - { - this.Set( - value: item, - updateMetadataOnly: false); - } + var blockData = this.Get(blockHash: key); + this.ActiveTransaction.AddUpdateMemoryBlock(block: blockData); + blocks.Add(item: blockData); } - /// - /// Add a node that the cache manager should trust. - /// - /// Node submitting the block to the cache. - public void Trust(BrightChainNode node) + return blocks; + } + + public virtual async IAsyncEnumerable Get(IAsyncEnumerable keys) + { + if (this.ActiveTransaction is null) { - this.trustedNodes.Add(node); + throw new BrightChainException(message: "Must be in transaction"); } - /// - /// Returns the maximum number of bytes storable for a given block size. - /// - /// - /// - public static long MaximumStorageLength(BlockSize blockSize) + await foreach (var key in keys) { - var iBlockSize = BlockSizeMap.BlockSize(blockSize); - var hashesPerBlockSquared = BlockSizeMap.HashesPerBlock(blockSize, 2); - - // right now, we can contain 1 SuperCBL with hashesPerSegment blocks, and up to hashesPerSegment blocks there. - // this means total size is hashes^2*size - return hashesPerBlockSquared * iBlockSize; + yield return this.Get(blockHash: key); } + } + + public void ExtendStorage(BrightenedBlock block, DateTime keepUntilAtLeast, + RedundancyContractType redundancy = RedundancyContractType.Unknown) + { + // duplicate block with extended attributes + var newBlock = new BrightenedBlock( + blockParams: new BrightenedBlockParams( + cacheManager: block.CacheManager, + allowCommit: block.AllowCommit, + blockParams: new BlockParams( + blockSize: block.BlockSize, + requestTime: block.StorageContract.RequestTime, + keepUntilAtLeast: keepUntilAtLeast, + redundancy: redundancy == RedundancyContractType.Unknown ? block.StorageContract.RedundancyContractType : redundancy, + privateEncrypted: block.StorageContract.PrivateEncrypted, + originalType: block.OriginalType)), + data: block.Bytes, + constituentBlockHashes: block.ConstituentBlocks); + + this.RemoveExpiration(block: block); + this.AddExpiration(block: newBlock); + this.Set( + value: block, + updateMetadataOnly: false); + } - public IEnumerable UncommittedBlocksByStatus(TransactionStatus transactionStatus) => - this.Get(keys: this.UncommittedHashesByStatus[transactionStatus].ToArray()); + /// + /// Returns the maximum number of bytes storable for a given block size. + /// + /// + /// + public static long MaximumStorageLength(BlockSize blockSize) + { + var iBlockSize = BlockSizeMap.BlockSize(blockSize: blockSize); + var hashesPerBlockSquared = BlockSizeMap.HashesPerBlock(blockSize: blockSize, + exponent: 2); - public IEnumerable UncommittedBlocks => this.UncomittedBlocksByHash.Values; + // right now, we can contain 1 SuperCBL with hashesPerSegment blocks, and up to hashesPerSegment blocks there. + // this means total size is hashes^2*size + return hashesPerBlockSquared * iBlockSize; } } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Events.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Events.cs old mode 100644 new mode 100755 index c472ab0c..538eb855 --- a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Events.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Events.cs @@ -1,32 +1,31 @@ -namespace BrightChain.Engine.Services.CacheManagers.Block -{ - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Services.CacheManagers.Block; +/// +/// Block Cache Manager. +/// +public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager +{ /// - /// Block Cache Manager. + /// Fired whenever a block is added to the cache /// - public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager - { - /// - /// Fired whenever a block is added to the cache - /// - public abstract event ICacheManager.KeyAddedEventHandler KeyAdded; + public abstract event ICacheManager.KeyAddedEventHandler KeyAdded; - /// - /// Fired whenever a block is expired from the cache - /// - public abstract event ICacheManager.KeyExpiredEventHandler KeyExpired; + /// + /// Fired whenever a block is expired from the cache + /// + public abstract event ICacheManager.KeyExpiredEventHandler KeyExpired; - /// - /// Fired whenever a block is removed from the collection - /// - public abstract event ICacheManager.KeyRemovedEventHandler KeyRemoved; + /// + /// Fired whenever a block is removed from the collection + /// + public abstract event ICacheManager.KeyRemovedEventHandler KeyRemoved; - /// - /// Fired whenever a block is requested from the cache but is not present. - /// - public abstract event ICacheManager.CacheMissEventHandler CacheMiss; - } + /// + /// Fired whenever a block is requested from the cache but is not present. + /// + public abstract event ICacheManager.CacheMissEventHandler CacheMiss; } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.ExpirationIndex.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.ExpirationIndex.cs old mode 100644 new mode 100755 index f5f221b5..6c6c88d0 --- a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.ExpirationIndex.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.ExpirationIndex.cs @@ -1,27 +1,25 @@ -namespace BrightChain.Engine.Services.CacheManagers.Block -{ - using System.Collections.Generic; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; +using System.Collections.Generic; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Services.CacheManagers.Block; - public partial class BrightenedBlockCacheManagerBase - { - public abstract IEnumerable GetBlocksExpiringAt(long date); +public partial class BrightenedBlockCacheManagerBase +{ + public abstract IEnumerable GetBlocksExpiringAt(long date); - public abstract void AddExpiration(BrightenedBlock block, bool noCheckContains = false); + public abstract void AddExpiration(BrightenedBlock block, bool noCheckContains = false); - public abstract void RemoveExpiration(BrightenedBlock block); + public abstract void RemoveExpiration(BrightenedBlock block); - public abstract void ExpireBlocks(long date); + public abstract void ExpireBlocks(long date); - /// - /// - /// - /// - /// determine/lookup oldest block in cache - /// expire all seconds between, inclusive, that time and specified time - /// - /// - public abstract void ExpireBlocksThrough(long date); - } + /// + /// + /// + /// determine/lookup oldest block in cache + /// expire all seconds between, inclusive, that time and specified time + /// + /// + public abstract void ExpireBlocksThrough(long date); } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Transactions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Transactions.cs new file mode 100755 index 00000000..7a059aa9 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.Transactions.cs @@ -0,0 +1,56 @@ +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models; + +namespace BrightChain.Engine.Services.CacheManagers.Block; + +public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager +{ + private BrightenedBlockTransaction ActiveTransaction { get; set; } + + public BrightenedBlockTransaction NewTransaction() + { + if (this.ActiveTransaction is not null) + { + throw new BrightChainException(message: "Already in transaction"); + } + + var transaction = new BrightenedBlockTransaction(cacheManager: this); + this.ActiveTransaction = transaction; + return transaction; + } + + public (bool Result, BrightenedBlockTransaction Transaction) Commit() + { + if (this.ActiveTransaction is null) + { + throw new BrightChainException(message: "Must be in transaction"); + } + + var result = this.ActiveTransaction.Commit(); + var activeTransaction = this.ActiveTransaction; + if (result) + { + this.ActiveTransaction = null; + } + + return (Result: result, Transaction: activeTransaction); + } + + public (bool Result, BrightenedBlockTransaction Transaction) Rollback() + { + if (this.ActiveTransaction is null) + { + throw new BrightChainException(message: "Must be in transaction"); + } + + var result = this.ActiveTransaction.Rollback(); + var activeTransaction = this.ActiveTransaction; + if (result) + { + this.ActiveTransaction = null; + } + + return (Result: result, Transaction: activeTransaction); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.cs old mode 100644 new mode 100755 index ffbedbe4..2e7b4eec --- a/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/BrightenedBlockCacheManagerBase.cs @@ -1,113 +1,100 @@ -using BrightChain.Engine.Models.Hashes; +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Nodes; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NeuralFabric.Helpers; -namespace BrightChain.Engine.Services.CacheManagers.Block -{ - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Nodes; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; +namespace BrightChain.Engine.Services.CacheManagers.Block; +/// +/// Block Cache Manager. +/// +public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager +{ /// - /// Block Cache Manager. + /// Whether the device and store files will delete on shutdown for testing. /// - public abstract partial class BrightenedBlockCacheManagerBase : IBrightenedBlockCacheManager - { - /// - /// Whether the device and store files will delete on shutdown for testing. - /// - protected readonly bool testingSelfDestruct = false; - - /// - /// List of nodes we trust. - /// - private readonly List trustedNodes; + protected readonly bool testingSelfDestruct; - /// - /// Gets a string with the full path to the config file. - /// - public string ConfigFile { get; private set; } + /// + /// List of nodes we trust. + /// + private readonly List trustedNodes; - /// - /// Gets the IConfiguration for this instance. - /// - public IConfiguration Configuration { get; private set; } + /// + /// Initializes a new instance of the class. + /// + /// Logging provider. + /// Configuration data. + /// Root block definition with authority for the store. + /// Whether to delete store and device files on shutdown. + public BrightenedBlockCacheManagerBase(ILogger logger, IConfiguration configuration, RootBlock rootBlock, + bool testingSelfDestruct = false) + { + this.trustedNodes = new List(); + this.Logger = logger; + this.Configuration = configuration; + this.RootBlock = rootBlock; + this.RootBlock.CacheManager = this; + this.DatabaseName = Utilities.HashToFormattedString(hashBytes: this.RootBlock.Guid.ToByteArray()); + this.testingSelfDestruct = testingSelfDestruct; - /// - /// Gets a string with the Database/directory name for this instance's tree root. - /// - public string DatabaseName { get; private set; } + // TODO: load supported block sizes from configurations, etc. + var section = this.Configuration.GetSection(key: "NodeOptions"); + } - /// - /// Gets the ILogger for this instance. - /// - public ILogger Logger { get; private set; } + /// + /// Initializes a new instance of the class. + /// Blocked parameterless constructor. + /// + private BrightenedBlockCacheManagerBase() + { + throw new NotImplementedException(); + } - /// - /// gets a RootBlock with authority for this block cache. - /// - public RootBlock RootBlock { get; private set; } + /// + /// Gets a string with the full path to the config file. + /// + public string ConfigFile { get; private set; } - /// - /// Gets a dictionary of block sizes supported for read by this node. - /// Done as a dictionary instead of a list for fast search. - /// - public Dictionary SupportedReadBlockSizes { get; private set; } + /// + /// Gets the IConfiguration for this instance. + /// + public IConfiguration Configuration { get; } - /// - /// Gets a dictionary of block sizes supported for write by this node. - /// Done as a dictionary instead of a list for fast search. - /// - public Dictionary SupportedWriteBlockSizes { get; private set; } + /// + /// Gets a string with the Database/directory name for this instance's tree root. + /// + public string DatabaseName { get; } - /// - /// Gets a lower classed BlockCacheManager of this object. - /// - public BrightenedBlockCacheManagerBase AsBlockCacheManager => this; + /// + /// Gets the ILogger for this instance. + /// + public ILogger Logger { get; } - /// - /// Blocks that are in-memory either pending write to the cache or confirmation of no-rollback required. - /// - public readonly Dictionary UncomittedBlocksByHash; - /// - /// Hashes of concomitted blocks grouped by transactions status. - /// - public readonly Dictionary> UncommittedHashesByStatus; + /// + /// gets a RootBlock with authority for this block cache. + /// + public RootBlock RootBlock { get; } - /// - /// Initializes a new instance of the class. - /// - /// Logging provider. - /// Configuration data. - /// Root block definition with authority for the store. - /// Whether to delete store and device files on shutdown. - public BrightenedBlockCacheManagerBase(ILogger logger, IConfiguration configuration, RootBlock rootBlock, bool testingSelfDestruct = false) - { - this.trustedNodes = new List(); - this.Logger = logger; - this.Configuration = configuration; - this.RootBlock = rootBlock; - this.RootBlock.CacheManager = this; - this.DatabaseName = Utilities.HashToFormattedString(this.RootBlock.Guid.ToByteArray()); - this.testingSelfDestruct = testingSelfDestruct; - this.UncomittedBlocksByHash = new Dictionary(); - this.UncommittedHashesByStatus = new Dictionary>(); + /// + /// Gets a dictionary of block sizes supported for read by this node. + /// Done as a dictionary instead of a list for fast search. + /// + public Dictionary SupportedReadBlockSizes { get; private set; } - // TODO: load supported block sizes from configurations, etc. - var section = this.Configuration.GetSection("NodeOptions"); - } + /// + /// Gets a dictionary of block sizes supported for write by this node. + /// Done as a dictionary instead of a list for fast search. + /// + public Dictionary SupportedWriteBlockSizes { get; private set; } - /// - /// Initializes a new instance of the class. - /// Blocked parameterless constructor. - /// - private BrightenedBlockCacheManagerBase() - { - throw new NotImplementedException(); - } - } + /// + /// Gets a lower classed BlockCacheManager of this object. + /// + public BrightenedBlockCacheManagerBase AsBlockCacheManager => this; } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CBLIndex.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CBLIndex.cs new file mode 100755 index 00000000..da6b3b7e --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CBLIndex.cs @@ -0,0 +1,118 @@ +using System; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Indices; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + private static string CblIndexKey(DataHash sourceHash) + { + return string.Format(format: "Source:{0}", + arg0: sourceHash.ToString()); + } + + public override BrightHandle GetCbl(DataHash sourceHash) + { + using var sessionContext = this.NewFasterSessionContext; + { + var result = sessionContext.SharedCacheSession.Read(key: CblIndexKey(sourceHash: sourceHash)); + if (result.status == Status.NOTFOUND) + { + throw new IndexOutOfRangeException(message: sourceHash.ToString()); + } + + if (result.status != Status.OK) + { + throw new BrightChainException( + message: string.Format(format: "cbl handle fetch error: {0}", + arg0: result.status.ToString())); + } + + if (result.output is BrightHandleIndexValue brightHandle) + { + return brightHandle.BrightHandle; + } + + throw new BrightChainException(message: "Unexpected index result type for key"); + } + } + + public override void SetCbl(BlockHash brightenedCblHash, DataHash identifiableSourceHash, BrightHandle brightHandle) + { + // technically the node can allow the CBL to be committed even if the store doesn't have the final block necessary to recreate it + // this would be allowed in some circumstances TBD. + // the parameter is provided as a means to check that. + if (!brightHandle.BrightenedCblHash.Equals(other: brightenedCblHash)) + { + throw new BrightChainException(message: nameof(brightenedCblHash)); + } + + if (!brightHandle.IdentifiableSourceHash.Equals(other: identifiableSourceHash)) + { + throw new BrightChainException(message: nameof(identifiableSourceHash)); + } + + using var sessionContext = this.NewFasterSessionContext; + { + sessionContext.SharedCacheSession.Upsert( + key: CblIndexKey(sourceHash: identifiableSourceHash), + desiredValue: new BrightHandleIndexValue(brightHandle: brightHandle).AsIndex); + + sessionContext.CompletePending(waitForCommit: false); + } + } + + private static string CorrelationIndexKey(Guid correlationId) + { + return string.Format(format: "Correlation:{0}", + arg0: correlationId.ToString()); + } + + public override void UpdateCblVersion(ConstituentBlockListBlock newCbl, ConstituentBlockListBlock oldCbl = null) + { + newCbl.CorrelationId = oldCbl.CorrelationId; + newCbl.PreviousVersionHash = oldCbl.SourceId; + + base.UpdateCblVersion(newCbl: newCbl, + oldCbl: oldCbl); + using var sessionContext = this.NewFasterSessionContext; + { + sessionContext.SharedCacheSession.Upsert( + key: CorrelationIndexKey(correlationId: newCbl.CorrelationId), + desiredValue: new CBLDataHashIndexValue(dataHash: newCbl.SourceId).AsIndex); + } + } + + public override BrightHandle GetCbl(Guid correlationId) + { + using var sessionContext = this.NewFasterSessionContext; + { + var key = CorrelationIndexKey(correlationId: correlationId); + var result = sessionContext.SharedCacheSession.Read(key: key); + if (result.status == Status.NOTFOUND) + { + throw new IndexOutOfRangeException(message: correlationId.ToString()); + } + + if (result.status != Status.OK) + { + throw new BrightChainException( + message: string.Format(format: "cbl correlation fetch error: {0}", + arg0: result.status.ToString())); + } + + if (result.output is BrightHandleIndexValue brightHandle) + { + return brightHandle.BrightHandle; + } + + throw new BrightChainException(message: "Unexpected index result type for key"); + } + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CoreFunctions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CoreFunctions.cs new file mode 100755 index 00000000..f81012f9 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.CoreFunctions.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + /// + /// Returns whether the cache manager has the given key and it is not expired. + /// + /// key to check the collection for. + /// boolean with whether key is present. + public override bool Contains(BlockHash key) + { + using var sessionContext = this.NewFasterSessionContext; + { + return sessionContext.Contains(blockHash: key); + } + } + + /// + /// Removes a key from the cache and returns a boolean wither whether it was actually present. + /// + /// key to drop from the collection. + /// Skips the contains check for performance. + /// whether requested key was present and actually dropped. + public override bool Drop(BlockHash key, bool noCheckContains = true) + { + bool contains; + BrightenedBlock block = null; + try + { + block = this.Get(blockHash: key); + contains = true; + } + catch (Exception _) + { + contains = false; + } + + if (!base.Drop(key: key, + noCheckContains: true)) + { + return false; + } + + using var sessionContext = this.NewFasterSessionContext; + { + if (!sessionContext.Drop(blockHash: key, + complete: true)) + { + return false; + } + } + + this.RemoveExpiration(block: block); + + return true; + } + + /// + /// Retrieves a block from the cache if it is present. + /// + /// key to retrieve. + /// returns requested block or throws. + public override BrightenedBlock Get(BlockHash blockHash) + { + using var sessionContext = this.NewFasterSessionContext; + { + return sessionContext.Get(blockHash: blockHash); + } + } + + /// + /// Adds a key to the cache if it is not already present. + /// + /// block to palce in the cache. + public void Set(BrightenedBlock block) + { + base.Set(value: block); + block.SetCacheManager(cacheManager: this); + using var sessionContext = this.NewFasterSessionContext; + { + sessionContext.Upsert( + block: block, + completePending: false); + } + this.AddExpiration(block: block, + noCheckContains: true); + } + + public override void SetAll(IEnumerable items) + { + var blocks = (BrightenedBlock[])items; + + for (var i = 0; i < blocks.Length; i++) + { + this.Set(block: blocks[i]); + } + + using var sessionContext = this.NewFasterSessionContext; + { + sessionContext.CompletePending(waitForCommit: false); + } + } + + public override async void SetAllAsync(IAsyncEnumerable items) + { + await foreach (var block in items) + { + this.Set(block: block); + } + + using var sessionContext = this.NewFasterSessionContext; + { + await sessionContext.CompletePendingAsync(waitForCommit: false).ConfigureAwait(continueOnCapturedContext: false); + } + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Events.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Events.cs new file mode 100755 index 00000000..95cf9341 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Events.cs @@ -0,0 +1,28 @@ +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + /// + /// Fired whenever a block is added to the cache + /// + public override event ICacheManager.KeyAddedEventHandler KeyAdded; + + /// + /// Fired whenever a block is expired from the cache + /// + public override event ICacheManager.KeyExpiredEventHandler KeyExpired; + + /// + /// Fired whenever a block is removed from the collection + /// + public override event ICacheManager.KeyRemovedEventHandler KeyRemoved; + + /// + /// Fired whenever a block is requested from the cache but is not present. + /// + public override event ICacheManager.CacheMissEventHandler CacheMiss; +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.ExpirationIndex.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.ExpirationIndex.cs new file mode 100755 index 00000000..76c78c1b --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.ExpirationIndex.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Indices; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + public static string BlockExpirationIndexKey(long date) + { + return string.Format(format: "Expiration:{0}", + arg0: date); + } + + public override IEnumerable GetBlocksExpiringAt(long date) + { + using var sessionContext = this.NewFasterSessionContext; + { + var resultTuple = sessionContext.SharedCacheSession.Read(key: BlockExpirationIndexKey(date: date)); + if (resultTuple.status == Status.OK) + { + if (resultTuple.output is null) + { + throw new BrightChainExceptionImpossible(message: "Cache returned null value"); + } + + if (resultTuple.output is BlockExpirationIndexValue expirationIndex) + { + return expirationIndex.ExpiringHashes; + } + + throw new BrightChainException(message: "Unexpected index value type for key"); + } + + if (resultTuple.status == Status.NOTFOUND) + { + return new BlockHash[] { }; + } + + throw new BrightChainException(message: resultTuple.status.ToString()); + } + } + + public override void AddExpiration(BrightenedBlock block, bool noCheckContains = false) + { + using var sessionContext = this.NewFasterSessionContext; + { + if (!noCheckContains && !sessionContext.Contains(blockHash: block.Id)) + { + throw new IndexOutOfRangeException(message: block.Id.ToString()); + } + + var ticks = block.StorageContract.KeepUntilAtLeast.Ticks; + var expiring = (BlockHash[])this.GetBlocksExpiringAt(date: ticks); + if (!expiring.Contains(value: block.Id)) + { + var size = expiring.Count(); + Array.Resize(array: ref expiring, + newSize: size + 1); + expiring[size] = block.Id; + } + + sessionContext.SharedCacheSession.Upsert( + key: BlockExpirationIndexKey(date: ticks), + desiredValue: new BlockExpirationIndexValue(hashes: expiring)); + } + } + + public override void RemoveExpiration(BrightenedBlock block) + { + var ticks = block.StorageContract.KeepUntilAtLeast.Ticks; + var expiring = new List(collection: this.GetBlocksExpiringAt(date: ticks)); + expiring.Remove(item: block.Id); + + using var sessionContext = this.NewFasterSessionContext; + { + sessionContext.SharedCacheSession.Upsert( + key: BlockExpirationIndexKey(date: ticks), + desiredValue: new BlockExpirationIndexValue(hashes: expiring.ToArray())); + } + } + + public override void ExpireBlocks(long date) + { + using var sessionContext = this.NewFasterSessionContext; + { + // checkpoint + foreach (var blockHash in this.GetBlocksExpiringAt(date: date)) + { + sessionContext.Drop(blockHash: blockHash); + } + // checkpoint + } + } + + public override void ExpireBlocksThrough(long date) + { + // determine/lookup oldest block in cache + // expire all seconds between, inclusive, that time and specified time + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Helpers.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Helpers.cs new file mode 100755 index 00000000..7813cf62 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Helpers.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Faster.Enumerations; +using BrightChain.Engine.Faster.Serializers; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + private static LogSettings NewLogSettings(Dictionary storeDevices, bool useReadCache) + { + return new LogSettings + { + LogDevice = storeDevices[key: CacheDeviceType.Log], + ObjectLogDevice = storeDevices[key: CacheDeviceType.Data], + ReadCacheSettings = useReadCache ? new ReadCacheSettings() : null, + }; + } + + private static CheckpointSettings NewCheckpointSettings(string cacheDir) + { + return new CheckpointSettings {CheckpointDir = cacheDir}; + } + + private DirectoryInfo EnsuredDirectory(string dir) + { + if (!Directory.Exists(path: dir)) + { + return Directory.CreateDirectory(path: dir); + } + + return new DirectoryInfo(path: dir); + } + + protected DirectoryInfo GetDiskCacheDirectory() + { + return Directory.CreateDirectory( + path: Path.Combine( + path1: this.baseDirectory.FullName, + path2: "BrightChain", + path3: this.DatabaseName)); + } + + protected string GetDevicePath(string nameSpace, out DirectoryInfo cacheDirectoryInfo) + { + cacheDirectoryInfo = this.GetDiskCacheDirectory(); + + return Path.Combine( + path1: cacheDirectoryInfo.FullName, + path2: string.Format( + provider: CultureInfo.InvariantCulture, + format: "{0}-{1}.log", + arg0: this.DatabaseName, + arg1: nameSpace)); + } + + protected IDevice CreateLogDevice(string nameSpace) + { + var devicePath = this.GetDevicePath(nameSpace: nameSpace, + cacheDirectoryInfo: out var _); + + return Devices.CreateLogDevice( + logPath: devicePath); + } + + private + (Dictionary Devices, + FasterBase Store) + InitFaster() + { + var cacheDir = this.GetDiskCacheDirectory().FullName; + var kv = new FasterBase(); + var devices = new Dictionary(); + var logDevicesByType = new Dictionary(); + foreach (CacheDeviceType deviceType in Enum.GetValues(enumType: typeof(CacheDeviceType))) + { + var device = this.CreateLogDevice(nameSpace: deviceType.ToString()); + logDevicesByType.Add(key: deviceType, + value: device); + } + + var blockDataSerializerSettings = new SerializerSettings + { + keySerializer = () => new FasterBlockHashSerializer(), + valueSerializer = () => new DataContractObjectSerializer(), + }; + + var newStore = new FasterKV( + size: HashTableBuckets, + logSettings: NewLogSettings(storeDevices: devices, + useReadCache: this.useReadCache), + checkpointSettings: NewCheckpointSettings(cacheDir: cacheDir), + serializerSettings: blockDataSerializerSettings, + comparer: BlockSizeMap.ZeroVectorHash(blockSize: BlockSize + .Micro)); // gets an arbitrary BlockHash object which has the IFasterEqualityComparer on the class. + + return (devices, newStore); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.SessionContext.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.SessionContext.cs new file mode 100755 index 00000000..3247ff32 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.SessionContext.cs @@ -0,0 +1,27 @@ +using BrightChain.Engine.Faster.Functions; +using BrightChain.Engine.Faster.Indices; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + private BlockSessionContext NewFasterSessionContext => new( + logger: this.Logger, + dataSession: this.NewDataSession, + cblIndicesSession: this.NewCblIndicesSession); + + private ClientSession + NewDataSession + => this.KV + .For(functions: new BrightChainBlockHashAdvancedFunctions()) + .NewSession(); + + private ClientSession NewCblIndicesSession + => this.cblIndicesKV + .For(functions: new BrightChainIndicesFunctions()) + .NewSession(); +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Transactable.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Transactable.cs new file mode 100755 index 00000000..e6c6a04a --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.Transactable.cs @@ -0,0 +1,172 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Enumerations; +using FASTER.core; + +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ + private readonly BlockSessionCheckpoint lastCheckpoint; + private readonly BlockSessionAddresses lastCommit; + private readonly BlockSessionAddresses lastHead; + + public BlockSessionCheckpoint TakeFullCheckpoint(CheckpointType checkpointType = CheckpointType.Snapshot) + { + return this.CheckpointFunc(operation: FasterCheckpointOperation.Full, + checkpointType: checkpointType); + } + + private async Task TakeFullCheckpointAsync(CheckpointType checkpointType = CheckpointType.Snapshot) + { + return await this.CheckpointFuncAsync(func: () => new Dictionary> + { + {CacheStoreType.BlockData, this.KV.TakeFullCheckpointAsync(checkpointType: checkpointType).AsTask()}, + {CacheStoreType.Indices, this.cblIndicesKV.TakeFullCheckpointAsync(checkpointType: checkpointType).AsTask()}, + }).ConfigureAwait(continueOnCapturedContext: false); + } + + public BlockSessionCheckpoint TakeHybridCheckpoint(CheckpointType checkpointType) + { + return this.CheckpointFunc(operation: FasterCheckpointOperation.Hybrid, + checkpointType: checkpointType); + } + + public async Task TakeHybridCheckpointAsync(CheckpointType checkpointType = CheckpointType.Snapshot) + { + return await this.CheckpointFuncAsync(func: () => new Dictionary> + { + {CacheStoreType.BlockData, this.KV.TakeHybridLogCheckpointAsync(checkpointType: checkpointType).AsTask()}, + {CacheStoreType.Indices, this.cblIndicesKV.TakeHybridLogCheckpointAsync(checkpointType: checkpointType).AsTask()}, + }).ConfigureAwait(continueOnCapturedContext: false); + } + + public BlockSessionCheckpoint TakeIndexCheckpoint() + { + return this.CheckpointFunc(operation: FasterCheckpointOperation.Index); + } + + public async Task TakeIndexCheckPointAsync() + { + return await this.CheckpointFuncAsync(func: () => new Dictionary> + { + {CacheStoreType.BlockData, this.KV.TakeIndexCheckpointAsync().AsTask()}, + {CacheStoreType.Indices, this.cblIndicesKV.TakeIndexCheckpointAsync().AsTask()}, + }).ConfigureAwait(continueOnCapturedContext: false); + } + + public BlockSessionCheckpoint CheckpointFunc(FasterCheckpointOperation operation, + CheckpointType checkpointType = CheckpointType.Snapshot) + { + bool dataResult, expirationResult, cblResult, cblIndexResult; + Guid dataToken, expirationToken, cblToken, cblIndexsToken; + switch (operation) + { + case FasterCheckpointOperation.Full: + dataResult = this.KV.TakeFullCheckpoint(token: out dataToken, + checkpointType: checkpointType); + cblIndexResult = this.cblIndicesKV.TakeFullCheckpoint(token: out cblIndexsToken, + checkpointType: checkpointType); + break; + case FasterCheckpointOperation.Hybrid: + dataResult = this.KV.TakeHybridLogCheckpoint(out dataToken); + cblIndexResult = this.cblIndicesKV.TakeHybridLogCheckpoint(out cblIndexsToken); + break; + case FasterCheckpointOperation.Index: + dataResult = this.KV.TakeIndexCheckpoint(out dataToken); + cblIndexResult = this.cblIndicesKV.TakeIndexCheckpoint(out cblIndexsToken); + break; + default: + throw new BrightChainExceptionImpossible(message: "Unexpected type"); + } + + return new BlockSessionCheckpoint( + success: dataResult && cblIndexResult, + results: new Dictionary + { + {CacheStoreType.BlockData, dataResult}, {CacheStoreType.Indices, cblIndexResult}, + }, + guids: new Dictionary {{CacheStoreType.BlockData, dataToken}, {CacheStoreType.Indices, cblIndexsToken}}); + } + + public async Task CheckpointFuncAsync(Func>> func) + { + var taskDict = func(); + + await Task.WhenAll(taskDict.Values) + .ConfigureAwait(continueOnCapturedContext: false); + + var resultDict = new Dictionary(); + var guidDict = new Dictionary(); + var allGood = true; + foreach (var task in taskDict) + { + var result = task.Value.Result; + resultDict.Add(key: task.Key, + value: result.Item1); + guidDict.Add(key: task.Key, + value: result.Item2); + + allGood = allGood && result.Item1; + } + + return new BlockSessionCheckpoint(success: allGood, + result: resultDict, + guid: guidDict); + } + + public async Task CompleteCheckpointAsync() + { + await Task + .WhenAll(this.KV.CompleteCheckpointAsync().AsTask(), + this.cblIndicesKV.CompleteCheckpointAsync().AsTask()) + .ConfigureAwait(continueOnCapturedContext: false); + } + + public BlockSessionAddresses NextSerials() + { + using var sessionContext = this.NewFasterSessionContext; + { + return new BlockSessionAddresses(addresses: new Dictionary + { + {CacheStoreType.BlockData, sessionContext.BlockDataBlobSession.NextSerialNo}, + {CacheStoreType.Indices, sessionContext.SharedCacheSession.NextSerialNo}, + }); + } + } + + public BlockSessionAddresses HeadAddresses() + { + return new BlockSessionAddresses(addresses: new Dictionary + { + {CacheStoreType.BlockData, this.KV.Log.HeadAddress}, {CacheStoreType.Indices, this.cblIndicesKV.Log.HeadAddress}, + }); + } + + public BlockSessionAddresses Compact(bool shiftBeginAddress = true) + { + using var sessionContext = this.NewFasterSessionContext; + { + return new BlockSessionAddresses(addresses: new Dictionary + { + { + CacheStoreType.BlockData, sessionContext.BlockDataBlobSession.Compact( + untilAddress: this.KV.Log.HeadAddress, + shiftBeginAddress: shiftBeginAddress) + }, + { + CacheStoreType.Indices, sessionContext.SharedCacheSession.Compact( + untilAddress: this.cblIndicesKV.Log.HeadAddress, + shiftBeginAddress: shiftBeginAddress) + }, + }); + } + } + + public async void Recover() + { + Task.WaitAll(tasks: new Task[] {this.KV.RecoverAsync().AsTask(), this.cblIndicesKV.RecoverAsync().AsTask()}); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.TypeHelpers.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.TypeHelpers.cs new file mode 100755 index 00000000..6dc419ea --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.TypeHelpers.cs @@ -0,0 +1,5 @@ +namespace BrightChain.Engine.Faster.CacheManager; + +public partial class FasterBlockCacheManager +{ +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.cs new file mode 100755 index 00000000..c8b5602b --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/FasterBlockCacheManager.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Enumerations; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Services.CacheManagers.Block; +using FASTER.core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace BrightChain.Engine.Faster.CacheManager; + +/// +/// Disk/Memory hybrid Block Cache Manager based on Microsoft FASTER KV. +/// +/// +/// The plan is to keep a couple separate caches of data in sync using the FasterKV checkpointing. +/// Hopefully errors where we need to put back or take out blocks that have already been altered on disk are rare. +/// The primary, Write Once*, Read Many cache: +/// - The Data cache contains the actual raw block data only. These blocks are not to be altered unless deleted through a revocation +/// certificate or normal expiration. +/// The secondary, Multiple Write Multiple Read cache is a combined cache that serves as a shared index table +/// - The BlockMetadata cache contains block metadata that may be updated. +/// - BlockExpirationIndexValues contain a list of Block ID's expiring in any given second. +/// - CBLDataHashIndexValues contain the latest CBL source hash associated with a given correlation ID. +/// - BrightHandleIndexValues contain the CBL handles for a given source hash ID. +/// - CBLTagIndexValue contain the correlation IDs for a given tag. +/// Sessions are what you issue a sequence of operations against. \ +/// You checkpoint the database periodically, which ensures some prefix of operations \ +/// on the session are persisted, i.e., can survive process failure. If you Upsert and try \ +/// to read back the data in the same session, it should be there. +/// +public partial class FasterBlockCacheManager : BrightenedBlockCacheManagerBase, IDisposable +{ + /// + /// hash table size (number of 64-byte buckets). + /// + private const long HashTableBuckets = 1L << 20; + + /// + /// Directory where the block tree root will be placed. + /// + private readonly DirectoryInfo baseDirectory; + + private readonly Dictionary fasterDevices; + private readonly FasterBase fasterStore; + + /// + /// Whether we enable a read cache. + /// Updated from config. + /// + private readonly bool useReadCache; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the logging provider. + /// Instance of the configuration provider. + /// Database/directory name for the store. + /// Block containing key information for store. + /// Whether to delete device files on shutdown. + public FasterBlockCacheManager(ILogger logger, IConfiguration configuration, RootBlock rootBlock, bool testingSelfDestruct = false) + : base(logger: logger, + configuration: configuration, + rootBlock: rootBlock, + testingSelfDestruct: testingSelfDestruct) + { + var nodeOptions = configuration.GetSection(key: "NodeOptions"); + if (nodeOptions is null) + { + throw new BrightChainException(message: "'NodeOptions' config section must be defined, but is not"); + } + + var configOption = nodeOptions.GetSection(key: "BasePath"); + var dir = configOption is not null && configOption.Value.Any() + ? configOption.Value + : Path.Join(path1: Path.GetTempPath(), + path2: "brightchain"); + + this.baseDirectory = this.EnsuredDirectory(dir: dir); + + var configuredDbName + = nodeOptions.GetSection(key: "DatabaseName"); + + if (configuredDbName is null || !configuredDbName.Value.Any()) + { + //ConfigurationHelper.AddOrUpdateAppSetting("NodeOptions:DatabaseName", this.databaseName); + } + else + { + var expectedGuid = Guid.Parse(input: configuredDbName.Value); + if (expectedGuid != this.RootBlock.Guid) + { + throw new BrightChainException(message: "Provided root block does not match configured root block guid"); + } + } + + var readCache = nodeOptions.GetSection(key: "EnableReadCache"); + this.useReadCache = readCache is null || readCache.Value is null ? false : Convert.ToBoolean(value: readCache.Value); + + (this.fasterDevices, this.fasterStore) = this.InitFaster(); + this.lastHead = this.HeadAddresses(); + this.lastCommit = this.lastHead; + this.lastCheckpoint = this.TakeFullCheckpoint(); + } + + /// + /// Gets the full path to the configuration file. + /// + public string ConfigurationFilePath + => this.ConfigFile; + + public void Dispose() + { + foreach (var entry in this.fasterDevices) + { + var faster = this.fasterStore; + (faster as IDisposable).Dispose(); + entry.Value.Dispose(); + } + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainBlockHashAdvancedFunctions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainBlockHashAdvancedFunctions.cs new file mode 100755 index 00000000..e44bee5f --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainBlockHashAdvancedFunctions.cs @@ -0,0 +1,11 @@ +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; + +namespace BrightChain.Engine.Faster.Functions; + +public class BrightChainBlockHashAdvancedFunctions : FunctionsBase +{ + +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainFunctions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainFunctions.cs new file mode 100644 index 00000000..a9963353 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainFunctions.cs @@ -0,0 +1,10 @@ +using FASTER.core; + +namespace BrightChain.Engine.Faster.Functions; + +public class BrightChainFunctions : FunctionsBase + where Input : Value + where Output : Input, Value +{ + +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainIndicesFunctions.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainIndicesFunctions.cs new file mode 100644 index 00000000..dfba7935 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Functions/BrightChainIndicesFunctions.cs @@ -0,0 +1,9 @@ +using BrightChain.Engine.Faster.Indices; +using FASTER.core; + +namespace BrightChain.Engine.Faster.Functions; + +public class BrightChainIndicesFunctions : FunctionsBase +{ + +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockExpirationIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockExpirationIndexValue.cs new file mode 100755 index 00000000..8fccb276 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockExpirationIndexValue.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using BrightChain.Engine.Faster.Serializers; +using BrightChain.Engine.Models.Hashes; + +namespace BrightChain.Engine.Faster.Indices; + +public class BlockExpirationIndexValue : BrightChainIndexValue +{ + public readonly IEnumerable ExpiringHashes; + + public BlockExpirationIndexValue(IEnumerable hashes) + : base(data: InternalSerialize(data: hashes)) + { + this.ExpiringHashes = hashes; + } + + public BlockExpirationIndexValue(ReadOnlyMemory data) + : base(data: data) + { + this.ExpiringHashes = InternalDeserialize(data: data).ExpiringHashes; + } + + private static ReadOnlyMemory InternalSerialize(IEnumerable data) + { + var serializer = new FasterBlockHashSerializer(); + var memory = new MemoryStream(); + + memory.Write(buffer: BitConverter.GetBytes(value: data.Count())); + serializer.BeginSerialize(stream: memory); + foreach (var item in data) + { + var refItem = item; + serializer.Serialize(obj: ref refItem); + } + + var retval = new ReadOnlyMemory(array: memory.ToArray()); + serializer.EndSerialize(); + return retval; + } + + private static BlockExpirationIndexValue InternalDeserialize(ReadOnlyMemory data) + { + var deserializer = new FasterBlockHashSerializer(); + var s = new MemoryStream(buffer: data.ToArray()); + deserializer.BeginDeserialize(stream: s); + + var iBytes = new byte[sizeof(int)]; + s.Read(buffer: iBytes, + offset: 0, + count: sizeof(int)); + var count = BitConverter.ToInt32(value: new ReadOnlySpan(array: iBytes)); + var hashes = new BlockHash[count]; + for (var i = 0; i < count; i++) + { + deserializer.Deserialize(obj: out hashes[i]); + } + + deserializer.EndDeserialize(); + return new BlockExpirationIndexValue(hashes: hashes); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockMetadataIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockMetadataIndexValue.cs new file mode 100755 index 00000000..5180a3f0 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BlockMetadataIndexValue.cs @@ -0,0 +1,46 @@ +using System; +using System.IO; +using BrightChain.Engine.Models.Blocks; +using FASTER.core; + +namespace BrightChain.Engine.Faster.Indices; + +public class BlockMetadataIndexValue : BrightChainIndexValue +{ + public readonly BrightenedBlock Block; + + public BlockMetadataIndexValue(BrightenedBlock block) + : base(data: InternalSerialize(data: block)) + { + this.Block = block; + } + + public BlockMetadataIndexValue(ReadOnlyMemory data) + : base(data: data) + { + this.Block = InternalDeserialize(data: data).Block; + } + + private static ReadOnlyMemory InternalSerialize(BrightenedBlock data) + { + var serializer = new DataContractObjectSerializer(); + var memory = new MemoryStream(); + serializer.BeginSerialize(stream: memory); + serializer.Serialize(obj: ref data); + var bytes = memory.ToArray(); + serializer.EndSerialize(); + + var retval = new ReadOnlyMemory(array: bytes); + return retval; + } + + private static BlockMetadataIndexValue InternalDeserialize(ReadOnlyMemory data) + { + var deserializer = new DataContractObjectSerializer(); + var s = new MemoryStream(buffer: data.ToArray()); + deserializer.BeginDeserialize(stream: s); + deserializer.Deserialize(obj: out var block); + deserializer.EndDeserialize(); + return new BlockMetadataIndexValue(block: block); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightChainIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightChainIndexValue.cs new file mode 100755 index 00000000..9a7bfb7c --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightChainIndexValue.cs @@ -0,0 +1,15 @@ +using System; + +namespace BrightChain.Engine.Faster.Indices; + +public abstract class BrightChainIndexValue +{ + public readonly ReadOnlyMemory Data; + + public BrightChainIndexValue(ReadOnlyMemory data) + { + this.Data = data; + } + + public BrightChainIndexValue AsIndex => this; +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightHandleIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightHandleIndexValue.cs new file mode 100755 index 00000000..386480ea --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/BrightHandleIndexValue.cs @@ -0,0 +1,27 @@ +using System; +using System.Text; +using BrightChain.Engine.Models.Blocks.DataObjects; + +namespace BrightChain.Engine.Faster.Indices; + +public class BrightHandleIndexValue : BrightChainIndexValue +{ + public readonly BrightHandle BrightHandle; + + public BrightHandleIndexValue(BrightHandle brightHandle) + : base(data: new ReadOnlyMemory( + array: Encoding.ASCII.GetBytes( + s: brightHandle.BrightChainAddress( + hostName: "hostname") + .ToString()))) + { + this.BrightHandle = brightHandle; + } + + public BrightHandleIndexValue(ReadOnlyMemory data) + : base(data: data) + { + var uriString = Encoding.ASCII.GetString(bytes: data.ToArray()); + this.BrightHandle = new BrightHandle(brightChainAddress: new Uri(uriString: uriString)); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLDataHashIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLDataHashIndexValue.cs new file mode 100755 index 00000000..ba9d51b7 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLDataHashIndexValue.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using NeuralFabric.Models.Hashes; +using ProtoBuf; + +namespace BrightChain.Engine.Faster.Indices; + +public class CBLDataHashIndexValue : BrightChainIndexValue +{ + public readonly DataHash DataHash; + + public CBLDataHashIndexValue(DataHash dataHash) + : base(data: InternalSerialize(data: dataHash)) + { + this.DataHash = dataHash; + } + + public CBLDataHashIndexValue(ReadOnlyMemory data) + : base(data: data) + { + this.DataHash = InternalDeserialize(data: data); + } + + internal static ReadOnlyMemory InternalSerialize(T data) + { + var s = new MemoryStream(); + Serializer.Serialize(destination: s, + instance: data); + return new ReadOnlyMemory(array: s.ToArray()); + } + + internal static T InternalDeserialize(ReadOnlyMemory data) + { + var s = new MemoryStream(buffer: data.ToArray()); + return Serializer.Deserialize(source: s); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLTagIndexValue.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLTagIndexValue.cs new file mode 100755 index 00000000..c87f5bb7 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Indices/CBLTagIndexValue.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.IO; +using ProtoBuf; + +namespace BrightChain.Engine.Faster.Indices; + +public class CBLTagIndexValue : BrightChainIndexValue +{ + public readonly IEnumerable CorrelationIds; + + public CBLTagIndexValue(IEnumerable guids) + : base(data: InternalSerialize(data: guids)) + { + this.CorrelationIds = guids; + } + + public CBLTagIndexValue(ReadOnlyMemory data) + : base(data: data) + { + this.CorrelationIds = InternalDeserialize(data: data); + } + + internal static ReadOnlyMemory InternalSerialize(IEnumerable data) + { + var s = new MemoryStream(); + Serializer.Serialize(destination: s, + instance: data); + return new ReadOnlyMemory(array: s.ToArray()); + } + + internal static IEnumerable InternalDeserialize(ReadOnlyMemory data) + { + var s = new MemoryStream(buffer: data.ToArray()); + return Serializer.Deserialize>(source: s); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/MemoryDictionaryBlockCacheManager.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/MemoryDictionaryBlockCacheManager.cs old mode 100644 new mode 100755 index b8a65702..b807504e --- a/src/BrightChain.Engine/Services/CacheManagers/Block/MemoryDictionaryBlockCacheManager.cs +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/MemoryDictionaryBlockCacheManager.cs @@ -1,167 +1,172 @@ -namespace BrightChain.Engine.Services.CacheManagers.Block +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Services.CacheManagers.Block; + +/// +/// Memory based Block Cache Manager. +/// +public class MemoryDictionaryBlockCacheManager : BrightenedBlockCacheManagerBase { - using System; - using System.Collections.Generic; - using System.Threading.Tasks; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; + /// + /// Hashtable collection for blocks stored in memory + /// + private readonly Dictionary blocks = new(); /// - /// Memory based Block Cache Manager. + /// Initializes a new instance of the class. /// - public class MemoryDictionaryBlockCacheManager : BrightenedBlockCacheManagerBase + /// Instance of the logging provider. + /// Instance of the configuration provider. + public MemoryDictionaryBlockCacheManager(ILogger logger, IConfiguration configuration, RootBlock rootBlock) + : base(logger: logger, + configuration: configuration, + rootBlock: rootBlock) { - /// - /// Hashtable collection for blocks stored in memory - /// - private readonly Dictionary blocks = new(); - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the logging provider. - /// Instance of the configuration provider. - public MemoryDictionaryBlockCacheManager(ILogger logger, IConfiguration configuration, RootBlock rootBlock) - : base(logger, configuration, rootBlock) - { - } + } - /// - /// Fired whenever a block is added to the cache - /// - public override event ICacheManager.KeyAddedEventHandler KeyAdded; - - /// - /// Fired whenever a block is expired from the cache - /// - public override event ICacheManager.KeyExpiredEventHandler KeyExpired; - - /// - /// Fired whenever a block is removed from the collection - /// - public override event ICacheManager.KeyRemovedEventHandler KeyRemoved; - - /// - /// Fired whenever a block is requested from the cache but is not present. - /// - public override event ICacheManager.CacheMissEventHandler CacheMiss; - - /// - /// Returns whether the cache manager has the given key and it is not expired. - /// - /// key to check the collection for. - /// boolean with whether key is present. - public override bool Contains(BlockHash key) - { - return this.blocks.ContainsKey(key); - } + /// + /// Fired whenever a block is added to the cache + /// + public override event ICacheManager.KeyAddedEventHandler KeyAdded; - /// - /// Removes a key from the cache and returns a boolean wither whether it was actually present. - /// - /// key to drop from the collection. - /// Skips the contains check for performance. - /// whether requested key was present and actually dropped. - public override bool Drop(BlockHash key, bool noCheckContains = true) - { - if (!base.Drop(key, noCheckContains)) - { - return false; - } + /// + /// Fired whenever a block is expired from the cache + /// + public override event ICacheManager.KeyExpiredEventHandler KeyExpired; - this.blocks.Remove(key); - return true; - } + /// + /// Fired whenever a block is removed from the collection + /// + public override event ICacheManager.KeyRemovedEventHandler KeyRemoved; - /// - /// Retrieves a block from the cache if it is present - /// - /// key to retrieve - /// returns requested block or throws - public override BrightenedBlock Get(BlockHash blockHash) - { - BrightenedBlock block; - var found = this.blocks.TryGetValue(blockHash, out block); - if (!found) - { - throw new IndexOutOfRangeException(message: blockHash.ToString()); - } - - if (!block.Validate()) - { - throw new BrightChainValidationEnumerableException( - block.ValidationExceptions, - "Will not return invalid block. Is store corrupt?"); - } - - return block; - } + /// + /// Fired whenever a block is requested from the cache but is not present. + /// + public override event ICacheManager.CacheMissEventHandler CacheMiss; - /// - /// Adds a key to the cache if it is not already present - /// - /// block to palce in the cache - public override void Set(BrightenedBlock block, bool updateMetadataOnly = false) - { - base.Set(block, updateMetadataOnly: updateMetadataOnly); - this.blocks[block.Id] = block; - } + /// + /// Returns whether the cache manager has the given key and it is not expired. + /// + /// key to check the collection for. + /// boolean with whether key is present. + public override bool Contains(BlockHash key) + { + return this.blocks.ContainsKey(key: key); + } - public async Task CopyContentAsync(BrightenedBlockCacheManagerBase destinationCache) + /// + /// Removes a key from the cache and returns a boolean wither whether it was actually present. + /// + /// key to drop from the collection. + /// Skips the contains check for performance. + /// whether requested key was present and actually dropped. + public override bool Drop(BlockHash key, bool noCheckContains = true) + { + if (!base.Drop(key: key, + noCheckContains: noCheckContains)) { - await foreach (var key in this.KeysAsync()) - { - destinationCache.Set(this.Get(key)); - } + return false; } - public async IAsyncEnumerable KeysAsync() - { - foreach (var key in this.blocks.Keys) - { - yield return key; - } - } + this.blocks.Remove(key: key); + return true; + } - public override BrightHandle GetCbl(DataHash sourceHash) + /// + /// Retrieves a block from the cache if it is present + /// + /// key to retrieve + /// returns requested block or throws + public override BrightenedBlock Get(BlockHash blockHash) + { + BrightenedBlock block; + var found = this.blocks.TryGetValue(key: blockHash, + value: out block); + if (!found) { - throw new NotImplementedException(); + throw new IndexOutOfRangeException(message: blockHash.ToString()); } - public override void SetCbl(BlockHash cblHash, DataHash dataHash, BrightHandle brightHandle) + if (!block.Validate()) { - throw new NotImplementedException(); + throw new BrightChainValidationEnumerableException( + exceptions: block.ValidationExceptions, + message: "Will not return invalid block. Is store corrupt?"); } - public override BrightHandle GetCbl(Guid correlationID) - { - throw new NotImplementedException(); - } + return block; + } - public override List GetBlocksExpiringAt(long date) - { - return default; - } + /// + /// Adds a key to the cache if it is not already present + /// + /// block to palce in the cache + public override void Set(BrightenedBlock block, bool updateMetadataOnly = false) + { + base.Set(value: block, + updateMetadataOnly: updateMetadataOnly); + this.blocks[key: block.Id] = block; + } - public override void AddExpiration(BrightenedBlock block, bool noCheckContains = false) + public async Task CopyContentAsync(BrightenedBlockCacheManagerBase destinationCache) + { + await foreach (var key in this.KeysAsync()) { + destinationCache.Set(value: this.Get(blockHash: key)); } + } - public override void RemoveExpiration(BrightenedBlock block) + public async IAsyncEnumerable KeysAsync() + { + foreach (var key in this.blocks.Keys) { + yield return key; } + } - public override void ExpireBlocks(long date) - { - } + public override BrightHandle GetCbl(DataHash sourceHash) + { + throw new NotImplementedException(); + } - public override void ExpireBlocksThrough(long date) - { - } + public override void SetCbl(BlockHash cblHash, DataHash dataHash, BrightHandle brightHandle) + { + throw new NotImplementedException(); + } + + public override BrightHandle GetCbl(Guid correlationID) + { + throw new NotImplementedException(); + } + + public override List GetBlocksExpiringAt(long date) + { + return default; + } + + public override void AddExpiration(BrightenedBlock block, bool noCheckContains = false) + { + } + + public override void RemoveExpiration(BrightenedBlock block) + { + } + + public override void ExpireBlocks(long date) + { + } + + public override void ExpireBlocksThrough(long date) + { } } diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBlockHashSerializer.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBlockHashSerializer.cs new file mode 100755 index 00000000..f0957f30 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBlockHashSerializer.cs @@ -0,0 +1,45 @@ +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Hashes; +using FASTER.core; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Faster.Serializers; + +/// +/// Serializer for CacheKey - used if CacheKey is changed from struct to class +/// +public class FasterBlockHashSerializer + : BinaryObjectSerializer +{ + public override void Deserialize(out BlockHash obj) + { + var hashSize = this.reader.ReadInt32(); + var blockSizeString = this.reader.ReadString(); + var blockSize = (BlockSize)Enum.Parse(enumType: typeof(BlockSize), + value: blockSizeString); + var blockBytes = this.reader.ReadBytes(count: hashSize); + var blockType = Type.GetType(typeName: this.reader.ReadString()); + var computed = this.reader.ReadBoolean(); + + obj = new BlockHash( + blockType: blockType, + originalBlockSize: blockSize, + providedHashBytes: blockBytes, + computed: computed); + } + + public override void Serialize(ref BlockHash obj) + { + if (obj is null) + { + throw new ArgumentNullException(paramName: nameof(obj)); + } + + this.writer.Write(value: DataHash.HashSizeBytes); + this.writer.Write(value: obj.BlockSize.ToString()); + this.writer.Write(buffer: obj.HashBytes.ToArray()); + this.writer.Write(value: obj.BlockType.AssemblyQualifiedName); + this.writer.Write(value: obj.Computed); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBrightChainIndexValueSerializer.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBrightChainIndexValueSerializer.cs new file mode 100755 index 00000000..47480fe1 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterBrightChainIndexValueSerializer.cs @@ -0,0 +1,49 @@ +using System; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.Indices; +using FASTER.core; + +namespace BrightChain.Engine.Faster.Serializers; + +/// +/// Serializer for CacheKey - used if CacheKey is changed from struct to class +/// +public class FasterBrightChainIndexValueSerializer + : BinaryObjectSerializer +{ + public override void Deserialize(out BrightChainIndexValue obj) + { + var length = this.reader.ReadInt32(); + var type = Type.GetType(typeName: this.reader.ReadString()); + var data = this.reader.ReadBytes(count: length); + + if (type.Equals(o: typeof(BlockExpirationIndexValue))) + { + obj = new BlockExpirationIndexValue(data: new ReadOnlyMemory(array: data)); + } + else if (type.Equals(o: typeof(CBLDataHashIndexValue))) + { + obj = new CBLDataHashIndexValue(data: new ReadOnlyMemory(array: data)); + } + else if (type.Equals(o: typeof(CBLTagIndexValue))) + { + obj = new CBLTagIndexValue(data: new ReadOnlyMemory(array: data)); + } + else + { + throw new BrightChainException(message: "Unexpected type"); + } + } + + public override void Serialize(ref BrightChainIndexValue obj) + { + if (obj is null) + { + throw new ArgumentNullException(paramName: nameof(obj)); + } + + this.writer.Write(value: obj.Data.Length); + this.writer.Write(value: obj.GetType().AssemblyQualifiedName); + this.writer.Write(buffer: obj.Data.ToArray()); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterDataHashSerializer.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterDataHashSerializer.cs new file mode 100755 index 00000000..39f0ae3a --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterDataHashSerializer.cs @@ -0,0 +1,38 @@ +using System; +using FASTER.core; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Faster.Serializers; + +/// +/// Serializer for CacheKey - used if CacheKey is changed from struct to class +/// +public class FasterDataHashSerializer + : BinaryObjectSerializer +{ + public override void Deserialize(out DataHash obj) + { + var hashSize = this.reader.ReadInt32(); + var sourceLength = this.reader.ReadInt64(); + var dataBytes = this.reader.ReadBytes(count: hashSize); + var computed = this.reader.ReadBoolean(); + + obj = new DataHash( + providedHashBytes: dataBytes, + sourceDataLength: sourceLength, + computed: computed); + } + + public override void Serialize(ref DataHash obj) + { + if (obj is null) + { + throw new ArgumentNullException(paramName: nameof(obj)); + } + + this.writer.Write(value: DataHash.HashSizeBytes); + this.writer.Write(value: obj.SourceDataLength); + this.writer.Write(buffer: obj.HashBytes.ToArray()); + this.writer.Write(value: obj.Computed); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterGuidSerializer.cs b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterGuidSerializer.cs new file mode 100755 index 00000000..7f3e1637 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/Block/Serializers/FasterGuidSerializer.cs @@ -0,0 +1,21 @@ +using System; +using FASTER.core; + +namespace BrightChain.Engine.Faster.Serializers; + +/// +/// Serializer for CacheKey - used if CacheKey is changed from struct to class +/// +public class FasterGuidSerializer + : BinaryObjectSerializer +{ + public override void Deserialize(out Guid obj) + { + obj = Guid.Parse(input: this.reader.ReadString()); + } + + public override void Serialize(ref Guid obj) + { + this.writer.Write(value: obj.ToString()); + } +} diff --git a/src/BrightChain.Engine/Services/CacheManagers/FasterCacheManager.cs b/src/BrightChain.Engine/Services/CacheManagers/FasterCacheManager.cs deleted file mode 100644 index 7afe721c..00000000 --- a/src/BrightChain.Engine/Services/CacheManagers/FasterCacheManager.cs +++ /dev/null @@ -1,238 +0,0 @@ -namespace BrightChain.Engine.Services.CacheManagers -{ - using System; - using System.Globalization; - using System.IO; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Faster; - using BrightChain.Engine.Faster.Functions; - using BrightChain.Engine.Interfaces; - using FASTER.core; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - - /// - /// Disk/Memory hybrid Cache Manager based on Microsoft FASTER KV. - /// - public class FasterCacheManager - : ICacheManager, IDisposable - where Tkey : IComparable - where TkeySerializer : BinaryObjectSerializer, new() - where TvalueSerializer : BinaryObjectSerializer, new() - { - /// - /// Full to the config file. - /// - protected readonly string configFile; - - protected readonly string databaseName; - - /// - /// Directory where the block tree root will be placed. - /// - private readonly DirectoryInfo baseDirectory; - - private readonly IDevice logDevice; - - // Whether we enable a read cache - static readonly bool useReadCache = false; - - /// - /// Backing storage device. - /// - private readonly IDevice fasterDevice; - - private readonly FasterKV fasterKV; - - /// - /// Initializes a new instance of the class. - /// - /// Instance of the logging provider. - /// Instance of the configuration provider. - /// Database/directory name for the store. - public FasterCacheManager(ILogger logger, IConfiguration configuration, string databaseName) - { - this.databaseName = databaseName; - - var nodeOptions = configuration.GetSection("NodeOptions"); - if (nodeOptions is null) - { - throw new BrightChainException("'NodeOptions' config section must be defined, but is not"); - } - - var configOption = nodeOptions.GetSection("BasePath"); - if (configOption is null || configOption.Value is null) - { - throw new BrightChainException("'BasePath' config option must be set, but is not"); - } - - var dir = configOption.Value; - if (dir.Length == 0 || !Directory.Exists(dir)) - { - throw new BrightChainException(string.Format("'BasePath' must exist, but does not: \"{0}\"", dir)); - } - - this.baseDirectory = new DirectoryInfo(dir); - - this.logDevice = this.OpenDevice(string.Format("{0}-log", typeof(Tkey).Name)); - this.fasterDevice = this.OpenDevice(string.Format("{0}-data", typeof(Tkey).Name)); - - var logSettings = new LogSettings // log settings (devices, page size, memory size, etc.) - { - LogDevice = this.fasterDevice, - ObjectLogDevice = this.fasterDevice, - ReadCacheSettings = useReadCache ? new ReadCacheSettings() : null, - }; - - // Define serializers; otherwise FASTER will use the slower DataContract - // Needed only for class keys/values - var serializerSettings = new SerializerSettings - { - keySerializer = () => new TkeySerializer(), - valueSerializer = () => new TvalueSerializer(), - }; - - this.fasterKV = new FasterKV( - size: 1L << 20, // hash table size (number of 64-byte buckets) - logSettings: logSettings, - checkpointSettings: new CheckpointSettings - { - CheckpointDir = this.GetDiskCacheDirectory().FullName, - }, - serializerSettings: serializerSettings, - comparer: null); - } - - /// - /// Initializes a new instance of the class. - /// Can not build a cache manager with no logger. - /// - private FasterCacheManager() - { - throw new NotImplementedException(); - } - - /// - /// Full path to the configuration file. - /// - public string ConfigurationFilePath - => this.configFile; - - protected DirectoryInfo GetDiskCacheDirectory() - { - return Directory.CreateDirectory( - Path.Combine( - this.baseDirectory.FullName, - string.Format( - CultureInfo.InvariantCulture, - "BrightChain-{0}", - this.databaseName))); - } - - protected string GetDevicePath(string nameSpace, out DirectoryInfo cacheDirectoryInfo) - { - cacheDirectoryInfo = this.GetDiskCacheDirectory(); - - return Path.Combine( - cacheDirectoryInfo.FullName, - string.Format( - provider: System.Globalization.CultureInfo.InvariantCulture, - format: "brightchain-{0}-{1}.log", - this.databaseName, - nameSpace)); - } - - protected IDevice OpenDevice(string nameSpace) - { - var devicePath = this.GetDevicePath(nameSpace, out DirectoryInfo _); - - return Devices.CreateLogDevice( - logPath: devicePath); - } - - /// - /// Fired whenever a block is added to the cache - /// - public event ICacheManager.KeyAddedEventHandler KeyAdded; - - /// - /// Fired whenever a block is expired from the cache - /// - public event ICacheManager.KeyExpiredEventHandler KeyExpired; - - /// - /// Fired whenever a block is removed from the collection - /// - public event ICacheManager.KeyRemovedEventHandler KeyRemoved; - - /// - /// Fired whenever a block is requested from the cache but is not present. - /// - public event ICacheManager.CacheMissEventHandler CacheMiss; - - /// - /// Returns whether the cache manager has the given key and it is not expired. - /// - /// key to check the collection for. - /// boolean with whether key is present. - public bool Contains(Tkey key) - { - using var session = this.fasterKV.NewSession(functions: new BrightChainAdvancedFunctions()); - var resultTuple = session.Read(key); - return resultTuple.status == Status.OK; - } - - /// - /// Removes a key from the cache and returns a boolean wither whether it was actually present. - /// - /// key to drop from the collection. - /// Skips the contains check for performance. - /// whether requested key was present and actually dropped. - public bool Drop(Tkey key, bool noCheckContains = true) - { - using var session = this.fasterKV.NewSession(functions: new BrightChainAdvancedFunctions()); - var resultStatus = session.Delete(key); - return resultStatus == Status.OK; - } - - /// - /// Retrieves a block from the cache if it is present. - /// - /// key to retrieve. - /// returns requested block or throws. - public Tvalue Get(Tkey blockHash) - { - using var session = this.fasterKV.NewSession(functions: new BrightChainAdvancedFunctions()); - var resultTuple = session.Read(blockHash); - - if (resultTuple.status != Status.OK) - { - throw new IndexOutOfRangeException(message: blockHash.ToString()); - } - - return resultTuple.output; - } - - /// - /// Adds a key to the cache if it is not already present. - /// - /// block to palce in the cache. - public void Set(Tkey key, Tvalue value) - { - var functions = new BrightChainAdvancedFunctions(); - using var session = this.fasterKV.NewSession(functions: functions); - var resultStatus = session.Upsert( - key: key, - desiredValue: value); - if (resultStatus != Status.OK) - { - throw new BrightChainException("Unable to store block"); - } - } - - public void Dispose() - { - throw new NotImplementedException(); - } - } -} diff --git a/src/BrightChain.Engine/Services/CacheManagers/TapestryCacheManager.cs b/src/BrightChain.Engine/Services/CacheManagers/TapestryCacheManager.cs new file mode 100644 index 00000000..4db63dd4 --- /dev/null +++ b/src/BrightChain.Engine/Services/CacheManagers/TapestryCacheManager.cs @@ -0,0 +1,149 @@ +using System; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster; +using BrightChain.Engine.Faster.CacheManager; +using BrightChain.Engine.Faster.Functions; +using BrightChain.Engine.Interfaces; +using FASTER.core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NeuralFabric.Models; + +namespace BrightChain.Engine.Services.CacheManagers; + +/// +/// Disk/Memory hybrid Cache Manager based on Microsoft FASTER KV. +/// +public class TapestryCacheManager + : ICacheManager, IDisposable + where Tkey : IComparable + where TkeySerializer : BinaryObjectSerializer, new() + where TvalueSerializer : BinaryObjectSerializer, new() +{ + protected readonly Tapestry _tapestry; + + /// + /// Full to the config file. + /// + protected readonly string configFile; + + /// + /// Initializes a new instance of the class. + /// + /// Instance of the logging provider. + /// Instance of the configuration provider. + /// Database/directory name for the store. + public TapestryCacheManager(ILogger logger, IConfiguration configuration, string collectionName) + { + this._tapestry = new Tapestry( + logger: logger, + configuration: configuration, + collectionName: collectionName); + } + + /// + /// Initializes a new instance of the class. + /// Can not build a cache manager with no logger. + /// + private TapestryCacheManager() + { + throw new NotImplementedException(); + } + + /// + /// Full path to the configuration file. + /// + public string ConfigurationFilePath + => this.configFile; + + /// + /// Fired whenever a block is added to the cache + /// + public event ICacheManager.KeyAddedEventHandler KeyAdded; + + /// + /// Fired whenever a block is expired from the cache + /// + public event ICacheManager.KeyExpiredEventHandler KeyExpired; + + /// + /// Fired whenever a block is removed from the collection + /// + public event ICacheManager.KeyRemovedEventHandler KeyRemoved; + + /// + /// Fired whenever a block is requested from the cache but is not present. + /// + public event ICacheManager.CacheMissEventHandler CacheMiss; + + /// + /// Returns whether the cache manager has the given key and it is not expired. + /// + /// key to check the collection for. + /// boolean with whether key is present. + public bool Contains(Tkey key) + { + using var session = + this.fasterKV.NewSession( + functions: new BrightChainFunctions()); + var resultTuple = session.Read(key); + return resultTuple.status == Status.OK; + } + + /// + /// Removes a key from the cache and returns a boolean wither whether it was actually present. + /// + /// key to drop from the collection. + /// Skips the contains check for performance. + /// whether requested key was present and actually dropped. + public bool Drop(Tkey key, bool noCheckContains = true) + { + using var session = + this.fasterKV.NewSession( + functions: new BrightChainFunctions()); + var resultStatus = session.Delete(key); + return resultStatus == Status.OK; + } + + /// + /// Retrieves a block from the cache if it is present. + /// + /// key to retrieve. + /// returns requested block or throws. + public Tvalue Get(Tkey blockHash) + { + using var session = + this.fasterKV.NewSession( + functions: new BrightChainFunctions()); + var resultTuple = session.Read(blockHash); + + if (resultTuple.status != Status.OK) + { + throw new IndexOutOfRangeException(message: blockHash.ToString()); + } + + return resultTuple.output; + } + + /// + /// Adds a key to the cache if it is not already present. + /// + /// block to palce in the cache. + public void Set(Tkey key, Tvalue value) + { + var functions = new BrightChainFunctions(); + using var session = this.fasterKV.NewSession(functions: functions); + var resultStatus = session.Upsert( + key: key, + desiredValue: value); + if (resultStatus != Status.OK) + { + throw new BrightChainException(message: "Unable to store block"); + } + } + + public void Dispose() + { + throw new NotImplementedException(); + } +} diff --git a/src/BrightChain.Engine/Services/RsaKeyFormatBroker.cs b/src/BrightChain.Engine/Services/RsaKeyFormatBroker.cs old mode 100644 new mode 100755 index 3f2a58e2..e3e0a18a --- a/src/BrightChain.Engine/Services/RsaKeyFormatBroker.cs +++ b/src/BrightChain.Engine/Services/RsaKeyFormatBroker.cs @@ -1,336 +1,374 @@ -namespace BrightChain.Engine.Services -{ - using System; - using System.IdentityModel.Tokens.Jwt; - using System.IO; - using System.Security.Cryptography; - using System.Text; - using Microsoft.IdentityModel.Tokens; - using Org.BouncyCastle.Crypto; - using Org.BouncyCastle.Crypto.Parameters; - using Org.BouncyCastle.OpenSsl; - using Org.BouncyCastle.Security; +using System; +using System.IdentityModel.Tokens.Jwt; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using Microsoft.IdentityModel.Tokens; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.OpenSsl; +using Org.BouncyCastle.Security; - /// - /// from: https://stackoverflow.com/questions/15629551/read-rsa-privatekey-in-c-sharp-and-bouncy-castle - /// - public static class RsaKeyFormatBroker +namespace BrightChain.Engine.Services; + +/// +/// from: https://stackoverflow.com/questions/15629551/read-rsa-privatekey-in-c-sharp-and-bouncy-castle +/// +public static class RsaKeyFormatBroker +{ + public static JwtSecurityToken GenerateJWTToken(SigningCredentials rsaPrivateKey, string audience) { - public static JwtSecurityToken GenerateJWTToken(SigningCredentials rsaPrivateKey, string audience) - { - return new System.IdentityModel.Tokens.Jwt.JwtSecurityToken( - issuer: "BrightChain", - audience: audience, - claims: null, - notBefore: null, - expires: null, - signingCredentials: rsaPrivateKey); - } + return new JwtSecurityToken( + issuer: "BrightChain", + audience: audience, + claims: null, + notBefore: null, + expires: null, + signingCredentials: rsaPrivateKey); + } - private static SecurityKey GetSymmetricSecurityKey(byte[] symmetricKey) - { - return new SymmetricSecurityKey(symmetricKey); - } + private static SecurityKey GetSymmetricSecurityKey(byte[] symmetricKey) + { + return new SymmetricSecurityKey(key: symmetricKey); + } - private static RSAParameters GetRsaParameters(string rsaPrivateKey) + private static RSAParameters GetRsaParameters(string rsaPrivateKey) + { + var byteArray = Encoding.ASCII.GetBytes(s: rsaPrivateKey); + using (var ms = new MemoryStream(buffer: byteArray)) { - var byteArray = Encoding.ASCII.GetBytes(rsaPrivateKey); - using (var ms = new MemoryStream(byteArray)) + using (var sr = new StreamReader(stream: ms)) { - using (var sr = new StreamReader(ms)) - { - // use Bouncy Castle to convert the private key to RSA parameters - var pemReader = new PemReader(sr); - var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair; - return DotNetUtilities.ToRSAParameters(keyPair.Private as RsaPrivateCrtKeyParameters); - } + // use Bouncy Castle to convert the private key to RSA parameters + var pemReader = new PemReader(reader: sr); + var keyPair = pemReader.ReadObject() as AsymmetricCipherKeyPair; + return DotNetUtilities.ToRSAParameters(privKey: keyPair.Private as RsaPrivateCrtKeyParameters); } } + } - /// - /// Import OpenSSH PEM private key string into MS RSACryptoServiceProvider. - /// - /// - /// - public static RSACryptoServiceProvider ImportPrivateKey(string pem) - { - PemReader pr = new PemReader(new StringReader(pem)); - AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject(); - RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private); + /// + /// Import OpenSSH PEM private key string into MS RSACryptoServiceProvider. + /// + /// + /// + public static RSACryptoServiceProvider ImportPrivateKey(string pem) + { + var pr = new PemReader(reader: new StringReader(s: pem)); + var KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject(); + var rsaParams = DotNetUtilities.ToRSAParameters(privKey: (RsaPrivateCrtKeyParameters)KeyPair.Private); - RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams); - csp.ImportParameters(rsaParams); - return csp; - } + var csp = new RSACryptoServiceProvider(); // cspParams); + csp.ImportParameters(parameters: rsaParams); + return csp; + } - /// - /// Import OpenSSH PEM public key string into MS RSACryptoServiceProvider. - /// - /// - /// - public static RSACryptoServiceProvider ImportPublicKey(string pem) - { - PemReader pr = new PemReader(new StringReader(pem)); - AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject(); - RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey); + /// + /// Import OpenSSH PEM public key string into MS RSACryptoServiceProvider. + /// + /// + /// + public static RSACryptoServiceProvider ImportPublicKey(string pem) + { + var pr = new PemReader(reader: new StringReader(s: pem)); + var publicKey = (AsymmetricKeyParameter)pr.ReadObject(); + var rsaParams = DotNetUtilities.ToRSAParameters(rsaKey: (RsaKeyParameters)publicKey); - RSACryptoServiceProvider csp = new RSACryptoServiceProvider();// cspParams); - csp.ImportParameters(rsaParams); - return csp; - } + var csp = new RSACryptoServiceProvider(); // cspParams); + csp.ImportParameters(parameters: rsaParams); + return csp; + } - /// - /// Export private (including public) key from MS RSACryptoServiceProvider into OpenSSH PEM string. - /// slightly modified from https://stackoverflow.com/a/23739932/2860309 - /// - /// - /// - public static string ExportPrivateKey(RSACryptoServiceProvider csp, bool armor = true, bool base64Encode = true) + /// + /// Export private (including public) key from MS RSACryptoServiceProvider into OpenSSH PEM string. + /// slightly modified from https://stackoverflow.com/a/23739932/2860309 + /// + /// + /// + public static string ExportPrivateKey(RSACryptoServiceProvider csp, bool armor = true, bool base64Encode = true) + { + if (csp is null) { - if (csp is null) - { - throw new ArgumentNullException(paramName: nameof(csp)); - } + throw new ArgumentNullException(paramName: nameof(csp)); + } - if (csp.PublicOnly) - { - throw new ArgumentException( - message: "CSP does not contain a private key", - paramName: nameof(csp)); - } + if (csp.PublicOnly) + { + throw new ArgumentException( + message: "CSP does not contain a private key", + paramName: nameof(csp)); + } - string result; // filled at end of using - using (StringWriter outputStream = new StringWriter()) + string result; // filled at end of using + using (var outputStream = new StringWriter()) + { + var parameters = csp.ExportParameters(includePrivateParameters: true); + using (var stream = new MemoryStream()) + using (var writer = new BinaryWriter(output: stream)) { - var parameters = csp.ExportParameters(true); - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) + writer.Write(value: (byte)0x30); // SEQUENCE + using (var innerStream = new MemoryStream()) + using (var innerWriter = new BinaryWriter(output: innerStream)) { - writer.Write((byte)0x30); // SEQUENCE - using (var innerStream = new MemoryStream()) - using (var innerWriter = new BinaryWriter(innerStream)) - { - EncodeIntegerBigEndian(innerWriter, new byte[] { 0x00 }); // Version - EncodeIntegerBigEndian(innerWriter, parameters.Modulus); - EncodeIntegerBigEndian(innerWriter, parameters.Exponent); - EncodeIntegerBigEndian(innerWriter, parameters.D); - EncodeIntegerBigEndian(innerWriter, parameters.P); - EncodeIntegerBigEndian(innerWriter, parameters.Q); - EncodeIntegerBigEndian(innerWriter, parameters.DP); - EncodeIntegerBigEndian(innerWriter, parameters.DQ); - EncodeIntegerBigEndian(innerWriter, parameters.InverseQ); - var length = (int)innerStream.Length; - EncodeLength(writer, length); - writer.Write(innerStream.GetBuffer(), 0, length); // TODO: verify if these should be ToArray() - } + EncodeIntegerBigEndian(stream: innerWriter, + value: new byte[] {0x00}); // Version + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.Modulus); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.Exponent); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.D); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.P); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.Q); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.DP); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.DQ); + EncodeIntegerBigEndian(stream: innerWriter, + value: parameters.InverseQ); + var length = (int)innerStream.Length; + EncodeLength(stream: writer, + length: length); + writer.Write(buffer: innerStream.GetBuffer(), + index: 0, + count: length); // TODO: verify if these should be ToArray() + } - // WriteLine terminates with \r\n, we want only \n - if (armor) - { - outputStream.Write("-----BEGIN RSA PRIVATE KEY-----\n"); - } + // WriteLine terminates with \r\n, we want only \n + if (armor) + { + outputStream.Write(value: "-----BEGIN RSA PRIVATE KEY-----\n"); + } - // Output as Base64 with lines chopped at 64 characters - if (base64Encode) - { - var base64 = Convert.ToBase64String( - inArray: stream.GetBuffer(), - offset: 0, - length: (int)stream.Length).ToCharArray(); - for (var i = 0; i < base64.Length; i += 64) - { - outputStream.Write(base64, i, Math.Min(64, base64.Length - i)); - outputStream.Write("\n"); - } - } - else + // Output as Base64 with lines chopped at 64 characters + if (base64Encode) + { + var base64 = Convert.ToBase64String( + inArray: stream.GetBuffer(), + offset: 0, + length: (int)stream.Length).ToCharArray(); + for (var i = 0; i < base64.Length; i += 64) { - outputStream.Write(stream.GetBuffer()); + outputStream.Write(buffer: base64, + index: i, + count: Math.Min(val1: 64, + val2: base64.Length - i)); + outputStream.Write(value: "\n"); } + } + else + { + outputStream.Write(value: stream.GetBuffer()); + } - if (armor) - { - outputStream.Write("-----END RSA PRIVATE KEY-----"); - } + if (armor) + { + outputStream.Write(value: "-----END RSA PRIVATE KEY-----"); + } - result = outputStream.ToString(); + result = outputStream.ToString(); - return result; - } // end using + return result; } // end using - } // end func - - /// - /// Export public key from MS RSACryptoServiceProvider into OpenSSH PEM string - /// slightly modified from https://stackoverflow.com/a/28407693. - /// - /// - /// - /// - /// - public static string ExportPublicKey(RSACryptoServiceProvider csp, bool armor = true, bool base64Encode = true) + } // end using + } // end func + + /// + /// Export public key from MS RSACryptoServiceProvider into OpenSSH PEM string + /// slightly modified from https://stackoverflow.com/a/28407693. + /// + /// + /// + /// + /// + public static string ExportPublicKey(RSACryptoServiceProvider csp, bool armor = true, bool base64Encode = true) + { + if (csp is null) { - if (csp is null) - { - throw new ArgumentNullException(paramName: nameof(csp)); - } + throw new ArgumentNullException(paramName: nameof(csp)); + } - string result; // filled at end - using (StringWriter outputStream = new StringWriter()) + string result; // filled at end + using (var outputStream = new StringWriter()) + { + var parameters = csp.ExportParameters(includePrivateParameters: false); + using (var stream = new MemoryStream()) + using (var writer = new BinaryWriter(output: stream)) { - var parameters = csp.ExportParameters(false); - using (var stream = new MemoryStream()) - using (var writer = new BinaryWriter(stream)) + writer.Write(value: (byte)0x30); // SEQUENCE + using (var innerStream = new MemoryStream()) + using (var innerWriter = new BinaryWriter(output: innerStream)) { - writer.Write((byte)0x30); // SEQUENCE - using (var innerStream = new MemoryStream()) - using (var innerWriter = new BinaryWriter(innerStream)) + innerWriter.Write(value: (byte)0x30); // SEQUENCE + EncodeLength(stream: innerWriter, + length: 13); + innerWriter.Write(value: (byte)0x06); // OBJECT IDENTIFIER + var rsaEncryptionOid = new byte[] {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}; + EncodeLength(stream: innerWriter, + length: rsaEncryptionOid.Length); + innerWriter.Write(buffer: rsaEncryptionOid); + innerWriter.Write(value: (byte)0x05); // NULL + EncodeLength(stream: innerWriter, + length: 0); + innerWriter.Write(value: (byte)0x03); // BIT STRING + using (var bitStringStream = new MemoryStream()) + using (var bitStringWriter = new BinaryWriter(output: bitStringStream)) { - innerWriter.Write((byte)0x30); // SEQUENCE - EncodeLength(innerWriter, 13); - innerWriter.Write((byte)0x06); // OBJECT IDENTIFIER - var rsaEncryptionOid = new byte[] { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 }; - EncodeLength(innerWriter, rsaEncryptionOid.Length); - innerWriter.Write(rsaEncryptionOid); - innerWriter.Write((byte)0x05); // NULL - EncodeLength(innerWriter, 0); - innerWriter.Write((byte)0x03); // BIT STRING - using (var bitStringStream = new MemoryStream()) - using (var bitStringWriter = new BinaryWriter(bitStringStream)) + bitStringWriter.Write(value: (byte)0x00); // # of unused bits + bitStringWriter.Write(value: (byte)0x30); // SEQUENCE + using (var paramsStream = new MemoryStream()) + using (var paramsWriter = new BinaryWriter(output: paramsStream)) { - bitStringWriter.Write((byte)0x00); // # of unused bits - bitStringWriter.Write((byte)0x30); // SEQUENCE - using (var paramsStream = new MemoryStream()) - using (var paramsWriter = new BinaryWriter(paramsStream)) - { - EncodeIntegerBigEndian(paramsWriter, parameters.Modulus); // Modulus - EncodeIntegerBigEndian(paramsWriter, parameters.Exponent); // Exponent - var paramsLength = (int)paramsStream.Length; - EncodeLength(bitStringWriter, paramsLength); - bitStringWriter.Write(paramsStream.GetBuffer(), 0, paramsLength); - } - var bitStringLength = (int)bitStringStream.Length; - EncodeLength(innerWriter, bitStringLength); - innerWriter.Write(bitStringStream.GetBuffer(), 0, bitStringLength); + EncodeIntegerBigEndian(stream: paramsWriter, + value: parameters.Modulus); // Modulus + EncodeIntegerBigEndian(stream: paramsWriter, + value: parameters.Exponent); // Exponent + var paramsLength = (int)paramsStream.Length; + EncodeLength(stream: bitStringWriter, + length: paramsLength); + bitStringWriter.Write(buffer: paramsStream.GetBuffer(), + index: 0, + count: paramsLength); } - var length = (int)innerStream.Length; - EncodeLength(writer, length); - writer.Write(innerStream.GetBuffer(), 0, length); - } - // WriteLine terminates with \r\n, we want only \n - if (armor) - { - outputStream.Write("-----BEGIN PUBLIC KEY-----\n"); + var bitStringLength = (int)bitStringStream.Length; + EncodeLength(stream: innerWriter, + length: bitStringLength); + innerWriter.Write(buffer: bitStringStream.GetBuffer(), + index: 0, + count: bitStringLength); } - if (base64Encode) - { - var base64 = Convert.ToBase64String( - inArray: stream.GetBuffer(), - offset: 0, - length: (int)stream.Length).ToCharArray(); + var length = (int)innerStream.Length; + EncodeLength(stream: writer, + length: length); + writer.Write(buffer: innerStream.GetBuffer(), + index: 0, + count: length); + } - for (var i = 0; i < base64.Length; i += 64) - { - outputStream.Write(base64, i, Math.Min(64, base64.Length - i)); - outputStream.Write("\n"); - } - } - else - { - outputStream.Write(stream.GetBuffer()); - } + // WriteLine terminates with \r\n, we want only \n + if (armor) + { + outputStream.Write(value: "-----BEGIN PUBLIC KEY-----\n"); + } - if (armor) + if (base64Encode) + { + var base64 = Convert.ToBase64String( + inArray: stream.GetBuffer(), + offset: 0, + length: (int)stream.Length).ToCharArray(); + + for (var i = 0; i < base64.Length; i += 64) { - outputStream.Write("-----END PUBLIC KEY-----"); + outputStream.Write(buffer: base64, + index: i, + count: Math.Min(val1: 64, + val2: base64.Length - i)); + outputStream.Write(value: "\n"); } } + else + { + outputStream.Write(value: stream.GetBuffer()); + } - result = outputStream.ToString(); + if (armor) + { + outputStream.Write(value: "-----END PUBLIC KEY-----"); + } } - return result; + result = outputStream.ToString(); } - /// - /// https://stackoverflow.com/a/23739932/2860309. - /// - /// - /// - private static void EncodeLength(BinaryWriter stream, int length) + return result; + } + + /// + /// https://stackoverflow.com/a/23739932/2860309. + /// + /// + /// + private static void EncodeLength(BinaryWriter stream, int length) + { + if (length < 0) { - if (length < 0) - { - throw new ArgumentOutOfRangeException("length", "Length must be non-negative"); - } + throw new ArgumentOutOfRangeException(paramName: "length", + message: "Length must be non-negative"); + } - if (length < 0x80) + if (length < 0x80) + { + // Short form + stream.Write(value: (byte)length); + } + else + { + // Long form + var temp = length; + var bytesRequired = 0; + while (temp > 0) { - // Short form - stream.Write((byte)length); + temp >>= 8; + bytesRequired++; } - else - { - // Long form - var temp = length; - var bytesRequired = 0; - while (temp > 0) - { - temp >>= 8; - bytesRequired++; - } - stream.Write((byte)(bytesRequired | 0x80)); - for (var i = bytesRequired - 1; i >= 0; i--) - { - stream.Write((byte)(length >> (8 * i) & 0xff)); - } + stream.Write(value: (byte)(bytesRequired | 0x80)); + for (var i = bytesRequired - 1; i >= 0; i--) + { + stream.Write(value: (byte)((length >> (8 * i)) & 0xff)); } } + } - /// - /// https://stackoverflow.com/a/23739932/2860309 - /// - /// - /// - /// - private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true) + /// + /// https://stackoverflow.com/a/23739932/2860309 + /// + /// + /// + /// + private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true) + { + stream.Write(value: (byte)0x02); // INTEGER + var prefixZeros = 0; + for (var i = 0; i < value.Length; i++) { - stream.Write((byte)0x02); // INTEGER - var prefixZeros = 0; - for (var i = 0; i < value.Length; i++) + if (value[i] != 0) { - if (value[i] != 0) - { - break; - } - prefixZeros++; + break; } - if (value.Length - prefixZeros == 0) + prefixZeros++; + } + + if (value.Length - prefixZeros == 0) + { + EncodeLength(stream: stream, + length: 1); + stream.Write(value: (byte)0); + } + else + { + if (forceUnsigned && value[prefixZeros] > 0x7f) { - EncodeLength(stream, 1); - stream.Write((byte)0); + // Add a prefix zero to force unsigned if the MSB is 1 + EncodeLength(stream: stream, + length: value.Length - prefixZeros + 1); + stream.Write(value: (byte)0); } else { - if (forceUnsigned && value[prefixZeros] > 0x7f) - { - // Add a prefix zero to force unsigned if the MSB is 1 - EncodeLength(stream, value.Length - prefixZeros + 1); - stream.Write((byte)0); - } - else - { - EncodeLength(stream, value.Length - prefixZeros); - } + EncodeLength(stream: stream, + length: value.Length - prefixZeros); + } - for (var i = prefixZeros; i < value.Length; i++) - { - stream.Write(value[i]); - } + for (var i = prefixZeros; i < value.Length; i++) + { + stream.Write(value: value[i]); } } } diff --git a/src/BrightChain.Engine/brightChainSettings.json b/src/BrightChain.Engine/brightChainSettings.json old mode 100644 new mode 100755 diff --git a/src/ENT b/src/ENT index edbac712..744e82d6 160000 --- a/src/ENT +++ b/src/ENT @@ -1 +1 @@ -Subproject commit edbac712eabd214b4b508b96c1e66b5f6017db0b +Subproject commit 744e82d666a5546c55302fd8b5b38ccee015a8d7 diff --git a/src/LUHN-mod-n b/src/LUHN-mod-n index e3e885be..423bcfdf 160000 --- a/src/LUHN-mod-n +++ b/src/LUHN-mod-n @@ -1 +1 @@ -Subproject commit e3e885be5ea3068b58f4457848fe52b6e0797589 +Subproject commit 423bcfdfa180e693a9f1d79d9cdc905c2da6ca2f diff --git a/src/NeuralFabric b/src/NeuralFabric new file mode 160000 index 00000000..dbd5761b --- /dev/null +++ b/src/NeuralFabric @@ -0,0 +1 @@ +Subproject commit dbd5761b4e2968dc6912761b32b1625a1b850619 diff --git a/src/Shart b/src/Shart new file mode 160000 index 00000000..18a789c4 --- /dev/null +++ b/src/Shart @@ -0,0 +1 @@ +Subproject commit 18a789c40c077507b76aca5b58fd4ef3e64722bd diff --git a/src/stylecop.json b/src/stylecop.json old mode 100644 new mode 100755 diff --git a/test/BrightChain.Engine.Client.Tests/BrightChain.Engine.Client.Tests.csproj b/test/BrightChain.Engine.Client.Tests/BrightChain.Engine.Client.Tests.csproj old mode 100644 new mode 100755 index acc9adea..f701b73c --- a/test/BrightChain.Engine.Client.Tests/BrightChain.Engine.Client.Tests.csproj +++ b/test/BrightChain.Engine.Client.Tests/BrightChain.Engine.Client.Tests.csproj @@ -7,25 +7,25 @@ - + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - - + + + all diff --git a/test/BrightChain.Engine.Client.Tests/BrightChainClientTests.cs b/test/BrightChain.Engine.Client.Tests/BrightChainClientTests.cs old mode 100644 new mode 100755 index c8501a79..80a699a1 --- a/test/BrightChain.Engine.Client.Tests/BrightChainClientTests.cs +++ b/test/BrightChain.Engine.Client.Tests/BrightChainClientTests.cs @@ -1,20 +1,19 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace BrightChain.Engine.Client.Tests +namespace BrightChain.Engine.Client.Tests; + +[TestClass] +public class BrightChainClientTests { - [TestClass] - public class BrightChainClientTests + [TestInitialize] + public void SetUp() { - [TestInitialize] - public void SetUp() - { - Assert.IsTrue(true); - } + Assert.IsTrue(condition: true); + } - [TestMethod] - public void ItDoesNothingTest() - { - Assert.IsTrue(true); - } + [TestMethod] + public void ItDoesNothingTest() + { + Assert.IsTrue(condition: true); } } diff --git a/test/BrightChain.Engine.Quorum.Tests b/test/BrightChain.Engine.Quorum.Tests new file mode 160000 index 00000000..a1960ec9 --- /dev/null +++ b/test/BrightChain.Engine.Quorum.Tests @@ -0,0 +1 @@ +Subproject commit a1960ec9dcf1651c5b4b77d3f9b24f90b21a6965 diff --git a/test/BrightChain.Engine.Tests/BBPTest.cs b/test/BrightChain.Engine.Tests/BBPTest.cs old mode 100644 new mode 100755 index efa4cd4e..8a99ab0b --- a/test/BrightChain.Engine.Tests/BBPTest.cs +++ b/test/BrightChain.Engine.Tests/BBPTest.cs @@ -1,13 +1,12 @@ -namespace BrightChain.Engine.Tests -{ - using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; - [TestClass] - public class BBPTest +[TestClass] +public class BBPTest +{ + [TestMethod] + public void TestBBP() { - [TestMethod] - public void TestBBP() - { - } } } diff --git a/test/BrightChain.Engine.Tests/BackblazeGaloisTest.cs b/test/BrightChain.Engine.Tests/BackblazeGaloisTest.cs new file mode 100644 index 00000000..4b3ebd10 --- /dev/null +++ b/test/BrightChain.Engine.Tests/BackblazeGaloisTest.cs @@ -0,0 +1,215 @@ +using System.Linq; +using BrightChain.Engine.Quorum.BackblazeReedSolomon; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; + +/// +/// This is a totally paranoid test that ensure that the Galois class +/// actually implements a field, with all of the properties that a field +/// must have. +/// +[TestClass] +public class BackblazeGaloisTest +{ + [TestMethod] + public void testClosure() + { + // Unlike the Python implementation, there is no need to test + // for closure. Because add(), subtract(), multiply(), and + // divide() all return bytes, there's no way they could + // possible return something outside the field. + } + + [TestMethod] + public void testAssociativity() + { + for (var i = -128; i < 128; i++) + { + var a = (byte)i; + for (var j = -128; j < 128; j++) + { + var b = (byte)j; + for (var k = -128; k < 128; k++) + { + var c = (byte)k; + Assert.Equals( + objA: Galois.add(a: a, + b: Galois.add(a: b, + b: c)), + objB: Galois.add(a: Galois.add(a: a, + b: b), + b: c) + ); + Assert.Equals( + objA: Galois.multiply(a: a, + b: (byte)Galois.multiply(a: b, + b: c)), + objB: Galois.multiply(a: (byte)Galois.multiply(a: a, + b: b), + b: c) + ); + } + } + } + } + + [TestMethod] + public void testIdentity() + { + for (var i = -128; i < 128; i++) + { + var a = (byte)i; + Assert.Equals(objA: a, + objB: Galois.add(a: a, + b: 0)); + Assert.Equals(objA: a, + objB: Galois.multiply(a: a, + b: 1)); + } + } + + [TestMethod] + public void testInverse() + { + for (var i = -128; i < 128; i++) + { + sbyte a = (sbyte)i; + { + var b = Galois.subtract(a: 0, + b: (byte) a); + Assert.Equals(objA: 0, + objB: Galois.add(a: (byte) a, + b: b)); + } + if (a != 0) + { + byte b = (byte)Galois.divide( + a: 1, + b: a); + Assert.Equals(objA: 1, + objB: Galois.multiply(a: (byte) a, + b: b)); + } + } + } + + [TestMethod] + public void testCommutativity() + { + for (var i = -128; i < 128; i++) + { + for (var j = -128; j < 128; j++) + { + var a = (byte)i; + var b = (byte)j; + Assert.Equals(objA: Galois.add(a: a, + b: b), + objB: Galois.add(a: b, + b: a)); + Assert.Equals(objA: Galois.multiply(a: a, + b: b), + objB: Galois.multiply(a: b, + b: a)); + } + } + } + + [TestMethod] + public void testDistributivity() + { + for (var i = -128; i < 128; i++) + { + var a = (byte)i; + for (var j = -128; j < 128; j++) + { + var b = (byte)j; + for (var k = -128; k < 128; k++) + { + var c = (byte)k; + Assert.Equals( + objA: Galois.multiply(a: a, + b: Galois.add(a: b, + b: c)), + objB: Galois.add(a: (byte)Galois.multiply(a: a, + b: b), + b: (byte)Galois.multiply(a: a, + b: c)) + ); + } + } + } + } + + [TestMethod] + public void testExp() + { + for (var i = -128; i < 128; i++) + { + var a = (byte)i; + short power = 1; + for (var j = 0; j < 256; j++) + { + Assert.Equals(objA: power, + objB: Galois.exp(a: a, + n: j)); + power = Galois.multiply(a: (byte)power, + b: a); + } + } + } + + [TestMethod] + public void testGenerateLogTable() + { + var logTable = Galois.generateLogTable(polynomial: Galois.GENERATING_POLYNOMIAL); + Assert.IsTrue(condition: Galois.LOG_TABLE.SequenceEqual(second: logTable)); + + var expTable = Galois.generateExpTable(logTable: logTable); + Assert.IsTrue(condition: Galois.EXP_TABLE.SequenceEqual(second: expTable)); + + int[] polynomials = {29, 43, 45, 77, 95, 99, 101, 105, 113, 135, 141, 169, 195, 207, 231, 245}; + Assert.IsTrue(condition: polynomials.SequenceEqual(second: Galois.allPossiblePolynomials())); + } + + [TestMethod] + public void testMultiplicationTable() + { + var table = Galois.MULTIPLICATION_TABLE; + for (var a = -128; a < 128; a++) + { + for (var b = -128; b < 128; b++) + { + Assert.Equals(objA: Galois.multiply(a: (byte)a, + b: (byte)b), + objB: table[a & 0xFF, + b & 0xFF]); + } + } + } + + [TestMethod] + public void testWithPythonAnswers() + { + // These values were copied output of the Python code. + Assert.Equals(objA: 12, + objB: Galois.multiply(a: 3, + b: 4)); + Assert.Equals(objA: 21, + objB: Galois.multiply(a: 7, + b: 7)); + Assert.Equals(objA: 41, + objB: Galois.multiply(a: 23, + b: 45)); + + Assert.Equals(objA: (byte)4, + objB: Galois.exp(a: 2, + n: 2)); + Assert.Equals(objA: (byte)235, + objB: Galois.exp(a: 5, + n: 20)); + Assert.Equals(objA: (byte)43, + objB: Galois.exp(a: 13, + n: 7)); + } +} diff --git a/test/BrightChain.Engine.Tests/BackblazeMatrixTest.cs b/test/BrightChain.Engine.Tests/BackblazeMatrixTest.cs new file mode 100644 index 00000000..1366b7e3 --- /dev/null +++ b/test/BrightChain.Engine.Tests/BackblazeMatrixTest.cs @@ -0,0 +1,9 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class BackblazeMatrixTest +{ + +} diff --git a/test/BrightChain.Engine.Tests/BackblazeReedSolomonTest.cs b/test/BrightChain.Engine.Tests/BackblazeReedSolomonTest.cs new file mode 100644 index 00000000..7d68f228 --- /dev/null +++ b/test/BrightChain.Engine.Tests/BackblazeReedSolomonTest.cs @@ -0,0 +1,9 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class BackblazeReedSolomonTest +{ + +} diff --git a/test/BrightChain.Engine.Tests/BlockValidatorExtensionsTest.cs b/test/BrightChain.Engine.Tests/BlockValidatorExtensionsTest.cs old mode 100644 new mode 100755 index 16be615f..d6cb8dfc --- a/test/BrightChain.Engine.Tests/BlockValidatorExtensionsTest.cs +++ b/test/BrightChain.Engine.Tests/BlockValidatorExtensionsTest.cs @@ -1,84 +1,88 @@ -namespace BrightChain.Engine.Tests +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class BlockValidatorExtensionsTest { - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; + protected ILogger logger { get; set; } - [TestClass] - public class BlockValidatorExtensionsTest + [TestInitialize] + public void PreTestSetUp() { - protected ILogger logger { get; set; } - - [TestInitialize] - public void PreTestSetUp() - { - this.logger = new Mock>().Object; - } + this.logger = new Mock>().Object; + } - [DataTestMethod] - [DataRow(BlockSize.Nano)] - [DataRow(BlockSize.Micro)] - [DataRow(BlockSize.Message)] - [DataRow(BlockSize.Tiny)] - [DataRow(BlockSize.Small)] - [DataRow(BlockSize.Medium)] - [DataRow(BlockSize.Large)] - public void ItValidatesValidBlocksTest(BlockSize blockSize) - { - Assert.IsTrue(new ZeroVectorBlock( + [DataTestMethod] + [DataRow(data1: BlockSize.Nano)] + [DataRow(data1: BlockSize.Micro)] + [DataRow(data1: BlockSize.Message)] + [DataRow(data1: BlockSize.Tiny)] + [DataRow(data1: BlockSize.Small)] + [DataRow(data1: BlockSize.Medium)] + [DataRow(data1: BlockSize.Large)] + public void ItValidatesValidBlocksTest(BlockSize blockSize) + { + Assert.IsTrue(condition: new ZeroVectorBlock( blockParams: new BlockParams( blockSize: blockSize, requestTime: DateTime.Now, keepUntilAtLeast: DateTime.MaxValue, - redundancy: Enumerations.RedundancyContractType.HeapAuto, + redundancy: RedundancyContractType.HeapAuto, privateEncrypted: false, originalType: typeof(ZeroVectorBlock))) - .Validate()); + .Validate()); - var loggerMock = Mock.Get(this.logger); - loggerMock.Verify(l => l.Log( + var loggerMock = Mock.Get(mocked: this.logger); + loggerMock.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), (Func)It.IsAny()), - Times.Exactly(0)); - loggerMock.VerifyNoOtherCalls(); - } + times: Times.Exactly(callCount: 0)); + loggerMock.VerifyNoOtherCalls(); + } - [TestMethod, Ignore] - public void ItValidatesUnknownBlockSizeTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItValidatesUnknownBlockSizeTest() + { + throw new NotImplementedException(); + } - [TestMethod, Ignore] - public void ItValidatesBlockSizeMatchesDataSizeTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItValidatesBlockSizeMatchesDataSizeTest() + { + throw new NotImplementedException(); + } - [TestMethod, Ignore] - public void ItValidatesBlockHashMatchesBlockHashTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItValidatesBlockHashMatchesBlockHashTest() + { + throw new NotImplementedException(); + } - [TestMethod, Ignore] - public void ItValidatesStorageContractDataLengthTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItValidatesStorageContractDataLengthTest() + { + throw new NotImplementedException(); + } - [TestMethod, Ignore] - public void ItValidatesStorageContractMatchesRedundancyContractTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItValidatesStorageContractMatchesRedundancyContractTest() + { + throw new NotImplementedException(); } } diff --git a/test/BrightChain.Engine.Tests/BrightChain.Engine.Tests.csproj b/test/BrightChain.Engine.Tests/BrightChain.Engine.Tests.csproj old mode 100644 new mode 100755 index f338fdf6..6b582d9a --- a/test/BrightChain.Engine.Tests/BrightChain.Engine.Tests.csproj +++ b/test/BrightChain.Engine.Tests/BrightChain.Engine.Tests.csproj @@ -27,26 +27,26 @@ - + - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - - + + + diff --git a/test/BrightChain.Engine.Tests/BrightChainBlockServiceTest.cs b/test/BrightChain.Engine.Tests/BrightChainBlockServiceTest.cs old mode 100644 new mode 100755 index 2e825430..40c45e6d --- a/test/BrightChain.Engine.Tests/BrightChainBlockServiceTest.cs +++ b/test/BrightChain.Engine.Tests/BrightChainBlockServiceTest.cs @@ -1,213 +1,220 @@ -namespace BrightChain.Engine.Tests +using System; +using System.IO; +using System.Threading.Tasks; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +using static Utilities; + +/// +/// Exercises the core API service +/// +[TestClass] +public class BrightChainBlockServiceTest { - using System; - using System.IO; - using System.Threading.Tasks; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Services; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using static BrightChain.Engine.Helpers.Utilities; + private IConfiguration _configuration; + private ILogger _logger; + private ILoggerFactory _loggerFactory; + private IServiceCollection _services; - /// - /// Exercises the core API service - /// - [TestClass] - public class BrightChainBlockServiceTest + [TestInitialize] + public void PreTestSetup() { - private ILoggerFactory _loggerFactory; - private IConfiguration _configuration; - private IServiceCollection _services; - private ILogger _logger; + var mockConfiguration = new Mock(); - [TestInitialize] - public void PreTestSetup() - { - var mockConfiguration = new Mock(); + this._configuration = mockConfiguration.Object; + this._services = new Mock().Object; + this._logger = new Mock().Object; - this._configuration = mockConfiguration.Object; - this._services = new Mock().Object; - this._logger = new Mock().Object; + var mockPathSection = new Mock(); + mockPathSection.Setup(expression: x => x.Value).Returns(value: Path.GetTempPath()); - Mock mockPathSection = new Mock(); - mockPathSection.Setup(x => x.Value).Returns(Path.GetTempPath()); + var mockNodeSection = new Mock(); + mockNodeSection.Setup(expression: x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(value: mockPathSection.Object); - var mockNodeSection = new Mock(); - mockNodeSection.Setup(x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(mockPathSection.Object); + mockConfiguration.Setup(expression: x => x.GetSection(It.Is(k => k == "NodeOptions"))) + .Returns(value: mockNodeSection.Object); - mockConfiguration.Setup(x => x.GetSection(It.Is(k => k == "NodeOptions"))).Returns(mockNodeSection.Object); + var factoryMock = new Mock(); - var factoryMock = new Mock(); + factoryMock + .SetupAllProperties() + .Setup(expression: f => f.CreateLogger(It.IsAny())).Returns(value: this._logger); - factoryMock - .SetupAllProperties() - .Setup(f => f.CreateLogger(It.IsAny())).Returns(this._logger); - - this._loggerFactory = factoryMock.Object; - } + this._loggerFactory = factoryMock.Object; + } - [TestMethod] - public void ItInitializesTest() - { - var loggerMock = Mock.Get(this._logger); + [TestMethod] + public void ItInitializesTest() + { + var loggerMock = Mock.Get(mocked: this._logger); - var brightChainService = new BrightBlockService( - logger: this._loggerFactory, - configuration: this._configuration); + var brightChainService = new BrightBlockService( + logger: this._loggerFactory, + configuration: this._configuration); - loggerMock.Verify(l => l.Log( + loggerMock.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(2)); - loggerMock.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 2)); + loggerMock.VerifyNoOtherCalls(); + } - /// - /// TODO: move to BlockHashTests. - /// - [DataTestMethod] - //[DataRow(BlockSize.Nano)] - //[DataRow(BlockSize.Micro)] - [DataRow(BlockSize.Message)] - [DataRow(BlockSize.Tiny)] - [DataRow(BlockSize.Small)] - [DataRow(BlockSize.Medium)] - [DataRow(BlockSize.Large)] - public void ItHasCorrectHashSizesTest(BlockSize blockSize) - { - var expectedVector = BlockSizeMap.ZeroVectorHash(blockSize); - BlockHash zeroVector; - GenerateZeroVectorAndVerify(blockSize, out zeroVector); - Assert.IsNotNull(zeroVector); - Assert.AreEqual(expectedVector.ToString(), zeroVector.ToString()); - } + /// + /// TODO: move to BlockHashTests. + /// + [DataTestMethod] + //[DataRow(BlockSize.Nano)] + //[DataRow(BlockSize.Micro)] + [DataRow(data1: BlockSize.Message)] + [DataRow(data1: BlockSize.Tiny)] + [DataRow(data1: BlockSize.Small)] + [DataRow(data1: BlockSize.Medium)] + [DataRow(data1: BlockSize.Large)] + public void ItHasCorrectHashSizesTest(BlockSize blockSize) + { + var expectedVector = BlockSizeMap.ZeroVectorHash(blockSize: blockSize); + BlockHash zeroVector; + GenerateZeroVectorAndVerify(blockSize: blockSize, + blockHash: out zeroVector); + Assert.IsNotNull(value: zeroVector); + Assert.AreEqual(expected: expectedVector.ToString(), + actual: zeroVector.ToString()); + } - [DataTestMethod] - //[DataRow(BlockSize.Nano)] - //[DataRow(BlockSize.Micro)] - [DataRow(BlockSize.Message)] - [DataRow(BlockSize.Tiny)] - [DataRow(BlockSize.Small)] - [DataRow(BlockSize.Medium)] - [DataRow(BlockSize.Large)] + [DataTestMethod] + //[DataRow(BlockSize.Nano)] + //[DataRow(BlockSize.Micro)] + [DataRow(data1: BlockSize.Message)] + [DataRow(data1: BlockSize.Tiny)] + [DataRow(data1: BlockSize.Small)] + [DataRow(data1: BlockSize.Medium)] + [DataRow(data1: BlockSize.Large)] + public async Task ItBrightensBlocksAndCreatesCblsTest(BlockSize blockSize) + { + var loggerMock = Mock.Get(mocked: this._logger); + + var brightChainService = new BrightBlockService( + logger: this._loggerFactory, + configuration: this._configuration); + + var sourceInfo = RandomDataHelper.GenerateRandomFile( + blockSize: blockSize, + lengthFunc: blockSize => + (BlockSizeMap.BlockSize(blockSize: blockSize) * 2) + 7); // don't land on even block mark for data testing + + var brightenedCbl = await brightChainService.MakeCblOrSuperCblFromFileAsync( + fileName: sourceInfo.FileInfo.FullName, + blockParams: new BlockParams( + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.HeapAuto, + privateEncrypted: false, + blockSize: blockSize, + originalType: typeof(ConstituentBlockListBlock))); - public async Task ItBrightensBlocksAndCreatesCblsTest(BlockSize blockSize) + if (brightenedCbl is SuperConstituentBlockListBlock) { - var loggerMock = Mock.Get(this._logger); - - var brightChainService = new BrightBlockService( - logger: this._loggerFactory, - configuration: this._configuration); - - var sourceInfo = RandomDataHelper.GenerateRandomFile( - blockSize: blockSize, - lengthFunc: (BlockSize blockSize) => - (BlockSizeMap.BlockSize(blockSize) * 2) + 7); // don't land on even block mark for data testing - - BrightChain brightenedCbl = await brightChainService.MakeCblOrSuperCblFromFileAsync( - fileName: sourceInfo.FileInfo.FullName, - blockParams: new BlockParams( - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: Enumerations.RedundancyContractType.HeapAuto, - privateEncrypted: false, - blockSize: blockSize, - originalType: typeof(ConstituentBlockListBlock))); - - if (brightenedCbl is SuperConstituentBlockListBlock) + throw new NotImplementedException(); + foreach (var blockHash in brightenedCbl.ConstituentBlocks) { - throw new NotImplementedException(); - foreach (var blockHash in brightenedCbl.ConstituentBlocks) - { - var fetchedBlock = await brightChainService - .FindBlockByIdAsync(blockHash) - .ConfigureAwait(false); - var cbl = (SuperConstituentBlockListBlock)fetchedBlock.AsBlock; - Assert.IsTrue(cbl.Validate()); - Assert.AreEqual(sourceInfo.FileInfo.Length, cbl.TotalLength); - Assert.AreEqual( - HashToFormattedString(sourceInfo.SourceId.HashBytes.ToArray()), - HashToFormattedString(cbl.SourceId.HashBytes.ToArray())); - - var cblMap = cbl.CreateBrightMap(); - Assert.IsTrue(cblMap is BrightMap); - } - } - else - { - Assert.IsTrue(brightenedCbl.Validate()); - Assert.AreEqual(sourceInfo.FileInfo.Length, brightenedCbl.TotalLength); + var fetchedBlock = await brightChainService + .FindBlockByIdAsync(id: blockHash) + .ConfigureAwait(continueOnCapturedContext: false); + var cbl = (SuperConstituentBlockListBlock)fetchedBlock.AsBlock; + Assert.IsTrue(condition: cbl.Validate()); + Assert.AreEqual(expected: sourceInfo.FileInfo.Length, + actual: cbl.TotalLength); Assert.AreEqual( - HashToFormattedString(sourceInfo.SourceId.HashBytes.ToArray()), - HashToFormattedString(brightenedCbl.SourceId.HashBytes.ToArray())); + expected: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: sourceInfo.SourceId.HashBytes.ToArray()), + actual: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: cbl.SourceId.HashBytes.ToArray())); - var cblMap = brightenedCbl.CreateBrightMap(); - Assert.IsTrue(cblMap is BrightMap); + var cblMap = cbl.CreateBrightMap(); + Assert.IsTrue(condition: cblMap is BrightMap); } + } + + { + Assert.IsTrue(condition: brightenedCbl.Validate()); + Assert.AreEqual(expected: sourceInfo.FileInfo.Length, + actual: brightenedCbl.TotalLength); + Assert.AreEqual( + expected: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: sourceInfo.SourceId.HashBytes.ToArray()), + actual: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: brightenedCbl.SourceId.HashBytes.ToArray())); + + var cblMap = brightenedCbl.CreateBrightMap(); + Assert.IsTrue(condition: cblMap is BrightMap); + } - loggerMock.Verify(l => l.Log( + loggerMock.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(2)); - loggerMock.VerifyNoOtherCalls(); - } - - [DataTestMethod] - //[DataRow(BlockSize.Nano)] - //[DataRow(BlockSize.Micro)] - [DataRow(BlockSize.Message)] - [DataRow(BlockSize.Tiny)] - [DataRow(BlockSize.Small)] - [DataRow(BlockSize.Medium)] - [DataRow(BlockSize.Large)] - public async Task ItReadsCBLsBackToDisk(BlockSize blockSize) - { - var loggerMock = Mock.Get(this._logger); - - var brightChainService = new BrightBlockService( - logger: this._loggerFactory, - configuration: this._configuration); + (Func)It.IsAny()), + times: Times.Exactly(callCount: 2)); + loggerMock.VerifyNoOtherCalls(); + } - var sourceInfo = RandomDataHelper.GenerateRandomFile( + [DataTestMethod] + //[DataRow(BlockSize.Nano)] + //[DataRow(BlockSize.Micro)] + [DataRow(data1: BlockSize.Message)] + [DataRow(data1: BlockSize.Tiny)] + [DataRow(data1: BlockSize.Small)] + [DataRow(data1: BlockSize.Medium)] + [DataRow(data1: BlockSize.Large)] + public async Task ItReadsCBLsBackToDisk(BlockSize blockSize) + { + var loggerMock = Mock.Get(mocked: this._logger); + + var brightChainService = new BrightBlockService( + logger: this._loggerFactory, + configuration: this._configuration); + + var sourceInfo = RandomDataHelper.GenerateRandomFile( + blockSize: blockSize, + lengthFunc: blockSize => + (BlockSizeMap.BlockSize(blockSize: blockSize) * 2) + 7); // don't land on even block mark for data testing + + ConstituentBlockListBlock cblBlock = await brightChainService.MakeCblOrSuperCblFromFileAsync( + fileName: sourceInfo.FileInfo.FullName, + blockParams: new BlockParams( + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.HeapAuto, + privateEncrypted: false, blockSize: blockSize, - lengthFunc: (BlockSize blockSize) => - (BlockSizeMap.BlockSize(blockSize) * 2) + 7); // don't land on even block mark for data testing - - ConstituentBlockListBlock cblBlock = await brightChainService.MakeCblOrSuperCblFromFileAsync( - fileName: sourceInfo.FileInfo.FullName, - blockParams: new BlockParams( - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: Enumerations.RedundancyContractType.HeapAuto, - privateEncrypted: false, - blockSize: blockSize, - originalType: typeof(ConstituentBlockListBlock))); + originalType: typeof(ConstituentBlockListBlock))); - var restoredFile = await brightChainService.RestoreFileFromCBLAsync(cblBlock); + var restoredFile = await brightChainService.RestoreFileFromCBLAsync(constituentBlockListBlock: cblBlock); - Assert.AreEqual( - HashToFormattedString(sourceInfo.SourceId.HashBytes.ToArray()), - HashToFormattedString(restoredFile.SourceId.HashBytes.ToArray())); + Assert.AreEqual( + expected: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: sourceInfo.SourceId.HashBytes.ToArray()), + actual: NeuralFabric.Helpers.Utilities.HashToFormattedString(hashBytes: restoredFile.SourceId.HashBytes.ToArray())); - loggerMock.Verify(l => l.Log( + loggerMock.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(2)); - loggerMock.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 2)); + loggerMock.VerifyNoOtherCalls(); } } diff --git a/test/BrightChain.Engine.Tests/BrightChainKeyServiceTest.cs b/test/BrightChain.Engine.Tests/BrightChainKeyServiceTest.cs old mode 100644 new mode 100755 index da67d4e4..93d84e62 --- a/test/BrightChain.Engine.Tests/BrightChainKeyServiceTest.cs +++ b/test/BrightChain.Engine.Tests/BrightChainKeyServiceTest.cs @@ -1,61 +1,66 @@ -namespace BrightChain.Engine.Tests +using BrightChain.Engine.Services; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class BrightChainKeyServiceTest { - using BrightChain.Engine.Services; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - - [TestClass] - public class BrightChainKeyServiceTest + private readonly IConfiguration configuration; + + //private BlockCacheManager blockCacheManager; + private ILogger logger; + + [TestInitialize] + public void SetUp() + { + this.logger = new Mock().Object; + var mockConfiguration = new Mock(); + + //Mock mockSection = new Mock(); + //mockSection.Setup(x => x.Value).Returns(Path.GetTempPath()); + //mockConfiguration.Setup(x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(mockSection.Object); + //this.configuration = new Mock().Object; + // the cache manager under test + //var mockCacheManager = new Mock(this.logger, this.configuration); + //this.blockCacheManager = mockCacheManager.Object; + } + + [TestMethod] + public void ItLoadsPrivateKeysTest() { - //private BlockCacheManager blockCacheManager; - private ILogger logger; - private readonly IConfiguration configuration; - - [TestInitialize] - public void SetUp() - { - this.logger = new Moq.Mock().Object; - var mockConfiguration = new Mock(); - - //Mock mockSection = new Mock(); - //mockSection.Setup(x => x.Value).Returns(Path.GetTempPath()); - //mockConfiguration.Setup(x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(mockSection.Object); - //this.configuration = new Mock().Object; - // the cache manager under test - //var mockCacheManager = new Mock(this.logger, this.configuration); - //this.blockCacheManager = mockCacheManager.Object; - } - - [TestMethod] - public void ItLoadsPrivateKeysTest() - { - const string privateKey = "c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef"; - var privateECDsa = BrightChainKeyService.LoadPrivateKey(privateKey); - Assert.IsNotNull(privateECDsa); - } - - [TestMethod] - public void ItLoadsPublicKeysTest() - { - const string publicKey = "04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb"; - var publicECDsa = BrightChainKeyService.LoadPublicKey(publicKey); - Assert.IsNotNull(publicECDsa); - } - - [TestMethod] - public void ItValidatesJwtTest() - { - const string privateKey = "c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef"; - const string publicKey = "04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb"; - - var privateECDsa = BrightChainKeyService.LoadPrivateKey(privateKey); - var publicECDsa = BrightChainKeyService.LoadPublicKey(publicKey); - - var jwt = BrightChainKeyService.CreateSignedJwt(privateECDsa, "user1234"); - var isValid = BrightChainKeyService.VerifySignedJwt(publicECDsa, jwt, "user1234"); - Assert.IsTrue(isValid); - } + const string privateKey = "c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef"; + var privateECDsa = BrightChainKeyService.LoadPrivateKey(hexKeyString: privateKey); + Assert.IsNotNull(value: privateECDsa); + } + + [TestMethod] + public void ItLoadsPublicKeysTest() + { + const string publicKey = + "04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb"; + var publicECDsa = BrightChainKeyService.LoadPublicKey(hexKeyString: publicKey); + Assert.IsNotNull(value: publicECDsa); + } + + [TestMethod] + public void ItValidatesJwtTest() + { + const string privateKey = "c711e5080f2b58260fe19741a7913e8301c1128ec8e80b8009406e5047e6e1ef"; + const string publicKey = + "04e33993f0210a4973a94c26667007d1b56fe886e8b3c2afdd66aa9e4937478ad20acfbdc666e3cec3510ce85d40365fc2045e5adb7e675198cf57c6638efa1bdb"; + + var privateECDsa = BrightChainKeyService.LoadPrivateKey(hexKeyString: privateKey); + var publicECDsa = BrightChainKeyService.LoadPublicKey(hexKeyString: publicKey); + + var jwt = BrightChainKeyService.CreateSignedJwt(eCDsa: privateECDsa, + audience: "user1234"); + var isValid = BrightChainKeyService.VerifySignedJwt(eCDsa: publicECDsa, + token: jwt, + audience: "user1234"); + Assert.IsTrue(condition: isValid); } } diff --git a/test/BrightChain.Engine.Tests/CacheManagerTest.cs b/test/BrightChain.Engine.Tests/CacheManagerTest.cs old mode 100644 new mode 100755 index 19d907e0..9dca45a8 --- a/test/BrightChain.Engine.Tests/CacheManagerTest.cs +++ b/test/BrightChain.Engine.Tests/CacheManagerTest.cs @@ -1,243 +1,256 @@ -namespace BrightChain.Engine.Tests +using System; +using System.Collections.Generic; +using System.IO; +using BrightChain.Engine.Interfaces; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +/// +/// Test harness for cache managers. Inherit, implement, and run. It will excercise your cache. +/// +/// +/// +/// +[TestClass] +public abstract class CacheManagerTest + where Tkey : IComparable + where Tvalue : IComparable + where Tcache : ICacheManager { - using System; - using System.Collections.Generic; - using System.IO; - using BrightChain.Engine.Interfaces; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; + protected Tcache cacheManager; + protected Mock configuration; + protected Mock> logger; /// - /// Test harness for cache managers. Inherit, implement, and run. It will excercise your cache. + /// Each test will generate a cache key to be set/get/etc /// - /// - /// - /// - [TestClass] - public abstract class CacheManagerTest - where Tkey : IComparable - where Tvalue : IComparable - where Tcache : ICacheManager - { - protected Mock> logger; - protected Mock configuration; - protected Tcache cacheManager; - - /// - /// Creates a new value type for test using the standard new(). Override to be more rigorous or for special cases. - /// - /// - abstract internal KeyValuePair NewKeyValue(); - - /// - /// Due to the generics/templates, we are not able to return null at compile time at this class level. The derived classes will have to just have a simple method that returns null. - /// - /// - abstract internal Tvalue NewNullData(); - - /// - /// Method for the derived tests to instantiate the cache manager for the tests with all the right options - /// - /// - abstract internal Tcache NewCacheManager(ILogger logger, IConfiguration configuration); - - /// - /// Each test will generate a cache key to be set/get/etc - /// - protected KeyValuePair testPair; - - public CacheManagerTest() - { - } + protected KeyValuePair testPair; - [TestInitialize] - public void PreTestSetup() - { - this.logger = new Mock>(); - this.configuration = new Mock(); + /// + /// Creates a new value type for test using the standard new(). Override to be more rigorous or for special cases. + /// + /// + internal abstract KeyValuePair NewKeyValue(); - Mock mockPathSection = new Mock(); - mockPathSection.Setup(x => x.Value).Returns(Path.GetTempPath()); + /// + /// Due to the generics/templates, we are not able to return null at compile time at this class level. The derived classes will have to + /// just have a simple method that returns null. + /// + /// + internal abstract Tvalue NewNullData(); - var mockNodeSection = new Mock(); - mockNodeSection.Setup(x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(mockPathSection.Object); + /// + /// Method for the derived tests to instantiate the cache manager for the tests with all the right options + /// + /// + internal abstract Tcache NewCacheManager(ILogger logger, IConfiguration configuration); - this.configuration.Setup(x => x.GetSection(It.Is(k => k == "NodeOptions"))).Returns(mockNodeSection.Object); + [TestInitialize] + public void PreTestSetup() + { + this.logger = new Mock>(); + this.configuration = new Mock(); - // the cache manager under test - this.cacheManager = this.NewCacheManager(logger: this.logger.Object, configuration: this.configuration.Object); + var mockPathSection = new Mock(); + mockPathSection.Setup(expression: x => x.Value).Returns(value: Path.GetTempPath()); - // a key to be used for each test - this.testPair = this.NewKeyValue(); - Assert.IsFalse(this.cacheManager.Contains(this.testPair.Key)); - // at this point, the tests begin, knowing the key is not already in the cache - } + var mockNodeSection = new Mock(); + mockNodeSection.Setup(expression: x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(value: mockPathSection.Object); - /// - /// Create and push a non null object into the cache - /// - [TestMethod] - public void ItPutsNonNullValuesTest() - { - // Arrange - // generate a new value type - // pre-setup + this.configuration.Setup(expression: x => x.GetSection(It.Is(k => k == "NodeOptions"))) + .Returns(value: mockNodeSection.Object); - // Act - this.cacheManager.Set(this.testPair.Key, this.testPair.Value); + // the cache manager under test + this.cacheManager = this.NewCacheManager(logger: this.logger.Object, + configuration: this.configuration.Object); - // Assert - Assert.IsNotNull(this.testPair.Key); - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); - this.logger.Verify(l => l.Log( + // a key to be used for each test + this.testPair = this.NewKeyValue(); + Assert.IsFalse(condition: this.cacheManager.Contains(key: this.testPair.Key)); + // at this point, the tests begin, knowing the key is not already in the cache + } + + /// + /// Create and push a non null object into the cache + /// + [TestMethod] + public void ItPutsNonNullValuesTest() + { + // Arrange + // generate a new value type + // pre-setup + + // Act + this.cacheManager.Set(key: this.testPair.Key, + value: this.testPair.Value); + + // Assert + Assert.IsNotNull(value: this.testPair.Key); + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } - - /// - /// Push a null value into the cache - /// - [TestMethod] - public virtual void ItPutsNullValuesTest() - { - // Arrange - Tvalue newData = this.NewNullData(); + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); + } - // Act - this.cacheManager.Set(this.testPair.Key, newData); + /// + /// Push a null value into the cache + /// + [TestMethod] + public virtual void ItPutsNullValuesTest() + { + // Arrange + var newData = this.NewNullData(); + + // Act + this.cacheManager.Set(key: this.testPair.Key, + value: newData); - // Assert - Assert.IsNull(newData); - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); - this.logger.Verify(l => l.Log( + // Assert + Assert.IsNull(value: newData); + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } - - /// - /// Ensure a k/v placed into the cache emerge when a get request occurs - /// - [TestMethod] - public void ItHitsTheCacheTest() - { - // Arrange - var expectation = this.testPair.Value; - this.cacheManager.Set(this.testPair.Key, expectation); - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); + } - // Act - Tvalue result = this.cacheManager.Get(this.testPair.Key); + /// + /// Ensure a k/v placed into the cache emerge when a get request occurs + /// + [TestMethod] + public void ItHitsTheCacheTest() + { + // Arrange + var expectation = this.testPair.Value; + this.cacheManager.Set(key: this.testPair.Key, + value: expectation); + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); + + // Act + var result = this.cacheManager.Get(blockHash: this.testPair.Key); - // Assert - Assert.IsNotNull(expectation); - Assert.AreEqual(expectation, result); - this.logger.Verify(l => l.Log( + // Assert + Assert.IsNotNull(value: expectation); + Assert.AreEqual(expected: expectation, + actual: result); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } - - /// - /// Look for an item not already in the cache - /// - [TestMethod] - public void ItMissesTheCacheTest() + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); + } + + /// + /// Look for an item not already in the cache + /// + [TestMethod] + public void ItMissesTheCacheTest() + { + // Arrange + // none + + // Assert[/act] + Assert.ThrowsException(action: () => { - // Arrange - // none - - // Assert[/act] - Assert.ThrowsException(() => - { - // Act - Tvalue result = this.cacheManager.Get(this.testPair.Key); - }); - this.logger.Verify(l => l.Log( + // Act + var result = this.cacheManager.Get(blockHash: this.testPair.Key); + }); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } - - /// - /// Make sure items are removed from the cache - /// - [TestMethod] - public void ItDropsCacheKeysTest() - { - // Arrange - this.cacheManager.Set(this.testPair.Key, this.testPair.Value); - // verify that the key tests good before we drop - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); + } - // Act - this.cacheManager.Drop(this.testPair.Key); + /// + /// Make sure items are removed from the cache + /// + [TestMethod] + public void ItDropsCacheKeysTest() + { + // Arrange + this.cacheManager.Set(key: this.testPair.Key, + value: this.testPair.Value); + // verify that the key tests good before we drop + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); - // Assert - Assert.IsFalse(this.cacheManager.Contains(this.testPair.Key)); - this.logger.Verify(l => l.Log( + // Act + this.cacheManager.Drop(key: this.testPair.Key); + + // Assert + Assert.IsFalse(condition: this.cacheManager.Contains(key: this.testPair.Key)); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } - - /// - /// ignored test since TTL is not yet implemented - /// - /// - [TestMethod, Ignore] - public void ItExpiresCacheKeysTest() + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); + } + + /// + /// ignored test since TTL is not yet implemented + /// + /// + [TestMethod] + [Ignore] + public void ItExpiresCacheKeysTest() + { + var expectation = this.testPair.Value; + this.cacheManager.Set(key: this.testPair.Key, + value: expectation); + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); + // TODO: System.Threading.Thread.Sleep((cacheManager.TTL * 1000) + 1); + Assert.IsFalse(condition: this.cacheManager.Contains(key: this.testPair.Key)); + Assert.ThrowsException(action: () => { - var expectation = this.testPair.Value; - this.cacheManager.Set(this.testPair.Key, expectation); - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); - // TODO: System.Threading.Thread.Sleep((cacheManager.TTL * 1000) + 1); - Assert.IsFalse(this.cacheManager.Contains(this.testPair.Key)); - Assert.ThrowsException(() => - { - Tvalue result = this.cacheManager.Get(this.testPair.Key); - Assert.IsNull(result); - }); - this.logger.Verify(l => l.Log( + var result = this.cacheManager.Get(blockHash: this.testPair.Key); + Assert.IsNull(value: result); + }); + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(4)); - this.logger.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 4)); + this.logger.VerifyNoOtherCalls(); + } - [TestMethod] - public void ItVerifiesCacheDataIntegrityTest() - { - // Arrange - var expectation = this.testPair.Value; - this.cacheManager.Set(this.testPair.Key, expectation); + [TestMethod] + public void ItVerifiesCacheDataIntegrityTest() + { + // Arrange + var expectation = this.testPair.Value; + this.cacheManager.Set(key: this.testPair.Key, + value: expectation); - // Act - Tvalue result = this.cacheManager.Get(this.testPair.Key); + // Act + var result = this.cacheManager.Get(blockHash: this.testPair.Key); - // Assert - Assert.IsNotNull(expectation); - Assert.AreEqual(expectation, result); - } + // Assert + Assert.IsNotNull(value: expectation); + Assert.AreEqual(expected: expectation, + actual: result); } } diff --git a/test/BrightChain.Engine.Tests/ChainLinqDataBlockTest.cs b/test/BrightChain.Engine.Tests/ChainLinqDataBlockTest.cs old mode 100644 new mode 100755 index 6481b6fa..e5e472b0 --- a/test/BrightChain.Engine.Tests/ChainLinqDataBlockTest.cs +++ b/test/BrightChain.Engine.Tests/ChainLinqDataBlockTest.cs @@ -1,156 +1,177 @@ -namespace BrightChain.Engine.Tests +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Faster.CacheManager; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Services; +using BrightChain.Engine.Services.CacheManagers.Block; +using BrightChain.Engine.Tests.TestModels; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class ChainLinqDataBlockTest { - using System; - using System.Collections.Generic; - using System.IO; - using System.Linq; - using System.Threading.Tasks; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Faster.CacheManager; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Services; - using BrightChain.Engine.Services.CacheManagers.Block; - using BrightChain.Engine.Tests.TestModels; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - - [TestClass] - public class ChainLinqDataBlockTest + protected BrightenedBlockCacheManagerBase cacheManager; + protected Mock configuration; + protected Mock> logger; + protected Mock loggerFactory; + + [TestInitialize] + public void PreTestSetup() { - protected Mock> logger; - protected Mock configuration; - protected Mock loggerFactory; - protected BrightenedBlockCacheManagerBase cacheManager; + this.logger = new Mock>(); + this.configuration = new Mock(); - [TestInitialize] - public new void PreTestSetup() - { - this.logger = new Mock>(); - this.configuration = new Mock(); + var factoryMock = new Mock(); - var factoryMock = new Mock(); + factoryMock + .SetupAllProperties() + .Setup(expression: f => f.CreateLogger(It.IsAny())).Returns(value: this.logger.Object); - factoryMock - .SetupAllProperties() - .Setup(f => f.CreateLogger(It.IsAny())).Returns(this.logger.Object); + this.loggerFactory = factoryMock; - this.loggerFactory = factoryMock; + var mockPathSection = new Mock(); + mockPathSection.Setup(expression: x => x.Value).Returns(value: Path.GetTempPath()); - Mock mockPathSection = new Mock(); - mockPathSection.Setup(x => x.Value).Returns(Path.GetTempPath()); + var mockNodeSection = new Mock(); + mockNodeSection.Setup(expression: x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(value: mockPathSection.Object); - var mockNodeSection = new Mock(); - mockNodeSection.Setup(x => x.GetSection(It.Is(k => k == "BasePath"))).Returns(mockPathSection.Object); + this.configuration.Setup(expression: x => x.GetSection(It.Is(k => k == "NodeOptions"))) + .Returns(value: mockNodeSection.Object); - this.configuration.Setup(x => x.GetSection(It.Is(k => k == "NodeOptions"))).Returns(mockNodeSection.Object); + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + this.cacheManager = new FasterBlockCacheManager( + logger: this.logger.Object, + configuration: this.configuration.Object, + rootBlock: rootBlock, + testingSelfDestruct: true); + } - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - this.cacheManager = new FasterBlockCacheManager( - logger: this.logger.Object, - configuration: this.configuration.Object, - rootBlock: rootBlock, - testingSelfDestruct: true); - } + public async Task ForgeChainAsync(BrightBlockService brightBlockService, BlockSize blockSize, + int objectCount) + { + var requestParams = new BlockParams( + blockSize: blockSize, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.HeapAuto, + privateEncrypted: false, + originalType: typeof(ChainLinqObjectBlock)); + + var datas = ChainLinqExampleSerializable.MakeMultiple(count: objectCount); + Assert.AreEqual(expected: objectCount, + actual: datas.Count()); + + var chainLinq = ChainLinq.ForgeChainLinq( + blockParams: requestParams, + objects: datas); + Assert.AreEqual(expected: objectCount, + actual: chainLinq.Count()); + + var brightChain = await chainLinq.BrightenAllAsync( + brightBlockService: brightBlockService); + + return brightChain; + } - public async Task ForgeChainAsync(BrightBlockService brightBlockService, BlockSize blockSize, int objectCount) - { - var requestParams = new BlockParams( - blockSize: blockSize, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: RedundancyContractType.HeapAuto, - privateEncrypted: false, - originalType: typeof(ChainLinqObjectBlock)); - - var datas = ChainLinqExampleSerializable.MakeMultiple(objectCount); - Assert.AreEqual(objectCount, datas.Count()); - - var chainLinq = ChainLinq.ForgeChainLinq( - blockParams: requestParams, - objects: datas); - Assert.AreEqual(objectCount, chainLinq.Count()); - - var brightChain = await chainLinq.BrightenAllAsync( - brightBlockService: brightBlockService); - - return brightChain; - } - - [DataTestMethod] - //[DataRow(BlockSize.Nano, 2)] - //[DataRow(BlockSize.Micro, 2)] - [DataRow(BlockSize.Message, 4)] - [DataRow(BlockSize.Tiny, 4)] - [DataRow(BlockSize.Small, 4)] - [DataRow(BlockSize.Medium, 4)] - [DataRow(BlockSize.Large, 4)] - public async Task ItSavesDataCorrectlyTest(BlockSize blockSize, int objectCount) - { - var brightBlockService = new BrightBlockService( - logger: this.loggerFactory.Object, - configuration: this.configuration.Object); - - var brightChain = await this.ForgeChainAsync( - brightBlockService: brightBlockService, - blockSize: blockSize, - objectCount: objectCount); - - Assert.AreEqual(brightChain.ConstituentBlocks.Count(), brightChain.Count()); - - await Assert.ThrowsExceptionAsync(async () => - { - var retrievedChainNull = await brightBlockService.FindBlockByIdAsync(brightChain.Id); - Assert.IsNull(retrievedChainNull); - }); - - var brightHandle = brightBlockService.BrightenCbl(brightChain, true, out BrightenedBlock brightenedCbl); - - // in order to get our original blocks back, first get the chain head - var retrievedChain = await brightBlockService.FindBlockByIdAsync(brightHandle.BrightenedCblHash); - Assert.IsNotNull(retrievedChain); - - var retrievedHandle = brightBlockService.FindSourceById(brightChain.SourceId); - Assert.IsNotNull(retrievedHandle); - } - - [DataTestMethod] - //[DataRow(BlockSize.Nano, 2)] - //[DataRow(BlockSize.Micro, 2)] - [DataRow(BlockSize.Message, 4)] - [DataRow(BlockSize.Tiny, 4)] - [DataRow(BlockSize.Small, 4)] - [DataRow(BlockSize.Medium, 4)] - [DataRow(BlockSize.Large, 4)] - public async Task ItLoadsDataCorrectlyTest(BlockSize blockSize, int objectCount) + [DataTestMethod] + //[DataRow(BlockSize.Nano, 2)] + //[DataRow(BlockSize.Micro, 2)] + [DataRow(data1: BlockSize.Message, + 4)] + [DataRow(data1: BlockSize.Tiny, + 4)] + [DataRow(data1: BlockSize.Small, + 4)] + [DataRow(data1: BlockSize.Medium, + 4)] + [DataRow(data1: BlockSize.Large, + 4)] + public async Task ItSavesDataCorrectlyTest(BlockSize blockSize, int objectCount) + { + var brightBlockService = new BrightBlockService( + logger: this.loggerFactory.Object, + configuration: this.configuration.Object); + + var brightChain = await this.ForgeChainAsync( + brightBlockService: brightBlockService, + blockSize: blockSize, + objectCount: objectCount); + + Assert.AreEqual(expected: brightChain.ConstituentBlocks.Count(), + actual: brightChain.Count()); + + await Assert.ThrowsExceptionAsync(action: async () => { - var brightBlockService = new BrightBlockService( - logger: this.loggerFactory.Object, - configuration: this.configuration.Object); + var retrievedChainNull = await brightBlockService.FindBlockByIdAsync(id: brightChain.Id); + Assert.IsNull(value: retrievedChainNull); + }); - var brightChain = await this.ForgeChainAsync( - brightBlockService: brightBlockService, - blockSize: blockSize, - objectCount: objectCount); + var brightHandle = brightBlockService.BrightenCbl(cblBlock: brightChain, + persist: true, + brightenedCbl: out var brightenedCbl); - Assert.AreEqual(brightChain.ConstituentBlocks.Count(), brightChain.Count()); + // in order to get our original blocks back, first get the chain head + var retrievedChain = await brightBlockService.FindBlockByIdAsync(id: brightHandle.BrightenedCblHash); + Assert.IsNotNull(value: retrievedChain); - await Assert.ThrowsExceptionAsync(async () => - { - var retrievedChainNull = await brightBlockService.FindBlockByIdAsync(brightChain.Id); - Assert.IsNull(retrievedChainNull); - }); + var retrievedHandle = brightBlockService.FindSourceById(requestedHash: brightChain.SourceId); + Assert.IsNotNull(value: retrievedHandle); + } + + [DataTestMethod] + //[DataRow(BlockSize.Nano, 2)] + //[DataRow(BlockSize.Micro, 2)] + [DataRow(data1: BlockSize.Message, + 4)] + [DataRow(data1: BlockSize.Tiny, + 4)] + [DataRow(data1: BlockSize.Small, + 4)] + [DataRow(data1: BlockSize.Medium, + 4)] + [DataRow(data1: BlockSize.Large, + 4)] + public async Task ItLoadsDataCorrectlyTest(BlockSize blockSize, int objectCount) + { + var brightBlockService = new BrightBlockService( + logger: this.loggerFactory.Object, + configuration: this.configuration.Object); + + var brightChain = await this.ForgeChainAsync( + brightBlockService: brightBlockService, + blockSize: blockSize, + objectCount: objectCount); + + Assert.AreEqual(expected: brightChain.ConstituentBlocks.Count(), + actual: brightChain.Count()); + + await Assert.ThrowsExceptionAsync(action: async () => + { + var retrievedChainNull = await brightBlockService.FindBlockByIdAsync(id: brightChain.Id); + Assert.IsNull(value: retrievedChainNull); + }); - var brightHandle = brightBlockService.BrightenCbl(brightChain, true, out BrightenedBlock brightenedCbl); + var brightHandle = brightBlockService.BrightenCbl(cblBlock: brightChain, + persist: true, + brightenedCbl: out var brightenedCbl); - // in order to get our original blocks back, first get the chain head - var retrievedChain = await brightBlockService.FindBlockByIdAsync(brightenedCbl.Id); - Assert.IsNotNull(retrievedChain); + // in order to get our original blocks back, first get the chain head + var retrievedChain = await brightBlockService.FindBlockByIdAsync(id: brightenedCbl.Id); + Assert.IsNotNull(value: retrievedChain); - Assert.AreEqual(brightenedCbl.Crc32, retrievedChain.Crc32); - } + Assert.AreEqual(expected: brightenedCbl.Crc32, + actual: retrievedChain.Crc32); } } diff --git a/test/BrightChain.Engine.Tests/ContstituentBlockListBlockTest.cs b/test/BrightChain.Engine.Tests/ContstituentBlockListBlockTest.cs old mode 100644 new mode 100755 index f7dd12c2..77967d9a --- a/test/BrightChain.Engine.Tests/ContstituentBlockListBlockTest.cs +++ b/test/BrightChain.Engine.Tests/ContstituentBlockListBlockTest.cs @@ -1,25 +1,26 @@ -namespace BrightChain.Engine.Tests -{ - using System; - using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; - /// - /// Tests the CBL blocks for their ability to represent a file. - /// - [TestClass] - public class ContstituentBlockListBlockTest +/// +/// Tests the CBL blocks for their ability to represent a file. +/// +[TestClass] +public class ContstituentBlockListBlockTest +{ + [TestMethod] + [Ignore] + public void ItCalculatesTotalCostSumTest() { - [TestMethod, Ignore] - public void ItCalculatesTotalCostSumTest() - { - // TODO: create a block set and verify the total cost - throw new NotImplementedException(); - } + // TODO: create a block set and verify the total cost + throw new NotImplementedException(); + } - [TestMethod, Ignore] - public void ItIncludesAllBlocksTest() - { - throw new NotImplementedException(); - } + [TestMethod] + [Ignore] + public void ItIncludesAllBlocksTest() + { + throw new NotImplementedException(); } } diff --git a/test/BrightChain.Engine.Tests/FasterBlockCacheManagerTest.cs b/test/BrightChain.Engine.Tests/FasterBlockCacheManagerTest.cs old mode 100644 new mode 100755 index 6fa1683c..feaaf879 --- a/test/BrightChain.Engine.Tests/FasterBlockCacheManagerTest.cs +++ b/test/BrightChain.Engine.Tests/FasterBlockCacheManagerTest.cs @@ -1,144 +1,150 @@ -namespace BrightChain.Engine.Tests +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Faster.CacheManager; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +/// +/// Serializable testable test block class +/// +public class FasterCacheTestBlock : BrightenedBlock { - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Faster.CacheManager; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; + public static new FasterBlockCacheManager CacheManager; - /// - /// Serializable testable test block class - /// - public class FasterCacheTestBlock : BrightenedBlock + public FasterCacheTestBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data) + : base( + blockParams: blockParams, + data: data) { - public static new FasterBlockCacheManager CacheManager; - - public FasterCacheTestBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data) - : base( - blockParams: blockParams, - data: data) - { - } + } - internal FasterCacheTestBlock() - : base( - blockParams: new BrightenedBlockParams( - cacheManager: FasterCacheTestBlock.CacheManager, - allowCommit: true, - blockParams: new BlockParams( + internal FasterCacheTestBlock() + : base( + blockParams: new BrightenedBlockParams( + cacheManager: CacheManager, + allowCommit: true, + blockParams: new BlockParams( blockSize: BlockSize.Message, requestTime: DateTime.Now, keepUntilAtLeast: DateTime.MaxValue, redundancy: RedundancyContractType.HeapAuto, privateEncrypted: false, originalType: typeof(FasterCacheTestBlock))), - data: NewRandomData()) - { - } + data: NewRandomData()) + { + } - public static ReadOnlyMemory NewRandomData() + public static ReadOnlyMemory NewRandomData() + { + var random = new Random(Seed: Guid.NewGuid().GetHashCode()); + var data = new byte[BlockSizeMap.BlockSize(blockSize: BlockSize.Message)]; + for (var i = 0; i < data.Length; i++) { - var random = new Random(Guid.NewGuid().GetHashCode()); - var data = new byte[BlockSizeMap.BlockSize(BlockSize.Message)]; - for (int i = 0; i < data.Length; i++) - { - data[i] = (byte)random.Next(0, 255); - } - - return new ReadOnlyMemory(data); + data[i] = (byte)random.Next(minValue: 0, + maxValue: 255); } - public override void Dispose() - { - throw new NotImplementedException(); - } + return new ReadOnlyMemory(array: data); } - /// - /// Tests disk block cache managers - /// - [TestClass] - public class FasterBlockCacheManagerTest : TransactableBlockCacheManagerTest + public override void Dispose() { - [TestInitialize] - public new void PreTestSetup() - { - base.PreTestSetup(); - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - FasterCacheTestBlock.CacheManager = new FasterBlockCacheManager( - logger: this.logger.Object, - configuration: this.configuration.Object, - rootBlock: rootBlock, - testingSelfDestruct: true); - this.cacheManager = FasterCacheTestBlock.CacheManager; - } + throw new NotImplementedException(); + } +} - internal override FasterBlockCacheManager NewCacheManager(ILogger logger, IConfiguration configuration) - { - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - return new FasterBlockCacheManager( - logger: logger, - configuration: configuration, - rootBlock: rootBlock, - testingSelfDestruct: true); - } +/// +/// Tests disk block cache managers +/// +[TestClass] +public class FasterBlockCacheManagerTest : TransactableBlockCacheManagerTest +{ + [TestInitialize] + public new void PreTestSetup() + { + base.PreTestSetup(); + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + FasterCacheTestBlock.CacheManager = new FasterBlockCacheManager( + logger: this.logger.Object, + configuration: this.configuration.Object, + rootBlock: rootBlock, + testingSelfDestruct: true); + this.cacheManager = FasterCacheTestBlock.CacheManager; + } - internal override KeyValuePair NewKeyValue() - { - var random = new Random(Guid.NewGuid().GetHashCode()); - var data = new byte[BlockSizeMap.BlockSize(BlockSize.Message)]; - for (int i = 0; i < BlockSizeMap.BlockSize(BlockSize.Message); i++) - { - data[i] = (byte)random.Next(0, 255); - } - - var block = new FasterCacheTestBlock( - blockParams: new BrightenedBlockParams( - cacheManager: this.cacheManager, - allowCommit: true, - blockParams: new BlockParams( - blockSize: BlockSize.Message, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: Enumerations.RedundancyContractType.LocalNone, - privateEncrypted: false, - originalType: typeof(FasterCacheTestBlock))), - data: data); - - return new KeyValuePair(block.Id, block); - } + internal override FasterBlockCacheManager NewCacheManager(ILogger logger, IConfiguration configuration) + { + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + return new FasterBlockCacheManager( + logger: logger, + configuration: configuration, + rootBlock: rootBlock, + testingSelfDestruct: true); + } - internal override FasterCacheTestBlock NewNullData() + internal override KeyValuePair NewKeyValue() + { + var random = new Random(Seed: Guid.NewGuid().GetHashCode()); + var data = new byte[BlockSizeMap.BlockSize(blockSize: BlockSize.Message)]; + for (var i = 0; i < BlockSizeMap.BlockSize(blockSize: BlockSize.Message); i++) { - return null; + data[i] = (byte)random.Next(minValue: 0, + maxValue: 255); } - /// - /// Tries to push a null value into the cache and expects an exception. - /// - [TestMethod] - public override void ItPutsNullValuesTest() - { - // Arrange - var newData = this.NewNullData(); + var block = new FasterCacheTestBlock( + blockParams: new BrightenedBlockParams( + cacheManager: this.cacheManager, + allowCommit: true, + blockParams: new BlockParams( + blockSize: BlockSize.Message, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.LocalNone, + privateEncrypted: false, + originalType: typeof(FasterCacheTestBlock))), + data: data); + + return new KeyValuePair(key: block.Id, + value: block); + } - // Act/Expect - Exceptions.BrightChainException brightChainException = Assert.ThrowsException(() => - this.cacheManager.Set(newData)); + internal override FasterCacheTestBlock NewNullData() + { + return null; + } - this.logger.Verify(l => l.Log( + /// + /// Tries to push a null value into the cache and expects an exception. + /// + [TestMethod] + public override void ItPutsNullValuesTest() + { + // Arrange + var newData = this.NewNullData(); + + // Act/Expect + var brightChainException = Assert.ThrowsException(action: () => + this.cacheManager.Set(block: newData)); + + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); } } diff --git a/test/BrightChain.Engine.Tests/FasterCacheManagerTest.cs b/test/BrightChain.Engine.Tests/FasterCacheManagerTest.cs old mode 100644 new mode 100755 index 3192f8fe..c1ba3cbe --- a/test/BrightChain.Engine.Tests/FasterCacheManagerTest.cs +++ b/test/BrightChain.Engine.Tests/FasterCacheManagerTest.cs @@ -1,76 +1,87 @@ -namespace BrightChain.Engine.Tests +using System; +using System.Collections.Generic; +using System.Linq; +using BrightChain.Engine.Helpers; +using BrightChain.Engine.Services.CacheManagers; +using FASTER.core; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests; + +[TestClass] +public class FasterCacheManagerTest + : CacheManagerTest< + TapestryCacheManager> + , string, ProtoContractTestObject> { - using System; - using System.Collections.Generic; - using System.Linq; - using BrightChain.Engine.Helpers; - using BrightChain.Engine.Services.CacheManagers; - using FASTER.core; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; + private static int TestKeyLength { get; } = 11; - [TestClass] - public class FasterCacheManagerTest - : CacheManagerTest>, string, ProtoContractTestObject> + public static string GenerateTestKey() { - private static int TestKeyLength { get; } = 11; - - public static string GenerateTestKey() - { - const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - var random = new Random(Guid.NewGuid().GetHashCode()); - var randomString = new string(Enumerable.Repeat(chars, TestKeyLength) - .Select(s => s[random.Next(s.Length)]).ToArray()); - return randomString; - } + var random = new Random(Seed: Guid.NewGuid().GetHashCode()); + var randomString = new string(value: Enumerable.Repeat(element: chars, + count: TestKeyLength) + .Select(selector: s => s[index: random.Next(maxValue: s.Length)]).ToArray()); + return randomString; + } - internal override FasterCacheManager> NewCacheManager(ILogger logger, IConfiguration configuration) - { - return new FasterCacheManager>( -logger: this.logger.Object, -configuration: this.configuration.Object, -databaseName: Guid.NewGuid().ToString()); - } + internal override + TapestryCacheManager> + NewCacheManager(ILogger logger, IConfiguration configuration) + { + return new TapestryCacheManager>( + logger: this.logger.Object, + configuration: this.configuration.Object, + collectionName: Guid.NewGuid().ToString()); + } - internal override KeyValuePair NewKeyValue() - { - var testKey = GenerateTestKey(); - var testValue = new ProtoContractTestObject(testKey); - return new KeyValuePair(testKey, testValue); - } + internal override KeyValuePair NewKeyValue() + { + var testKey = GenerateTestKey(); + var testValue = new ProtoContractTestObject(id: testKey); + return new KeyValuePair(key: testKey, + value: testValue); + } - internal override ProtoContractTestObject NewNullData() - { - return null; - } + internal override ProtoContractTestObject NewNullData() + { + return null; + } - [TestMethod] - public void TestSetGetIntegrity() - { - // Arrange - var expectation = this.testPair.Value; - this.cacheManager.Set(this.testPair.Key, expectation); - Assert.IsTrue(this.cacheManager.Contains(this.testPair.Key)); + [TestMethod] + public void TestSetGetIntegrity() + { + // Arrange + var expectation = this.testPair.Value; + this.cacheManager.Set(key: this.testPair.Key, + value: expectation); + Assert.IsTrue(condition: this.cacheManager.Contains(key: this.testPair.Key)); - // Act - object result = this.cacheManager.Get(this.testPair.Key); + // Act + object result = this.cacheManager.Get(blockHash: this.testPair.Key); - // Assert - Assert.IsNotNull(expectation); - Assert.AreEqual(expectation, result); - Assert.AreSame(expectation, result); - Assert.AreEqual(this.testPair.Key, expectation.id); + // Assert + Assert.IsNotNull(value: expectation); + Assert.AreEqual(expected: expectation, + actual: result); + Assert.AreSame(expected: expectation, + actual: result); + Assert.AreEqual(expected: this.testPair.Key, + actual: expectation.id); - this.logger.Verify(l => l.Log( + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); } } diff --git a/test/BrightChain.Engine.Tests/Helpers/TestHelpers.cs b/test/BrightChain.Engine.Tests/Helpers/TestHelpers.cs old mode 100644 new mode 100755 index 11cf6361..dc6bb9f6 --- a/test/BrightChain.Engine.Tests/Helpers/TestHelpers.cs +++ b/test/BrightChain.Engine.Tests/Helpers/TestHelpers.cs @@ -1,16 +1,15 @@ -namespace BrightChain.Engine.Tests.Helpers -{ - using System; - using BrightChain.Engine.Enumerations; +using System; +using BrightChain.Engine.Enumerations; + +namespace BrightChain.Engine.Tests.Helpers; - public static class TestHelpers +public static class TestHelpers +{ + public static BlockSize RandomBlockSize() { - public static BlockSize RandomBlockSize() - { - Array values = Enum.GetValues(typeof(BlockSize)); - Random random = new Random(); - var blockSize = (BlockSize)values.GetValue(random.Next(values.Length)); - return (blockSize == BlockSize.Unknown) ? RandomBlockSize() : blockSize; - } + var values = Enum.GetValues(enumType: typeof(BlockSize)); + var random = new Random(); + var blockSize = (BlockSize)values.GetValue(index: random.Next(maxValue: values.Length)); + return blockSize == BlockSize.Unknown ? RandomBlockSize() : blockSize; } } diff --git a/test/BrightChain.Engine.Tests/MemoryBlockCacheManagerTest.cs b/test/BrightChain.Engine.Tests/MemoryBlockCacheManagerTest.cs old mode 100644 new mode 100755 index 8e3b2292..056f7e87 --- a/test/BrightChain.Engine.Tests/MemoryBlockCacheManagerTest.cs +++ b/test/BrightChain.Engine.Tests/MemoryBlockCacheManagerTest.cs @@ -1,144 +1,150 @@ -namespace BrightChain.Engine.Tests +using System; +using System.Collections.Generic; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using ProtoBuf; + +namespace BrightChain.Engine.Tests; + +/// +/// Serializable testable test block class +/// +[ProtoContract] +public class MemoryDictionaryCacheTestBlock : BrightenedBlock { - using System; - using System.Collections.Generic; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using ProtoBuf; + public static new MemoryDictionaryBlockCacheManager CacheManager; - /// - /// Serializable testable test block class - /// - [ProtoContract] - public class MemoryDictionaryCacheTestBlock : BrightenedBlock + public MemoryDictionaryCacheTestBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data) + : base( + blockParams: blockParams, + data: data) { - public static new MemoryDictionaryBlockCacheManager CacheManager; - - public MemoryDictionaryCacheTestBlock(BrightenedBlockParams blockParams, ReadOnlyMemory data) - : base( - blockParams: blockParams, - data: data) - { - } + } - internal MemoryDictionaryCacheTestBlock() - : base( - blockParams: new BrightenedBlockParams( - cacheManager: MemoryDictionaryCacheTestBlock.CacheManager, - allowCommit: true, - blockParams: new BlockParams( + internal MemoryDictionaryCacheTestBlock() + : base( + blockParams: new BrightenedBlockParams( + cacheManager: CacheManager, + allowCommit: true, + blockParams: new BlockParams( blockSize: BlockSize.Message, requestTime: DateTime.Now, keepUntilAtLeast: DateTime.MaxValue, redundancy: RedundancyContractType.HeapAuto, privateEncrypted: false, originalType: typeof(MemoryDictionaryCacheTestBlock))), - data: NewRandomData()) - { - } + data: NewRandomData()) + { + } - public static ReadOnlyMemory NewRandomData() + public static ReadOnlyMemory NewRandomData() + { + var random = new Random(Seed: Guid.NewGuid().GetHashCode()); + var data = new byte[BlockSizeMap.BlockSize(blockSize: BlockSize.Message)]; + for (var i = 0; i < data.Length; i++) { - var random = new Random(Guid.NewGuid().GetHashCode()); - var data = new byte[BlockSizeMap.BlockSize(BlockSize.Message)]; - for (int i = 0; i < data.Length; i++) - { - data[i] = (byte)random.Next(0, 255); - } - - return new ReadOnlyMemory(data); + data[i] = (byte)random.Next(minValue: 0, + maxValue: 255); } - public override void Dispose() - { - throw new NotImplementedException(); - } + return new ReadOnlyMemory(array: data); } - /// - /// Tests disk block cache managers - /// - [TestClass] - public class MemoryBlockCacheManagerTest : TransactableBlockCacheManagerTest + public override void Dispose() { - [TestInitialize] - public new void PreTestSetup() - { - base.PreTestSetup(); - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - MemoryDictionaryCacheTestBlock.CacheManager = new MemoryDictionaryBlockCacheManager( - logger: this.logger.Object, - configuration: this.configuration.Object, - rootBlock: rootBlock); - this.cacheManager = MemoryDictionaryCacheTestBlock.CacheManager; - } + throw new NotImplementedException(); + } +} - internal override MemoryDictionaryBlockCacheManager NewCacheManager(ILogger logger, IConfiguration configuration) - { - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - return new MemoryDictionaryBlockCacheManager( - logger: logger, - configuration: configuration, - rootBlock: rootBlock); - } +/// +/// Tests disk block cache managers +/// +[TestClass] +public class MemoryBlockCacheManagerTest : TransactableBlockCacheManagerTest +{ + [TestInitialize] + public new void PreTestSetup() + { + base.PreTestSetup(); + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + MemoryDictionaryCacheTestBlock.CacheManager = new MemoryDictionaryBlockCacheManager( + logger: this.logger.Object, + configuration: this.configuration.Object, + rootBlock: rootBlock); + this.cacheManager = MemoryDictionaryCacheTestBlock.CacheManager; + } - internal override KeyValuePair NewKeyValue() - { - var random = new Random(Guid.NewGuid().GetHashCode()); - var data = new byte[BlockSizeMap.BlockSize(BlockSize.Message)]; - for (int i = 0; i < BlockSizeMap.BlockSize(BlockSize.Message); i++) - { - data[i] = (byte)random.Next(0, 255); - } - - var block = new MemoryDictionaryCacheTestBlock( - blockParams: new BrightenedBlockParams( - cacheManager: this.cacheManager, - allowCommit: true, - blockParams: new BlockParams( - blockSize: BlockSize.Message, - requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.MaxValue, - redundancy: Enumerations.RedundancyContractType.LocalNone, - privateEncrypted: false, - originalType: typeof(MemoryDictionaryCacheTestBlock))), - data: data); - - return new KeyValuePair(block.Id, block); - } + internal override MemoryDictionaryBlockCacheManager NewCacheManager(ILogger logger, IConfiguration configuration) + { + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + return new MemoryDictionaryBlockCacheManager( + logger: logger, + configuration: configuration, + rootBlock: rootBlock); + } - internal override MemoryDictionaryCacheTestBlock NewNullData() + internal override KeyValuePair NewKeyValue() + { + var random = new Random(Seed: Guid.NewGuid().GetHashCode()); + var data = new byte[BlockSizeMap.BlockSize(blockSize: BlockSize.Message)]; + for (var i = 0; i < BlockSizeMap.BlockSize(blockSize: BlockSize.Message); i++) { - return null; + data[i] = (byte)random.Next(minValue: 0, + maxValue: 255); } - /// - /// Tries to push a null value into the cache and expects an exception. - /// - [TestMethod] - public override void ItPutsNullValuesTest() - { - // Arrange - var newData = this.NewNullData(); + var block = new MemoryDictionaryCacheTestBlock( + blockParams: new BrightenedBlockParams( + cacheManager: this.cacheManager, + allowCommit: true, + blockParams: new BlockParams( + blockSize: BlockSize.Message, + requestTime: DateTime.Now, + keepUntilAtLeast: DateTime.MaxValue, + redundancy: RedundancyContractType.LocalNone, + privateEncrypted: false, + originalType: typeof(MemoryDictionaryCacheTestBlock))), + data: data); + + return new KeyValuePair(key: block.Id, + value: block); + } - // Act/Expect - Exceptions.BrightChainException brightChainException = Assert.ThrowsException(() => - this.cacheManager.Set(newData)); + internal override MemoryDictionaryCacheTestBlock NewNullData() + { + return null; + } - this.logger.Verify(l => l.Log( + /// + /// Tries to push a null value into the cache and expects an exception. + /// + [TestMethod] + public override void ItPutsNullValuesTest() + { + // Arrange + var newData = this.NewNullData(); + + // Act/Expect + var brightChainException = Assert.ThrowsException(action: () => + this.cacheManager.Set(block: newData)); + + this.logger.Verify(expression: l => l.Log( LogLevel.Information, It.IsAny(), It.IsAny(), It.IsAny(), - (Func)It.IsAny()), Times.Exactly(0)); - this.logger.VerifyNoOtherCalls(); - } + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + this.logger.VerifyNoOtherCalls(); } } diff --git a/test/BrightChain.Engine.Tests/RandomizerBlockTest.cs b/test/BrightChain.Engine.Tests/RandomizerBlockTest.cs old mode 100644 new mode 100755 index a209be99..79747010 --- a/test/BrightChain.Engine.Tests/RandomizerBlockTest.cs +++ b/test/BrightChain.Engine.Tests/RandomizerBlockTest.cs @@ -1,85 +1,82 @@ -namespace BrightChain.Engine.Tests -{ - using System; - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Models; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; +using System; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Models; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; - /// - /// Verifies random blocks are random, generated correctly and are inserted into the cache - /// - [TestClass] - public class RandomizerBlockTest - { - private MemoryDictionaryBlockCacheManager cacheManager; - private ILogger logger; +namespace BrightChain.Engine.Tests; - public RandomizerBlockTest() - { - } +/// +/// Verifies random blocks are random, generated correctly and are inserted into the cache +/// +[TestClass] +public class RandomizerBlockTest +{ + private MemoryDictionaryBlockCacheManager cacheManager; + private ILogger logger; - [TestInitialize] - public void PreTestSetUp() - { - this.logger = new Moq.Mock().Object; - var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), blockSize: BlockSize.Large); - this.cacheManager = new MemoryDictionaryBlockCacheManager( - logger: this.logger, - configuration: new BrightChainConfiguration(), - rootBlock: rootBlock); - } + [TestInitialize] + public void PreTestSetUp() + { + this.logger = new Mock().Object; + var rootBlock = new RootBlock(databaseGuid: Guid.NewGuid(), + blockSize: BlockSize.Large); + this.cacheManager = new MemoryDictionaryBlockCacheManager( + logger: this.logger, + configuration: new BrightChainConfiguration(), + rootBlock: rootBlock); + } - [DataTestMethod] - [DataRow(BlockSize.Nano)] - [DataRow(BlockSize.Micro)] - [DataRow(BlockSize.Message)] - [DataRow(BlockSize.Tiny)] - [DataRow(BlockSize.Small)] - [DataRow(BlockSize.Medium)] - [DataRow(BlockSize.Large)] - public void ItCreatesValidRandomDataBlocksTest(BlockSize blockSize) - { - var zeroBlock = new ZeroVectorBlock( - blockParams: new BlockParams( + [DataTestMethod] + [DataRow(data1: BlockSize.Nano)] + [DataRow(data1: BlockSize.Micro)] + [DataRow(data1: BlockSize.Message)] + [DataRow(data1: BlockSize.Tiny)] + [DataRow(data1: BlockSize.Small)] + [DataRow(data1: BlockSize.Medium)] + [DataRow(data1: BlockSize.Large)] + public void ItCreatesValidRandomDataBlocksTest(BlockSize blockSize) + { + var zeroBlock = new ZeroVectorBlock( + blockParams: new BlockParams( blockSize: blockSize, requestTime: DateTime.Now, - keepUntilAtLeast: DateTime.Now.AddDays(1), - redundancy: Enumerations.RedundancyContractType.HeapAuto, + keepUntilAtLeast: DateTime.Now.AddDays(value: 1), + redundancy: RedundancyContractType.HeapAuto, privateEncrypted: false, originalType: typeof(ZeroVectorBlock))); - Assert.IsTrue(zeroBlock.Validate()); + Assert.IsTrue(condition: zeroBlock.Validate()); - var randomBlock = new RandomizerBlock( - destinationCache: this.cacheManager, - blockSize: blockSize, - keepUntilAtLeast: DateTime.Now.AddDays(1), - redundancyContractType: Enumerations.RedundancyContractType.HeapAuto); + var randomBlock = new RandomizerBlock( + destinationCache: this.cacheManager, + blockSize: blockSize, + keepUntilAtLeast: DateTime.Now.AddDays(value: 1), + redundancyContractType: RedundancyContractType.HeapAuto); - Assert.IsTrue(randomBlock.Validate()); - Assert.IsFalse(this.cacheManager.Contains(randomBlock.Id)); + Assert.IsTrue(condition: randomBlock.Validate()); + Assert.IsFalse(condition: this.cacheManager.Contains(key: randomBlock.Id)); - var zeroBlockEntResult = zeroBlock.EntropyEstimate; - Assert.AreEqual(0, zeroBlockEntResult.Entropy); + var zeroBlockEntResult = zeroBlock.EntropyEstimate; + Assert.AreEqual(expected: 0, + actual: zeroBlockEntResult.Entropy); - var randomBlockEntResult = randomBlock.EntropyEstimate; - Assert.IsTrue(randomBlockEntResult.Entropy > 6.0D); + var randomBlockEntResult = randomBlock.EntropyEstimate; + Assert.IsTrue(condition: randomBlockEntResult.Entropy > 6.0D); - var mockLogger = Mock.Get(this.logger); - mockLogger.Verify( - l => l.Log( - LogLevel.Information, - It.IsAny(), - It.IsAny(), - It.IsAny(), - (Func)It.IsAny()), - Times.Exactly(0)); - mockLogger.VerifyNoOtherCalls(); - } + var mockLogger = Mock.Get(mocked: this.logger); + mockLogger.Verify( + expression: l => l.Log( + LogLevel.Information, + It.IsAny(), + It.IsAny(), + It.IsAny(), + (Func)It.IsAny()), + times: Times.Exactly(callCount: 0)); + mockLogger.VerifyNoOtherCalls(); } } diff --git a/test/BrightChain.Engine.Tests/Services/BlockBrightenerServiceTests.cs b/test/BrightChain.Engine.Tests/Services/BlockBrightenerServiceTests.cs old mode 100644 new mode 100755 index 47960bf1..6deea4aa --- a/test/BrightChain.Engine.Tests/Services/BlockBrightenerServiceTests.cs +++ b/test/BrightChain.Engine.Tests/Services/BlockBrightenerServiceTests.cs @@ -1,52 +1,49 @@ -namespace BrightChain.Engine.Tests.Services +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Services; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace BrightChain.Engine.Tests.Services; + +[TestClass] +public class BlockBrightenerServiceTests { - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Services; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using System; - - [TestClass] - public class BlockBrightenerServiceTests + private Mock mockBrightenedBlockCacheManagerBase; + private MockRepository mockRepository; + + [TestInitialize] + public void TestInitialize() + { + this.mockRepository = new MockRepository(defaultBehavior: MockBehavior.Strict); + + this.mockBrightenedBlockCacheManagerBase = this.mockRepository.Create(); + } + + private BlockBrightenerService CreateService() + { + return new BlockBrightenerService( + resultCache: this.mockBrightenedBlockCacheManagerBase.Object); + } + + [TestMethod] + public void Brighten_StateUnderTest_ExpectedBehavior() { - private MockRepository mockRepository; - - private Mock mockBrightenedBlockCacheManagerBase; - - [TestInitialize] - public void TestInitialize() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); - - this.mockBrightenedBlockCacheManagerBase = this.mockRepository.Create(); - } - - private BlockBrightenerService CreateService() - { - return new BlockBrightenerService( - this.mockBrightenedBlockCacheManagerBase.Object); - } - - [TestMethod] - public void Brighten_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - IdentifiableBlock identifiableBlock = null; - BrightenedBlock[] randomizersUsed = null; - TupleStripe brightenedStripe = default(global::BrightChain.Engine.Models.Blocks.Chains.TupleStripe); - - // Act - var result = service.Brighten( - identifiableBlock, - out randomizersUsed, - out brightenedStripe); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Arrange + var service = this.CreateService(); + IdentifiableBlock identifiableBlock = null; + BrightenedBlock[] randomizersUsed = null; + var brightenedStripe = default(TupleStripe); + + // Act + var result = service.Brighten( + identifiableBlock: identifiableBlock, + randomizersUsed: out randomizersUsed, + brightenedStripe: out brightenedStripe); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); } } diff --git a/test/BrightChain.Engine.Tests/Services/BrightBlockServiceTests.cs b/test/BrightChain.Engine.Tests/Services/BrightBlockServiceTests.cs old mode 100644 new mode 100755 index 4b2f24bf..ff17a98b --- a/test/BrightChain.Engine.Tests/Services/BrightBlockServiceTests.cs +++ b/test/BrightChain.Engine.Tests/Services/BrightBlockServiceTests.cs @@ -1,443 +1,436 @@ -namespace BrightChain.Engine.Tests.Services +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using BrightChain.Engine.Enumerations; +using BrightChain.Engine.Exceptions; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Blocks.Chains; +using BrightChain.Engine.Models.Blocks.DataObjects; +using BrightChain.Engine.Models.Contracts; +using BrightChain.Engine.Models.Hashes; +using BrightChain.Engine.Services; +using BrightChain.Engine.Services.CacheManagers.Block; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using NeuralFabric.Models.Hashes; + +namespace BrightChain.Engine.Tests.Services; + +[TestClass] +public class BrightBlockServiceTests { - using BrightChain.Engine.Enumerations; - using BrightChain.Engine.Exceptions; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Blocks.Chains; - using BrightChain.Engine.Models.Blocks.DataObjects; - using BrightChain.Engine.Models.Contracts; - using BrightChain.Engine.Models.Hashes; - using BrightChain.Engine.Services; - using BrightChain.Engine.Services.CacheManagers.Block; - using Microsoft.Extensions.Configuration; - using Microsoft.Extensions.Logging; - using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; - using System; - using System.Collections; - using System.Collections.Generic; - using System.IO; - using System.Threading.Tasks; - - [TestClass] - public class BrightBlockServiceTests - { - private MockRepository mockRepository; - - private Mock mockLoggerFactory; - private Mock mockConfiguration; + private Mock mockConfiguration; - [TestInitialize] - public void TestInitialize() - { - this.mockRepository = new MockRepository(MockBehavior.Strict); + private Mock mockLoggerFactory; + private MockRepository mockRepository; - this.mockLoggerFactory = this.mockRepository.Create(); - this.mockConfiguration = this.mockRepository.Create(); - } - - private BrightBlockService CreateService() - { - return new BrightBlockService( - this.mockLoggerFactory.Object, - this.mockConfiguration.Object); - } - - [TestMethod] - public async Task StreamCreatedBrightenedBlocksFromFileAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - SourceFileInfo sourceInfo = default(global::BrightChain.Engine.Models.Blocks.DataObjects.SourceFileInfo); - BlockParams blockParams = null; - BlockSize? blockSize = null; - - // Act - await foreach (var brightenedBlock in service.StreamCreatedBrightenedBlocksFromFileAsync( - sourceInfo, - blockParams, - blockSize)) - { - - } - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestInitialize] + public void TestInitialize() + { + this.mockRepository = new MockRepository(defaultBehavior: MockBehavior.Strict); - [TestMethod] - public async Task MakeCBLChainFromParamsAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - string fileName = null; - BlockParams blockParams = null; - - // Act - var result = await service.MakeCBLChainFromParamsAsync( - fileName, - blockParams); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + this.mockLoggerFactory = this.mockRepository.Create(); + this.mockConfiguration = this.mockRepository.Create(); + } - [TestMethod] - public async Task MakeSuperCBLFromCBLChainAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BlockParams blockParams = null; - IEnumerable chainedCbls = null; - DataHash sourceId = null; - - // Act - var result = await service.MakeSuperCBLFromCBLChainAsync( - blockParams, - chainedCbls, - sourceId); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + private BrightBlockService CreateService() + { + return new BrightBlockService( + logger: this.mockLoggerFactory.Object, + configuration: this.mockConfiguration.Object); + } - [TestMethod] - public async Task MakeCblOrSuperCblFromFileAsync_StateUnderTest_ExpectedBehavior() + [TestMethod] + public async Task StreamCreatedBrightenedBlocksFromFileAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + var sourceInfo = default(SourceFileInfo); + BlockParams blockParams = null; + BlockSize? blockSize = null; + + // Act + await foreach (var brightenedBlock in service.StreamCreatedBrightenedBlocksFromFileAsync( + sourceInfo: sourceInfo, + blockParams: blockParams, + blockSize: blockSize)) { - // Arrange - var service = this.CreateService(); - string fileName = null; - BlockParams blockParams = null; - - // Act - var result = await service.MakeCblOrSuperCblFromFileAsync( - fileName, - blockParams); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); } - [TestMethod] - public void GetCBLBlocksFromCacheAsDictionary_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BrightenedBlockCacheManagerBase blockCacheManager = null; - ConstituentBlockListBlock block = null; - - // Act - var result = BrightBlockService.GetCBLBlocksFromCacheAsDictionary( - blockCacheManager, - block); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task RestoreStreamFromCBLAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - ConstituentBlockListBlock constituentBlockListBlock = null; - Stream? destination = null; - - // Act - var result = await service.RestoreStreamFromCBLAsync( - constituentBlockListBlock, - destination); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public async Task MakeCBLChainFromParamsAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + string fileName = null; + BlockParams blockParams = null; + + // Act + var result = await service.MakeCBLChainFromParamsAsync( + fileName: fileName, + blockParams: blockParams); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task RestoreFileFromCBLAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - ConstituentBlockListBlock constituentBlockListBlock = null; + [TestMethod] + public async Task MakeSuperCBLFromCBLChainAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + BlockParams blockParams = null; + IEnumerable chainedCbls = null; + DataHash sourceId = null; + + // Act + var result = await service.MakeSuperCBLFromCBLChainAsync( + blockParams: blockParams, + chainedCbls: chainedCbls, + sourceId: sourceId); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - var result = await service.RestoreFileFromCBLAsync( - constituentBlockListBlock); + [TestMethod] + public async Task MakeCblOrSuperCblFromFileAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + string fileName = null; + BlockParams blockParams = null; + + // Act + var result = await service.MakeCblOrSuperCblFromFileAsync( + fileName: fileName, + blockParams: blockParams); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public void GetCBLBlocksFromCacheAsDictionary_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + BrightenedBlockCacheManagerBase blockCacheManager = null; + ConstituentBlockListBlock block = null; + + // Act + var result = BrightBlockService.GetCBLBlocksFromCacheAsDictionary( + blockCacheManager: blockCacheManager, + block: block); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task FindBlockByIdAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BlockHash id = null; + [TestMethod] + public async Task RestoreStreamFromCBLAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + ConstituentBlockListBlock constituentBlockListBlock = null; + Stream? destination = null; + + // Act + var result = await service.RestoreStreamFromCBLAsync( + constituentBlockListBlock: constituentBlockListBlock, + destination: destination); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - var result = await service.FindBlockByIdAsync( - id); + [TestMethod] + public async Task RestoreFileFromCBLAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + ConstituentBlockListBlock constituentBlockListBlock = null; - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Act + var result = await service.RestoreFileFromCBLAsync( + constituentBlockListBlock: constituentBlockListBlock); - [TestMethod] - public async Task FindBlocksByIdAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - IAsyncEnumerable blockIdSource = null; + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - await foreach (var block in service.FindBlocksByIdAsync( - blockIdSource)) - { + [TestMethod] + public async Task FindBlockByIdAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + BlockHash id = null; - } + // Act + var result = await service.FindBlockByIdAsync( + id: id); - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task FindBlockByIdAsync_StateUnderTest_ExpectedBehavior1() - { - // Arrange - var service = this.CreateService(); - BlockHash id = null; - bool useAsBlock = false; - - // Act - var result = await service.FindBlockByIdAsync( - id, - useAsBlock); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public async Task FindBlocksByIdAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + IAsyncEnumerable blockIdSource = null; - [TestMethod] - public async Task DropBlockByIdAsync_StateUnderTest_ExpectedBehavior() + // Act + await foreach (var block in service.FindBlocksByIdAsync( + blockIdSource: blockIdSource)) { - // Arrange - var service = this.CreateService(); - BlockHash id = null; - RevocationCertificate? ownershipToken = null; - - // Act - var result = await service.DropBlockByIdAsync( - id, - ownershipToken); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); } - [TestMethod] - public async Task DropBlocksByIdAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - IAsyncEnumerable idSource = null; - RevocationCertificate? ownershipToken = null; - - // Act - await foreach ((BlockHash blockHash, Block block) in service.DropBlocksByIdAsync( - idSource, - ownershipToken)) - { - - } - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task StoreBlockAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BrightenedBlock block = null; + [TestMethod] + public async Task FindBlockByIdAsync_StateUnderTest_ExpectedBehavior1() + { + // Arrange + var service = this.CreateService(); + BlockHash id = null; + var useAsBlock = false; + + // Act + var result = await service.FindBlockByIdAsync( + id: id, + useAsBlock: useAsBlock); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - var result = await service.StoreBlockAsync( - block); + [TestMethod] + public async Task DropBlockByIdAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + BlockHash id = null; + RevocationCertificate? ownershipToken = null; + + // Act + var result = await service.DropBlockByIdAsync( + id: id, + ownershipToken: ownershipToken); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); + [TestMethod] + public async Task DropBlocksByIdAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + IAsyncEnumerable idSource = null; + RevocationCertificate? ownershipToken = null; + + // Act + await foreach ((var blockHash, var block) in service.DropBlocksByIdAsync( + idSource: idSource, + ownershipToken: ownershipToken)) + { } - [TestMethod] - public async Task StoreBlocksAsync_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - IAsyncEnumerable blockSource = null; + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - await foreach ((Block block, IEnumerable brightChainException) in service.StoreBlocksAsync( - blockSource)) - { + [TestMethod] + public async Task StoreBlockAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + BrightenedBlock block = null; - } + // Act + var result = await service.StoreBlockAsync( + block: block); - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public async Task BrightenBlocksAsyncEnumerable_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - IAsyncEnumerable identifiableBlocks = null; + [TestMethod] + public async Task StoreBlocksAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + IAsyncEnumerable blockSource = null; - // Act - await foreach (var brightenedBlock in service.BrightenBlocksAsyncEnumerable( - identifiableBlocks)) - { + // Act + await foreach ((var block, IEnumerable brightChainException) in service.StoreBlocksAsync( + blockSource: blockSource)) + { + } - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public async Task BrightenBlocksAsyncEnumerable_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + IAsyncEnumerable identifiableBlocks = null; - [TestMethod] - public async Task ForgeChainAsync_StateUnderTest_ExpectedBehavior() + // Act + await foreach (var brightenedBlock in service.BrightenBlocksAsyncEnumerable( + identifiableBlocks: identifiableBlocks)) { - // Arrange - var service = this.CreateService(); - DataHash sourceId = null; - IAsyncEnumerable brightenedBlocks = null; - - // Act - var result = await service.ForgeChainAsync( - sourceId, - brightenedBlocks); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); } - [TestMethod] - public void CblToBrightHandle_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - ConstituentBlockListBlock cblBlock = null; - BrightenedBlock brightenedCbl = null; - TupleStripe cblStripe = default(global::BrightChain.Engine.Models.Blocks.Chains.TupleStripe); - - // Act - var result = service.CblToBrightHandle( - cblBlock, - brightenedCbl, - cblStripe); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public void BrightenCbl_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - ConstituentBlockListBlock cblBlock = null; - bool persist = false; - BrightenedBlock brightenedCbl = null; - - // Act - var result = service.BrightenCbl( - cblBlock, - persist, - out brightenedCbl); - - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public async Task ForgeChainAsync_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + DataHash sourceId = null; + IAsyncEnumerable brightenedBlocks = null; + + // Act + var result = await service.ForgeChainAsync( + sourceId: sourceId, + brightenedBlocks: brightenedBlocks); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public void FindSourceById_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - DataHash requestedHash = null; + [TestMethod] + public void CblToBrightHandle_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + ConstituentBlockListBlock cblBlock = null; + BrightenedBlock brightenedCbl = null; + var cblStripe = default(TupleStripe); + + // Act + var result = service.CblToBrightHandle( + cblBlock: cblBlock, + brightenedCbl: brightenedCbl, + cblStripe: cblStripe); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - var result = service.FindSourceById( - requestedHash); + [TestMethod] + public void BrightenCbl_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + ConstituentBlockListBlock cblBlock = null; + var persist = false; + BrightenedBlock brightenedCbl = null; + + // Act + var result = service.BrightenCbl( + cblBlock: cblBlock, + persist: persist, + brightenedCbl: out brightenedCbl); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + [TestMethod] + public void FindSourceById_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + DataHash requestedHash = null; - [TestMethod] - public void BrightHandleToTupleStripe_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BrightHandle brightHandle = default(global::BrightChain.Engine.Models.Blocks.DataObjects.BrightHandle); + // Act + var result = service.FindSourceById( + requestedHash: requestedHash); + + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - // Act - var result = service.BrightHandleToTupleStripe( - brightHandle); + [TestMethod] + public void BrightHandleToTupleStripe_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + var brightHandle = default(BrightHandle); - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Act + var result = service.BrightHandleToTupleStripe( + brightHandle: brightHandle); - [TestMethod] - public void BrightHandleToIdentifiableBlock_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); - BrightHandle brightHandle = default(global::BrightChain.Engine.Models.Blocks.DataObjects.BrightHandle); + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } + + [TestMethod] + public void BrightHandleToIdentifiableBlock_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); + var brightHandle = default(BrightHandle); - // Act - var result = service.BrightHandleToIdentifiableBlock( - brightHandle); + // Act + var result = service.BrightHandleToIdentifiableBlock( + brightHandle: brightHandle); - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); + } - [TestMethod] - public void Dispose_StateUnderTest_ExpectedBehavior() - { - // Arrange - var service = this.CreateService(); + [TestMethod] + public void Dispose_StateUnderTest_ExpectedBehavior() + { + // Arrange + var service = this.CreateService(); - // Act - service.Dispose(); + // Act + service.Dispose(); - // Assert - Assert.Fail(); - this.mockRepository.VerifyAll(); - } + // Assert + Assert.Fail(); + this.mockRepository.VerifyAll(); } } diff --git a/test/BrightChain.Engine.Tests/TestModels/ChainLinqExampleSerializable.cs b/test/BrightChain.Engine.Tests/TestModels/ChainLinqExampleSerializable.cs old mode 100644 new mode 100755 index 87053946..c89d1f2b --- a/test/BrightChain.Engine.Tests/TestModels/ChainLinqExampleSerializable.cs +++ b/test/BrightChain.Engine.Tests/TestModels/ChainLinqExampleSerializable.cs @@ -1,39 +1,37 @@ -namespace BrightChain.Engine.Tests.TestModels -{ - using System; - using System.Collections.Generic; - using ProtoBuf; +using System; +using System.Collections.Generic; +using Bogus.DataSets; +using ProtoBuf; + +namespace BrightChain.Engine.Tests.TestModels; - [ProtoContract] - public class ChainLinqExampleSerializable - : IDisposable +[ProtoContract] +public class ChainLinqExampleSerializable + : IDisposable +{ + public ChainLinqExampleSerializable() { - public ChainLinqExampleSerializable() - { - this.PublicData = new Bogus.DataSets.Lorem().Text(); - this.PrivateData = new Bogus.DataSets.Lorem().Text(); - } + this.PublicData = new Lorem().Text(); + this.PrivateData = new Lorem().Text(); + } - public static IEnumerable MakeMultiple(int count) - { - ChainLinqExampleSerializable[] datas = new ChainLinqExampleSerializable[count]; - for (int i = 0; i < count; i++) - { - datas[i] = new ChainLinqExampleSerializable(); - } + [ProtoMember(tag: 1)] public string PublicData { get; } - return datas; - } + [ProtoMember(tag: 2)] private string PrivateData { get; } + + public void Dispose() + { + throw new NotImplementedException(); + } - public void Dispose() + public static IEnumerable MakeMultiple(int count) + { + var datas = new ChainLinqExampleSerializable[count]; + for (var i = 0; i < count; i++) { - throw new NotImplementedException(); + datas[i] = new ChainLinqExampleSerializable(); } - [ProtoMember(1)] - public string PublicData { get; } - - [ProtoMember(2)] - private string PrivateData { get; } + return datas; } } diff --git a/test/BrightChain.Engine.Tests/TransactableBlockCacheManagerTest.cs b/test/BrightChain.Engine.Tests/TransactableBlockCacheManagerTest.cs old mode 100644 new mode 100755 index 9e8b4fb1..99248741 --- a/test/BrightChain.Engine.Tests/TransactableBlockCacheManagerTest.cs +++ b/test/BrightChain.Engine.Tests/TransactableBlockCacheManagerTest.cs @@ -1,16 +1,15 @@ -namespace BrightChain.Engine.Tests -{ - using BrightChain.Engine.Interfaces; - using BrightChain.Engine.Models.Blocks; - using BrightChain.Engine.Models.Hashes; - using Microsoft.VisualStudio.TestTools.UnitTesting; +using BrightChain.Engine.Interfaces; +using BrightChain.Engine.Models.Blocks; +using BrightChain.Engine.Models.Hashes; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace BrightChain.Engine.Tests; - /// - /// Test transactable blocks using the BPlusTreeCacheManagerTest - /// - [TestClass] - public abstract class TransactableBlockCacheManagerTest : CacheManagerTest - where TcacheManager : ICacheManager - { - } +/// +/// Test transactable blocks using the BPlusTreeCacheManagerTest +/// +[TestClass] +public abstract class TransactableBlockCacheManagerTest : CacheManagerTest + where TcacheManager : ICacheManager +{ } diff --git a/test/Crockford.Base32.Tests/CrockfordBase32.Tests.Core.csproj b/test/Crockford.Base32.Tests/CrockfordBase32.Tests.Core.csproj old mode 100644 new mode 100755 diff --git a/test/NeuralFabric.Tests b/test/NeuralFabric.Tests new file mode 160000 index 00000000..8070e588 --- /dev/null +++ b/test/NeuralFabric.Tests @@ -0,0 +1 @@ +Subproject commit 8070e588102ebe25c7e6ea21226c90774ed3e6b6 diff --git a/test/Shart.Test b/test/Shart.Test new file mode 160000 index 00000000..e50cf64b --- /dev/null +++ b/test/Shart.Test @@ -0,0 +1 @@ +Subproject commit e50cf64b39fb8054cd6679a3f8a473bcedd205cb