mirror of
https://code.gri.mw/GUI/grim.git
synced 2026-07-06 06:57:28 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| eaefc58c5a | |||
| 2519e68dd5 | |||
| 73c0884f95 | |||
| f7b2150228 | |||
| 03924b5300 | |||
| a479189135 | |||
| e691a7b02d | |||
| f2b79cd70d | |||
| f20d1ee2c2 | |||
| 534c4cc86a | |||
| 558ac034b2 | |||
| 13bf8e830c | |||
| 57f319edfc | |||
| 748aebffb6 | |||
| b32085a423 | |||
| a9c65546e3 | |||
| b94241b82a | |||
| 8a1a69b739 | |||
| 01d17e25ee | |||
| cab38097fa | |||
| 0026fc3717 | |||
| 0fd04f14a4 | |||
| 3338f51de5 | |||
| 0fa8963bd2 | |||
| 70bba5d7ce | |||
| 0bb43e1e5d | |||
| fd52757549 |
@@ -13,8 +13,10 @@ jobs:
|
||||
runs-on: ubuntu
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- name: Check commit
|
||||
id: check
|
||||
run: |
|
||||
|
||||
+112
-92
@@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
version:
|
||||
runs-on: ubuntu
|
||||
runs-on: debian-release
|
||||
outputs:
|
||||
v: ${{ steps.version.outputs.v }}
|
||||
pre: ${{ steps.version.outputs.pre }}
|
||||
@@ -18,8 +18,10 @@ jobs:
|
||||
last_tag: ${{ steps.check_prev.outputs.last_tag }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- name: Get version
|
||||
id: version
|
||||
run: |
|
||||
@@ -52,6 +54,18 @@ jobs:
|
||||
if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
|
||||
working-directory: release
|
||||
run: for f in *; do mv "$f" "$(echo "$f" | sed s/-dev-/-/)"; done
|
||||
- name: Delete dev release
|
||||
if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
|
||||
uses: actions/delete-release@v1
|
||||
with:
|
||||
release_name: "${{ forgejo.ref_name }}-dev"
|
||||
- name: Check previous release
|
||||
id: check_prev
|
||||
run: |
|
||||
git fetch --tags
|
||||
[[ ${{ forgejo.ref_type }} == 'tag' ]] && skip=0 || skip=1
|
||||
last_tag=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=${skip} --max-count=1)) || true
|
||||
echo "last_tag=${last_tag}" >> "$FORGEJO_OUTPUT"
|
||||
- uses: actions/forgejo-release@v2.11.3
|
||||
if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
|
||||
with:
|
||||
@@ -62,26 +76,17 @@ jobs:
|
||||
prerelease: false
|
||||
release-dir: ./release
|
||||
release-notes: "Full Changelog: [${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }}](https://code.gri.mw/${{ forgejo.repository }}/compare/${{ steps.check_prev.outputs.last_tag }}...${{ steps.version.outputs.v }})"
|
||||
- name: Delete dev release
|
||||
if: ${{ forgejo.ref_type == 'tag' && steps.check.outputs.exists == 'true' }}
|
||||
uses: actions/delete-release@v1
|
||||
with:
|
||||
release_name: "${{ forgejo.ref_name }}-dev"
|
||||
- name: Check previous release
|
||||
id: check_prev
|
||||
run: |
|
||||
git fetch --tags
|
||||
last_tag=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1))
|
||||
echo "last_tag=${last_tag}" >> "$FORGEJO_OUTPUT"
|
||||
|
||||
android_libs:
|
||||
android:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu
|
||||
runs-on: macos
|
||||
needs: version
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -93,11 +98,9 @@ jobs:
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: grim-android-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Setup registry
|
||||
run: |
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
- name: Build libs
|
||||
run: |
|
||||
rustup -q update
|
||||
chmod +x scripts/android.sh && ./scripts/android.sh lib ${{ needs.version.outputs.v }}
|
||||
- name: Save cargo cache
|
||||
uses: actions/cache/save@v5
|
||||
@@ -109,20 +112,6 @@ jobs:
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
cd android/app/src/main
|
||||
tar -czf jniLibs.tar.gz jniLibs
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file jniLibs.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/jniLibs.tar.gz
|
||||
|
||||
android_release:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu-android
|
||||
needs: [version, android_libs]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Restore gradle cache
|
||||
id: cache-gradle-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -133,23 +122,17 @@ jobs:
|
||||
key: grim-android-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Download artifacts
|
||||
run: |
|
||||
cd android/app/src/main
|
||||
curl -o jniLibs.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/jniLibs.tar.gz
|
||||
tar -xzf jniLibs.tar.gz
|
||||
rm jniLibs.tar.gz
|
||||
- name: Setup build
|
||||
run: |
|
||||
chmod +x android/gradlew
|
||||
echo "${{ secrets.ANDROID_KEYSTORE }}" > release.keystore.txt
|
||||
base64 -d release.keystore.txt > android/keystore
|
||||
base64 -d < release.keystore.txt -o android/keystore
|
||||
echo "${{ secrets.ANDROID_KEYSTORE_PROPS }}" > release.keystore.props.txt
|
||||
base64 -d release.keystore.props.txt > android/keystore.properties
|
||||
base64 -d < release.keystore.props.txt -o android/keystore.properties
|
||||
mkdir ~/.gradle && touch ~/.gradle/gradle.properties
|
||||
printf "mavenHost=${{ secrets.MAVEN_HOST }}\n" >> ~/.gradle/gradle.properties
|
||||
printf "mavenHost=${{ secrets.MAVEN_LOCAL_HOST }}\n" >> ~/.gradle/gradle.properties
|
||||
printf "mavenUser=${{ secrets.MAVEN_USER }}\n" >> ~/.gradle/gradle.properties
|
||||
printf "mavenPassword=${{ secrets.MAVEN_PASSWORD }}" >> ~/.gradle/gradle.properties
|
||||
printf "mavenPassword=${{ secrets.MAVEN_PASSWORD }}" >> ~/.gradle/gradle.properties
|
||||
- name: Release ARMv7+v8 APK
|
||||
working-directory: android
|
||||
run: |
|
||||
@@ -194,16 +177,18 @@ jobs:
|
||||
mkdir release
|
||||
mv android/grim* release
|
||||
tar -czf android.tar.gz release
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file android.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/android.tar.gz
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file android.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/android.tar.gz
|
||||
|
||||
linux_arm:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu
|
||||
needs: [version, android_libs]
|
||||
runs-on: debian-rust-arm
|
||||
needs: [version]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -217,9 +202,11 @@ jobs:
|
||||
key: grim-linux-arm-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Setup registry
|
||||
run: |
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
- name: Release Linux ARM
|
||||
run: cargo zigbuild --release --target aarch64-unknown-linux-gnu
|
||||
run: |
|
||||
rustup -q update
|
||||
cargo zigbuild --release --target aarch64-unknown-linux-gnu
|
||||
- name: Save cargo cache
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
@@ -230,28 +217,45 @@ jobs:
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: ${{ steps.cache-cargo-restore.outputs.cache-primary-key }}
|
||||
- name: AppImage ARM
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file target/aarch64-unknown-linux-gnu/release/grim ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/grim-linux-arm
|
||||
|
||||
linux_arm_appimage:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: debian-arm
|
||||
needs: [version, linux_arm]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Download Artifact
|
||||
run: |
|
||||
wget ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/grim-linux-arm
|
||||
- name: AppImage
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir release
|
||||
cp target/aarch64-unknown-linux-gnu/release/grim linux/Grim.AppDir/AppRun
|
||||
appimagetool linux/Grim.AppDir grim-${{ needs.version.outputs.v }}-linux-arm.AppImage
|
||||
cp grim-${{ needs.version.outputs.v }}-linux-arm.AppImage release/
|
||||
chmod +x grim-linux-arm
|
||||
mv grim-linux-arm linux/Grim.AppDir/AppRun
|
||||
ARCH=aarch64 appimagetool linux/Grim.AppDir grim-${{ needs.version.outputs.v }}-linux-arm.AppImage
|
||||
mv grim-${{ needs.version.outputs.v }}-linux-arm.AppImage release/
|
||||
- name: Checksum AppImage ARM
|
||||
working-directory: release
|
||||
run: sha256sum grim-${{ needs.version.outputs.v }}-linux-arm.AppImage > grim-${{ needs.version.outputs.v }}-linux-arm-appimage-sha256sum.txt
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
tar -czf linux-arm.tar.gz release
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-arm.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-arm.tar.gz
|
||||
tar -czf linux-arm.appimage.tar.gz release
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-arm.appimage.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/linux-arm.appimage.tar.gz
|
||||
|
||||
linux_x86:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu-linux-x86
|
||||
runs-on: debian-rust-x86_64
|
||||
needs: [version]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
uses: actions/cache/restore@v5
|
||||
@@ -262,12 +266,14 @@ jobs:
|
||||
~/.cargo/registry/cache/
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: grim-linux-x86-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
key: grim-linux-arm-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Setup registry
|
||||
run: |
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_LOCAL_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
- name: Release Linux x86
|
||||
run: cargo zigbuild --release --target x86_64-unknown-linux-gnu
|
||||
run: |
|
||||
rustup -q update
|
||||
cargo zigbuild --release --target x86_64-unknown-linux-gnu
|
||||
- name: Save cargo cache
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
@@ -281,25 +287,27 @@ jobs:
|
||||
- name: AppImage x86
|
||||
run: |
|
||||
mkdir release
|
||||
cp target/x86_64-unknown-linux-gnu/release/grim linux/Grim.AppDir/AppRun
|
||||
mv target/x86_64-unknown-linux-gnu/release/grim linux/Grim.AppDir/AppRun
|
||||
appimagetool linux/Grim.AppDir grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage
|
||||
cp grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage release/
|
||||
mv grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage release/
|
||||
- name: Checksum AppImage x86
|
||||
working-directory: release
|
||||
run: sha256sum grim-${{ needs.version.outputs.v }}-linux-x86_64.AppImage > grim-${{ needs.version.outputs.v }}-linux-x86_64-appimage-sha256sum.txt
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
tar -czf linux-x86_64.tar.gz release
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-x86_64.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-x86_64.tar.gz
|
||||
tar -czf linux-x86_64.appimage.tar.gz release
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file linux-x86_64.appimage.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/linux-x86_64.appimage.tar.gz
|
||||
|
||||
macos:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu
|
||||
needs: [version, android_libs, linux]
|
||||
runs-on: macos
|
||||
needs: [version, android]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
sed -i -- 's#https://code\.gri\.mw#${{ secrets.REPO_HOST }}#g' .gitmodules
|
||||
git submodule update --init
|
||||
- run: mkdir release
|
||||
- name: Restore cargo cache
|
||||
id: cache-cargo-restore
|
||||
@@ -312,13 +320,14 @@ jobs:
|
||||
~/.cargo/git/db/
|
||||
target/
|
||||
key: grim-macos-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Setup registry
|
||||
run: |
|
||||
echo -e '[registries.nexus]\nindex = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"\n[registry]\ndefault = "nexus"\n[source.crates-io]\nreplace-with = "nexus"\n[source.nexus]\nregistry = "sparse+${{ secrets.MAVEN_HOST }}/repository/cargo/"' > ~/.cargo/config.toml
|
||||
- name: Release MacOS Universal
|
||||
run: |
|
||||
cargo zigbuild --release --target universal2-apple-darwin
|
||||
cp target/universal2-apple-darwin/release/grim macos/Grim.app/Contents/MacOS
|
||||
rustup -q update
|
||||
export MACOSX_DEPLOYMENT_TARGET=11.0
|
||||
cargo build --release --target x86_64-apple-darwin
|
||||
cargo build --release --target aarch64-apple-darwin
|
||||
lipo -create -output grim "target/x86_64-apple-darwin/release/grim" "target/aarch64-apple-darwin/release/grim"
|
||||
mv grim macos/Grim.app/Contents/MacOS
|
||||
- name: Save cargo cache
|
||||
uses: actions/cache/save@v5
|
||||
with:
|
||||
@@ -340,7 +349,7 @@ jobs:
|
||||
- name: Upload artifacts
|
||||
run: |
|
||||
tar -czf macos.tar.gz release
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file macos.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/macos.tar.gz
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file macos.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/macos.tar.gz
|
||||
|
||||
windows:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
@@ -348,11 +357,22 @@ jobs:
|
||||
needs: [version]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Checkout submodules
|
||||
run: |
|
||||
(Get-content .gitmodules) | Foreach-Object {$_ -replace "https://code.gri.mw", "${{ secrets.REPO_HOST }}"} | Set-Content .gitmodules
|
||||
git submodule update --init
|
||||
- name: Update UpgradeCode
|
||||
shell: powershell
|
||||
run: |
|
||||
$guid = [guid]::NewGuid().ToString()
|
||||
$wix = [xml](Get-Content wix/main.wxs)
|
||||
$wix.Wix.Product.UpgradeCode = $guid
|
||||
$wix.Save("wix/main.wxs")
|
||||
Get-Content wix/main.wxs
|
||||
- run: mkdir release
|
||||
- name: Release Windows x86
|
||||
run: |
|
||||
rustup -q update
|
||||
cargo wix -p grim -o grim-${{ needs.version.outputs.v }}-win-x86_64.msi --nocapture
|
||||
mv grim-${{ needs.version.outputs.v }}-win-x86_64.msi release\
|
||||
Compress-Archive -Path target\release\grim.exe -DestinationPath grim-${{ needs.version.outputs.v }}-win-x86_64.zip
|
||||
@@ -366,28 +386,28 @@ jobs:
|
||||
run: |
|
||||
tar -czf windows.tar.gz release
|
||||
Remove-Item alias:curl
|
||||
curl -v -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file windows.tar.gz ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/windows.tar.gz
|
||||
curl -s -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} --upload-file windows.tar.gz ${{ secrets.MAVEN_LOCAL_HOST }}/repository/grim-ci/${{ forgejo.repository }}/windows.tar.gz
|
||||
|
||||
release:
|
||||
if: ${{ forgejo.ref_type == 'branch' || needs.version.outputs.exists == 'false' }}
|
||||
runs-on: ubuntu
|
||||
needs: [version, android_release, linux, linux_x86, macos, windows]
|
||||
runs-on: debian-release
|
||||
needs: [version, android, linux_x86, linux_arm_appimage, macos, windows]
|
||||
steps:
|
||||
- name: Download All Artifacts
|
||||
run: |
|
||||
curl -o android.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/android.tar.gz
|
||||
curl -s -o android.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci/${{ forgejo.repository }}/android.tar.gz
|
||||
tar -xzf android.tar.gz
|
||||
rm android.tar.gz
|
||||
curl -o linux-arm.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-arm.tar.gz
|
||||
tar -xzf linux-arm.tar.gz
|
||||
rm linux-arm.tar.gz
|
||||
curl -o linux-x86_64.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/linux-x86_64.tar.gz
|
||||
tar -xzf linux-x86_64.tar.gz
|
||||
rm linux-x86_64.tar.gz
|
||||
curl -o macos.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/macos.tar.gz
|
||||
curl -s -o linux-x86_64.appimage.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci/${{ forgejo.repository }}/linux-x86_64.appimage.tar.gz
|
||||
tar -xzf linux-x86_64.appimage.tar.gz
|
||||
rm linux-x86_64.appimage.tar.gz
|
||||
curl -s -o linux-arm.appimage.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci/${{ forgejo.repository }}/linux-arm.appimage.tar.gz
|
||||
tar -xzf linux-arm.appimage.tar.gz
|
||||
rm linux-arm.appimage.tar.gz
|
||||
curl -s -o macos.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci/${{ forgejo.repository }}/macos.tar.gz
|
||||
tar -xzf macos.tar.gz
|
||||
rm macos.tar.gz
|
||||
curl -o windows.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci-artifacts/${{ forgejo.repository }}/windows.tar.gz
|
||||
curl -s -o windows.tar.gz -u ${{ secrets.MAVEN_USER }}:${{ secrets.MAVEN_PASSWORD }} ${{ secrets.MAVEN_HOST }}/repository/grim-ci/${{ forgejo.repository }}/windows.tar.gz
|
||||
tar -xzf windows.tar.gz
|
||||
rm windows.tar.gz
|
||||
- name: Upload release to Forgejo
|
||||
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2026 The Grim Developers
|
||||
#
|
||||
# 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.
|
||||
|
||||
rustfmt --version &>/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
printf "[pre_commit] \033[0;31merror\033[0m: \"rustfmt\" not available. \n"
|
||||
printf "[pre_commit] \033[0;31merror\033[0m: rustfmt can be installed via - \n"
|
||||
printf "[pre_commit] $ rustup component add rustfmt-preview \n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
problem_files=()
|
||||
|
||||
# first collect all the files that need reformatting
|
||||
for file in $(git diff --name-only --cached); do
|
||||
if [ ${file: -3} == ".rs" ]; then
|
||||
rustfmt --check $file &>/dev/null
|
||||
if [ $? != 0 ]; then
|
||||
problem_files+=($file)
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#problem_files[@]} == 0 ]; then
|
||||
# nothing to do
|
||||
printf "[pre_commit] rustfmt \033[0;32mok\033[0m \n"
|
||||
else
|
||||
# reformat the files that need it and re-stage them.
|
||||
printf "[pre_commit] the following files were rustfmt'd before commit: \n"
|
||||
for file in ${problem_files[@]}; do
|
||||
rustfmt $file
|
||||
git add $file
|
||||
printf "\033[0;32m $file\033[0m \n"
|
||||
done
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Generated
+369
-345
File diff suppressed because it is too large
Load Diff
+13
-13
@@ -1,12 +1,12 @@
|
||||
[package]
|
||||
name = "grim"
|
||||
version = "0.3.3"
|
||||
version = "0.3.5"
|
||||
authors = ["Ardocrat <ardocrat@gri.mw>"]
|
||||
description = "Cross-platform GUI for Grin with focus on usability and availability to be used by anyone, anywhere."
|
||||
license = "Apache-2.0"
|
||||
repository = "https://code.gri.mw/GUI/grim"
|
||||
keywords = [ "crypto", "grin", "mimblewimble" ]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
[[bin]]
|
||||
@@ -92,23 +92,23 @@ uuid = { version = "0.8.2", features = ["v4"] }
|
||||
num-bigint = "0.4.6"
|
||||
|
||||
## tor
|
||||
arti-client = { version = "0.38.0", features = ["pt-client", "static", "onion-service-service", "onion-service-client", "experimental-api", "bridge-client"] }
|
||||
tor-rtcompat = { version = "0.38.0", features = ["static"] }
|
||||
tor-config = "0.38.0"
|
||||
fs-mistrust = "0.13.1"
|
||||
tor-hsservice = "0.38.0"
|
||||
tor-hsrproxy = "0.38.0"
|
||||
tor-keymgr = "0.38.0"
|
||||
tor-llcrypto = "0.38.0"
|
||||
tor-hscrypto = "0.38.0"
|
||||
tor-error = "0.38.0"
|
||||
arti-client = { version = "0.41.0", features = ["pt-client", "static", "onion-service-service", "onion-service-client", "experimental-api", "bridge-client"] }
|
||||
tor-rtcompat = { version = "0.41.0", features = ["static"] }
|
||||
tor-config = "0.41.0"
|
||||
fs-mistrust = "0.14.1"
|
||||
tor-hsservice = "0.41.0"
|
||||
tor-hsrproxy = "0.41.0"
|
||||
tor-keymgr = "0.41.0"
|
||||
tor-llcrypto = "0.41.0"
|
||||
tor-hscrypto = "0.41.0"
|
||||
tor-error = "0.41.0"
|
||||
sha2 = "0.10.8"
|
||||
ed25519-dalek = "2.1.1"
|
||||
curve25519-dalek = "4.1.3"
|
||||
hyper-tor = { version = "0.14.32", features = ["full"], package = "hyper" }
|
||||
tls-api = "0.12.0"
|
||||
tls-api-native-tls = "0.12.1"
|
||||
safelog = "0.7.0"
|
||||
safelog = "0.8.1"
|
||||
|
||||
## stratum server
|
||||
tokio-old = { version = "0.2", features = ["full"], package = "tokio" }
|
||||
|
||||
@@ -12,7 +12,7 @@ android {
|
||||
minSdk 24
|
||||
targetSdk 36
|
||||
versionCode 5
|
||||
versionName "0.3.3"
|
||||
versionName "0.3.5"
|
||||
}
|
||||
|
||||
lint {
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/*" />
|
||||
<data android:mimeType="application/*" />
|
||||
<data android:pathPattern=".*\\.slatepack" />
|
||||
</intent-filter>
|
||||
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: Die Entscheidung über das Verbot trifft der Knoten auf der Grundlage der Korrektheit der von der Gegenstelle erhaltenen Daten.
|
||||
max_inbound_count: 'Maximale Anzahl der eingehenden Peer-Verbindungen:'
|
||||
max_outbound_count: 'Maximale Anzahl von ausgehenden Peer-Verbindungen:'
|
||||
reset_peers_desc: Peer-Daten zurücksetzen. Verwenden Sie diese Funktion nur, wenn es Probleme beim finden von Peers gibt.
|
||||
reset_peers: Peers zurücksetzten
|
||||
reset_data_desc: Reset-Knotendaten. Verwenden Sie diese Funktion nur, wenn es Probleme mit der Synchronisation gibt.
|
||||
reset_data: Daten zurücksetzten
|
||||
modal:
|
||||
cancel: Abbrechen
|
||||
save: Speichern
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: The decision to ban is made by node, based on the correctness of the data received from the peer.
|
||||
max_inbound_count: 'Maximum number of inbound peer connections:'
|
||||
max_outbound_count: 'Maximum number of outbound peer connections:'
|
||||
reset_peers_desc: Reset peers data. Use it with a caution only if there are problems with finding peers.
|
||||
reset_peers: Reset peers
|
||||
reset_data_desc: Reset the node data. Use it with a caution only if there are problems with synchronization.
|
||||
reset_data: Reset data
|
||||
modal:
|
||||
cancel: Cancel
|
||||
save: Save
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: La décision de bannir est prise par le noeud, en fonction de la validité des données reçues du pair.
|
||||
max_inbound_count: 'Nombre maximum de connexions de pairs entrants :'
|
||||
max_outbound_count: 'Nombre maximum de connexions de pairs sortants :'
|
||||
reset_peers_desc: Réinitialiser les données des pairs. Utilisez-le avec précaution uniquement en cas de problèmes pour trouver des pairs.
|
||||
reset_peers: Réinitialiser les pairs
|
||||
reset_data_desc: Réinitialisez les données du noeud. Utilisez-le avec prudence uniquement en cas de problème de synchronisation.
|
||||
reset_data: Réinitialisation des données
|
||||
modal:
|
||||
cancel: Annuler
|
||||
save: Sauvegarder
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: Решение о запрете принимается узлом, основываясь на корректности данных полученных от пира.
|
||||
max_inbound_count: 'Максимальное количество входящих подключений пиров:'
|
||||
max_outbound_count: 'Максимальное количество исходящих подключений к пирам:'
|
||||
reset_peers_desc: Сбросить данные пиров. Используйте с осторожностью, только при наличии проблем с поиском пиров.
|
||||
reset_peers: Сбросить пиры
|
||||
reset_data_desc: Сбросить данные узла. Используйте с осторожностью, только при наличии проблем с синхронизацией.
|
||||
reset_data: Сброс данных
|
||||
modal:
|
||||
cancel: Отмена
|
||||
save: Сохранить
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: Banlama karari, peerden alinan verilerin dogruluguna bagli olarak Node tarafindan verilir.
|
||||
max_inbound_count: 'Maksimum gelen Peer baglanti sayisi:'
|
||||
max_outbound_count: 'Maksimum giden Peer baglanti sayisi:'
|
||||
reset_peers_desc: Peers verilerini sifirlayin. Yalnizca Peers bulma konusunda sorun yasiyorsaniz dikkatli kullanin.
|
||||
reset_peers: Peers Resetle
|
||||
reset_data_desc: Node verisini sifirlama. Sadece senkronizasyonda sorun varsa dikkatli kullanin.
|
||||
reset_data: Verileri sifirlama
|
||||
modal:
|
||||
cancel: Iptal
|
||||
save: Kaydet
|
||||
|
||||
+2
-2
@@ -300,8 +300,8 @@ network_settings:
|
||||
ban_window_desc: 禁止的决定是由节点 根据从网络对点收到的数据的正确性做出的.
|
||||
max_inbound_count: '入站网络对点连接的最大数量:'
|
||||
max_outbound_count: '最大出站网络对点连接数:'
|
||||
reset_peers_desc: 重置网络对点数据。仅当查找网络对点出现问题时,才请谨慎使用它.
|
||||
reset_peers: 重置网络对点
|
||||
reset_data_desc: 重置节点数据。只有在出现同步问题时才需谨慎使用.
|
||||
reset_data: 重置数据
|
||||
modal:
|
||||
cancel: 取消
|
||||
save: 保存
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.3.3</string>
|
||||
<string>0.3.5</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
|
||||
+1
-1
Submodule node updated: 42b928a42f...3a37d24dca
@@ -0,0 +1,2 @@
|
||||
hard_tabs = true
|
||||
edition = "2024"
|
||||
@@ -41,13 +41,10 @@ function build_lib() {
|
||||
sed -i -e 's/"cdylib","rlib"]/"rlib"]/g' Cargo.toml
|
||||
sed -i -e 's/"rlib"]/"cdylib","rlib"]/g' Cargo.toml
|
||||
|
||||
# Fix for https://stackoverflow.com/questions/57193895/error-use-of-undeclared-identifier-pthread-mutex-robust-cargo-build-liblmdb-s
|
||||
export CPPFLAGS="-DMDB_USE_ROBUST=0" && export CFLAGS="-DMDB_USE_ROBUST=0"
|
||||
cargo ndk -t "${arch}" -o android/app/src/main/jniLibs build --profile release-apk
|
||||
if [ $? -ne 0 ]; then
|
||||
success=0
|
||||
fi
|
||||
unset CPPFLAGS && unset CFLAGS
|
||||
|
||||
sed -i -e 's/"cdylib","rlib"]/"rlib"]/g' Cargo.toml
|
||||
rm -f Cargo.toml-e
|
||||
|
||||
+1
-1
@@ -418,7 +418,7 @@ impl<Platform: PlatformCallbacks> eframe::App for App<Platform> {
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Handle Back key code event from Android.
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onBack(
|
||||
_env: jni::JNIEnv,
|
||||
|
||||
@@ -203,7 +203,7 @@ lazy_static! {
|
||||
|
||||
/// Callback from Java code with last entered character from soft keyboard.
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onCameraImage(
|
||||
env: JNIEnv,
|
||||
_class: JObject,
|
||||
@@ -218,7 +218,7 @@ pub extern "C" fn Java_mw_gri_android_MainActivity_onCameraImage(
|
||||
|
||||
/// Callback from Java code with picked file path.
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onFilePick(
|
||||
_env: JNIEnv,
|
||||
_class: JObject,
|
||||
|
||||
@@ -404,7 +404,7 @@ lazy_static! {
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Callback from Java code with last entered character from soft keyboard.
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onTextInput(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -429,7 +429,7 @@ pub extern "C" fn Java_mw_gri_android_MainActivity_onTextInput(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Callback from Java code when Clear key was pressed at soft keyboard.
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onClearInput(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -442,7 +442,7 @@ pub extern "C" fn Java_mw_gri_android_MainActivity_onClearInput(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Callback from Java code when Enter key was pressed at soft keyboard.
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onEnterInput(
|
||||
_env: jni::JNIEnv,
|
||||
|
||||
@@ -16,7 +16,7 @@ use egui::{RichText, ScrollArea};
|
||||
use egui::scroll_area::ScrollBarVisibility;
|
||||
|
||||
use crate::gui::Colors;
|
||||
use crate::gui::icons::ARROW_COUNTER_CLOCKWISE;
|
||||
use crate::gui::icons::{ARROW_COUNTER_CLOCKWISE, TRASH};
|
||||
use crate::gui::platform::PlatformCallbacks;
|
||||
use crate::gui::views::{Modal, Content, View};
|
||||
use crate::gui::views::network::setup::{DandelionSetup, NodeSetup, P2PSetup, PoolSetup, StratumSetup};
|
||||
@@ -36,6 +36,9 @@ pub struct NetworkSettings {
|
||||
pool: PoolSetup,
|
||||
/// Dandelion server setup content.
|
||||
dandelion: DandelionSetup,
|
||||
|
||||
/// Flag to check if reset of data was called.
|
||||
data_reset: bool,
|
||||
}
|
||||
|
||||
/// Identifier for settings reset confirmation [`Modal`].
|
||||
@@ -49,6 +52,7 @@ impl Default for NetworkSettings {
|
||||
stratum: StratumSetup::default(),
|
||||
pool: PoolSetup::default(),
|
||||
dandelion: DandelionSetup::default(),
|
||||
data_reset: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +114,15 @@ impl ContentContainer for NetworkSettings {
|
||||
// Draw Dandelion server setup section.
|
||||
self.dandelion.ui(ui, cb);
|
||||
|
||||
// Draw content to reset the data.
|
||||
if !Node::is_restarting() && !self.data_reset {
|
||||
ui.add_space(4.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
self.reset_data_ui(ui);
|
||||
}
|
||||
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::stroke());
|
||||
ui.add_space(6.0);
|
||||
@@ -179,7 +192,7 @@ impl NetworkSettings {
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
if saved_ip != selected_ip {
|
||||
(on_change)(&selected_ip.to_string());
|
||||
on_change(&selected_ip.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,37 +206,53 @@ impl NetworkSettings {
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw content to reset data.
|
||||
fn reset_data_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(4.0);
|
||||
View::colored_text_button(ui,
|
||||
format!("{} {}", TRASH, t!("network_settings.reset_data")),
|
||||
Colors::red(),
|
||||
Colors::white_or_black(false), || {
|
||||
Node::reset_data(false);
|
||||
self.data_reset = true;
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("network_settings.reset_data_desc"))
|
||||
.size(16.0)
|
||||
.color(Colors::inactive_text())
|
||||
);
|
||||
ui.add_space(4.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Draw button to reset integrated node settings to default values.
|
||||
fn reset_settings_ui(ui: &mut egui::Ui) {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(RichText::new(t!("network_settings.reset_settings_desc"))
|
||||
.size(16.0)
|
||||
.color(Colors::text(false)));
|
||||
ui.add_space(8.0);
|
||||
let button_text = format!("{} {}",
|
||||
ARROW_COUNTER_CLOCKWISE,
|
||||
t!("network_settings.reset_settings"));
|
||||
View::action_button(ui, button_text, || {
|
||||
// Show modal to confirm settings reset.
|
||||
Modal::new(RESET_SETTINGS_CONFIRMATION_MODAL)
|
||||
.position(ModalPosition::Center)
|
||||
.title(t!("confirmation"))
|
||||
.show();
|
||||
});
|
||||
|
||||
// Show reminder to restart enabled node.
|
||||
if Node::is_running() {
|
||||
ui.add_space(12.0);
|
||||
ui.label(RichText::new(t!("network_settings.restart_node_required"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
);
|
||||
}
|
||||
ui.add_space(12.0);
|
||||
ui.label(RichText::new(t!("network_settings.reset_settings_desc"))
|
||||
.size(16.0)
|
||||
.color(Colors::text(false)));
|
||||
ui.add_space(8.0);
|
||||
let button_text = format!("{} {}",
|
||||
ARROW_COUNTER_CLOCKWISE,
|
||||
t!("network_settings.reset_settings"));
|
||||
View::action_button(ui, button_text, || {
|
||||
// Show modal to confirm settings reset.
|
||||
Modal::new(RESET_SETTINGS_CONFIRMATION_MODAL)
|
||||
.position(ModalPosition::Center)
|
||||
.title(t!("confirmation"))
|
||||
.show();
|
||||
});
|
||||
|
||||
// Show reminder to restart enabled node.
|
||||
if Node::is_running() {
|
||||
ui.add_space(12.0);
|
||||
ui.label(RichText::new(t!("network_settings.restart_node_required"))
|
||||
.size(16.0)
|
||||
.color(Colors::gray())
|
||||
);
|
||||
}
|
||||
ui.add_space(10.0);
|
||||
}
|
||||
|
||||
/// Confirmation to reset settings to default values.
|
||||
|
||||
@@ -65,9 +65,6 @@ pub struct P2PSetup {
|
||||
|
||||
/// Maximum number of outbound peer connections.
|
||||
max_outbound_count: String,
|
||||
|
||||
/// Flag to check if reset of peers was called.
|
||||
peers_reset: bool,
|
||||
}
|
||||
|
||||
/// Identifier for port value [`Modal`].
|
||||
@@ -111,7 +108,6 @@ impl Default for P2PSetup {
|
||||
ban_window_edit: NodeConfig::get_p2p_ban_window(),
|
||||
max_inbound_count: NodeConfig::get_max_inbound_peers(),
|
||||
max_outbound_count: NodeConfig::get_max_outbound_peers(),
|
||||
peers_reset: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,15 +212,6 @@ impl ContentContainer for P2PSetup {
|
||||
|
||||
// Show maximum outbound peers value setup.
|
||||
self.max_outbound_ui(ui);
|
||||
|
||||
if !Node::is_restarting() && !self.peers_reset {
|
||||
ui.add_space(6.0);
|
||||
View::horizontal_line(ui, Colors::item_stroke());
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Show peers data reset content.
|
||||
self.reset_peers_ui(ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -753,23 +740,6 @@ impl P2PSetup {
|
||||
ui.add_space(6.0);
|
||||
});
|
||||
}
|
||||
|
||||
/// Draw content to reset peers data.
|
||||
fn reset_peers_ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add_space(4.0);
|
||||
View::colored_text_button(ui,
|
||||
format!("{} {}", TRASH, t!("network_settings.reset_peers")),
|
||||
Colors::red(),
|
||||
Colors::white_or_black(false), || {
|
||||
Node::reset_peers(false);
|
||||
self.peers_reset = true;
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
ui.label(RichText::new(t!("network_settings.reset_peers_desc"))
|
||||
.size(16.0)
|
||||
.color(Colors::inactive_text())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw peer list item.
|
||||
|
||||
@@ -113,7 +113,7 @@ pub enum PullToRefreshState {
|
||||
/// `far_enough` is true if the user dragged far enough to trigger a refresh.
|
||||
far_enough: bool,
|
||||
},
|
||||
/// The user dragged far enough to trigger a refresh and released the pointer.
|
||||
/// The user dragged far enough to trigger a refresh.
|
||||
DoRefresh,
|
||||
/// The refresh is currently happening.
|
||||
Refreshing,
|
||||
@@ -298,6 +298,12 @@ impl PullToRefresh {
|
||||
} else {
|
||||
state = PullToRefreshState::Idle;
|
||||
}
|
||||
} else if let PullToRefreshState::Dragging {
|
||||
far_enough: enough, ..
|
||||
} = state.clone() {
|
||||
if enough {
|
||||
state = PullToRefreshState::DoRefresh;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
state = PullToRefreshState::Idle;
|
||||
|
||||
@@ -709,7 +709,7 @@ lazy_static! {
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Callback from Java code to update display insets (cutouts).
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onDisplayInsets(
|
||||
_env: jni::JNIEnv,
|
||||
|
||||
@@ -64,7 +64,7 @@ impl WalletContentContainer for WalletAccountContent {
|
||||
CREATE_MODAL_ID => self.create_account_content.ui(ui, wallet, modal, cb),
|
||||
SEND_MODAL_ID => {
|
||||
if let Some(c) = self.send_content.as_mut() {
|
||||
c.modal_ui(ui, wallet, modal, cb);
|
||||
c.ui(ui, wallet, modal, cb);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -58,36 +58,41 @@ pub struct WalletContent {
|
||||
const INVOICE_MODAL_ID: &'static str = "invoice_request_modal";
|
||||
/// Identifier for sending request creation [`Modal`].
|
||||
const SEND_MODAL_ID: &'static str = "send_request_modal";
|
||||
/// Identifier for Slatepack message input [`Modal`].
|
||||
pub const MESSAGE_MODAL_ID: &'static str = "input_message_modal";
|
||||
|
||||
impl WalletContentContainer for WalletContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![
|
||||
INVOICE_MODAL_ID,
|
||||
SEND_MODAL_ID,
|
||||
MESSAGE_MODAL_ID
|
||||
MessageInputContent::MODAL_ID
|
||||
]
|
||||
}
|
||||
|
||||
fn modal_ui(&mut self, ui: &mut egui::Ui, w: &Wallet, m: &Modal, cb: &dyn PlatformCallbacks) {
|
||||
match m.id {
|
||||
INVOICE_MODAL_ID => {
|
||||
if let Some(c) = self.invoice_content.as_mut() {
|
||||
c.modal_ui(ui, w, m, cb);
|
||||
if self.invoice_content.is_none() {
|
||||
self.invoice_content = Some(InvoiceRequestContent::default());
|
||||
}
|
||||
self.invoice_content.as_mut().unwrap().ui(ui, w, m, cb);
|
||||
}
|
||||
SEND_MODAL_ID => {
|
||||
if let Some(c) = self.send_content.as_mut() {
|
||||
c.modal_ui(ui, w, m, cb);
|
||||
if self.send_content.is_none() {
|
||||
self.send_content = Some(SendRequestContent::new(None));
|
||||
}
|
||||
self.send_content.as_mut().unwrap().ui(ui, w, m, cb);
|
||||
}
|
||||
MESSAGE_MODAL_ID => {
|
||||
if let Some(c) = self.message_content.as_mut() {
|
||||
c.ui(ui, w, m, cb);
|
||||
MessageInputContent::MODAL_ID => {
|
||||
if self.message_content.is_none() {
|
||||
self.message_content = Some(MessageInputContent::default());
|
||||
}
|
||||
self.message_content.as_mut().unwrap().ui(ui, w, m, cb);
|
||||
}
|
||||
_ => {
|
||||
self.invoice_content = None;
|
||||
self.send_content = None;
|
||||
self.message_content = None;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,7 +399,10 @@ impl WalletContent {
|
||||
} else {
|
||||
let (icon, color) = (FILE_ARROW_DOWN, Some(Colors::green()));
|
||||
View::tab_button(ui, icon, color, active, |_| {
|
||||
self.invoice_content = Some(InvoiceRequestContent::default());
|
||||
if self.txs_content.is_none() {
|
||||
self.txs_content = Some(WalletTransactionsContent::new(None));
|
||||
self.settings_content = None;
|
||||
}
|
||||
Modal::new(INVOICE_MODAL_ID)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.receive"))
|
||||
@@ -409,8 +417,11 @@ impl WalletContent {
|
||||
} else {
|
||||
let (icon, color) = (FILE_TEXT, Some(Colors::gold_dark()));
|
||||
View::tab_button(ui, icon, color, active, |_| {
|
||||
self.message_content = Some(MessageInputContent::default());
|
||||
Modal::new(MESSAGE_MODAL_ID)
|
||||
if self.txs_content.is_none() {
|
||||
self.txs_content = Some(WalletTransactionsContent::new(None));
|
||||
self.settings_content = None;
|
||||
}
|
||||
Modal::new(MessageInputContent::MODAL_ID)
|
||||
.position(ModalPosition::Center)
|
||||
.title(t!("wallets.messages"))
|
||||
.show();
|
||||
@@ -425,7 +436,10 @@ impl WalletContent {
|
||||
} else {
|
||||
let (icon, color) = (FILE_ARROW_UP, Some(Colors::red()));
|
||||
View::tab_button(ui, icon, color, active, |_| {
|
||||
self.send_content = Some(SendRequestContent::new(None));
|
||||
if self.txs_content.is_none() {
|
||||
self.txs_content = Some(WalletTransactionsContent::new(None));
|
||||
self.settings_content = None;
|
||||
}
|
||||
Modal::new(SEND_MODAL_ID)
|
||||
.position(ModalPosition::CenterTop)
|
||||
.title(t!("wallets.send"))
|
||||
@@ -488,7 +502,7 @@ impl WalletContent {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
MESSAGE_MODAL_ID => {
|
||||
MessageInputContent::MODAL_ID => {
|
||||
match t {
|
||||
WalletTask::VerifyProof(proof, res) => {
|
||||
if let Some(res) = res {
|
||||
|
||||
@@ -56,6 +56,9 @@ impl Default for MessageInputContent {
|
||||
}
|
||||
|
||||
impl MessageInputContent {
|
||||
/// Identifier for [`Modal`].
|
||||
pub const MODAL_ID: &'static str = "input_message_modal";
|
||||
|
||||
/// Draw [`Modal`] content.
|
||||
pub fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
@@ -236,15 +239,13 @@ impl MessageInputContent {
|
||||
if self.message_edit.is_empty() {
|
||||
return;
|
||||
}
|
||||
match wallet.parse_slatepack(&self.message_edit) {
|
||||
Ok(_) => {
|
||||
wallet.task(WalletTask::OpenMessage(self.message_edit.to_string()));
|
||||
self.message_edit = "".to_string();
|
||||
Modal::close();
|
||||
}
|
||||
Err(_) => {
|
||||
self.parse_error = true;
|
||||
}
|
||||
if self.message_edit.starts_with("BEGINSLATEPACK.") &&
|
||||
self.message_edit.ends_with("ENDSLATEPACK.") {
|
||||
wallet.task(WalletTask::OpenMessage(self.message_edit.to_string()));
|
||||
self.message_edit = "".to_string();
|
||||
Modal::close();
|
||||
} else {
|
||||
self.parse_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ impl Default for InvoiceRequestContent {
|
||||
|
||||
impl InvoiceRequestContent {
|
||||
/// Draw [`Modal`] content.
|
||||
pub fn modal_ui(&mut self,
|
||||
pub fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
modal: &Modal,
|
||||
|
||||
@@ -73,11 +73,11 @@ impl SendRequestContent {
|
||||
}
|
||||
|
||||
/// Draw [`Modal`] content.
|
||||
pub fn modal_ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
pub fn ui(&mut self,
|
||||
ui: &mut egui::Ui,
|
||||
wallet: &Wallet,
|
||||
modal: &Modal,
|
||||
cb: &dyn PlatformCallbacks) {
|
||||
ui.add_space(6.0);
|
||||
|
||||
// Draw QR code scanner content if requested.
|
||||
@@ -287,9 +287,14 @@ impl SendRequestContent {
|
||||
});
|
||||
columns[1].vertical_centered_justified(|ui| {
|
||||
// Button to create Slatepack message request.
|
||||
View::button(ui, t!("continue"), Colors::white_or_black(false), || {
|
||||
self.on_continue(wallet);
|
||||
});
|
||||
if self.max_calculating || wallet.fee_calculating() {
|
||||
ui.add_space(4.0);
|
||||
View::small_loading_spinner(ui);
|
||||
} else {
|
||||
View::button(ui, t!("continue"), Colors::white_or_black(false), || {
|
||||
self.on_continue(wallet);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
ui.add_space(6.0);
|
||||
@@ -297,7 +302,7 @@ impl SendRequestContent {
|
||||
|
||||
/// Callback when Continue button was pressed.
|
||||
fn on_continue(&mut self, wallet: &Wallet) {
|
||||
if self.amount_edit.is_empty() || self.max_calculating || wallet.fee_calculating() {
|
||||
if self.amount_edit.is_empty() {
|
||||
return;
|
||||
}
|
||||
// Check address to send over Tor if enabled.
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::gui::views::network::ConnectionsContent;
|
||||
use crate::gui::views::types::{ContentContainer, ModalPosition};
|
||||
use crate::gui::views::{Modal, View};
|
||||
use crate::gui::Colors;
|
||||
use crate::node::Node;
|
||||
use crate::wallet::types::ConnectionMethod;
|
||||
use crate::wallet::{ConnectionsConfig, ExternalConnection};
|
||||
|
||||
@@ -35,8 +36,17 @@ pub struct ConnectionSettings {
|
||||
|
||||
impl Default for ConnectionSettings {
|
||||
fn default() -> Self {
|
||||
let method = {
|
||||
let ext_conn_list = ConnectionsConfig::ext_conn_list();
|
||||
if Node::is_running() || Node::is_starting() || ext_conn_list.is_empty() {
|
||||
ConnectionMethod::Integrated
|
||||
} else {
|
||||
let ext_conn = ext_conn_list.get(0).unwrap();
|
||||
ConnectionMethod::External(ext_conn.id, ext_conn.url.clone())
|
||||
}
|
||||
};
|
||||
Self {
|
||||
method: ConnectionMethod::Integrated,
|
||||
method,
|
||||
ext_conn_modal: ExternalConnectionModal::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,13 @@ pub struct WalletTransactionsContent {
|
||||
manual_sync: Option<u128>
|
||||
}
|
||||
|
||||
/// Identifier for transaction information [`Modal`].
|
||||
const TX_INFO_MODAL: &'static str = "tx_info_modal";
|
||||
/// Identifier for transaction cancellation confirmation [`Modal`].
|
||||
const CANCEL_TX_CONFIRMATION_MODAL: &'static str = "cancel_tx_conf_modal";
|
||||
/// Identifier for transaction deletion confirmation [`Modal`].
|
||||
const DELETE_TX_CONFIRMATION_MODAL: &'static str = "delete_tx_conf_modal";
|
||||
|
||||
impl WalletContentContainer for WalletTransactionsContent {
|
||||
fn modal_ids(&self) -> Vec<&'static str> {
|
||||
vec![TX_INFO_MODAL, CANCEL_TX_CONFIRMATION_MODAL, DELETE_TX_CONFIRMATION_MODAL]
|
||||
@@ -78,16 +85,9 @@ impl WalletContentContainer for WalletTransactionsContent {
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifier for transaction information [`Modal`].
|
||||
const TX_INFO_MODAL: &'static str = "tx_info_modal";
|
||||
/// Identifier for transaction cancellation confirmation [`Modal`].
|
||||
const CANCEL_TX_CONFIRMATION_MODAL: &'static str = "cancel_tx_conf_modal";
|
||||
/// Identifier for transaction deletion confirmation [`Modal`].
|
||||
const DELETE_TX_CONFIRMATION_MODAL: &'static str = "delete_tx_conf_modal";
|
||||
|
||||
impl WalletTransactionsContent {
|
||||
/// Height of transaction list item.
|
||||
pub const TX_ITEM_HEIGHT: f32 = 73.0;
|
||||
pub const TX_ITEM_HEIGHT: f32 = 75.0;
|
||||
|
||||
/// Create new content instance with opening tx info.
|
||||
pub fn new(tx: Option<WalletTx>) -> Self {
|
||||
|
||||
@@ -28,6 +28,8 @@ use crate::gui::Colors;
|
||||
use crate::wallet::types::{WalletTask, WalletTx};
|
||||
use crate::wallet::Wallet;
|
||||
use crate::AppConfig;
|
||||
use crate::gui::views::types::ModalPosition;
|
||||
use crate::gui::views::wallets::wallet::message::MessageInputContent;
|
||||
|
||||
/// Transaction information [`Modal`] content.
|
||||
pub struct WalletTransactionContent {
|
||||
@@ -219,6 +221,8 @@ impl WalletTransactionContent {
|
||||
// Setup spacing between buttons.
|
||||
ui.spacing_mut().item_spacing = egui::Vec2::new(8.0, 0.0);
|
||||
|
||||
let mut finalization_needed = false;
|
||||
|
||||
ui.columns(2, |columns| {
|
||||
columns[0].vertical_centered_justified(|ui| {
|
||||
// Draw button to show Slatepack message as QR code.
|
||||
@@ -232,7 +236,12 @@ impl WalletTransactionContent {
|
||||
let copy_text = format!("{} {}", COPY, t!("copy"));
|
||||
View::button(ui, copy_text, Colors::white_or_black(false), || {
|
||||
cb.copy_string_to_buffer(m.clone());
|
||||
Modal::close();
|
||||
// Show message input or close modal.
|
||||
if tx.can_finalize() {
|
||||
finalization_needed = true;
|
||||
} else {
|
||||
Modal::close();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -249,10 +258,22 @@ impl WalletTransactionContent {
|
||||
let name = format!("{}.{}.slatepack", slate_id, tx.state);
|
||||
let data = m.as_bytes().to_vec();
|
||||
cb.share_data(name, data).unwrap_or_default();
|
||||
Modal::close();
|
||||
// Show message input or close modal.
|
||||
if tx.can_finalize() {
|
||||
finalization_needed = true;
|
||||
} else {
|
||||
Modal::close();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if finalization_needed {
|
||||
Modal::new(MessageInputContent::MODAL_ID)
|
||||
.position(ModalPosition::Center)
|
||||
.title(t!("wallets.messages"))
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
/// Android platform entry point.
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
fn android_main(app: AndroidApp) {
|
||||
// Setup logger.
|
||||
logger::init_logger();
|
||||
@@ -273,7 +273,7 @@ lazy_static! {
|
||||
#[allow(dead_code)]
|
||||
#[allow(non_snake_case)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onData(
|
||||
_env: jni::JNIEnv,
|
||||
_class: jni::objects::JObject,
|
||||
|
||||
+60
-65
@@ -28,7 +28,7 @@ use grin_p2p::msg::PeerAddrs;
|
||||
use grin_p2p::Seeding;
|
||||
use grin_servers::{Server, ServerStats, StratumServerConfig, StratumStats};
|
||||
use grin_servers::common::types::Error;
|
||||
|
||||
use log::error;
|
||||
use crate::node::{NodeConfig, NodeError, PeersConfig};
|
||||
use crate::node::stratum::{StratumStopState, StratumServer};
|
||||
|
||||
@@ -57,8 +57,8 @@ pub struct Node {
|
||||
stop_needed: AtomicBool,
|
||||
/// Flag to check if app exit is needed after [`Server`] stop.
|
||||
exit_after_stop: AtomicBool,
|
||||
/// Flag to reset peers data and restart the [`Server`].
|
||||
reset_peers: AtomicBool,
|
||||
/// Flag to reset data and restart the [`Server`].
|
||||
reset_data: AtomicBool,
|
||||
/// Flag to change data directory and restart the [`Server`].
|
||||
change_data_dir: AtomicBool,
|
||||
|
||||
@@ -78,7 +78,7 @@ impl Default for Node {
|
||||
exit_after_stop: AtomicBool::new(false),
|
||||
start_stratum_needed: AtomicBool::new(false),
|
||||
error: Arc::new(RwLock::new(None)),
|
||||
reset_peers: AtomicBool::new(false),
|
||||
reset_data: AtomicBool::new(false),
|
||||
change_data_dir: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
@@ -89,26 +89,20 @@ impl Node {
|
||||
pub const STATS_UPDATE_DELAY: Duration = Duration::from_millis(1000);
|
||||
|
||||
/// Default Mainnet DNS Seeds
|
||||
pub const MAINNET_DNS_SEEDS: &'static[&'static str] = &[
|
||||
"main.gri.mw",
|
||||
"grincoin.org",
|
||||
"mainnet.grinffindor.org",
|
||||
"mainnet.seed.grin.lesceller.com",
|
||||
"grinseed.revcore.net",
|
||||
"mainnet-seed.grinnode.live",
|
||||
"mainnet.grin.punksec.de",
|
||||
"grinnode.30-r.com"
|
||||
pub const MAINNET_DNS_SEEDS: &[&str] = &[
|
||||
"mainnet-seed.grinnode.live", // info@grinnode.live
|
||||
"grincoin.org", // xmpp:aglkm@conversations.im
|
||||
"main.gri.mw", // admin@gri.mw
|
||||
"mainnet.grinffindor.org", // support@grinffindor.org
|
||||
"main-seed.grin.money", // support@grinily.com
|
||||
];
|
||||
|
||||
/// Default Testnet DNS Seeds
|
||||
pub const TESTNET_DNS_SEEDS: &'static[&'static str] = &[
|
||||
"test.gri.mw",
|
||||
"testnet.grincoin.org",
|
||||
"testnet.grinffindor.org",
|
||||
"floonet.seed.grin.lesceller.com",
|
||||
"grintestseed.revcore.net",
|
||||
"testnet.grin.punksec.de",
|
||||
"testnet.grinnode.30-r.com"
|
||||
pub const TESTNET_DNS_SEEDS: &[&str] = &[
|
||||
"testnet.grincoin.org", // xmpp:aglkm@conversations.im
|
||||
"test.gri.mw", // admin@gri.mw
|
||||
"testnet.grinffindor.org", // support@grinffindor.org
|
||||
"test-seed.grin.money", // support@grinily.com
|
||||
];
|
||||
|
||||
/// Stop the [`Server`] and setup exit flag after if needed.
|
||||
@@ -175,12 +169,12 @@ impl Node {
|
||||
|
||||
/// Check if [`Node`] is restarting.
|
||||
pub fn is_restarting() -> bool {
|
||||
NODE_STATE.restart_needed.load(Ordering::Relaxed) || Self::reset_peers_needed()
|
||||
NODE_STATE.restart_needed.load(Ordering::Relaxed) || Self::reset_data_needed()
|
||||
}
|
||||
|
||||
/// Check if reset of [`Server`] peers is needed.
|
||||
fn reset_peers_needed() -> bool {
|
||||
NODE_STATE.reset_peers.load(Ordering::Relaxed)
|
||||
fn reset_data_needed() -> bool {
|
||||
NODE_STATE.reset_data.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
/// Get node [`Server`] statistics.
|
||||
@@ -269,9 +263,9 @@ impl Node {
|
||||
server.stop();
|
||||
// Wait server after stop.
|
||||
thread::sleep(Duration::from_millis(5000));
|
||||
// Reset peers data if requested.
|
||||
if Self::reset_peers_needed() {
|
||||
Node::reset_peers(true);
|
||||
// Reset data if requested.
|
||||
if Self::reset_data_needed() {
|
||||
Node::reset_data(true);
|
||||
}
|
||||
// Reset stratum stats.
|
||||
{
|
||||
@@ -285,7 +279,7 @@ impl Node {
|
||||
NODE_STATE.restart_needed.store(false, Ordering::Relaxed);
|
||||
}
|
||||
Err(e) => {
|
||||
// Set an error.
|
||||
error!("Error starting node: {:?}", e);
|
||||
{
|
||||
let mut w_err = NODE_STATE.error.write();
|
||||
*w_err = Some(e);
|
||||
@@ -339,7 +333,7 @@ impl Node {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
// Set an error.
|
||||
error!("Error starting node: {:?}", e);
|
||||
{
|
||||
let mut w_err = NODE_STATE.error.write();
|
||||
*w_err = Some(e);
|
||||
@@ -434,24 +428,20 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset [`Server`] peers data.
|
||||
pub fn reset_peers(force: bool) {
|
||||
/// Reset [`Server`] data.
|
||||
pub fn reset_data(force: bool) {
|
||||
if force || !Node::is_running() {
|
||||
// Get saved server config.
|
||||
let config = NodeConfig::node_server_config();
|
||||
let server_config = config.server.clone();
|
||||
// Remove peers folder.
|
||||
let mut peers_dir = PathBuf::from(&server_config.db_root);
|
||||
peers_dir.push("peer");
|
||||
if peers_dir.exists() {
|
||||
match fs::remove_dir_all(peers_dir) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {}
|
||||
}
|
||||
// Remove data folder.
|
||||
let data_dir = PathBuf::from(&server_config.db_root);
|
||||
match fs::remove_dir_all(data_dir) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {}
|
||||
}
|
||||
NODE_STATE.reset_peers.store(false, Ordering::Relaxed);
|
||||
NODE_STATE.reset_data.store(false, Ordering::Relaxed);
|
||||
} else {
|
||||
NODE_STATE.reset_peers.store(true, Ordering::Relaxed);
|
||||
NODE_STATE.reset_data.store(true, Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,20 +575,25 @@ fn start_node_server() -> Result<Server, Error> {
|
||||
PeersConfig::load_to_server_config(&mut config);
|
||||
let mut server_config = config.server.clone();
|
||||
|
||||
// Setup Mainnet DNSSeed
|
||||
if server_config.chain_type == ChainTypes::Mainnet && NodeConfig::is_default_seeding_type() {
|
||||
// DNS seed setup.
|
||||
if NodeConfig::is_default_seeding_type() {
|
||||
server_config.p2p_config.seeding_type = Seeding::List;
|
||||
server_config.p2p_config.seeds = Some(PeerAddrs::default());
|
||||
for seed in Node::MAINNET_DNS_SEEDS {
|
||||
let addr = format!("{}:3414", seed);
|
||||
let is_mainnet = server_config.chain_type == ChainTypes::Mainnet;
|
||||
let seed_list = if is_mainnet {
|
||||
Node::MAINNET_DNS_SEEDS
|
||||
} else {
|
||||
Node::TESTNET_DNS_SEEDS
|
||||
};
|
||||
let seed_port = if is_mainnet {
|
||||
3414
|
||||
} else {
|
||||
13414
|
||||
};
|
||||
for seed_addr in seed_list {
|
||||
let addr = format!("{}:{}", seed_addr, seed_port);
|
||||
if let Some(p) = PeersConfig::peer_to_addr(addr) {
|
||||
let mut seeds = server_config
|
||||
.p2p_config
|
||||
.seeds
|
||||
.clone()
|
||||
.unwrap_or(PeerAddrs::default());
|
||||
seeds.peers.insert(seeds.peers.len(), p);
|
||||
server_config.p2p_config.seeds = Some(seeds);
|
||||
server_config.p2p_config.seeds.as_mut().unwrap().peers.push(p)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -710,7 +705,7 @@ pub fn start_stratum_mining_server(server: &Server, config: StratumServerConfig)
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Get sync status text for Android notification from [`NODE_STATE`] in Java string format.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_getSyncStatusText(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -725,7 +720,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getSyncStatusText(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Get sync title for Android notification in Java string format.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_getSyncTitle(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -739,7 +734,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getSyncTitle(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Get start text for Android notification in Java string format.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_getStartText(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -753,7 +748,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getStartText(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Get stop text for Android notification in Java string format.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_getStopText(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -767,7 +762,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getStopText(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Get exit text for Android notification in Java string format.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_getExitText(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -781,7 +776,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_getExitText(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Check if node launch is possible.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_canStartNode(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -795,7 +790,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_canStartNode(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Check if node stop is possible.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_canStopNode(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -809,7 +804,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_canStopNode(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Start node from Android Java code.
|
||||
pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_startNode(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -822,7 +817,7 @@ pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_startNode(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Stop node from Android Java code.
|
||||
pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_stopNode(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -835,7 +830,7 @@ pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_stopNode(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Stop node from Android Java code.
|
||||
pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_stopNodeToExit(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -852,7 +847,7 @@ pub extern "C" fn Java_mw_gri_android_NotificationActionsReceiver_stopNodeToExit
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Check if app exit is needed after node stop to finish Android app at background.
|
||||
pub extern "C" fn Java_mw_gri_android_BackgroundService_exitAppAfterNodeStop(
|
||||
_env: jni::JNIEnv,
|
||||
@@ -866,7 +861,7 @@ pub extern "C" fn Java_mw_gri_android_BackgroundService_exitAppAfterNodeStop(
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
/// Handle unexpected application termination on Android (removal from recent apps).
|
||||
pub extern "C" fn Java_mw_gri_android_MainActivity_onTermination(
|
||||
_env: jni::JNIEnv,
|
||||
|
||||
+1
-1
@@ -656,7 +656,7 @@ impl Tor {
|
||||
}
|
||||
};
|
||||
// Wait to check service again.
|
||||
thread::sleep(duration);
|
||||
tokio::time::sleep(duration).await;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
+6
-6
@@ -59,12 +59,12 @@ impl TorBridge {
|
||||
|
||||
/// Default webtunnel protocol connection line.
|
||||
pub const DEFAULT_WEBTUNNEL_CONN_LINE: &'static str = "webtunnel [2001:db8:beb:5884:ffcc:bfe3:2858:b06b]:443 1E242C749707B4A68A269F0D31311CE36CDFEC28 url=https://wt.gri.mw/74Fm0lKUWWMMjZpKf6iSC0UH";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_1: &'static str = "webtunnel [2001:db8:1640:379c:ad30:db5f:bff5:37d0]:443 AF8F7548C886D6F53A652411DBB71D089517085A url=https://app05.oneclickhost.eu/alpfZGTB9FckCgOkOOA0OHlh";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_2: &'static str = "webtunnel [2001:db8:eedb:cae7:a345:4f72:f9cc:5de0]:443 B3C81E7A0CA474270DAA4A2C8633E1CA8935C37D url=https://wordpress.far-east-investment.ru/sORes7268CEUSRD7hAWvJU5A";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_3: &'static str = "webtunnel [2001:db8:945c:e0b9:7e4c:c974:ff00:d4c5]:443 91937F3EFB3BE5169788AC7C8BF07460B7E306DB url=https://kabel.entreri.de/YXbp1dNrJeOF8giAFFYWxvmf";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_4: &'static str = "webtunnel [2001:db8:4767:7aa2:df21:1b2b:d7f9:caee]:443 CD193CF0D0C29551928C01FCB28D1200D9F27CFA url=https://occurrence.pics/68SzSlQCRgnfSo32eLyjC1V3";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_5: &'static str = "webtunnel [2001:db8:ce90:3593:272e:4975:a031:55b]:443 12382A2F3912AD1983A97C8709CBAE47ADB60BE3 url=https://miranda.today/LWwxIXDHCyyScn7oDauPMTmX";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_6: &'static str = "webtunnel [2001:db8:a12b:ff8:8a1a:a05b:5f21:2ccc]:443 F2A9C5AEE0A420EB9D55F9497B3C0FA243A2A770 url=https://bridge.lovecloud.me/wss-wc3p0euqrlne98t9";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_1: &'static str = "webtunnel [2001:db8:289b:84cd:4be3:77f1:1cdd:9cb1]:443 D71C8E9C2180D2F35DEBF4A39BFCA6972F076D1C sni-imitation=yandex.ru,google.com,dzen.ru,vk.com,mail.ru,ozon.ru,ya.ru,www.wildberries.ru,rutube.ru,www.avito.ru,ok.ru,vkvideo.ru url=https://streaming.the-forgotten-tales.com/gz9X1VBgl0r1Xfx3dHdNl5Tl";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_2: &'static str = "webtunnel [2001:db8:dee9:5852:b4dc:7e14:21bd:c99b]:443 8ADF1761FA735FDD763781BB94A16EAB64A1CF6C url=https://app01.oneclickhost.eu/WJSgXJRlNnMStkuLZygVJ7lo";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_3: &'static str = "webtunnel [2001:db8:eedb:cae7:a345:4f72:f9cc:5de0]:443 B3C81E7A0CA474270DAA4A2C8633E1CA8935C37D url=https://wordpress.far-east-investment.ru/sORes7268CEUSRD7hAWvJU5A";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_4: &'static str = "webtunnel [2001:db8:945c:e0b9:7e4c:c974:ff00:d4c5]:443 91937F3EFB3BE5169788AC7C8BF07460B7E306DB url=https://kabel.entreri.de/YXbp1dNrJeOF8giAFFYWxvmf";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_5: &'static str = "webtunnel [2001:db8:7d4:9e13:8c7a:7e3:1f62:d790]:443 B7E362F9079D0C908F204581EB019034023BB224 url=https://balades-et-gouts.fr/xt70R9oyJt3B1xj89UCWPdLt";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_6: &'static str = "webtunnel [2001:db8:8c88:1b17:d7ae:cb68:f28e:e31c]:443 C115DAC2FE991CA25DDD43D7D4D398FEA9AA4C01 url=https://foglab.net/t9crLwo4LzFDWHdwcGf9gFrk";
|
||||
pub const ADDITIONAL_WEBTUNNEL_CONN_LINE_7: &'static str = "webtunnel [2001:db8:8ed6:e6c9:5fc9:9f20:a373:2374]:443 1636A2EFFBAA4B162F5FF461A1663EB55C41AE11 url=https://hanoi.delivery/roQFPLtlspWT6yIKeXD6lEci";
|
||||
|
||||
pub const DEFAULT_WEBTUNNEL_CONN_LINES: [&'static str; 8] = [
|
||||
|
||||
+44
-38
@@ -52,6 +52,7 @@ use std::{fs, path, thread};
|
||||
use chrono::Utc;
|
||||
use log::error;
|
||||
use num_bigint::BigInt;
|
||||
use tor_config::deps::Itertools;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Contains wallet instance, configuration and state, handles wallet commands.
|
||||
@@ -63,7 +64,7 @@ pub struct Wallet {
|
||||
instance: Arc<RwLock<Option<WalletInstance>>>,
|
||||
/// Connection of current wallet instance.
|
||||
connection: Arc<RwLock<ConnectionMethod>>,
|
||||
/// Wallet secret key for transport service.
|
||||
/// Keychain mask for API calls.
|
||||
keychain_mask: Arc<RwLock<Option<SecretKey>>>,
|
||||
|
||||
/// Wallet Slatepack address to receive txs at transport.
|
||||
@@ -532,13 +533,16 @@ impl Wallet {
|
||||
if !self.is_open() || !has_instance {
|
||||
return;
|
||||
}
|
||||
self.closing.store(true, Ordering::Relaxed);
|
||||
|
||||
// Stop repairing.
|
||||
if self.is_repairing() {
|
||||
self.repair_needed.store(false, Ordering::Relaxed);
|
||||
}
|
||||
// Close wallet at separate thread.
|
||||
let wallet_close = self.clone();
|
||||
let service_id = wallet_close.identifier();
|
||||
let conn = wallet_close.connection.clone();
|
||||
thread::spawn(move || {
|
||||
wallet_close.closing.store(true, Ordering::Relaxed);
|
||||
// Wait common operations to finish.
|
||||
while wallet_close.message_opening() || wallet_close.send_creating() ||
|
||||
wallet_close.invoice_creating() {
|
||||
@@ -648,8 +652,12 @@ impl Wallet {
|
||||
let w = lc.wallet_inst()?;
|
||||
let parent_key_id = w.parent_key_id();
|
||||
// Retrieve txs from database.
|
||||
let txs_iter = w.tx_log_iter()
|
||||
let txs: Vec<TxLogEntry> = w.tx_log_iter()
|
||||
.filter(|tx_entry| tx_entry.parent_key_id == parent_key_id)
|
||||
// Filter transactions to not show txs without slate (usually unspent outputs).
|
||||
.filter(|tx| {
|
||||
tx.tx_slate_id.is_some() || (tx.tx_slate_id.is_none() && tx.payment_proof.is_some())
|
||||
})
|
||||
.filter(|tx_entry| {
|
||||
if tx_entry.tx_type == TxLogEntryType::TxSent
|
||||
|| tx_entry.tx_type == TxLogEntryType::TxSentCancelled {
|
||||
@@ -661,20 +669,21 @@ impl Wallet {
|
||||
- BigInt::from(tx_entry.amount_debited)
|
||||
>= BigInt::from(1)
|
||||
}
|
||||
});
|
||||
let mut return_txs: Vec<TxLogEntry> = txs_iter.collect();
|
||||
// Sort txs by creation date and confirmation status reversing an order.
|
||||
return_txs.sort_by_key(|tx| if !tx.confirmed && (tx.tx_type == TxLogEntryType::TxSent ||
|
||||
tx.tx_type == TxLogEntryType::TxReceived) {
|
||||
i64::MAX
|
||||
} else {
|
||||
tx.creation_ts.timestamp()
|
||||
});
|
||||
// return_txs.sort_by_key(|tx| tx.confirmed);
|
||||
return_txs.reverse();
|
||||
// Apply limit.
|
||||
return_txs = return_txs.into_iter().take(limit as usize).collect();
|
||||
Ok(return_txs)
|
||||
})
|
||||
// Sort txs by creation date and confirmation status.
|
||||
.sorted_by_key(|tx| -tx.creation_ts.timestamp())
|
||||
// Sort to show unconfirmed at top.
|
||||
.sorted_by_key(|tx| {
|
||||
tx.confirmed || tx.tx_type == TxLogEntryType::TxReceivedCancelled ||
|
||||
tx.tx_type == TxLogEntryType::TxSentCancelled ||
|
||||
tx.tx_type == TxLogEntryType::TxReverted
|
||||
})
|
||||
// Apply limit.
|
||||
.take(limit as usize)
|
||||
.collect();
|
||||
// Reverse an order.
|
||||
// txs.reverse();
|
||||
Ok(txs)
|
||||
}
|
||||
|
||||
/// Send a task to the wallet.
|
||||
@@ -799,7 +808,7 @@ impl Wallet {
|
||||
let wallet = self.clone();
|
||||
thread::spawn(move || {
|
||||
// Wait when current sync will be finished.
|
||||
if wallet.syncing() {
|
||||
while wallet.syncing() {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
// Sync wallet data with new limit.
|
||||
@@ -978,7 +987,10 @@ impl Wallet {
|
||||
null
|
||||
]
|
||||
}).to_string();
|
||||
|
||||
// Wait Tor service to launch.
|
||||
while Tor::is_service_starting(&self.identifier()) {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
// Send request to receiver.
|
||||
let req_res = Tor::post(body, url).await;
|
||||
if req_res.is_none() {
|
||||
@@ -1126,13 +1138,17 @@ impl Wallet {
|
||||
/// Update transaction action status.
|
||||
fn on_tx_action(&self, id: u32, action: Option<WalletTxAction>) {
|
||||
let mut w_data = self.data.write();
|
||||
w_data.as_mut().unwrap().on_tx_action(id, action);
|
||||
if let Some(data) = w_data.as_mut() {
|
||||
data.on_tx_action(id, action);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update transaction action error status.
|
||||
fn on_tx_error(&self, id: u32, err: Option<Error>) {
|
||||
let mut w_data = self.data.write();
|
||||
w_data.as_mut().unwrap().on_tx_error(id, err);
|
||||
if let Some(data) = w_data.as_mut() {
|
||||
data.on_tx_error(id, err);
|
||||
}
|
||||
}
|
||||
|
||||
/// Save task result to consume later.
|
||||
@@ -1735,7 +1751,8 @@ async fn handle_task(w: &Wallet, t: WalletTask) {
|
||||
let tx = w.retrieve_tx_by_id(None, Some(s.id));
|
||||
if let Some(tx) = tx {
|
||||
if let Some(addr) = r {
|
||||
if Tor::is_service_running(&w.identifier()) {
|
||||
let id = w.identifier();
|
||||
if Tor::is_service_running(&id) || Tor::is_service_starting(&id) {
|
||||
w.send_creating.store(false, Ordering::Relaxed);
|
||||
send_tor(tx, &s, addr).await;
|
||||
return;
|
||||
@@ -1966,21 +1983,10 @@ fn update_txs(wallet: &Wallet, mut txs_limit: u32) -> Result<(), Error> {
|
||||
return Err(Error::GenericError("Wallet is not open".to_string()));
|
||||
}
|
||||
|
||||
// Filter transactions to not show txs without slate (usually unspent outputs).
|
||||
let mut filter_txs = txs.iter().map(|v| v.clone()).filter(|tx| {
|
||||
tx.tx_slate_id.is_some() || (tx.tx_slate_id.is_none() && tx.payment_proof.is_some())
|
||||
}).collect::<Vec<TxLogEntry>>();
|
||||
|
||||
// Sort to show unconfirmed at top.
|
||||
filter_txs.sort_by_key(|tx| {
|
||||
tx.confirmed || tx.tx_type == TxLogEntryType::TxReceivedCancelled ||
|
||||
tx.tx_type == TxLogEntryType::TxSentCancelled ||
|
||||
tx.tx_type == TxLogEntryType::TxReverted
|
||||
});
|
||||
|
||||
// Update limit with actual length.
|
||||
let txs_size = txs.len() as u32;
|
||||
let filter_size = filter_txs.len() as u32;
|
||||
let filter_size = txs.len() as u32;
|
||||
|
||||
if txs_size > filter_size && txs_limit >= filter_size {
|
||||
txs_limit = txs_limit - (txs_size - filter_size);
|
||||
}
|
||||
@@ -1990,7 +1996,7 @@ fn update_txs(wallet: &Wallet, mut txs_limit: u32) -> Result<(), Error> {
|
||||
let data = wallet.get_data().unwrap();
|
||||
let data_txs = data.txs.unwrap_or(vec![]);
|
||||
let mut new_txs: Vec<WalletTx> = vec![];
|
||||
for tx in &filter_txs {
|
||||
for tx in &txs {
|
||||
let mut height: Option<u64> = None;
|
||||
let mut broadcasting_height: Option<u64> = None;
|
||||
let mut action: Option<WalletTxAction> = None;
|
||||
@@ -2183,10 +2189,10 @@ fn repair_wallet(wallet: &Wallet) {
|
||||
}
|
||||
});
|
||||
|
||||
// Start wallet scanning.
|
||||
let r_inst = wallet.instance.as_ref().read();
|
||||
let instance = r_inst.clone().unwrap();
|
||||
let api = Owner::new(instance, Some(info_tx));
|
||||
// Start wallet scanning.
|
||||
match api.scan(wallet.keychain_mask().as_ref(), Some(1), false) {
|
||||
Ok(()) => {
|
||||
// Set sync error if scanning was not complete and wallet is open.
|
||||
|
||||
+1
-1
Submodule wallet updated: f54a8e7756...c1d7070291
+2
-2
@@ -7,8 +7,8 @@
|
||||
<?endif ?>
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="*" Version="0.3.3" UpgradeCode="C19F9B41-CD13-4F0E-B27D-E0EF8CF1CE91" Language="1033" Name="Grim" Manufacturer="Ardocrat">
|
||||
<Package Id="F0DD07CB-48B4-419C-9A20-CE41CD0D9252" InstallerVersion="300" Compressed="yes"/>
|
||||
<Product Id="*" Version="0.3.5" UpgradeCode="C19F9B41-CD13-4F0E-B27D-E0EF8CF1CE91" Language="1033" Name="Grim" Manufacturer="Ardocrat">
|
||||
<Package Id="E15A3211-C334-4B2D-8774-4834657A00B6" InstallerVersion="300" Compressed="yes"/>
|
||||
<Media Id="1" Cabinet="grim.cab" EmbedCab="yes" />
|
||||
|
||||
<MajorUpgrade AllowDowngrades = "yes"/>
|
||||
|
||||
Reference in New Issue
Block a user