Bad request when deploying smart contract - elrond

So I'm currently trying to deploy a router smart contract. I've been building it through erdpy contract build, which has been successful (I'm on rust nightly tool chain as the Smart contract needs it). And I am now trying to deploy it, but I can't manage to do it. I keep having a 400 BadRequest from https://devnet-api.elrond.com/transaction/send.
Here are the logs from the deployment:
erdpy contract deploy
INFO:accounts:Account.sync_nonce()
INFO:accounts:Account.sync_nonce() done: 0
INFO:cli.contracts:Contract address: erd1qqqqqqqqqqqqqpgqzqv7kk893c3ftwgaekvvv9whpqcfn4kazqxq3mud36
INFO:transactions:Transaction.send: nonce=0
CRITICAL:cli:Proxy request error for url [https://devnet-api.elrond.com/transaction/send]: {'statusCode': 400, 'message': 'Bad Request'}
And here is erdpy.json used to configure the command:
{
"configurations": {
"default": {
"proxy": "https://devnet-api.elrond.com",
"chainID": "D"
}
},
"contract":{
"deploy":{
"verbose": true,
"bytecode": "output/router.wasm",
"recall-nonce": true,
"nonce": 1,
"pem": "../../../wallets/owner/wallet-owner.pem",
"gas-limit": 600000000,
"send": true,
"outfile": "deploy-testnet.interaction.json"
}
}
}
The contract I'm trying to deploy is the following. I've also been through the OpenAPI Spec or the documentation searching for an answer, but there is nothing about it. This route is normally returning error message, but for this specific case it is not.
Some other contract like ping-pong are working properly with the same erdpy.json config.

After talking with someone who were interested into this issue, I ended up with the following command:
erdpy --verbose contract deploy --project=$PROJECT_NAME --pem="wallet-owner.pem" --gas-limit=600000000 --proxy="https://devnet-gateway.elrond.com" --outfile="elrond.workspace.json" --recall-nonce --send --chain="D"
Replace $PROJECT_NAME by the folder of your contract (you need to be one level upper than your smart contract folder).
It won't use the elrond.json file, but i guess you can move up the file to make the command use it.

I have you tried to deploy with the argument --verbose?
That should be something like that (not sure of the syntax because I am on phone)
erdpy --verbose contract deploy

I was getting the "bad request" error too, and I worked out that for me this was because my wallet was empty. To add xEGLD to your devnet wallet:
Go to https://devnet-wallet.elrond.com/faucet
Log in using your pem file / whatever you normally use to log in
Click the "Faucet" option from the left hand menu
This should pop up a modal to add 10 xEGLD to your wallet (You can request 10 xEGLD every 24 hours)
Now you can return to the terminal and run erdpy contract deploy
This worked for me, and now I'm getting the correct output.

In the suggested erdpy.json from Elrond Docs there is an "chainID": "D" variable inside configuration.default object.
Delete this and add inside contract.deploy this : "chain": "D".
Example
{
"configurations": {
"default": {
"proxy": "https://devnet-api.elrond.com"
"chainID": "D" <----- Delete this
}
},
"contract":{
"deploy":{
<Other fields>
"chain": "D" <----- Add this
}
}
}

Related

How to automatically change lambda layer version in zappa_settings.json file while publishing a new lambda layer version?

I have a lambda layer set up, and a shell file that deploys it. I have written github workflows that triggers this shell file whenever there's a change in code in that particular repository. Since a newer version is published, I would like to change the lambda-layer-version to change in zappa-settings.json. Is there a way to automate this, or will I have to manually do it everytime?
Here's my zappa-settings.json file:
{
"dev": {
"app_function": "app.app",
"profile_name": "zappa-dev",
"project_name": "zappa-app",
"runtime": "python3.8",
"s3_bucket": "zappa-app-dev",
"aws_region": "ap-south-1",
"slim_handler": true,
"layers": ["arn:aws:lambda:ap-south-1:594519763223:layer:testapp-lambda-layer:2"]
}
}
Over here, I would like to change '2' to the latest version. I have tried using $LATEST, but it throws regex error.
It seems zappa code in https://github.com/zappa/Zappa passes this value directly to boto3 client's create_function method. So the issue is with specifying latest layer version in AWS itself.
It can be manually updated by fetching list of versions and selecting the first result, like here:
https://stackoverflow.com/a/55752188/3014044

Automatically add addon from app.json, heroku.yml or other config

I would like to provide a button from github to directly deploy an app.
Its a go application which serves some website.
Now for persistent data it requires an addon "Heroku Postgres".
I tried defining a heroku.yml with:
setup:
addons:
- plan: heroku-postgresql
I tried app.json with:
{
"addons": ["heroku-postgresql:hobby-dev"]
}
But it does nothing at all, it never adds the addon. I know I can add it manually through the website or CLI, but I want a fully automatic way - if that is possible.
It should look something like this
"addons": [
{
"plan": "heroku-postgresql",
"options": {
"version": "12"
}
}
]
Example app.json from heroku

Execution failed due to configuration error: Invalid permissions on Lambda function

I am building a serverless application using AWS Lambda and API Gateway via Visual Studio. I am working in C#, and using the serverless application model (SAM) in order to deploy my API. I build the code in Visual Studio, then deploy via publish to Lambda. This is working, except every time I do a new build, and try to execute an API call, I get this error:
Execution failed due to configuration error: Invalid permissions on Lambda function
Doing some research, I found this fix mentioned elsewhere (to be done via the AWS Console):
Fix: went to API Gateway > API name > Resources > Resource name > Method > Integration Request > Lambda Function and reselected my existing function, before "saving" it with the little checkmark.
Now this works for me, but it breaks the automation of using the serverless.template (JSON) to build out my API. Does anyone know how to fix this within the serverless.template file? So that I don't need to take action in the console to resolve? Here's a sample of one of my methods from the serverless.template file
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Transform" : "AWS::Serverless-2016-10-31",
"Description" : "An AWS Serverless Application.",
"Resources" : {
"Get" : {
"Type" : "AWS::Serverless::Function",
"Properties": {
"VpcConfig":{
"SecurityGroupIds" : ["sg-111a1476"],
"SubnetIds" : [ "subnet-3029a769","subnet-5ec0b928"]
},
"Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::Get",
"Runtime": "dotnetcore2.0",
"CodeUri": "",
"MemorySize": 256,
"Timeout": 30,
"Role": null,
"Policies": [ "AWSLambdaBasicExecutionRole","AWSLambdaVPCAccessExecutionRole","AmazonSSMFullAccess"],
"Events": {
"PutResource": {
"Type": "Api",
"Properties": {
"Path": "/",
"Method": "GET"
}
}
}
}
},
You may have an issue in permission config, that's why API couldn't call your lambda. try to explicitly add to template.yaml file invoke permission to your lambda from apigateway as a principal here's a sample below:
ConfigLambdaPermission:
Type: "AWS::Lambda::Permission"
DependsOn:
- MyApiName
- MyLambdaFunctionName
Properties:
Action: lambda:InvokeFunction
FunctionName: !Ref MyLambdaFunctionName
Principal: apigateway.amazonaws.com
Here's the issue that was reported in SAM github repo for complete reference and here is an example of hello SAM project
If you would like to add permission by AWS CLI for testing things out, you may want to use aws lambda add-permission. please visit official documentation website for more details.
I had a similar issue - I deleted then re-installed a lambda function. My API Gateway was still pointing at the old one, so I had to go into the API Gateway and change my Resource Methods to alter the Integration Request setting to point to the new one (it may look like it's pointing to the correct one but wasn't in my case)
I was having the same issue but I was deploying through Terraform. After a suggestion from another user, I reselected my Lambda function in the Integration part of the API Gateway, and then checked what changed in my Lambda permissions. Turns out I needed to add a "*" where I was putting the stage name in the source_arn section of the API Gateway trigger in my Lambda resource. Not sure how SAM compares to Terraform but perhaps you can change the stage name or just try this troubleshooting technique that I tried.
My SO posting: AWS API Gateway and Lambda function deployed through terraform -- Execution failed due to configuration error: Invalid permissions on Lambda function
Same error, and the solution was simple: clearing and applying the "Lambda Function" mapping again in the integration setting of the API Gateway.
My mapping looks like this: MyFunction-894AR653OJX:test where "test" is the alias to point to the right version of my lambda
The problem was caused by removing the ALIAS "test" on the lambda, and recreating it on another version (after publishing). It seems that the API gateway internally still links to the `old' ALIAS instance.
You would expect that the match is purely done on name...
Bonus: so, via the AWS console you cannot move that ALIAS, but you can do this via the AWS CLI, using the following command:
aws lambda --profile <YOUR_PROFILE> update-alias --function-name <FUNCTION_NAME> --name <ALIAS_NAME> --function-version <VERSION_NUMBER>
I had the same issue. I changed the integration to mock first, i.e unsetting the integration type to Lambda, and then after one deployment, set the integration type to lambda again. It worked flawlessly thereafter.
I hope it helps.
Facing the same issue, I figured out the problem is : API Gateway is not able to invoke the Lambda function as I couldn't see any CloudWatch logs for the lambda Function.
So firstly I went through API Gateway console and under the Integration Request - gave the full ARN for the Lambda Function. and it is started working.
Secondly, through the CloudFormation
x-amazon-apigateway-integration:
credentials:
Fn::Sub: "${ApiGatewayLambdaRole.Arn}"
type: "aws"
uri:
Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambda_function.Arn}/invocations"
I had the same problem so I deleted then created the stack and it worked.
Looks like "Execution failed due to configuration error: Invalid permissions on Lambda function" is a catch all for multiple things :D
I deployed a stack with CloudFormation templates and hit this issue.
I was using the stage name in the SourceArn for the AWS::Lambda::Permission segment.
when i changed that to a * AWS was a bit more explicit about the cause, which in my case happened to be an invalid Handler reference (I was using Java, the handler had moved package) in the AWS::Lambda::Function section.
Also, when i hit my API GW i got this message
{
"message": "Internal server error"
}
It was only when I was at the console and sent through the payload as a test for the resource that I got the permissions error.
If I check the Cloudwatch logs for the API GW when I configured that, it does indeed mention the true cause even when the Stage Name is explicit.
Lambda execution failed with status 200 due to customer function error: No public method named ...
In my case, I got the error because the Lambda function had been renamed. Double-check your configuration just in case.
Technically, the error message was correct—there was no function, and therefore no permissions. A helpful message would, of course, have been useful.
I had a similar problem and was using Terraform. It needed the policy with the "POST" in it. For some reason the /*/ (wildcard) policy didn't work?
Here's the policy and the example terraform I used to solve the issue.
Many thanks to all above.
Here is what my Lambda function policy JSON looked like and the terraform:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "AllowAPIGatewayInvoke",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:999999999999:function:MY-APP",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:999999999999:d85kyq3jx3/test/*/MY-APP"
}
}
},
{
"Sid": "e841fc76-c755-43b5-bd2c-53edf052cb3e",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:999999999999:function:MY-APP",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:999999999999:d85kyq3jx3/*/POST/MY-APP"
}
}
}
]
}
add in a terraform like this:
//************************************************
// allows you to read in the ARN and parse out needed info, like region, and account
//************************************************
data "aws_arn" "api_gw_deployment_arn" {
arn = aws_api_gateway_deployment.MY-APP_deployment.execution_arn
}
//************************************************
// Add in this to support API GW testing in AWS Console.
//************************************************
resource "aws_lambda_permission" "apigw-post" {
statement_id = "AllowAPIGatewayInvokePOST"
action = "lambda:InvokeFunction"
//function_name = aws_lambda_function.lambda-MY-APP.arn
function_name = module.lambda.function_name
principal = "apigateway.amazonaws.com"
// "arn:aws:execute-api:us-east-1:473097069755:708lig5xuc/dev/POST1/cloudability-church-ws"
source_arn = "arn:aws:execute-api:${data.aws_arn.api_gw_deployment_arn.region}:${data.aws_arn.api_gw_deployment_arn.account}:${aws_api_gateway_deployment.MY-APP_deployment.rest_api_id}/*/POST/${var.api_gateway_root_path}"
}
The documentation for AWS lambda resource permissions shows 3 levels of access you can filter or wildcard, /*/*/*, which is documented as $stage/$method/$path. However, their example and most examples online only use 2 levels and I was bashing my head against the wall using 3 only to get Access Denied. I changed down to 2 levels and lambda then created the trigger. Hopefully, this will save someone from throwing their computer against the wall.
In my case I used Lambda path, that doesn't starts with a '/', like Path: "example/path" in my template.yaml.
As a result AWS generate incorrect permission for this lambda:
{
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:{Region}:{AccountId}:{ApiId}/*/GETexample/path/*"
}
}
So I fixed it by adding '/' to my lambda path in the template.

Heroku Pipeline Deploy Hook HTTP in app.json

I am setting up a Heroku pipeline and I want to add the "add-on" attribute however I did not see them be applied to my environment.
The format of the add ons block is:
"addons": [
"sendgrid",
{
"plan": "deployhooks:http",
"as": "SLACK-ENG-STATUS",
"options": {
"url": "THIS IS A RANDOM URL"
}
}
],
Is that the correct syntax to create the add-on? I do not see the configuration in the staging app when I directly deploy to it.
Do you expect your addon to be created on deploy? Because that is not how the app.json works. The app.json only created your addons for:
Review apps (https://devcenter.heroku.com/articles/github-integration-review-apps#app-json)
When you use the platform API to create your app (https://devcenter.heroku.com/articles/setting-up-apps-using-the-heroku-platform-api), including through the Heroku Button
If you already have an existing app, entries in the app.json will not modify it on deploy.

Configuring the Hyperledger Composer REST server with a persistent data store

I am following this tutorial
https://hyperledger.github.io/composer/integrating/deploying-the-rest-server.html
I have done all the steps. But when I run rest-server through github, it prints following stack trace.
Error
404 Cannot GET /auth/github
status: 404
Error: Cannot GET /auth/github
at raiseUrlNotFoundError (/home/praval/.nvm/versions/node/v6.11.1/lib/node_modules/composer-rest-server/node_modules/loopback/server/middleware/url-not-found.js:21:17)
I presume you installed the Github strategy via npm install -g passport-github?
If so did it create a folder /auth/github?
You are required to go to this Folder per documentation: "Authenticate to the REST server by navigating to the value of the authPath property specified in the environment variable COMPOSER_PROVIDERS. In the example above, this is http://localhost:3000/auth/github"
In my case that folder was not created. I read on Github website: https://github.com/cfsghost/passport-github
"The author of Passport-Github has not maintained the original module for a long time. Features in his module don't work since Github upgraded their API to version 3.0. We forked it and re-published it to NPM with a new name passport-github2"
I'm looking for guidance on this.
Before create private api just execute this command in your terminal.
export COMPOSER_PROVIDERS='{
"github": {
"provider": "github",
"module": "passport-github",
"clientID": "<your id>",
"clientSecret": "<your secret>",
"authPath": "/auth/github",
"callbackURL": "/auth/github/callback",
"successRedirect": "http://localhost(domain of angular app):4200(port)/home(page to redirect)",
"failureRedirect": "http://localhost(domain of angular app):4200(port)/login-github(page to redirect)""
}
}'
To check if all is fine - run command
echo $COMPOSER_PROVIDERS
After this you will see your COMPOSER_PROVIDERS value.
And after in github profile app (https://github.com/settings/applications/) you must configure "Homepage URL" (ex. http://APIdomain:3000/) and "Authorization callback URL" (ex. http://APIdomain:3000/auth/github/callback)

Resources