Not able to invoke erisdb.eventPoll rpc call - blockchain

I have my blockchain running locally . I was using node-json-rpc module to make rpc calls . I was able to make few calls like erisdb.getBlockchainInfo.
I tried the erisdb.eventSubscribe call :
client.call(
{
"jsonrpc": "2.0", "method": "erisdb.eventSubscribe", "params": {
"event_id": "NewBlock"
}, "id": "0"
},
and it successfully returned a sub_id to me :
{ result: { sub_id: '7878EB2ECC668AEE19D958B89C4ED6E145D9298E91366D67F93CD2A20E995829' },
error: null,
id: '0',
jsonrpc: '2.0' }
I used that sub_id to invoke erisdb.eventPoll call :
client.call(
{
"jsonrpc": "2.0", "method": "erisdb.eventPoll", "params": {
"sub_id":"7878EB2ECC668AEE19D958B89C4ED6E145D9298E91366D67F93CD2A20E995829"
}, "id": "1"
},
but it is giving the following error :
{ result: null,
error:
{ code: -32603,
message: 'Subscription not active. ID: 7878EB2ECC668AEE19D958B89C4ED6E145D9298E91366D67F93CD2A20E995829' },
id: '1',
jsonrpc: '2.0' }
My eris-db version is 0.12.1.

We have two different APIs at the moment. The one you are using we call the 'v0' API. It is optimised for long-polling Javascript clients. My guess is that your subscription is getting reaped before a certain hard-coded timeout that happens to be 10 seconds. Have you tried making the eventPoll call in quick sucession after the eventSubscribe call?
This is the 'v0' reaping function: https://github.com/eris-ltd/eris-db/blob/master/event/event_cache.go#L72. It runs in a loop clearing out old subscriptions that have not been polled recently. If you have waited longer than 10 seconds before polling then your subscription has probably been reaped (deleted).
We have another API optimised for chain administration called the 'tendermint' API (because of its heritage from the Tendermint consensus engine). It is something of a parallel API and it is used by the eris-pm tool. It also has a subscribe method accessible by a websocket endpoint. This might be useful for you because its subscriptions are never reaped.
You could try it out like this:
Start your chain:
$ eris chains start testchain
Get a simple websocket client:
$ go get github.com/raphael/wsc
Connect to the websocket endpoint:
$ wsc ws://0.0.0.0:46657/websocket
2017/01/21 01:03:51 connecting to ws://0.0.0.0:46657/websocket...
2017/01/21 01:03:51 ready, exit with CTRL+C.
Subscribe to the NewBlock event by pasting { "jsonrpc": "2.0", "method": "subscribe", "params": ["NewBlock"] } into the terminal as a single line:
>> { "jsonrpc": "2.0", "method": "subscribe", "params": ["NewBlock"] }
Then you should receive a stream of new block events (about 1 per second) like:
<< {"jsonrpc":"2.0","id":"#event","result":[19 {"event":"NewBlock","data":[1,{"block":{"header":{"chain_id":"testchain","height":206320,"time":"2017-01-21T01:04:01.095Z","num_txs":0,"last_block_hash":"2DB0D0AE6D92DA6DA07F8E7D1605AAB6CB96D8D2","last_block_parts":{"total":1,"hash":"A4AD1708714CF0BE3E5125B65F495DDDFA1ED8D9"},"last_commit_hash":"4C301C0367B7CECDD4E00C955D2F155802B2377E","data_hash":"","validators_hash":"46E43215C6C332446114BF7320D2D007114C5EEB","app_hash":"9A72DE9AAD6BD820A64DB98462CD706594217E1
<< 1"},"data":{"txs":[]},"last_commit":{"precommits":[{"height":206319,"round":0,"type":2,"block_hash":"2DB0D0AE6D92DA6DA07F8E7D1605AAB6CB96D8D2","block_parts_header":{"total":1,"hash":"A4AD1708714CF0BE3E5125B65F495DDDFA1ED8D9"},"signature":"45A6C3D0B0BD380A239F014681A29FD6217B52653CC7FC189FF5B7DC840A61062CF12FC652687A30A5CBBF0270937F32542D6075BA94A12180568560B322EC07"}]}}}]}],"error":""}
You could use a programmatic websocket client of your choice to interact with the chain using this websocket API and your subscriptions will never get reaped.
There is a grand unification of these APIs planned soon that should make them easier to use and better documented.
If you need help debugging, join us on: https://monax.slack.com/

Related

AWS PinPoint - SMS Message From Postman

I'm trying to initiate a SMS message using Postman, but I keep getting a response indicating "Invalid Request Body". I can't seem to find a good example on the AWS documentation (Is it just me or does anyone else encounter this with AWS?)
Below is the request body I'm submitting with my request. Any help would be much appreciated!
{
"ApplicationId": "<MyApplicationID>",
"MessageRequest": {
"Addresses": {
"[{{Destination}}]": {
"BodyOverride": "Test",
"ChannelType": "SMS"
}
},
"MessageConfiguration": {
"SMSMessage": {
"Body": "Test",
"SenderId": "Test",
"MessageType": "TRANSACTIONAL",
"Keyword": "<MyKeyword>",
"OriginationNumber": "<Origination number in E.164 Format>"
}
}
}
}
Looking at the Amazon Pinpoint SendMessages REST API, the request body doesn't include either the application-id key or MessageRequest key.
Resolution:
You will need to put the Amazon Pinpoint application-id in the URI part (or create an environmental variable) and then specify the request body as shown below :
Hope this helps!

AWS Kinesis: user address in event encoded / encrypted

In my React Native mobile app, I use AWS Amplify to send info about user actions (screen views, button taps, swipes, etc.) by means of Analytics.record(...) to AWS Pinpoint which in turn feeds them into a AWS Kinesis Data Stream. I have created an AWS Lambda Python 3 function that listens to events in this data stream.
Setup has been a breeze, thanks to outstanding documentation and everything works fine - except for one thing:
When a user logs in, I update the Pinpoint Endpoint with the user ID, email address and some more attributes using Analytics.updateEndpoint(...). In the lambda function, I base64-decode the event payload as shown in this sample code and a sample event payload looks roughly like this:
{
"event_type": "_session.start",
"event_timestamp": 1572345161558,
"application": {
"app_id": "<some app ID>",
"cognito_identity_pool_id": "us-east-1:<some pool ID>",
"sdk": {},
"version_name": "<the app version I put in using updateEndpoint(...)>"
... <snipped for brevity> ...
},
"attributes": {},
"endpoint": {
"ChannelType": "APNS",
"Address": "=ABAQRuUDJD ... <some longish binary value> j0eL+69lsY=",
"EndpointStatus": "ACTIVE",
"Location": {
"Country": "US"
},
"Demographic": {
"Make": "iPhone",
"Model": "iPhone X",
"ModelVersion": "13.1.3",
...
"Platform": "ios"
},
"User": {
"UserId": "us-east-1:<Cognito ID of the user that logged in>",
"UserAttributes": {}
},
... <snipped for brevity> ...
},
"awsAccountId": "<my account ID>"
}
The user email address in the "Address" field above is not contained in the Kinesis Data Stream event as plain text, but encoded (or encrypted ?) somehow.
My question: Can anybody tell me how it is encoded / encrypted ? And, ideally, how to get the plain text address ?
I tried to base64-decode it or decrypt it using my default AWS KMS key (and a combination thereof), but no luck.
Alternatively, I could use the (plain text) user ID to look up the email address in the AWS Cognito user pool used to manage auth & auth, but getting it from the event directly would obviously be a lot simpler...
I have searched the web up and down, asked in the AWS-Amplify channel on gitter, but that Address encoding / encryption just does not seem to be documented anywhere...

AWS X-Ray trace segments are missing or not connected

I have code that creates a segment when a queue is being read. In the first function (within the same lambda) I have this:
import * as AWSXRay from 'aws-xray-sdk'; // (using TypeScrpt)
AWSXRay.enableManualMode();
var segment1 = new AWSXRay.Segment("A");
In the second function (within the same lambda), called from the first, I have something like this:
var segment2 = new AWSXRay.Segment("B", segment1.trace_id, segment1.id);
Instead of seeing
*->A->B
On the AWS graph (on the website), I see:
*->A
*->B
...where they are not even associated, even though they have the same tracing ID, and the parent IDs are properly set. I seem to be missing something but not sure what...?
I even tried to pull X-Amzn-Trace-Id from the API request to use that as the root tracking ID for everything but that didn't work either.
This is the JSON for the first segment (A):
{
"Duration": 0.808,
"Id": "1-5d781a08-d41b49e35c3c0f38cdbd4912",
"Segments": [
{
"Document": {
"id": "74c99567f73185ce",
"name": "router",
"start_time": 1568152071.979,
"end_time": 1568152072.787,
"parent_id": "ef34fc0bcf23bbbe",
"aws": {
"xray": {
"sdk": "X-Ray for Node.js",
"sdk_version": "2.3.6",
"package": "aws-xray-sdk"
}
},
"service": {
"version": "unknown",
"runtime": "node",
"runtime_version": "v10.16.3",
"name": "unknown"
},
"trace_id": "1-5d781a08-d41b49e35c3c0f38cdbd4912"
},
"Id": "74c99567f73185ce"
}
]
}
This is the JSON for the second segment (B):
{
"Duration": 0.801,
"Id": "1-5d781a08-d9626abbab1cfbbfe4ff0dff",
"Segments": [
{
"Document": {
"id": "e2b4faaa6538bbb2",
"name": "handleCreateLoad",
"start_time": 1568152071.98,
"end_time": 1568152072.781,
"parent_id": "74c99567f73185ce",
"aws": {
"xray": {
"sdk": "X-Ray for Node.js",
"sdk_version": "2.3.6",
"package": "aws-xray-sdk"
}
},
"service": {
"version": "unknown",
"runtime": "node",
"runtime_version": "v10.16.3",
"name": "unknown"
},
"trace_id": "1-5d781a08-d9626abbab1cfbbfe4ff0dff",
"subsegments": [
{
"id": "08ccf2f374364066",
"name": "...-CreateLoad",
"start_time": 1568152071.981,
"end_time": 1568152072.781
}
]
},
"Id": "e2b4faaa6538bbb2"
}
]
}
It's quite clear the the parent ID for 'B' (74c99567f73185ce) points to "A"'s ID, but the graph does not connect them.
Also, I think _x_amzn_trace_id should be set when the lambda executes, but it is not. That may be root of my issues.
Turns out process.env._x_amzn_trace_id, required by the AWS XRay SDK, does NOT exist until the handler is called. It may help others to know what I went through:
At first I tried to get the trace details for the current lambda on start up (before the handler is called) to connect my new segments, but it didn't work. I have many handlers in the same project, so getting the lambda segment on startup is what I was hoping to do.
I then proceeded to create a main lambda segment (thinking I had to create the first segment myself) but all it did was create an orphaned segment. To make matters worse, each segment creates a new trace ID if one is not provided, and since I could not get the trace ID from the global start-up scope, nothing was connecting. The proper trace ID is important to pass along from start to finish for each request to make sure the calls down-stream are tracked properly.
Dumping of the environment variables before the handler is called and after clearly showed the trace ID is not provided until just before the handler gets called. It's sad that most of the online examples don't even bother to warn about this. I then moved the called to AWSXRay.getSegment() at the start of the lambda handler, then passed the details onto the child segments.
DO NOT set context.callbackWaitsForEmptyEventLoop = false while also calling the callback(error, response) callback passed to the lambda handler. Doing so will terminate the lambda without waiting for segment update events to flush to the daemon, resulting in orphaned segments. :(
Note: This documentation is lacking: https://docs.aws.amazon.com/xray-sdk-for-nodejs/latest/reference/
It states "You can retrieve the current segment or subsegment at any time" when in fact there are some times when you cannot. It's too bad there are no proper examples using actual working NodeJS Lambda code, instead of isolated lines of code thrown everywhere.

AWS Pinpoint/Ionic - "Resource not found" error when trying to send push through CLI

I am new at programming with AWS services, so some fundamental things are pretty hard for me. Recently, I was asked to develop an app that used Amazon Pinpoint to send push notifications, as a test for considering future implementations.
As you can see in another question I posted in here (Amazon Pinpoint and Ionic - Push notifications not working when app is in background), I was having trouble trying to send push notifications to users when my app is running in the background. The app was developed using Ionic by following these steps.
When I was almost giving up, I decided to try sending the pushes directly through Firebase, and it finally worked. Some research took me to this question, in which another user described the problem as only happening in AWS Console, so the solution would be to use CLI. After searching a little about it, I found this tutorial about how to sending pinpoint messages to users using CLI, that seems to be what I wanted. Combining it with this documentation about phonegap plugin, I was able to generate a JSON I thought could be a solution:
{
"ApplicationId":"io.ionic.starter",
"MessageRequest":{
"Addresses": {
"": {
"BodyOverride": "",
"ChannelType": "GCM",
"Context": {
"": ""
},
"RawContent": "",
"Substitutions": {},
"TitleOverride": ""
}
},
"Context": {
"": ""
},
"Endpoints": {"us-east-1": {
"BodyOverride": "",
"Context": {},
"RawContent": "",
"Substitutions": {},
"TitleOverride": ""
}
},
"MessageConfiguration": {
"GCMMessage": {
"Action": "OPEN_APP",
"Body": "string",
"CollapseKey": "",
"Data": {
"": ""
},
"IconReference": "",
"ImageIconUrl": "",
"ImageUrl": "",
"Priority": "High",
"RawContent": "{\"data\":{\"title\":\"sometitle\",\"body\":\"somebody\",\"url\":\"insertyourlinkhere.com\"}}",
"RestrictedPackageName": "",
"SilentPush": false,
"SmallImageIconUrl": "",
"Sound": "string",
"Substitutions": {},
"TimeToLive": 123,
"Title": "",
"Url": ""
}
}
}
}
But when I executed it in cmd with aws pinpoint send-messages --color on --region us-east-1 --cli-input-json file://test.json, I got the response An error occurred (NotFoundException) when calling the SendMessages operation: Resource not found.
I believe I didn't write the JSON file correctly, since it's my first time doing this. So please, if any of you know what I am doing wrong, no mattering which step I misunderstood, I would appreciate the help!
"Endpoints" field in the Message request deals with the endpoint id (the identifier associated with an end user device while registering to pinpoint and not the region.)
In case if you haven't registered any endpoints with Pinpoint, you can use the "Addresses" field. After registering the GCM Channel in Amazon Pinpoint, you can get the GCM device token from your device and specify it here.
Here is a sample for sending direct messages using Amazon Pinpoint Note: The example deals with sending SMS message. You should have registered a SMS channel first and created an endpoint with the endpoint id as "test-endpoint1". Otherwise, you can use the "Addresses" field instead of "Endpoints" field.
aws pinpoint send-messages --application-id $APP_ID --message-request '{"MessageConfiguration": {"SMSMessage":{"Body":"hi hello"}},"Endpoints": {"test-endpoint1": {}}}
Also Note: ApplicationId is generated by Pinpoint. When you visit the Pinpoint console and choose your application, the URL will be of the format
https://console.aws.amazon.com/pinpoint/home/?region=us-east-1#/apps/someverybigstringhere/
Here "someverybigstringhere" is the ApplicationId and not the name you give for your project.

Where can I log & debug Velocity Template Language (VTL) in AWS AppSync?

Is there any easy way to log or debug VTL coming from Request Mapping Template & Response Mapping Template rather than sending Queries & Mutations to debug & log?
Also, is there any Playground to check & play with VTL just like we can do with JavaScript in Web Console?
Can we work with AWS AppSync offline & check if everything written in VTL works as expected?
A super nasty way to log and debug is using validate in the response mapping
$util.validate(false, $util.time.nowISO8601().substring(0, 10) )
Here's how I logged a value in my VTL resolver:
Add a "$util.error" statement in your request or response template and then make the graphql call.
For example, I wanted to see what was the arguments passed as an input into my resolver, so I added the $util.error statement at the beginning of my template. So, my template was now:
$util.error("Test Error", $util.toJson($ctx))
{
"version" : "2017-02-28",
"operation" : "PutItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.arguments.user.id)
},
"attributeValues": {
"name": $util.dynamodb.toDynamoDBJson($ctx.arguments.user.name)
}
}
Then from the "Queries" section of the AWS AppSync console, I ran the following mutation:
mutation MyMutation {
addUser(user: {id: "002", name:"Rick Sanchez"}) {
id
name
}
}
This displayed the log results from my resolver as follows:
{
"data": null,
"errors": [
{
"path": [
"addUser"
],
"data": null,
"errorType": "{\"arguments\":{\"user\":{\"id\":\"002\",\"name\":\"Rick Sanchez\"}},\"identity\":null,\"source\":null,\"result\":null,\"request\":{\"headers\":{\"x-forwarded-for\":\"112.133.236.59, 130.176.75.151\",\"sec-ch-ua-mobile\":\"?0\",\"cloudfront-viewer-country\":\"IN\",\"cloudfront-is-tablet-viewer\":\"false\",\"via\":\"2.0 a691085135305af276cea0859fd6b129.cloudfront.net (CloudFront)\",\"cloudfront-forwarded-proto\":\"https\",\"origin\":\"https://console.aws.amazon.com\",\"content-length\":\"223\",\"accept-language\":\"en-GB,en;q=0.9,en-US;q=0.8\",\"host\":\"raxua52myfaotgiqzkto2rzqdy.appsync-api.us-east-1.amazonaws.com\",\"x-forwarded-proto\":\"https\",\"user-agent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66\",\"accept\":\"*/*\",\"cloudfront-is-mobile-viewer\":\"false\",\"cloudfront-is-smarttv-viewer\":\"false\",\"accept-encoding\":\"gzip, deflate, br\",\"referer\":\"https://console.aws.amazon.com/\",\"x-api-key\":\"api-key-has-been-edited-out\",\"content-type\":\"application/json\",\"sec-fetch-mode\":\"cors\",\"x-amz-cf-id\":\"AvTMLvtxRq9M8J8XntvkDj322SZa06Fjtyhpf_fSXd-GmHs2UeomDg==\",\"x-amzn-trace-id\":\"Root=1-5fee036a-13f9ff472ba6a1211d499b8b\",\"sec-fetch-dest\":\"empty\",\"x-amz-user-agent\":\"AWS-Console-AppSync/\",\"cloudfront-is-desktop-viewer\":\"true\",\"sec-fetch-site\":\"cross-site\",\"sec-ch-ua\":\"\\\"Chromium\\\";v=\\\"87\\\", \\\" Not;A Brand\\\";v=\\\"99\\\", \\\"Microsoft Edge\\\";v=\\\"87\\\"\",\"x-forwarded-port\":\"443\"}},\"info\":{\"fieldName\":\"addUser\",\"parentTypeName\":\"Mutation\",\"variables\":{}},\"error\":null,\"prev\":null,\"stash\":{},\"outErrors\":[]}",
"errorInfo": null,
"locations": [
{
"line": 9,
"column": 3,
"sourceName": null
}
],
"message": "Test Error"
}
]
}
The answers to each of your 3 questions are as follows:
To unit test request/response mapping templates, you could use the method described in this blog post (https://mechanicalrock.github.io/2020/04/27/ensuring-resolvers-aren't-rejected.html).
A Playground for VTL experimentation exists in the AWS AppSync console where you you can edit and test the VTL for your resolvers.
The Amplify framework has a mock functionality which mocks AppSync, the AppSync VTL environment and DynamoDB (using DynamoDB Local). This would allow you to perform e2e tests locally.
Looks like you are looking for this new VTL logging utility such as
$util.log.info(Object) : Void
Documentation:
https://docs.aws.amazon.com/appsync/latest/devguide/utility-helpers-in-util.html
When I realized how much a pain it was to debug VTL, I created a lambda (nodejs) that logged the contents of my VTL template.
// my nodejs based debug lambda -- very basic
exports.handler = (event, context, callback) => {
const origin = context.request || 'oops';
if (context && context.prev) {
console.log('--------with context----------------');
console.log({ prev: context.prev.result, context, origin });
console.log({ stash: context.stash });
console.log('--------END: with context----------------');
callback(null, context.prev.result);
}
console.log('inside - LOGGING_DEBUGGER');
console.log({ event, context: context || null, origin });
callback(null, event);
};
This lambda helped me debug many issues inside my pipeline resolvers. However, I forgot if I used it as a direct lambda or with request+response templates.
To use it, I put values that I wanted to debug into $ctx.stash in my other pipeline functions. Then in my pipeline, I added the "debugger" function after this step -- in case there was an issue where my pipeline would blow up before a fatal error occurred.
Check the $util.log.info(Object) : Void from CloudWatch logging utils
PS: you need to turn on logging to Amazon CloudWatch Logs plus setting Field resolver log level on ALL more details here.