Giter VIP home page Giter VIP logo

iota.rs's Introduction

Warning Deprecated - The client has been moved to https://github.com/iotaledger/iota-sdk

iota.rs (iota-client)

The official, general-purpose IOTA client library in Rust for interaction with the IOTA network (Tangle).

The goal of this library is to have one source code of truth, which means that there is one implementation in Rust and bindings to other programming languages.

For value transfers we recommend using wallet.rs.

This library allows you to do the following:

  • Create blocks with tagged data and transaction payloads
  • Get blocks and outputs
  • Sign transactions
  • Generate addresses
  • Interact with an IOTA node

Using the library

We recommend you to first update the Rust compiler to the latest stable version:

rustup update stable

The nightly Rust compiler should be fine but some changes might not be compatible.

Also for Linux libudev is needed for the ledger_nano feature and can be installed with apt install libudev-dev.

Add iota-client as a dependency in Cargo.toml:

[dependencies]
iota-client = "2.0.1-rc.6"

Or, for the latest changes:

[dependencies]
iota-client = { git = "https://github.com/iotaledger/iota.rs", branch = "develop" }

Then, use the library in code with:

// Note that the hyphen is replaced with an underscore
use iota_client;

Limitations

  • When using the mqtt feature, connecting to a MQTT broker using raw IP doesn't work with TCP. This is a limitation of rustls.

Examples

You can see examples using the library in the examples directory. Try them with:

# cargo run --example <name of the example without .rs>
cargo run --example node_api_core_get_info

For examples where a seed is required (e.g. 01_generate_addresses) you need to create a .env file under the current directory. You can do so by renaming .env.example to .env.

API reference

You can read the API reference here, or generate it yourself.

If you'd like to explore the implementation in more depth, the following command generates docs for the whole crate, including private modules:

cargo doc --document-private-items --no-deps --open

Bindings

Bindings to other programming languages are available under the folder bindings.

Joining the discussion

If you want to get involved in the community, need help with setting up, have any issues or just want to discuss IOTA with other people, feel free to join our Discord in the #client-libs channel.

License

The Apache 2.0 license can be found here.

iota.rs's People

Contributors

adrian-grassl avatar bernardoaraujor avatar bingyanglin avatar cvarley100 avatar cycraig avatar dependabot[bot] avatar dr-electron avatar fijter avatar github-actions[bot] avatar goodengineer avatar hribek25 avatar huhn511 avatar jkuruvilla avatar jyhi avatar laumair avatar lucas-tortora avatar lucasfernog avatar maxwellmattryan avatar melatron avatar njaremko avatar oddgrd avatar pelumi-ajayi avatar philippgackstatter avatar pvdrz avatar r-c-k avatar rajivshah3 avatar samuel-rufi avatar thibault-martinez avatar thoralf-m avatar tuditi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iota.rs's Issues

It's not possible to create value transactions ...

but messages transactions (value=0) works.

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /home/xxx/.cargo/registry/src/github.com-1ecc6299db9ec823/iota-model-0.3.0/bundle.rs:96:18

This part of the code is wrong

pub fn add_trytes(&mut self, signature_fragments: &[String]) {
    let empty_signature_fragment = "9".repeat(2187);
    let empty_hash = EMPTY_HASH;
    let empty_timestamp = 999_999_999;

    for (i, bundle) in self.0.iter_mut().enumerate() {
        let new_sig = if signature_fragments.is_empty() || signature_fragments[i].is_empty() {
            &empty_signature_fragment
        } else {
            &signature_fragments[i]
        };

It's not possible to use the index of the bundle iteration to access the signature_fragments!

WASM bindings fail to build

Bug description

Building bindings/wasm fails.

Specification

macOS Catalina 10.15.4
What hardware are you using?

Steps To reproduce the bug

Explain how the maintainer can reproduce the bug.

  1. Navigate to bindings/wasm/
  2. Run yarn

Expected behaviour

It should successfully build for node & web platforms

Actual behaviour

Running yarn build fails with the following error:

yarn run v1.21.1
$ yarn build:web && yarn build:nodejs
$ wasm-pack build --target web --out-dir wasm-web && node ./build/web
[INFO]: ๐ŸŽฏ  Checking for the Wasm target...
[INFO]: ๐ŸŒ€  Compiling to Wasm...
   Compiling clear_on_drop v0.2.3
   Compiling serde_json v1.0.53
   Compiling wasm-bindgen-macro v0.2.62
   Compiling iota-common-preview v0.1.0
   Compiling failure v0.1.8
error: failed to run custom build command for `clear_on_drop v0.2.3`

Caused by:
  process didn't exit successfully: `/Users/foo/workspace/iota.rs/bindings/wasm/target/release/build/clear_on_drop-5c1a578bdb052915/build-script-build` (exit code: 1)
--- stdout
TARGET = Some("wasm32-unknown-unknown")
OPT_LEVEL = Some("3")
HOST = Some("x86_64-apple-darwin")
CC_wasm32-unknown-unknown = None
CC_wasm32_unknown_unknown = None
TARGET_CC = None
CC = None
CFLAGS_wasm32-unknown-unknown = None
CFLAGS_wasm32_unknown_unknown = None
TARGET_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("false")
running: "clang" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-o" "/Users/umairsarfraz/workspace/iota.rs/bindings/wasm/target/wasm32-unknown-unknown/release/build/clear_on_drop-e6a0d73c7f42615d/out/src/hide.o" "-c" "src/hide.c"
cargo:warning=error: unable to create target: 'No available targets are compatible with triple "wasm32-unknown-unknown"'
cargo:warning=1 error generated.
exit code: 1

--- stderr


error occurred: Command "clang" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-Wall" "-Wextra" "-o" "/Users/umairsarfraz/workspace/iota.rs/bindings/wasm/target/wasm32-unknown-unknown/release/build/clear_on_drop-e6a0d73c7f42615d/out/src/hide.o" "-c" "src/hide.c" with args "clang" did not execute successfully (status code exit code: 1).



warning: build failed, waiting for other jobs to finish...
error: build failed
Error: Compiling your crate to WebAssembly failed
Caused by: failed to execute `cargo build`: exited with exit code: 101
  full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Use the Latest Bee Crates

Currently the bee crates already made some breaking changes, including

  1. Need to switch to chrysalis-pt-2 branch.
  2. Traits moved from the bee-common-ext to bee-common (like Packable).
  3. The message builder and its fields has been enhanced.

w/o updating the corresponding iota.rs codes, the iota.rs cannot even compile if we use the latest bee crates.

Re-export bee crates

We should re-export the crates users need to handle API. Add examples to show how to use them

Required APIs for Quorum module

Not all apis need to be verified from multiple nodes. Here's the list what we need at most:

  • find_transactions
  • get_balances*
  • get_bundle
  • get_inclusion_states
  • get_inputs
  • get_latest_inclusion*
  • get_latest_solid_subtangle_milestone
  • get_new_address
  • get_trytes
  • is_address_used
  • is_promotable
  • traverse_bundle
  • were_addresses_spent_from*

*apis have quorum support in trinity #82

failed to select a version for `quote`

failed to select a version for `quote`.
    ... required by package `serde_derive v1.0.110`
    ... which is depended on by `serde v1.0.110`
    ... which is depended on by `bee-ternary v0.1.0-alpha (https://github.com/iotaledger/bee.git#1f89702a)`
    ... which is depended on by `bee-crypto v0.1.0-alpha (https://github.com/Alex6323/bee-p.git#ccf02e4e)`
    ... which is depended on by `bee-signing v0.1.0-alpha (https://github.com/Alex6323/bee-p.git#ccf02e4e)`
    ... which is depended on by `bee-transaction v0.1.0-alpha (https://github.com/Alex6323/bee-p.git#ccf02e4e)`
    ... which is depended on by `iota-client v0.5.0-alpha.3 (\iota.rs\iota-client)`
    ... which is depended on by `iota-core v0.2.0-alpha.3 (\iota.rs\iota-core)`
    ... which is depended on by `examples v0.0.0 (\iota.rs\examples)`
versions that meet the requirements `= 1.0.5` are: 1.0.5

Implementation of retry, reattach & promote methods

The library currently misses the implementation of the following methods:

The implementation details are added to the specification document. For a reference implementation, see:

Related: #150

/cc @cvarley100 @fijter @bingyanglin @wusyong

[README]: add notes about bindings

The readme doesn't make notice of the fact that the WASM binding is now available at NPM. This can be discovered by navigating to bindings/wasm, but in my opinion should be clear from the root readme.

iota-ternary

Current interface of ternary crate is not that user friendly. We should define a higher abstraction instead of raw re-export. So it can be easier to work with.

client: Core API test cases.

  • add_neighbors
  • attach_to_tangle
  • broadcast_transactions
  • check_consistency
  • find_transactions
  • get_balances
  • get_inclution_states
  • get_neighbors
  • get_node_info
  • get_tips
  • get_transactions_to_approve
  • get_trytes
  • remove_neighbors
  • store_transactions
  • were_address_spent_from

Update README

We should sync README like libraries in other languages to let users easier to start with.

Bindings: API Requests require a synced node to make successful calls

When using the library with a single unsynced client it is impossible to make API calls.

e.g. Running a single local node for testing it is never in sync, so the following code always fails

const client = new ClientBuilder()
  .node('http://localhost:14265')
  .build();
const tips = await client.getTips();

The following error is returned.

Error: ClientTask error: Client(SyncedNodePoolEmpty)

This would also mean that if a node falls out of sync for any reason you can't use the API to diagnose the problem. You can't even call getInfo.

Refactor github actions

Bring back format check and maybe also add lint check.
We probably want to use other actions that won't break on stable release.

Documentation not clear

/// This stops working after a snapshot.

I think the warning was used in the other libs because they also checked if there is an transaction on an address (also without value)

This lib only checks for balance and if an address was used for an outgoing value tx and both things are stored independent of snapshots/pruning

Readme.md is not up to date

The minimal example in the readme.md is not up to date. It uses send_transfer instead of send_transfers. Further the method is missing an argument.

It would be nice if you can fix it, since I am a rust newb and can't get it to work myself. Thank you!

Bug: Infinite loop in async call (pre-chrysalis)

Streams team is experiencing an issue where using the iota.rs library call send hangs forever
https://github.com/iotaledger/iota.rs/blob/iota-1.0/iota-client/src/client.rs#L28
It seems like the issue is in reqwest or smol after a quick investigation, but this is unconfirmed.

If you want to recreate the issue all you need to do is:
Clone https://github.com/iot2tangle/Streams-http-gateway, and cargo run --release This will give you a channel root in the terminal, take that and put it to the side for now.

Send the curl command they have in their readme and run it 30-40 times to put some data into the channel
Clone https://github.com/iot2tangle/Example-streams-subscriber and cargo run --release [channel root here]

It will find just over 20 of the messages, and then it hangs
When we breakpoint our way through the process, we found that it was hanging on the findTransactions or getTrytes call from the iota.rs side while it uses the response! macro. Since it does this, and we await the response, our streams subscriber instance stalls out, and then so does the Example-Streams-Subscriber.
Because it doesn't return an error or an actual response, it's stuck awaiting forever

So the workaround we are thinking of applying is to timeout our calls to the client so that if it hangs, we can kill the call and return a timeout error on our end, as we've already tried adding a timeout into the client library itself, but it feels like it's just putting a bandaid on a potentially critical problem. On our end we do not utilize the async calls asynchronously, we await each one

We have tested this with different nodes.

Actual findings: (Dyrell)
24 successful rounds of 5 calls (4 find transactions and 1 get tryte)
then fails on the 4/5 call every time on the 25th round (so 124 seems to mean something?)

After inspecting network traffic with wireshark:
Red: Streams instance calls, Blue: Node responses
Small Responses: findTransactions, Big responses: getTrytes
PDF with data: packets.pdf
Explanation: All requests have a response, then the very last message (1124) is the FIN packet we send as there's no more connection (FIN ACK wasnt caught). Findings: All requests are send and we receive responses)


Actual findings: (Brord)
Example: Run the following in Example-streams-subscriber: cargo run --release 85f4e5ceedbab180cc7b2f117b86eaac2cf113b1a73d17bf90de1e44d7464c690000000000000000:b0a612fce2b888182963e792

It will stall out after receiving 17 messages, when fetching the data of the 18th. It finds the hash and then continues to call get_trytes, on which it stalls forever. (https://github.com/iotaledger/iota.rs/blob/iota-1.0/iota-client/src/client.rs#L342)

To clarify; it goes into our get_bundles method, does find_transactions, goes through handle_client_result, and passes the ensure!. Then it calls get_trytes and we wait forever.
streams get_bundles method: https://github.com/iotaledger/streams/blob/develop/iota-streams-app/src/transport/tangle/client.rs#L323

(Before sending the 18th message, it stalled on find_transactions in get_bundles, the second attempt. First time resulted in empty (no message), second one stalls)

Complete the need-to-modify/unimplemented APIs

The need-to-modify or unimplemented yet APIs follow

General API

  • find_messages(): not implemented yet, need a wrapper and use the already implemented low-level APIs.
  • get_address_balances(): Not implemented yet, need a wrapper and use the already implemented low-level APIs.
  • retry(): Not implemented yet.

Full Node API

  • find_outputs(): Not implemented yet, need a wrapper and use the already implemented low-level APIs.
  • find_addresses(): Need rename it from get_addresses().
  • reattach(): Not implemented yet.
  • promote(): Not implemented yet.

All of the above are documented in the specification and should be implemented.

iota-transaction

Current interface of bundle crate is not that user friendly. We should define a higher abstraction instead of raw re-export. So it can be easier to work with.

Support message transfer

Deliver messages is not available for now. We should bring it back with message can be more than one transaction long.

get_node_info doesn't work with hornet

use iota_client;

fn main() {
  println!("{:#?}", iota_client::get_node_info("https://nodes.comnet.thetangle.org".to_string()).unwrap());
}

thread 'main' panicked at 'called Result::unwrap() on an Err value: Error(Json(Error("missing field appName", line: 1, column: 80)))', C:\Users\Boss.cargo\registry\src\github.com-1ecc6299db9ec823\iota-client-0.1.0\lib.rs:272:44

Align send() API with specification

Current send() implementation does not support the following parameters for a message with value transaction

  1. output (Users can manually pick their own output instead of having node decide on which output should be used.)
  2. indexation_key (An optional indexation key of the indexation payload.)
  3. data (An optional indexation data of the indexation payload.)

Also, current output parameter in the send() is actually the address parameter defined in the spec, which is needed to be rename as address.

infra: Add warning lints to crates

As @Alex6323 proposed previously, here's the lints tokio also uses. If this good to everyone, I'll start doing it.

#![warn(
    missing_debug_implementations,
    missing_docs,
    rust_2018_idioms,
    unreachable_pub
)]

Higher level client module

Current client type is still fairly low level. We should provider a higher level abstraction for users. For now we want to have a node pool to let us choose random nodes, and a quorum setting to control how many nodes should it queries and how many should be considered as confirmed. The basic building structure looks like this:

struct IotaBuilder {
    node_pool: Vec<Url>, // Url type from hyper
    network: Network, // Network enum
    mwm: u8,
    quorum_size: usize,
    quorum_threshold: u8, // I don't like floating point here, maybe this can present as percentage.
}

impl IotaBuilder {
    // Fields will have default value when initializing
    fn new() -> IotaBuilder {
        IotaBuilder {
            node_pool: Default::default(),
            network: Network::Main,
            mwm: 14,
            quorum_size: 1
            quorum_threshold: 50,
        }
    }

    fn add_node(&self, node: Url) {
        self.node_pool.push(Url);
    }

    fn add_node_list() {
        todo!()
    }

    fn add_node_pool() {
        todo!()
    }

    // The instance is created here.
    fn build() -> Iota {
        todo!()
    }
}

Correct parameter/returned types in the spec

  1. In get_unspent_address(), the type of the returned tuple should be (Address, usize).
  2. in get_output(), the input parameter type should be UTXOInput, and the returned type should be OutputMetadata

Rename project name to iota.rs

Since it's now under official Github, maybe it's a good time to rename it to be same as other language libraries like iota.js, iota.go etc. Perhaps revise README.md is also needed? ๐Ÿค”

Better error handling

We use anyhow to easily propagate error for convenience. And there are some places we just unwrap/expect since we know the flow.
It would be better we have a concrete error type. And we will not need any error handling crate any more in this way.

Wasm support

This is the meta issue about wasm support. We should provide a binding crate under this workspace. The crate will provide the higher level intuitive abstraction to Javascript users.

iota.get_node_info().unwrap expects only IRI nodes.

get_node_info() expect the node to return a set of fields related to the Java Runtime, jre*, however node software such as Hornet doesn't return these fields as it uses Go.

I'm a bit of a Rust noob, so forgive the obvious solution I'm missing, but would it be best to drop these fields entirely as node software moving forward such as Bee and Hornet wont have these included.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error(Json(Error("missing field `jreAvailableProcessors`", line: 1, column: 655)))', /...../iota-client-0.3.0/client.rs:261:48
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Local POW is missing

It seems like we lost the local POW functionality that was present in the old iota-lib-rs. Will it be reimplemented?

trytes_converter only handles ASCII

Is there a reason why we can't just convert arbitrary binary data to trytes? The whole trytes_converter module seems overly complex to me, why do we have to use manual lookup tables from ascii to numerical values instead of just using str.bytes and converting? The latter change would also allow us to convert utf-8 to trytes.

traverse_bundle() fails with "Invalid tail transaction supplied"

I want to read the message from the transaction I sent.
Everything works fine if the message fits into a single transaction.
For larger messages I always get the error message "Invalid tail transaction supplied"

This line in traverse_bundle() seems to be the cause
ensure!(tx.current_index == 0, "Invalid tail transaction supplied.");

You cannot make this comparison >>> 'current_index == 0' <<< if you call this function recursively ...

Wrong assumption that sec-levels above 3 is invalid

I looked at the client-code, and at the getNewAddress-function and discovered a flaw compared to how the protocol has worked earlier.
There has never been any problems using security-levels above 3, they just don't gine any added security, but an address generated with securitylevel 4 or 5 would just need as many tx'es to publish the signature, and all parts of it would then be used to verify the signature.

At least this worked with IRI, and there has not been any mentions about changes in support for sec-levels above 3
samplebundle is KWCSPUKCALYCDPRGDWEVSU9HRIJWUDCXJCDYPCZZJSBDY9SYR9H9X99QWUHPLDDY9UVSBWAKHAZFKSCCC
just sendt and verified by hornet-nodes from an address created with sec-level 5 (using the old java-libs)

GetNodeInfoResponse is incomplete and outdated

GetNodeInfoResponse {
    app_name: "HORNET",  
    app_version: "0.5.0",
    jre_available_processors: None,
    jre_free_memory: None,
    jre_max_memory: None,
    jre_total_memory: None,
    jre_version: None,
    latest_milestone: "RJKTKKROBIWONMGTMQBXFMZUAHRBOLJOBTEHAAZFI9OV9HQRKODILCEURPUWXNQDDPVEAHX9GJIVDW999",
    latest_milestone_index: 827485,
    latest_solid_subtangle_milestone: "RJKTKKROBIWONMGTMQBXFMZUAHRBOLJOBTEHAAZFI9OV9HQRKODILCEURPUWXNQDDPVEAHX9GJIVDW999",
    latest_solid_subtangle_milestone_index: 827485,
    milestone_start_index: 827177,
    neighbors: 3,
    packets_queue_size: None,
    time: 1598358375000,
    tips: 100,
    transactions_to_request: 0,
}

For comparison the result you get from the iota.js lib

{
 "appName": "HORNET",
 "appVersion": "0.5.1",
 "latestMilestone": "WK9SYZVXUNHERXALUCBLCJIKBNTKGUKADZKQMY9TMRHLFLQNXQOYRXZH9PJGVUPXKBSPWCJTTWFX99999",
 "latestMilestoneIndex": 1589390,
 "latestSolidSubtangleMilestone": "WK9SYZVXUNHERXALUCBLCJIKBNTKGUKADZKQMY9TMRHLFLQNXQOYRXZH9PJGVUPXKBSPWCJTTWFX99999",
 "latestSolidSubtangleMilestoneIndex": 1589390,
 "isSynced": true,
 "isHealthy": true,
 "milestoneStartIndex": 1587019,
 "lastSnapshottedMilestoneIndex": 1587019,
 "neighbors": 24,
 "time": 1598358203526,
 "tips": 146,
 "transactionsToRequest": 0,
 "features": [
  "LoadBalancer",
  "RemotePOW",
  "WereAddressesSpentFrom"
 ],
 "coordinatorAddress": "UDYXTZBE9GZGPM9SSQV9LTZNDLJIZMPUVVXYXFYVBLIEUHLSEWFTKZZLXYRHHWVQV9MNNX9KZC9D9UZWZ",
 "duration": 0
}

Necessary APIs for Quorum module

Here are the api in Trinity that need quorum support. The first module implementation should start with these at least:

  • get_balances*
  • get_latest_inclusion*
  • were_addresses_spent_from*

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.