Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix provider mock #1187

Merged
merged 16 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions .github/workflows/provider_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
# create the provider image for AMD64
- name: Build the Provider Container
id: build_docker_provider_amd64
continue-on-error: true
continue-on-error: false
uses: docker/build-push-action@v5
with:
context: ${{github.workspace}}
Expand All @@ -130,7 +130,7 @@ jobs:
# create the provider image for ARM64
- name: Build the Provider Container
id: build_docker_provider_arm64
continue-on-error: true
continue-on-error: false
uses: docker/build-push-action@v5
with:
context: ${{github.workspace}}
Expand All @@ -157,3 +157,36 @@ jobs:
docker logs $CONTAINER >& provider.log
echo $(cat provider.log)
grep -oE "Version: \".*\"" provider.log || (echo $(cat provider.log) && exit 1)

- name: Build the provider-mock package
id: build_provider_mock_package
run: |
echo "Building the provider-mock package..."
npm run -w @prosopo/provider-mock build

# create the provider mock image for AMD64
- name: Build the Provider Mock Container
id: build_docker_provider_mock_amd64
continue-on-error: false
uses: docker/build-push-action@v5
with:
context: ${{github.workspace}}
file: ${{github.workspace}}/docker/images/provider.mock.dockerfile
platforms: linux/amd64
push: false
tags: prosopo/provider-mock:dev
outputs: type=docker,dest=provider-mock-amd64.tar

# load the provider-mock AMD64 image
- name: Load the Provider Container
run: docker load -i provider-mock-amd64.tar

# Check that the version command works when running the bundle in the provider image
- name: Check provider mock container runs
run: |
CONTAINER=$(docker run -d -p 9229:9229 prosopo/provider-mock:dev)
sleep 10s
docker logs $CONTAINER >& provider-mock.log
echo $(cat provider.log)
RESPONSE=$(curl --location 'http://localhost:9229/v1/prosopo/provider/verify' --header 'Content-Type: application/json' --data '{"user": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","dapp": "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM","blockNumber": 1}'| jq --raw-output '.status')
if [ "$RESPONSE" = "User verified" ]; then exit 0; else exit 1; fi
18 changes: 18 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,24 @@ jobs:
push: true
tags: prosopo/provider:${{ steps.next_version.outputs.version }},prosopo/provider:latest

- name: Build the provider-mock package
id: build_provider_mock_package
run: |
echo "Building the provider-mock package..."
npm run -w @prosopo/provider-mock build

- name: Build and push the Provider Mock Container
if: steps.check_version_docker_js_server.outputs.bump == 'true'
id: publish_docker_provider_mock
continue-on-error: true
uses: docker/build-push-action@v5
with:
context: ${{github.workspace}}
file: ${{github.workspace}}/docker/images/provider.mock.dockerfile
platforms: linux/amd64
push: true
tags: prosopo/provider:${{ steps.next_version.outputs.version }},prosopo/provider-mock:latest

- name: Docker provider release notification
if: always()
run: |
Expand Down
30 changes: 19 additions & 11 deletions demos/provider-mock/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@
// 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.
import { ApiPaths, VerifySolutionBody } from '@prosopo/types'
import {
ApiParams,
ApiPaths,
ImageVerificationResponse,
VerificationResponse,
VerifySolutionBody,
} from '@prosopo/types'
import { ProsopoApiError } from '@prosopo/common'
import { VerifySolutionBodyType } from '@prosopo/types'
import express, { Router } from 'express'
Expand Down Expand Up @@ -55,17 +61,19 @@ export function prosopoRouter(): Router {
) {
approved = true
statusMessage = 'API.USER_VERIFIED'
return res.json({
status: req.t(statusMessage),
verified: approved,
commitmentId: testCommitmentId,
})
const response: ImageVerificationResponse = {
[ApiParams.status]: req.t(statusMessage),
[ApiParams.verified]: approved,
[ApiParams.commitmentId]: testCommitmentId,
[ApiParams.blockNumber]: parsed.blockNumber,
}
return res.json(response)
}

return res.json({
status: req.t(statusMessage),
verified: false,
})
const verificationResponse: VerificationResponse = {
[ApiParams.status]: req.t(statusMessage),
[ApiParams.verified]: false,
}
return res.json(verificationResponse)
} catch (err) {
return next(new ProsopoApiError('API.UNKNOWN', { context: { error: err, errorCode: 500 } }))
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"setup": "npm -w @prosopo/scripts run setup",
"setup:all": "npm run deploy_protocol && npm run setup",
"start:provider": "npm -w @prosopo/cli run start",
"start:provider-gui": "npm -w @prosopo/provider-gui run start",
"start:server": "npm -w @prosopo/client-example-server run start",
"start:demo": "npm -w @prosopo/client-example run start",
"start:demo:pow": "npm -w @prosopo/client-pow-example run start",
Expand Down
5 changes: 3 additions & 2 deletions packages/contract/src/contract/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ export function getOptions(
value?: number | BN,
gasLimit?: WeightV2,
storageDeposit?: StorageDeposit,
increaseGas?: boolean
increaseGas?: boolean,
gasIncreaseFactor?: number
): ContractOptions {
const gasIncreaseFactor = increaseGas ? GAS_INCREASE_FACTOR : 1
gasIncreaseFactor = increaseGas ? gasIncreaseFactor || GAS_INCREASE_FACTOR : 1
const _gasLimit: WeightV2 | undefined = gasLimit
? api.registry.createType('WeightV2', {
refTime: gasLimit.refTime.toBn().muln(gasIncreaseFactor),
Expand Down
29 changes: 24 additions & 5 deletions packages/contract/src/contract/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ export class ProsopoCaptchaContract extends Contract implements IProsopoCaptchaC
async dryRunContractMethod<T>(
contractMethodName: string,
args: T[],
value?: number | BN | undefined
value?: number | BN | undefined,
gasIncreaseFactor?: number
): Promise<SubmittableExtrinsic> {
const message = this.getContractMethod(contractMethodName)
if (!this.nativeContract.query[message.method]) {
Expand All @@ -224,7 +225,7 @@ export class ProsopoCaptchaContract extends Contract implements IProsopoCaptchaC
)

// Increase the gas required by a factor of 1.1 to make sure we don't hit contracts.StorageDepositLimitExhausted
const options = getOptions(this.api, true, value, gasRequired, storageDeposit, true)
const options = getOptions(this.api, true, value, gasRequired, storageDeposit, true, gasIncreaseFactor)
const method = get(this.nativeContract.query, message.method)
const extrinsic = method(this.pair.address, options, ...args)
const secondResult = await extrinsic
Expand Down Expand Up @@ -257,7 +258,9 @@ export class ProsopoCaptchaContract extends Contract implements IProsopoCaptchaC
async getExtrinsicAndGasEstimates<T>(
contractMethodName: string,
args: T[],
value?: number | BN | undefined
value?: number | BN | undefined,
increaseGas = false,
gasIncreaseFactor?: number
): Promise<{ extrinsic: SubmittableExtrinsic; options: ContractOptions; storageDeposit: StorageDeposit }> {
// Always query first as errors are passed back from a dry run but not from a transaction
const message = this.abi.findMessage(contractMethodName)
Expand All @@ -281,7 +284,15 @@ export class ProsopoCaptchaContract extends Contract implements IProsopoCaptchaC

const response = (await extrinsic) as unknown as ContractCallOutcome
if (response.result.isOk) {
let options = getOptions(this.api, message.isMutating, value, response.gasRequired, response.storageDeposit)
let options = getOptions(
this.api,
message.isMutating,
value,
response.gasRequired,
response.storageDeposit,
increaseGas,
gasIncreaseFactor
)
let method = this.contract.tx[contractMethodName]
if (method === undefined) {
throw new RangeError(`Method ${contractMethodName} does not exist on contract ${this.contractName}`)
Expand All @@ -291,7 +302,15 @@ export class ProsopoCaptchaContract extends Contract implements IProsopoCaptchaC
const paymentInfo = await extrinsicTx.paymentInfo(this.pair.address)
this.logger.debug('Payment info: ', paymentInfo.partialFee.toHuman())
// increase the gas limit to make sure the tx succeeds
options = getOptions(this.api, message.isMutating, value, paymentInfo.weight, response.storageDeposit, true)
options = getOptions(
this.api,
message.isMutating,
value,
paymentInfo.weight,
response.storageDeposit,
true,
gasIncreaseFactor
)
// Will throw an error if the contract reverted
this.getQueryResult(message, response, args)

Expand Down
2 changes: 1 addition & 1 deletion packages/procaptcha/src/modules/Manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export function Manager(
undefined,
configOptional.challengeValidLength
)
if (verifyDappUserResponse.verified) {
if (verifyDappUserResponse.verified && verifyDappUserResponse.commitmentId) {
updateState({ isHuman: true, loading: false })
const output: ProcaptchaOutput = {
[ApiParams.providerUrl]: procaptchaStorage.providerUrl,
Expand Down
15 changes: 6 additions & 9 deletions packages/provider/src/api/captcha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,29 +143,26 @@ export function prosopoRouter(env: ProviderEnvironment): Router {
return next(new ProsopoApiError('CAPTCHA.PARSE_ERROR', { context: { code: 400, error: err } }))
}
try {
const failedVerificationResponse: VerificationResponse = {
[ApiParams.status]: req.t('API.USER_NOT_VERIFIED'),
[ApiParams.verified]: false,
}
const solution = await (parsed.commitmentId
? tasks.getDappUserCommitmentById(parsed.commitmentId)
: tasks.getDappUserCommitmentByAccount(parsed.user))

if (!solution) {
tasks.logger.debug('Not verified - no solution found')
return res.json({
[ApiParams.status]: req.t('API.USER_NOT_VERIFIED'),
[ApiParams.verified]: false,
})
return res.json(failedVerificationResponse)
}

if (parsed.maxVerifiedTime) {
const currentBlockNumber = await getCurrentBlockNumber(tasks.contract.api)
const blockTimeMs = getBlockTimeMs(tasks.contract.api)
const timeSinceCompletion = (currentBlockNumber - solution.completedAt) * blockTimeMs
const verificationResponse: VerificationResponse = {
[ApiParams.status]: req.t('API.USER_NOT_VERIFIED'),
[ApiParams.verified]: false,
}
if (timeSinceCompletion > parsed.maxVerifiedTime) {
tasks.logger.debug('Not verified - time run out')
return res.json(verificationResponse)
return res.json(failedVerificationResponse)
}
}

Expand Down
6 changes: 5 additions & 1 deletion packages/server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ export class ProsopoServer {
commitmentId?: string,
maxVerifiedTime = DEFAULT_MAX_VERIFIED_TIME_CACHED
) {
let verifyRecency = false
this.logger.info('Verifying with provider.')
const providerApi = await this.getProviderApi(providerUrl)
if (challenge) {
Expand All @@ -207,7 +208,10 @@ export class ProsopoServer {
return result.verified
}
const result = await providerApi.verifyDappUser(dapp, user, blockNumber, commitmentId, maxVerifiedTime)
const verifyRecency = await this.verifyRecency(result.blockNumber, maxVerifiedTime)

if (result.blockNumber) {
verifyRecency = await this.verifyRecency(result.blockNumber, maxVerifiedTime)
}
return result.verified && verifyRecency
}

Expand Down
4 changes: 2 additions & 2 deletions packages/types/src/provider/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ export interface VerificationResponse {
}

export interface ImageVerificationResponse extends VerificationResponse {
[ApiParams.commitmentId]: Hash
[ApiParams.commitmentId]?: Hash
// The block at which the captcha was requested
[ApiParams.blockNumber]: number
[ApiParams.blockNumber]?: number
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would the block at which the captcha was requested not be included in the image verification response?

}

export interface GetPowCaptchaResponse {
Expand Down
2 changes: 1 addition & 1 deletion provider-gui/components/Topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const TopBar = () => {
<Toolbar>
<Box display="flex" flexGrow={1}>
<Link href="/">
<Image src="/prosopo-logo-white.png" height={50} width={200} alt="Prosopo Logo" />
<Image src="/prosopo-logo-white.svg" height={50} width={200} alt="Prosopo Logo" />
</Link>
</Box>
<Box m={2}>
Expand Down
Binary file removed provider-gui/public/prosopo-logo-white.png
Binary file not shown.
1 change: 1 addition & 0 deletions provider-gui/public/prosopo-logo-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading