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

services/horizon: Use new ingestion data in /accounts/{account_id} #1868

Merged

Conversation

bartekn
Copy link
Contributor

@bartekn bartekn commented Oct 22, 2019

PR Checklist

PR Structure

  • This PR has reasonably narrow scope (if not, break it down into smaller PRs).
  • This PR avoids mixing refactoring changes with feature changes (split into two PRs
    otherwise).
  • This PR's title starts with name of package that is most changed in the PR, ex.
    services/friendbot, or all or doc if the changes are broad or impact many
    packages.

Thoroughness

  • This PR adds tests for the most critical parts of the new functionality or fixes.
  • I've updated any docs (developer docs, .md
    files, etc... affected by this change). Take a look in the docs folder for a given service,
    like this one.

Release planning

  • I've updated the relevant CHANGELOG (here for Horizon) if
    needed with deprecations, added features, breaking changes, and DB schema changes.
  • I've decided if this PR requires a new major/minor version according to
    semver, or if it's mainly a patch change. The PR is targeted at the next
    release branch if it's not a patch change.

Summary

This commit adds temporary code (to be removed in one of the future versions of Horizon) that compares account state in Stellar-Core and Horizon DB. If a difference is found it's logged with WARNING level.

Close #1766.
See #1726.

Known limitations & issues

  • It's possible that false alerts will happen because the old code does not use a DB transaction to get data from core DB. This means that new ledger can be applied during request is live.

Copy link
Contributor

@abuiles abuiles left a comment

Choose a reason for hiding this comment

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

@bartekn Looks good! I have a doubt though, shouldn't we check if expingestion is enabled before comparing results from both sources?

Also can we use the new pattern so the new action is used only if exp-ingestion is turned on.

@bartekn
Copy link
Contributor Author

bartekn commented Oct 28, 2019

shouldn't we check if expingestion is enabled before comparing results from both sources?

Good point, fixed and ready to review again.

Also can we use the new pattern so the new action is used only if exp-ingestion is turned on.

Not yet as we are still serving old data (and comparing with new data).

Copy link
Contributor

@abuiles abuiles left a comment

Choose a reason for hiding this comment

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

@bartekn looks good! Can you add test for the new methods on Q?

@bartekn
Copy link
Contributor Author

bartekn commented Oct 28, 2019

@abuiles great point about tests! I somehow though that I was using methods from #1835 but it's not true obviously.

@bartekn
Copy link
Contributor Author

bartekn commented Oct 30, 2019

@abuiles tests added. PTAL!

@bartekn bartekn requested a review from abuiles October 30, 2019 14:50
Copy link
Contributor

@abuiles abuiles left a comment

Choose a reason for hiding this comment

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

@bartekn LGTM! I think there is a typo, where you have two err assertions one after the other one.

assert.Equal(t, []byte(data1.DataValue), []byte(datas[0].Value))

assert.Equal(t, data2.DataName, xdr.String64(datas[1].Name))
assert.Equal(t, []byte(data2.DataValue), []byte(datas[1].Value))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: tt wraps assert, you could have tt.Assert( without having to pass t all the time.

_, err = q.InsertAccountData(data2, 1235)
assert.NoError(t, err)

datas, err := q.GetAccountDataByAccountID(data1.AccountId.Address())
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: data is already plural :), my workaround was to call this records, my mental model is that records are data from DB , which maps to Q'like structs

results, err := q.GetAccountSignersByAccountID(account)
tt.Assert.NoError(err)
tt.Assert.Len(results, 2)
tt.Assert.Equal(expected, results)
Copy link
Contributor

Choose a reason for hiding this comment

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

I've used this pattern too, something I think every time I do it is that this might break at some points because it's order dependent. I've been using the map, del and len assert approach. No strong feelings about this just an open thought -- I wonder what other patterns exists for this -- @leighmcculloch @tamirms thoughts?

Copy link
Contributor Author

@bartekn bartekn Oct 30, 2019

Choose a reason for hiding this comment

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

In this case I think we should actually sort signers so tools like horizon-cmp don't have to deal with this issue too. EDIT: added sorting to GetAccountSignersByAccountID.

tt.Assert.NoError(err)

resultAccount, err := q.GetAccountByID(account1.AccountId.Address())
assert.NoError(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

@bartekn why the double assert?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy&paste issue.

@bartekn
Copy link
Contributor Author

bartekn commented Oct 30, 2019

@abuiles PTAL!

Copy link
Contributor

@abuiles abuiles left a comment

Choose a reason for hiding this comment

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

🚀


// We send JSON bytes to compareAccountResults to prevent modifying
// `resource` in any way.
err = compareAccountResults(ctx, hq, c, addr)
Copy link
Contributor

Choose a reason for hiding this comment

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

should we check that both ingestion systems are at the same ledger before comparing results?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do check this using LastModifiedLedger in accountResourcesEqual.

}

if enableExperimentalIngestion {
c, err := json.Marshal(resource)
Copy link
Contributor

Choose a reason for hiding this comment

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

why not pass in the resource directly to compareAccountResults() ? you end up unmarshaling the bytes in compareAccountResults() so you could skip that step by sending the protocol.Account instance to compareAccountResults()

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 explained in the comments:

  // We send JSON bytes to compareAccountResults to prevent modifying
  // `resource` in any way.

It's to minimize chances of rendering data from expingest instead of stellar-core by accident. The compare code will be removed when expingest goes to production.

@bartekn bartekn merged commit 233c512 into stellar:release-horizon-v0.23.0 Oct 30, 2019
@bartekn bartekn deleted the expingest-account-details branch October 30, 2019 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants