Skip to content

Commit afe55e8

Browse files
committed
fix: cross-platform polkadot verification issues
1 parent 4000a37 commit afe55e8

File tree

11 files changed

+273
-4
lines changed

11 files changed

+273
-4
lines changed

.github/workflows/backend.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ on: [workflow_dispatch, push, pull_request]
44

55
jobs:
66
run:
7-
uses: flarum/framework/.github/workflows/REUSABLE_backend.yml@main
7+
uses: ./.github/workflows/reusable.yml
88
with:
99
enable_backend_testing: true
1010

1111
backend_directory: .
1212
php_versions: '["8.0", "8.1"]'
1313
php_extensions: curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip, gmp, FFI
1414
php_ini_values: error_reporting=E_ALL, ffi.enable=true
15+
operating_systems: '["ubuntu-latest", "debian-latest"]'
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build Bindings
2+
3+
on: [workflow_dispatch, push, pull_request]
4+
5+
jobs:
6+
files-changed:
7+
runs-on: ubuntu-latest
8+
outputs:
9+
changed: ${{ steps.files.outputs.changed }}
10+
steps:
11+
- uses: actions/checkout@v2
12+
- uses: dorny/paths-filter@v2
13+
id: files
14+
with:
15+
filters: |
16+
changed:
17+
- 'rs/**'
18+
- '.github/workflows/build-bindings.yml'
19+
20+
build:
21+
# run only if some file in 'src' folder was changed
22+
if: needs.files-changed.outputs.changed == 'true'
23+
strategy:
24+
matrix:
25+
include:
26+
- name: "Linux"
27+
os: ubuntu-latest
28+
29+
name: ${{ matrix.name }}
30+
runs-on: ${{ matrix.os }}
31+
steps:
32+
- uses: actions/checkout@v2
33+
- uses: actions-rs/toolchain@v1
34+
with:
35+
toolchain: stable
36+
override: true
37+
- uses: actions-rs/cargo@v1
38+
with:
39+
use-cross: true
40+
command: build
41+
args: --release --manifest-path rs/Cargo.toml
42+
- run: |
43+
git config --global user.name "github-actions[bot]"
44+
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
45+
git status
46+
git pull
47+
git add rs/target/*/release/libschnorrkelcbindings.* -f
48+
git commit -m "Build bindings for ${{ matrix.name }} for commit ${{ github.sha }}"
49+
git push

.github/workflows/reusable.yml

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
name: Flarum Backend Jobs
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
enable_backend_testing:
7+
description: "Enable Backend Testing?"
8+
type: boolean
9+
default: true
10+
required: false
11+
12+
enable_phpstan:
13+
description: "Enable PHPStan Static Analysis?"
14+
type: boolean
15+
default: false
16+
required: false
17+
18+
backend_directory:
19+
description: The directory of the project where backend code is located. This should contain a `composer.json` file, and is generally the root directory of the repo.
20+
type: string
21+
required: false
22+
default: '.'
23+
24+
php_versions:
25+
description: Versions of PHP to test with. Should be array of strings encoded as JSON array
26+
type: string
27+
required: false
28+
default: '["7.3", "7.4", "8.0", "8.1"]'
29+
30+
php_extensions:
31+
description: PHP extensions to install.
32+
type: string
33+
required: false
34+
default: 'curl, dom, gd, json, mbstring, openssl, pdo_mysql, tokenizer, zip'
35+
36+
db_versions:
37+
description: Versions of databases to test with. Should be array of strings encoded as JSON array
38+
type: string
39+
required: false
40+
default: '["mysql:5.7", "mysql:8.0.30", "mariadb"]'
41+
42+
php_ini_values:
43+
description: PHP ini values
44+
type: string
45+
required: false
46+
default: error_reporting=E_ALL
47+
48+
operating_systems:
49+
description: Operating systems to test on. Should be array of strings encoded as JSON array
50+
type: string
51+
required: false
52+
default: '["ubuntu-latest"]'
53+
54+
env:
55+
COMPOSER_ROOT_VERSION: dev-main
56+
FLARUM_TEST_TMP_DIR_LOCAL: tests/integration/tmp
57+
58+
jobs:
59+
test:
60+
strategy:
61+
matrix:
62+
php: ${{ fromJSON(inputs.php_versions) }}
63+
service: ${{ fromJSON(inputs.db_versions) }}
64+
os: ${{ fromJSON(inputs.operating_systems) }}
65+
prefix: ['']
66+
67+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude
68+
include:
69+
# Expands the matrix by naming DBs.
70+
- service: 'mysql:5.7'
71+
db: MySQL 5.7
72+
- service: 'mysql:8.0.30'
73+
db: MySQL 8.0
74+
- service: mariadb
75+
db: MariaDB
76+
77+
# Include Database prefix tests with only one PHP version.
78+
- php: ${{ fromJSON(inputs.php_versions)[0] }}
79+
service: 'mysql:5.7'
80+
db: MySQL 5.7
81+
os: ${{ fromJSON(inputs.operating_systems)[0] }}
82+
prefix: flarum_
83+
prefixStr: (prefix)
84+
- php: ${{ fromJSON(inputs.php_versions)[0] }}
85+
service: 'mysql:8.0.30'
86+
db: MySQL 8.0
87+
os: ${{ fromJSON(inputs.operating_systems)[0] }}
88+
prefix: flarum_
89+
prefixStr: (prefix)
90+
- php: ${{ fromJSON(inputs.php_versions)[0] }}
91+
service: mariadb
92+
db: MariaDB
93+
os: ${{ fromJSON(inputs.operating_systems)[0] }}
94+
prefix: flarum_
95+
prefixStr: (prefix)
96+
97+
# To reduce number of actions, we exclude some PHP versions from running with some DB versions.
98+
exclude:
99+
- php: ${{ fromJSON(inputs.php_versions)[1] }}
100+
service: 'mysql:8.0.30'
101+
- php: ${{ fromJSON(inputs.php_versions)[2] }}
102+
service: 'mysql:8.0.30'
103+
104+
services:
105+
mysql:
106+
image: ${{ matrix.service }}
107+
ports:
108+
- 13306:3306
109+
110+
name: 'PHP ${{ matrix.php }} / ${{ matrix.db }} ${{ matrix.prefixStr }} / ${{ matrix.os }}'
111+
runs-on: ${{ matrix.os }}
112+
113+
if: >-
114+
inputs.enable_backend_testing &&
115+
((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) || github.event_name != 'pull_request')
116+
117+
steps:
118+
- uses: actions/checkout@master
119+
120+
- name: Setup PHP
121+
uses: shivammathur/setup-php@v2
122+
with:
123+
php-version: ${{ matrix.php }}
124+
coverage: xdebug
125+
extensions: ${{ inputs.php_extensions }}
126+
tools: phpunit, composer:v2
127+
ini-values: ${{ inputs.php_ini_values }}
128+
129+
# The authentication alter is necessary because newer mysql versions use the `caching_sha2_password` driver,
130+
# which isn't supported prior to PHP7.4
131+
# When we drop support for PHP7.3, we should remove this from the setup.
132+
- name: Create MySQL Database
133+
run: |
134+
sudo systemctl start mysql
135+
mysql -uroot -proot -e 'CREATE DATABASE flarum_test;' --port 13306
136+
mysql -uroot -proot -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root';" --port 13306
137+
138+
- name: Install Composer dependencies
139+
run: composer install
140+
working-directory: ${{ inputs.backend_directory }}
141+
142+
- name: Setup Composer tests
143+
run: composer test:setup
144+
working-directory: ${{ inputs.backend_directory }}
145+
env:
146+
DB_PORT: 13306
147+
DB_PASSWORD: root
148+
DB_PREFIX: ${{ matrix.prefix }}
149+
150+
- name: Run Composer tests
151+
run: composer test
152+
working-directory: ${{ inputs.backend_directory }}
153+
env:
154+
COMPOSER_PROCESS_TIMEOUT: 600
155+
156+
phpstan:
157+
runs-on: ubuntu-latest
158+
159+
strategy:
160+
matrix:
161+
php: ${{ fromJSON(inputs.php_versions) }}
162+
163+
name: 'PHPStan PHP ${{ matrix.php }}'
164+
165+
if: >-
166+
inputs.enable_phpstan &&
167+
((github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) || github.event_name != 'pull_request')
168+
169+
steps:
170+
- uses: actions/checkout@master
171+
172+
- name: Setup PHP
173+
uses: shivammathur/setup-php@v2
174+
with:
175+
php-version: ${{ matrix.php }}
176+
coverage: xdebug
177+
extensions: ${{ inputs.php_extensions }}
178+
tools: phpunit, composer:v2
179+
ini-values: ${{ inputs.php_ini_values }}
180+
181+
- name: Install Composer dependencies
182+
run: composer install
183+
working-directory: ${{ inputs.backend_directory }}
184+
185+
- name: Run PHPStan
186+
run: composer analyse:phpstan

rs/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ target/*
33
target/release/*
44
!target/release/libschnorrkelcbindings.h
55
!target/release/libschnorrkelcbindings.so
6+
!target/release/libschnorrkelcbindings.d
7+
!target/release/libschnorrkelcbindings.a
-3.79 MB
Binary file not shown.
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target/x86_64-unknown-linux-gnu/release/libschnorrkelcbindings.so: /home/runner/work/flarum-ext-web3/flarum-ext-web3/rs/build.rs /home/runner/work/flarum-ext-web3/flarum-ext-web3/rs/src/lib.rs /home/runner/work/flarum-ext-web3/flarum-ext-web3/rs/src/sr25519.rs
Binary file not shown.

src/C/SchnorrSignaturesBindings.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,34 @@ class SchnorrSignaturesBindings
1111

1212
protected FFI $ffi;
1313

14+
/**
15+
* @throws \Exception
16+
*/
1417
public function __construct()
1518
{
1619
$this->ffi = FFI::cdef(
1720
file_get_contents(self::RUST_DIST_DIR . "/libschnorrkelcbindings.h"),
18-
self::RUST_DIST_DIR . '/libschnorrkelcbindings.so'
21+
$this->getBinaryPath()
1922
);
2023
}
2124

25+
/**
26+
* @throws \Exception
27+
*/
28+
private function getBinaryPath(): string
29+
{
30+
$targetDir = __DIR__ . '/../../rs/target';
31+
32+
match (PHP_OS_FAMILY) {
33+
'Linux' => $binary = "$targetDir/x86_64-unknown-linux-gnu/release/libschnorrkelcbindings.so",
34+
// 'Darwin' => $binary = 'libschnorrkelcbindings.dylib',
35+
// 'Windows' => $binary = 'libschnorrkelcbindings.dll',
36+
default => throw new \Exception('Unsupported OS'),
37+
};
38+
39+
return $binary;
40+
}
41+
2242
/**
2343
* Verifies sr25519 signed signature with a message.
2444
*

src/Verifier/PolkadotSignatureVerifier.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ public function verify(string $signature, string $message, string $publicKey): b
2222
return false;
2323
}
2424

25-
return (new SchnorrSignaturesBindings())->verifySignature($signature, "<Bytes>$message</Bytes>", $publicKey);
25+
try {
26+
$bindings = new SchnorrSignaturesBindings();
27+
} catch (\Throwable $e) {
28+
$this->logger->error('Could not load FFI bindings for Polkadot signature verification.', [
29+
'exception' => $e,
30+
]);
31+
32+
return false;
33+
}
34+
35+
return $bindings->verifySignature($signature, "<Bytes>$message</Bytes>", $publicKey);
2636
}
2737
}

0 commit comments

Comments
 (0)