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

Support search by zero address. #771

Merged
merged 6 commits into from
Nov 9, 2021
Merged

Conversation

tolikzinovyev
Copy link
Contributor

Summary

Zero address is a real address and we shouldn't ignore it. People are curious about transactions in which the zero address participates.

Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

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

This looks good, 2 requests for before you merge:

  1. Rename the commit with the feature being added so that the release notes are easier to write: Support search by zero address.
  2. Add comments for each switch case about why zero is only allowed sometimes. I'm pretty sure you got them all correct, but these are subtle details so things comments like "AssetSender is optional, non-zero values indicate a clawback transaction" may help the next person reading this code.

@tolikzinovyev tolikzinovyev changed the title Write zero address in txn_participation table Support search by zero address. Nov 5, 2021
@tolikzinovyev
Copy link
Contributor Author

Thanks, done. I wonder if we need to check for zero address in buildTransactionQuery(). For example, it doesn't make sense to set address to zero and address role to AddressRoleCloseRemainderTo in TransactionFilter. Should we trust the user to construct the right request?

@codecov-commenter
Copy link

Codecov Report

Merging #771 (372c50d) into develop (7dff12e) will decrease coverage by 0.15%.
The diff coverage is 0.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #771      +/-   ##
===========================================
- Coverage    54.47%   54.31%   -0.16%     
===========================================
  Files           28       28              
  Lines         3870     3874       +4     
===========================================
- Hits          2108     2104       -4     
- Misses        1481     1489       +8     
  Partials       281      281              
Impacted Files Coverage Δ
accounting/accounting.go 0.00% <0.00%> (ø)
idb/postgres/internal/writer/writer.go 76.63% <ø> (-0.43%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7dff12e...372c50d. Read the comment docs.

@winder
Copy link
Contributor

winder commented Nov 5, 2021

Thanks, done. I wonder if we need to check for zero address in buildTransactionQuery(). For example, it doesn't make sense to set address to zero and address role to AddressRoleCloseRemainderTo in TransactionFilter. Should we trust the user to construct the right request?

In that case, we'd just return no results. Technically correct, right? I don't think we need to bother with custom error messages.

@tolikzinovyev
Copy link
Contributor Author

Thanks, done. I wonder if we need to check for zero address in buildTransactionQuery(). For example, it doesn't make sense to set address to zero and address role to AddressRoleCloseRemainderTo in TransactionFilter. Should we trust the user to construct the right request?

In that case, we'd just return no results. Technically correct, right? I don't think we need to bother with custom error messages.

No. Suppose the query is Address = zero, Role = CloseAddress. It will find a transaction where receiver is zero and close address is zero. But it will not find a transaction where receiver is non-zero and close address is zero. We could suppose the user should not make such a query. Any thoughts?

@winder
Copy link
Contributor

winder commented Nov 5, 2021

Thanks, done. I wonder if we need to check for zero address in buildTransactionQuery(). For example, it doesn't make sense to set address to zero and address role to AddressRoleCloseRemainderTo in TransactionFilter. Should we trust the user to construct the right request?

In that case, we'd just return no results. Technically correct, right? I don't think we need to bother with custom error messages.

No. Suppose the query is Address = zero, Role = CloseAddress. It will find a transaction where receiver is zero and close address is zero. But it will not find a transaction where receiver is non-zero and close address is zero. We could suppose the user should not make such a query. Any thoughts?

I'm pretty this is OK. We use the txn_participation table to identify the initial set of transactions, but then have a second filter on the jsonb to match the specific field we're looking for. I guess it might timeout if there are too many transactions li ke this for the slow jsonb filter.

@winder
Copy link
Contributor

winder commented Nov 8, 2021

@tolikzinovyev I thought about this over the weekend and think the simplest solution is to prevent using AddressRole and a zero address. In converter_utils.go : transactionParamsToTransactionFilter this should do it:

	// Don't allow address role + zero address search, there are several invalid configurations.
	if params.AddressRole != nil && params.Address != nil {
		var zeroAddr basics.Address
		if zeroAddr.String() == *params.Address {
			errorArr = append(errorArr, errInvalidZeroAddressSearch)
		}
	}

@tolikzinovyev
Copy link
Contributor Author

@tolikzinovyev I thought about this over the weekend and think the simplest solution is to prevent using AddressRole and a zero address. In converter_utils.go : transactionParamsToTransactionFilter this should do it:

	// Don't allow address role + zero address search, there are several invalid configurations.
	if params.AddressRole != nil && params.Address != nil {
		var zeroAddr basics.Address
		if zeroAddr.String() == *params.Address {
			errorArr = append(errorArr, errInvalidZeroAddressSearch)
		}
	}

Maybe only disallow address role close address, asset sender and asset close address?

@winder
Copy link
Contributor

winder commented Nov 8, 2021

@tolikzinovyev I thought about this over the weekend and think the simplest solution is to prevent using AddressRole and a zero address. In converter_utils.go : transactionParamsToTransactionFilter this should do it:

	// Don't allow address role + zero address search, there are several invalid configurations.
	if params.AddressRole != nil && params.Address != nil {
		var zeroAddr basics.Address
		if zeroAddr.String() == *params.Address {
			errorArr = append(errorArr, errInvalidZeroAddressSearch)
		}
	}

Maybe only disallow address role close address, asset sender and asset close address?

We can make it less strict in the future, for now let's keep it simple

Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

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

LGTM

@winder winder self-requested a review November 8, 2021 17:57
Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

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

I think the parameter checking should go in a different spot

ctx, "searching transactions by zero address with address role is not supported")
}
}

Copy link
Contributor

Choose a reason for hiding this comment

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

This should go into transactionParamsToTransactionFilter or si.fetchTransactions to make sure the constraint is checked for all account searches.

Copy link
Contributor Author

@tolikzinovyev tolikzinovyev Nov 8, 2021

Choose a reason for hiding this comment

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

Only LookupApplicationLogsByID() violates, which I think is fine. If we do put it in fetchTransactions(), LookupApplicationLogsByID() would return a weird error.

Copy link
Contributor

Choose a reason for hiding this comment

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

I realize that this doesn't happen in practice, but all of the other parameter checking happens in transactionParamsToTransactionFilter so it would be good to keep that together.

The fact that the app log search violates this constraint is pretty weird, but do you think it's a problem to generate an error here? The zero address probably shouldn't be making application calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

transactionParamsToTransactionFilter() is a conversion function, I don't want to put business logic there.

I think the current code is ok, especially given that no one in their right mind will use LookupApplicationLogsByID() with zero address.

Copy link
Contributor

@winder winder Nov 8, 2021

Choose a reason for hiding this comment

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

It also validates the input, there's a test in api/handlers_test.go for it also so you can add a test:

    {
      name: "Invalid zero address search",
      params: generated.SearchForTransactionsParams{
        Address:     strPtr(basics.Address{}.String()),
        AddressRole: 9,
      },
      filter:        idb.TransactionFilter{},
      errorContains: []string{errInvalidZeroAddressSearch},
    }

Could you also add the error message to error_messages.go?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the error message to error_messages.go. transactionParamsToTransactionFilter() does a couple of sanity checks, but no more. Definitely no artificial limitations should be in there.

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 think it is incorrect that

AddressRole: strPtr(addrRoleSender),
becomes idb.AddressRoleSender | idb.AddressRoleAssetSender, so I set filter.AddressRole directly and run validation that used to be in transactionParamsToTransactionFilter() after.

}

filter, err := transactionParamsToTransactionFilter(searchParams)
if err != nil {
return badRequest(ctx, err.Error())
}
filter.AddressRole = idb.AddressRoleSender
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice 👍

Copy link
Contributor

@winder winder left a comment

Choose a reason for hiding this comment

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

LGTM

@tolikzinovyev tolikzinovyev merged commit 1fdbd3f into develop Nov 9, 2021
@tolikzinovyev tolikzinovyev deleted the tolik/participation-zero branch November 9, 2021 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants