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

ledger: remove "rowid" from the public interface #5177

Merged
merged 13 commits into from
Mar 7, 2023

Conversation

icorderi
Copy link
Contributor

@icorderi icorderi commented Mar 2, 2023

Summary

  • Removed rowid from the public interface
  • Rowid is now abstracted by a different interface on. each type that required identifier.
  • This work should allow us to have different identifier content on the kv implementation of the store

Test Plan

Existing tests.

Copy link
Contributor

@AlgoAxel AlgoAxel left a comment

Choose a reason for hiding this comment

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

Looking at your failing test I think it's just a missing assert update:

        	            	expected: int64(2)
        	            	actual  : sqlitedriver.sqlRowRef(sqlitedriver.sqlRowRef{rowid:2})

Also thinking out loud about how this is implemented -- outside of unit testing, are there compilation errors if production code doesn't use the new Ref structure? Just thinking that since the Ref just an opaque interface, it might be possible to miss updates? Maybe not, hence why I'm asking out loud :)

ledger/store/trackerdb/data.go Outdated Show resolved Hide resolved
Comment on lines 385 to +386
if len(buf) > 0 && rowid.Valid {
data.Addrid = rowid.Int64
data.AcctRef = sqlRowRef{rowid.Int64}
Copy link
Contributor

Choose a reason for hiding this comment

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

Just leaving the SQL NullInt64 implementation here, since this made me curious about what it looked like:

// NullInt64 represents an int64 that may be null.
// NullInt64 implements the Scanner interface so
// it can be used as a scan destination, similar to NullString.
type NullInt64 struct {
  Int64 int64
  Valid bool // Valid is true if Int64 is not NULL
}

@codecov
Copy link

codecov bot commented Mar 2, 2023

Codecov Report

Merging #5177 (ca26aac) into master (25e8e94) will decrease coverage by 0.08%.
The diff coverage is 41.98%.

@@            Coverage Diff             @@
##           master    #5177      +/-   ##
==========================================
- Coverage   53.59%   53.52%   -0.08%     
==========================================
  Files         439      439              
  Lines       54950    54985      +35     
==========================================
- Hits        29452    29432      -20     
- Misses      23218    23263      +45     
- Partials     2280     2290      +10     
Impacted Files Coverage Δ
ledger/catchpointtracker.go 56.66% <0.00%> (-0.77%) ⬇️
ledger/store/trackerdb/data.go 81.86% <ø> (ø)
ledger/store/trackerdb/sqlitedriver/accountsV2.go 13.54% <0.00%> (-0.38%) ⬇️
...tore/trackerdb/sqlitedriver/orderedAccountsIter.go 0.00% <0.00%> (ø)
ledger/store/trackerdb/sqlitedriver/sql.go 2.88% <0.00%> (-0.21%) ⬇️
ledger/acctdeltas.go 79.08% <77.41%> (-0.16%) ⬇️
ledger/acctonline.go 77.66% <100.00%> (ø)
ledger/acctupdates.go 69.36% <100.00%> (+0.23%) ⬆️
crypto/merkletrie/trie.go 66.42% <0.00%> (-2.19%) ⬇️
crypto/merkletrie/node.go 91.62% <0.00%> (-1.87%) ⬇️
... and 7 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@icorderi icorderi removed request for jannotti and cce March 3, 2023 13:39
@icorderi
Copy link
Contributor Author

icorderi commented Mar 3, 2023

Also thinking out loud about how this is implemented -- outside of unit testing, are there compilation errors if production code doesn't use the new Ref structure? Just thinking that since the Ref just an opaque interface, it might be possible to miss updates? Maybe not, hence why I'm asking out loud :)

It's a valid point @AlgoAxel, I wasn't too happy with the auto impl of the interface for any type either.
I added some "marker" methods on each to force an explicit impl for any type that can be used as a ref.

Comment on lines +29 to +42
// AccountRef is an opaque ref to an account in the db.
type AccountRef interface {
AccountRefMarker()
}

// OnlineAccountRef is an opaque ref to an "online" account in the db.
type OnlineAccountRef interface {
OnlineAccountRefMarker()
}

// ResourceRef is an opaque ref to a resource in the db.
type ResourceRef interface {
ResourceRefMarker()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

cool idea! this will certainly help keep us from using incompatible ref types.

Tagging @cce specifically because this could be a valuable pattern in other places and I'd like to highlight it. Specifically, our Peer interface is also an opaque ref

ledger/store/trackerdb/interface.go Outdated Show resolved Hide resolved
AlgoAxel
AlgoAxel previously approved these changes Mar 3, 2023
switch err {
case nil:
if len(acctDataBuf) > 0 {
persistedAcctData := &trackerdb.PersistedAccountData{Addr: addr, Rowid: rowid}
persistedAcctData := &trackerdb.PersistedAccountData{Addr: addr, Ref: ref}
Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like more like account id, not reference

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its intended name and use is as an opaque reference to the database entry.
You can't do much with except to give it back to the database engine.
Having an opaque identifier is a bit odd. This has no meaning outside of the engine it came out of.

In the case of the account, which is the identifier, the address? or the sqlite specific rowid?

ledger/acctdeltas_test.go Show resolved Hide resolved
ledger/store/trackerdb/sqlitedriver/accountsV2.go Outdated Show resolved Hide resolved
ledger/store/trackerdb/sqlitedriver/sql.go Outdated Show resolved Hide resolved
ledger/store/trackerdb/sqlitedriver/sql.go Show resolved Hide resolved
if delta.oldResource.AcctRef != nil {
acctRef = delta.oldResource.AcctRef
} else if acctRef, ok = knownAddresses[addr]; !ok {
acctRef, err = arw.LookupAccountRowID(addr)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: LookupAccountRowID -> LookupAccountByRef
maybe a separate PR

err = protocol.Decode(resDataBuf, &persistedResData.Data)
if err != nil {
return err
}
a.updateOld(missIdx, persistedResData)
} else {
err = fmt.Errorf("empty resource record: addrid=%d, aidx=%d", addrid, aidx)
err = fmt.Errorf("empty resource record: addrid=%d, aidx=%d", acctRef, aidx)
Copy link
Contributor

Choose a reason for hiding this comment

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

what it will print out? acctRef is an interface, %d expects a number

Copy link
Contributor

Choose a reason for hiding this comment

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

func main() {
	var acctRef AccountRef
	acctRef = ar{123}

	fmt.Println("ln", acctRef)
	fmt.Printf("as num %d", acctRef)
}

gives

ln {123}
as num {123}

So the output changes but not critical looks like

@algorandskiy
Copy link
Contributor

Please followup with with a PR addrid=%d -> addrid=%s + String() method in the interface

@algorandskiy algorandskiy changed the title refactor: Remove "rowid" from the public interface ledger: remove "rowid" from the public interface Mar 7, 2023
@algorandskiy algorandskiy merged commit 7fb8ebd into algorand:master Mar 7, 2023
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