Near Protocol | RPC Contract deployment | Deserialization error - deserialization

I am developing smart contracts in AssemblyScript, deploying contracts via RPC (Remote Procedural Calls), that is dynamically, while coding as and when required. Below is the code that carries out this task.
log(): void {
logging.log(this.owner);
const access_key = base58.decode(Context.senderPublicKey);
logging.log(access_key);
const CODE = base58.decode("build/release/nft.wasm");
ContractPromiseBatch
.create("d4." + this.owner)
.create_account()
.transfer(ONE_NEAR)
.add_full_access_key(access_key)
.deploy_contract(CODE);
}
After the code the new account has been created and the contract code deployed, I get a deserialization error even while carrying out the init calls for initialising the contract.
The error log is :
Failure:
{
"ActionError": {
"index": 0,
"kind": {
"FunctionCallError": {
"CompilationError": {
"PrepareError": "Deserialization"
}
}
}
}
}
The link to the transaction : https://explorer.testnet.near.org/transactions/2HjNsq6ytnN3hT9odoijaYxBsByhQQcwSUTZNwGgzuyg
Heres the init method of the contract I am trying to initialize

It appears the correct way to include your wasm code while deploying the contract is
const CODE = includeBytes("../../../build/release/nft.wasm");
and while deploying, parse CODE into base58 array
let promise = ContractPromiseBatch
.create("kust" + "." + this.owner)
.create_account()
.transfer(ONE_NEAR)
.add_full_access_key(access_key)
.deploy_contract(Uint8Array.wrap(changetype<ArrayBuffer>(CODE)));

Related

solclient send request resulting success and fail at the same time

I'm starting a new project with Solace as the load balancer. As I follow the guideline on the official doc to build a service that can send requests to Solace, I encounter a weird issue where my request is successful and fails simultaneously. Here's my code
function initSolace(pass: string) {
var factoryProps = new solace.SolclientFactoryProperties();
factoryProps.profile = solace.SolclientFactoryProfiles.version10;
solace.SolclientFactory.init(factoryProps);
session = solace.SolclientFactory.createSession({
"url": "ws://localhost:8008",
"userName": "tech_core",
"vpnName": "testing",
"password": pass
}, new solace.MessageRxCBInfo(messageRxCb));
session.on(solace.SessionEventCode.UP_NOTICE, function (sessionEvent: any) {
requestData(10000).subscribe();
});
session.connect();
}
async function messageRxCb(session: any, message: any) {
message = Parser.decodeBinaryAttachmentToPb(message, pnlPb.RespPnl);
console.log('result from RxCb', message); // I got the correct response here
}
function requestData(timeout = 10000) {
return new Observable(subscriber => {
const parsedPayload = Parser.createPb({displayCurrency: 'USD'}, pnlPb.ReqPnl);
const msg = Parser.encodePbToBinaryAttachment(parsedPayload, pnlPb.ReqPnl);
const request = solace.SolclientFactory.createMessage();
request.setDestination(solace.SolclientFactory.createTopicDestination('my/testing/topic'));
request.setDeliveryMode(solace.MessageDeliveryModeType.DIRECT);
request.setDeliverToOne(true);
request.setBinaryAttachment(msg);
session.sendRequest(request, timeout,
(ses: any, message: any) => {
console.log('SUCCESS', message);
subscriber.next(message);
},
(ses: any, event: any) => {
console.error('FAIL', event); // I got a timeout error here
subscriber.error(event);
},
'correlation test'
)
});
}
As I run the code, I gets the timeout error from the requestData function AND the correct data from the messageRxCb function as well.
How does this happening? Did I miss any config here?
The Request-Reply pattern is a closely coupled communication pattern.
Every request that is posted by the requestor requires a response from the replier within the timeout specified.
I see from your code sample that you have configured a timeout of 10000ms. What it means is that every request that is posted should receive an incoming reply within 10000ms. If this response is not received, then it would result in the timeout error that you see in the console.
The reason why you see that the request is successfull and the error is because while the request has been successfully posted, a reply was not received within the specified timeout.
Do you already have a replier setup for this interaction? If not then I would suggesting setting up a simple boilerplate replier listening on this and testing the flow again.
Additionally, it would be good coding practise to handle the timeout error in a functionally appropriate manner.
Regards
Hari

Getting data from REST API using cpprestsdk

I am following Pixabay API documentation to retrieve/download images.
I don't have a lot of understanding of URI/REST/HTTP workings but I was able to follow some documentation and get boilerplate code:
int main()
{
auto fileStream = std::make_shared<ostream>();
//Open stream for output file
pplx::task<void> requestTask = fstream::open_ostream("results.html")
.then([=](ostream outFile) {
http_client client("https://pixabay.com/");
uri_builder builder("/api/");
builder.append_query("key", "xxxxxxx-xxxxxx-xxxxxxx");
builder.append_query("q", "yellow%20flowers");
builder.append_query("image_type", "photo");
std::cout << builder.to_string() << std::endl;
return client.request(methods::GET, builder.to_string()); })
// Handle the response headers arriving
.then([=](http_response response) {
printf("Received response status code: %u\n", response.status_code());
return response.body().read_to_end(fileStream->streambuf()); })
// Close the file stream.
.then([=](size_t) {
return fileStream->close(); });
// Wait for all the outstanding I/O to complete and handle any exceptions
try {
requestTask.wait();
}
catch (const std::exception &e) {
printf("Exception: %s\n", e.what());
}
return 0;
}
Problem : This code always gives me status code 301.
If I directly run https://pixabay.com/api/?key=xxxxxxx-xxxxxx-xxxxxxx&q=yellow+flowers&image_type=photo&pretty=true this link in the browser, I am getting the JSON data back. I am not sure if I am able to build this URI correctly through URI builder using the above code.
Some variation of the code that I tried involves commenting out query parameter q , removing/adding / from http_client/uri_builder but none of that worked.
Please help me understand what is the correct way of getting this done.
Thanks!
on adding an http_client_config the same code worked for me.
web::http::client::http_client_config httpConfig;
httpConfig.set_timeout(std::chrono::seconds(25));
httpConfig.set_validate_certificates(false);
and use this config while creating http_client
http_client client("https://pixabay.com/", httpConfig);
The C++ REST SDK has built-in support for automatically following 301 redirects when making HTTP requests. By default, the SDK will automatically follow up to 5 redirects.

SignalR Core - Error: Websocket closed with status code: 1006

I use SignalR in an Angular app. When I destroy component in Angular I also want to stop connection to the hub. I use the command:
this.hubConnection.stop();
But I get an error in Chrome console:
Websocket closed with status code: 1006
In Edge: ERROR Error: Uncaught (in promise): Error: Invocation canceled due to connection being closed. Error: Invocation canceled due to connection being closed.
It actually works and connection has been stopped, but I would like to know why I get the error.
This is how I start the hub:
this.hubConnection = new HubConnectionBuilder()
.withUrl("/matchHub")
.build();
this.hubConnection.on("MatchUpdate", (match: Match) => {
// some magic
})
this.hubConnection
.start()
.then(() => {
this.hubConnection.invoke("SendUpdates");
});
EDIT
I finally find the issue. Its caused by change streams from Mongo. If I remove the code from SendUpdates() method then OnDisconnected is triggered.
public class MatchHub : Hub
{
private readonly IMatchManager matchManager;
public MatchHub(IMatchManager matchManager)
{
this.matchManager = matchManager;
}
public async Task SendUpdates() {
using (var changeStream = matchManager.GetChangeStream()) {
while (changeStream.MoveNext()) {
var changeStreamDocument = changeStream.Current.FullDocument;
if (changeStreamDocument == null) {
changeStreamDocument = BsonSerializer.Deserialize<Match>(changeStream.Current.DocumentKey);
}
await Clients.Caller.SendAsync("MatchUpdate", changeStreamDocument);
}
}
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await base.OnDisconnectedAsync(exception);
}
}
Method GetChangeStream from the manager.
ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
var watch = mongoDb.Matches.Watch(options).ToEnumerable().GetEnumerator();
return watch;
But I don't know how to fix it.
This can be for many reasons but i think it is most likely this one:
I think this is because of how the server is handling the connected / disconnected events. I can't say for sure but the connection closing needs to handled correctly on the server also with code. Try overriding the built in On Connected /Disconnected methods on the server and see. My assumption only is that you're closing it but the server isn't closing properly and therefore not relaying the proper closed response.
found as a comment at : getting the reason why websockets closed with close code 1006
Where you don't need to change the connection/disconection because evrything works fine. But as an answer this one is the most likely.
It throws error because the callback doesn't get clear properly.
And it is caused by the return data from websocket.
normally it should return like
However, for some reason it might return something like
the very last response breaking into 2 pieces
And that causes the issue.
I don't think there is a way to bypass this without changing the source code.
I reported this on github repo as well at here
It turns out that I can just utilize invocation response to notify client to stop the hub. So it doesn't trigger racing issue.

ServiceStack OrmLite and PostgreSQL - timeouts

I am updating large amounts of data using ServiceStack's OrmLite with a connection to PostgreSQL, however, I am getting a large amount of timeouts.
Sample Code:
public class AccountService : Service
{
public object Any(ImportAccounts request)
{
var sourceAccountService = this.ResolveService<SourceAccountService();
var sourceAccounts = (GetSourceAccountResponse)sourceAccountService.Get(new GetSourceAccounts());
foreach (var a in sourceAccounts)
{
Db.Save(a.ConvertTo<Account>());
}
}
}
The Source Account service, which sits in the same project & accesses the same Db.
public class SourceAccountService : Service
{
public object Get(GetSourceAccounts request)
{
return new GetSourceAccountsResponse { Result = Db.Select<SourceAccounts>().ToList() };
}
}
Questions,
Should I be expecting large amount of timeouts considering the above set up?
is it better to be using using (IDbConnection db = DbFactory.OpenDbConnection()) instead of Db?
If you're resolving and executing a Service you should do it in a using statement so its open Db connection and
other resources are properly disposed of:
using (var service = this.ResolveService<SourceAccountService())
{
var sourceAccounts = service.Get(new GetSourceAccounts());
foreach (var a in sourceAccounts)
{
Db.Save(a.ConvertTo<Account>());
}
}
If you're executing other Services it's better to specify the Return type on the Service for added type safety
and reduced boiler plate at each call site, e.g:
public class SourceAccountService : Service
{
public GetSourceAccountsResponse Get(GetSourceAccounts request)
{
return new GetSourceAccountsResponse {
Result = Db.Select<SourceAccounts>()
};
}
}
Note: Db.Select<T> returns a List so .ToList() is unnecessary,
Another alternative for executing a Service instead of ResolveService<T> is to use:
var sourceAccounts = (GetSourceAccountsResponse)base.ExecuteRequest(new GetSourceAccounts());
Which is same above and executes the Service within a using {}.

Raising events in KRL without using explicit

I'm writing an app that raises events, similar to how Phil Windley's personal data manager application works. However, if I try to use any event domain but explicit, the events don't get propagated. The following rules work fine with explicit as the domain, but not with driverreg.
rule driver_info_submit {
select when web pageview ".*"
pre {
driver_name = "Joe Driver";
driver_phone = "111-555-1212";
msg = <<
Current driver info: #{ent:driver_name}, #{ent:driver_phone}
>>;
}
notify("Started", msg);
fired {
raise explicit event new_driver_data with driver_name=driver_name and driver_phone=driver_phone;
}
}
// Save driver name
rule save_driver_name {
select when explicit new_driver_data
pre {
driver_name = event:param("driver_name") || ent:driver_name;
driver_phone = event:param("driver_phone") || ent:driver_phone;
}
noop();
always {
set ent:driver_name driver_name;
set ent:driver_phone driver_phone;
raise explicit event driver_data_updated;
}
}
rule driver_info_updated {
select when explicit driver_data_updated
{
notify("Driver name", ent:driver_name);
notify("Driver phone", ent:driver_phone);
}
}
It doesn't seem to be a problem with whether the app is deployed, as I've tried it both ways. What am I missing?
Only certain domains are allowed as domains in the raise statement:
explicit
http
system
notification
error
pds
This may be relaxed in the future.
This is covered in the documents here: https://kynetxdoc.atlassian.net/wiki/display/docs/Raising+Explicit+Events+in+the+Postlude
(note that this is a temporary home for the documentation)