(VDB-1230) Create kiss + diss batch event transformers#150
Conversation
| address_id INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| msg_sender INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| a_length INTEGER NOT NULL, | ||
| a TEXT ARRAY NOT NULL, |
There was a problem hiding this comment.
We landed on using a Postgres array to store addresses, as hopefully this approach will be more extensible if/when we update the transformers to be able to handle arrays of more than 4 addresses.
| header_id INTEGER NOT NULL REFERENCES public.headers (id) ON DELETE CASCADE, | ||
| address_id INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| msg_sender INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| a_length INTEGER NOT NULL, |
There was a problem hiding this comment.
Thought it would be a good idea to include a_length in this table, so that we can inform clients that records with a_length > 4 will be incomplete.
There was a problem hiding this comment.
Sounds good. I'll add to lift and drop as well.
There was a problem hiding this comment.
Could you remind me why we can only have 4 addresses in a - is it because that's all the data field on a log allows? Also I wonder if we should document this somewhere, since it's kind of different than other transformers.
There was a problem hiding this comment.
Yeah exactly, an array longer than 4 gets truncated in the log data. And definitely agree that we should make sure the client is aware of this limitation; thinking I'll include something in the vdb-postgraphile docs as well as the Google Doc.
go.mod
Outdated
| github.com/gogo/protobuf v1.1.1 | ||
| github.com/howeyc/fsnotify v0.9.0 // indirect | ||
| github.com/jmoiron/sqlx v0.0.0-20181024163419-82935fac6c1a | ||
| github.com/lib/pq v1.0.0 |
There was a problem hiding this comment.
Needed this so we can insert a Go slice into Postgres as the pq.Array type. Hopefully there aren't any issues with adding a hard dependency at this stage?
There was a problem hiding this comment.
Is there a reason we are using v1.0.0 vs v.1.3.0?
There was a problem hiding this comment.
Nope, GoLand did that automatically. I'd be fine with bumping the version
| event.AddressFK: contractAddressID, | ||
| constants.MsgSenderColumn: msgSenderAddressID, | ||
| constants.ALengthColumn: strconv.FormatUint(aLength, 10), | ||
| constants.AColumn: pq.Array(aAddresses), |
There was a problem hiding this comment.
This line introduces a dependency on the pq library, and also necessitates a small change in vDB allowing this type of value to be in the ColumnValues.
There was a problem hiding this comment.
👍 if this is a problem, maybe there's a way in the sqlx library to support array input.
There was a problem hiding this comment.
Good call, I forgot about that library. I'll see if that would be a better alternative
There was a problem hiding this comment.
Found this old closed issue on the sqlx repo: jmoiron/sqlx#106. Looks like they hadn't implemented pq arrays, but were thinking about it, though I didn't notice it in sqlx/types.
| header, headerErr := persistHeader(db, blockNumber, blockChain) | ||
| Expect(headerErr).NotTo(HaveOccurred()) | ||
|
|
||
| // TODO: fetch event from blockchain once one exists |
There was a problem hiding this comment.
Thought it would be a good idea to have at least a partial integration test in this instance, since the transformer test never actually interacts with the DB, and I wanted to make sure the new Postgres array stuff worked as expected.
| return nil, logNoteErr | ||
| } | ||
| addressHex := common.BytesToAddress(logDataBytes).Hex() | ||
| addresses = append(addresses, addressHex) |
There was a problem hiding this comment.
Worth noting that we're never actually adding the addresses in this list to public.addresses. We could hypothetically return an array of address FKs rather than the addresses themselves, but Postgres can't enforce referential integrity on an array of FKs, so I thought it would be safer to just use the raw addresses.
Maybe it would make sense to add a GetOrCreateAddress line in here, just so we have it in the addresses table, even if we aren't referencing it? But I figured that would be happening in the storage transformer anyway, so there's not much need to do it here. Interested to hear people's thoughts.
There was a problem hiding this comment.
I wonder if it would be easier (for the storage key loader) if the addresses are already in public.address? 🤔 Using storageRepository.GetWardsAddresses as my mental model, but that may not be the right way to think about it.
There was a problem hiding this comment.
Good call-- definitely worth thinking about, but so far I'm not really finding that it's any tougher when the addresses aren't in public.addresses, since we pretty much always interact with that table using the GetOrCreateAddress function.
And on the storageRepository side of things, we ultimately need a list of addresses (not address IDs) for the key loader, so it's pretty easy to just query them directly from the array in median_kiss_batch/median_diss_batch without doing any joins or anything.
yaoandrew
left a comment
There was a problem hiding this comment.
Thanks for working through the array args. I like where this ended up. 🚢
| header_id INTEGER NOT NULL REFERENCES public.headers (id) ON DELETE CASCADE, | ||
| address_id INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| msg_sender INTEGER NOT NULL REFERENCES public.addresses (id) ON DELETE CASCADE, | ||
| a_length INTEGER NOT NULL, |
There was a problem hiding this comment.
Sounds good. I'll add to lift and drop as well.
|
|
||
|
|
||
| -- +goose Down | ||
| DROP TABLE maker.median_kiss_batch; |
There was a problem hiding this comment.
Its probably redundant when we DROP the table, but in other migrations we seem to be adding a DROP for each index as well in the rollback commands.
There was a problem hiding this comment.
Yeah, I've moved away from adding those statements in newer code. Like you said, they seem to be totally unnecessary.
|
|
||
| expectedModel.ColumnValues[event.AddressFK] = contractAddressID | ||
| expectedModel.ColumnValues[constants.MsgSenderColumn] = msgSenderAddressID | ||
| expectedModel.ColumnValues[constants.AColumn] = pq.Array([]string{address0, address1, address2, address3}) |
| return nil, shared.ErrCouldNotCreateFK(msgSenderAddressErr) | ||
| } | ||
|
|
||
| aLength, aLengthErr := strconv.ParseUint(log.Log.Topics[3].Hex(), 0, 64) |
| event.AddressFK: contractAddressID, | ||
| constants.MsgSenderColumn: msgSenderAddressID, | ||
| constants.ALengthColumn: strconv.FormatUint(aLength, 10), | ||
| constants.AColumn: pq.Array(aAddresses), |
There was a problem hiding this comment.
👍 if this is a problem, maybe there's a way in the sqlx library to support array input.
0934498 to
7baa4ad
Compare
2bc19d4 to
9ddcae4
Compare
elizabethengelman
left a comment
There was a problem hiding this comment.
This looks good! ![]()
| return nil, logNoteErr | ||
| } | ||
| addressHex := common.BytesToAddress(logDataBytes).Hex() | ||
| addresses = append(addresses, addressHex) |
There was a problem hiding this comment.
I wonder if it would be easier (for the storage key loader) if the addresses are already in public.address? 🤔 Using storageRepository.GetWardsAddresses as my mental model, but that may not be the right way to think about it.
| event.AddressFK: contractAddressID, | ||
| constants.MsgSenderColumn: msgSenderAddressID, | ||
| constants.ALengthColumn: strconv.FormatUint(aLength, 10), | ||
| constants.AColumn: pq.Array(aAddresses), |
There was a problem hiding this comment.
Found this old closed issue on the sqlx repo: jmoiron/sqlx#106. Looks like they hadn't implemented pq arrays, but were thinking about it, though I didn't notice it in sqlx/types.
| @@ -0,0 +1,25 @@ | |||
| -- +goose Up | |||
| CREATE TABLE maker.median_diss_batch | |||
There was a problem hiding this comment.
Looks like this file needs an updated timestamp - latest on staging is 20200403103019
There was a problem hiding this comment.
Yup! I was just about to do that :) thanks for looking out though
| @@ -0,0 +1,25 @@ | |||
| -- +goose Up | |||
| CREATE TABLE maker.median_kiss_batch | |||
kissanddissare basically carbon copies, aside from the words "kiss" and "diss" being different. I wonder if it would be worth trying to reduce duplication between events with very similar signatures; as it stands, that would take some pretty serious refactoring.