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

the first working version of transaction fetcher #55

Merged
merged 9 commits into from
May 16, 2024
Merged

Conversation

konnov
Copy link
Contributor

@konnov konnov commented May 16, 2024

This PR presents a working implementation of transaction decoder. The core of this contribution is:

  • solarkraft/src/fetcher/callDecoder.ts extracts Soroban contract calls from a Horizon API.
  • solarkraft/src/fetcher/storage.ts is the basic storage data structure that is returned by callDecoder.
  • solarkraft/test/integration/callDecoder.test.ts is an integration test that fetches data from the testnet and compares the results to the expected outputs.
  • solarkraft/src/fetch.ts is work-in-progress code, ignore it.

The integration test is fragile as the test data will disappear after 1 month or when the testnet is reset. We have to find a more stable solution. However, for the development purposes, it should work.

@konnov konnov self-assigned this May 16, 2024
@konnov konnov added the enhancement New feature or request label May 16, 2024
@konnov konnov added this to the M1: Transaction extractor milestone May 16, 2024
* @param matcher a quick matcher over the contractId to avoid expensive deserialization
*/
export async function extractContractCall(
op: any,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there no way to be more precise here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not actually sure. Stellar SDK has Operation, but it does not look like what Horizon API is returning in Stellar SDK. Some of the methods return sdk.Horizon.ServerApi.OperationRecord but it's not exactly compatible with what I need.

solarkraft/src/fetcher/callDecoder.ts Outdated Show resolved Hide resolved
Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

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

Preliminary comments, I'm still looking at callDecoder.ts

@@ -64,7 +64,7 @@ impl SetterContract {
env.storage().instance().set(&MY_BOOL, &v);
log!(&env, "myBool: {}", v);
// bump the lifetime
env.storage().instance().extend_ttl(50, 100);
env.storage().instance().extend_ttl(env.storage().max_ttl() - 100, env.storage().max_ttl());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we subtract 100?

Copy link
Collaborator

Choose a reason for hiding this comment

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

+1, I had a similar question, but just assumed I was OOTL

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's a threshold of when the TTL is to be updated. I am not exactly sure how it works, so it's a bit arbitrary.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Makes sense. Could you add a brief comment? It looks a bit arbitrary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a comment. Actually, TTL is extended when it goes below the threshold, in this case, max_ttl - 100.

returnValue: any
/**
* Ordered mapping from field names to their native values (JS).
* This mapping contains values only for the fields that have been set
Copy link
Collaborator

Choose a reason for hiding this comment

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

So if I want all values after the tx, I have to merge oldFields and fields?

updatedFields may be a better name here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, actually, fields contains all fields stored so far. It's basically the new state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course, if a contract removes a field from the storage, then fields will have fewer fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have updated the comments a bit

Copy link
Collaborator

Choose a reason for hiding this comment

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

Then I dont understand the comment (contains values only for the fields that have been set by transactions). Which fields aren't set then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is the fresh version. It's all modulo my understanding of how Soroban stores the storage in Stellar:

    /**
     * Ordered mapping from field names to their native values (JS).
     * This mapping contains values only for the fields that have been created
     * or updated by a transaction in the past. It may happen that `fields` contains
     * fewer fields than `oldFields`, when the contract deletes some fields
     * from the storage. Also, `fields` may become empty when the storage
     * goes over TTL.
     */

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, you meant values that ever have been set! Understood, lg

Copy link
Collaborator

@thpani thpani left a comment

Choose a reason for hiding this comment

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

Remaining comments, rest lgtm

Comment on lines 26 to 28
// https://developers.stellar.org/network/horizon/api-reference/resources/operations/object
if (op.function === 'HostFunctionTypeHostFunctionTypeInvokeContract') {
// This operation represents a smart contract call.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't you just return none if !==.
Bit hard to follow controlflow here with the indentation.

const method = params[1]
const methodArgs = params.slice(2)

const tx = await op.transaction()
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is weird. Is it really async?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, it looks async. Basically, SDK makes another call to the server.

const methodArgs = params.slice(2)

const tx = await op.transaction()
// is it the right way to extract the height?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean, yeah. I hope someone more knowledgeable would read it tells me to fix it :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added TODO: for the future

`Expected TransactionMetaV3, found ${meta.switch()}: txHash = ${txHash}`
)
return none()
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also here, I don't think you need to nest inside else, since you return above?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, good catch. It grew too large organically. Pruned it

@konnov
Copy link
Contributor Author

konnov commented May 16, 2024

I will merge this one to continue with the storage.

@konnov konnov merged commit 38d57fd into main May 16, 2024
3 checks passed
@konnov konnov deleted the igor/fetcher-loop branch May 16, 2024 12:05
@konnov konnov mentioned this pull request May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants