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

bug: getrawtransaction output conflicts with zcashd output #8744

Open
4 tasks
str4d opened this issue Aug 5, 2024 · 5 comments
Open
4 tasks

bug: getrawtransaction output conflicts with zcashd output #8744

str4d opened this issue Aug 5, 2024 · 5 comments
Assignees
Labels
C-bug Category: This is a bug S-needs-triage Status: A bug report needs triage

Comments

@str4d
Copy link
Contributor

str4d commented Aug 5, 2024

What happened?

zcashd's getrawtransaction API is inherited from Bitcoin Core, and thus its behaviour around general transaction properties (as opposed to Zcash-specific properties) is likely ossified within the wider ecosystem (in particular for exchanges). In particular, the way it sets the confirmations field has been that way for many years.

In zcash/zcash@f381d4e zcashd brought in the Insight Block Explorer patches, which added a height field alongside the confirmations field. Thus everything I say below about how height is set applies equivalently to confirmations (just with different values as appropriate).

zcashd's getrawtransaction sets height in one of three ways:

zebrad does not implement this API, and instead sets height as follows:

  • If the transaction is in the main chain, height is set to the height of the block it was mined in.

    zebra/zebra-rpc/src/methods.rs

    Lines 1019 to 1028 in 16168d7

    zebra_state::ReadResponse::Transaction(Some(MinedTx {
    tx,
    height,
    confirmations,
    })) => Ok(GetRawTransaction::from_transaction(
    tx,
    Some(height),
    confirmations,
    verbose,
    )),

    zebra/zebra-rpc/src/methods.rs

    Lines 1692 to 1698 in 16168d7

    height: match height {
    Some(height) => height
    .0
    .try_into()
    .expect("valid block heights are limited to i32::MAX"),
    None => -1,
    },

  • If the transaction is in the mempool, height is set to -1.

    return Ok(GetRawTransaction::from_transaction(tx, None, 0, verbose));

  • If the transaction is not in the mempool and not in the main chain, but is still recognized due to being mined in a block that is currently orphaned (in a non-main chain), zebrad reports Err("transaction not found") because non-main chain blocks are not included in zebra_state::ReadResponse::Transaction.

    zebra/zebra-rpc/src/methods.rs

    Lines 1029 to 1031 in 16168d7

    zebra_state::ReadResponse::Transaction(None) => {
    Err("Transaction not found").map_server_error()
    }

What were you doing when the issue happened?

Debugging lightwalletd, which itself is misusing the output of getrawtransaction from zcashd: zcash/librustzcash#1473 (comment)

Zebra logs

No response

Zebra Version

No response

Which operating systems does the issue happen on?

  • Linux
  • macOS
  • Windows
  • Other OS

OS details

No response

Additional information

No response

@str4d str4d added C-bug Category: This is a bug S-needs-triage Status: A bug report needs triage labels Aug 5, 2024
@str4d
Copy link
Contributor Author

str4d commented Aug 5, 2024

This is also effectively a subset of #8646.

@daira
Copy link
Contributor

daira commented Aug 5, 2024

The fact that zebrad behaves differently than zcashd, but presumably lightwalletd clients do not adapt their behaviour to the backing node type, is further evidence to me that we cannot fix this in a backward-compatible way and shouldn't worry about doing so when changing lightwalletd.

@mpguerra
Copy link
Contributor

mpguerra commented Aug 6, 2024

We're going to wait until we're ready for NU6 testnet activation before prioritising this one

@nuttycom
Copy link

We also identified that the error codes returned from getrawtransaction in the case that the transaction is not found do not correspond to those from zcashd:

~/work/lightwalletd on ᚠfix/get_transaction_notfound [$] via 🐹 v1.22.2 on ☁️   [email protected](us-east1)
✗ grpcurl -d @ na-lax.zcashd.zec.rocks:443 cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction <<EOM
{"hash": "OVmYYbd17odbutVyi9YaHZqAbyBzixVG6q/wTdwgEFM="}
EOM
ERROR:
  Code: Unknown
  Message: -5: No such mempool or blockchain transaction. Use gettransaction for wallet transactions.

~/work/lightwalletd on ᚠfix/get_transaction_notfound [$] via 🐹 v1.22.2 on ☁️   [email protected](us-east1)
✗ grpcurl -d @ zec.rocks:443 cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction <<EOM
{"hash": "OVmYYbd17odbutVyi9YaHZqAbyBzixVG6q/wTdwgEFM="}
EOM
ERROR:
  Code: Unknown
  Message: 0: Transaction not found

Error codes should be drawn from https://github.com/zcash/zcash/blob/master/src/rpc/protocol.h#L32-L80

@upbqdn
Copy link
Member

upbqdn commented Oct 18, 2024

  • If the transaction is not in the mempool and not in the main chain, but is still recognized due to being mined in a block that is currently orphaned (in a non-main chain), height is set to -1.

@str4d, since Zebra doesn't keep orphaned blocks below the rollback limit, do you think it'd be OK to return the error "No such mempool or blockchain transaction. Use ..." in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug S-needs-triage Status: A bug report needs triage
Projects
Status: In progress
Development

No branches or pull requests

5 participants