-
Notifications
You must be signed in to change notification settings - Fork 502
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
Fix sum of asset in circulation in all assets endpoint #436
Conversation
Currently we hold sum of asset in circulation in `int64` variable. Given that issuer can send `MAX_INT64` of an asset to each of it's trustees it's very easy to overflow the type. This commit changes the type a variable that holds DB result for a query to `string` and adds a new function in `amount` package to convert string integer to Stellar amount.
11692c4
to
4cbce8a
Compare
@bartekn how does this affect data that is already in the table --do we need an upgrade script or an compatibility code? |
We probably need to reingest the history. |
@@ -15,7 +15,7 @@ func TestAssetsStatsQExec(t *testing.T) { | |||
Type: "credit_alphanum4", | |||
Code: "BTC", | |||
Issuer: "GC23QF2HUE52AMXUFUH3AYJAXXGXXV2VHXYYR6EYXETPKDXZSAW67XO4", | |||
Amount: 1009876000, | |||
Amount: "1009876000", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bartekn should this be 1009876000 * 10^7
= "10098760000000000"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's converted in resources.AssetStat.Populate
.
Count int32 `db:"count"` | ||
Sum int64 `db:"sum"` | ||
Count int32 `db:"count"` | ||
Sum string `db:"sum"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the query below var selectBalances = sq.Select("COUNT(*)", "COALESCE(SUM(balance), 0) as sum").From("trustlines")
will also need to change since balance
is an int so will the DB's SUM operation overflow and wil lthat return an int64
or a string
? fyi @bartekn
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point which also shows we need a test for this SUM(balance)
larger than bigint
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, it seems we're good here because postgres returns numeric
type for sum of bigint
s and balance
field in core is bigint
. But I will add the test anyway tomorrow.
@@ -128,7 +128,7 @@ type Asset struct { | |||
// AssetStat is a row in the asset_stats table representing the stats per Asset | |||
type AssetStat struct { | |||
ID int64 `db:"id"` | |||
Amount int64 `db:"amount"` | |||
Amount string `db:"amount"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will need the db upgrade script like we discussed on slack -- change the row in the assetStats table to be a character varying
instead of a bigint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
Added some inline comments. Summarizing our discussion on slack, @bartekn: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented on migrations
@@ -102,7 +102,7 @@ SET default_with_oids = false; | |||
|
|||
CREATE TABLE asset_stats ( | |||
id bigint NOT NULL, | |||
amount bigint NOT NULL, | |||
amount character varying NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this supposed to be left as-is?? @bartekn
anyone who starts a fresh install will go through both scripts so they will end up with the correct version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, latest.sql should contain the schema dump after applying all migrations. From @nullstyle:
The latest schema allows a new database to go from empty to the correct schema without all of the intermediary steps. This becomes important when you hit 50+ migrations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok good to know. so I guess there's some logic which knows when to apply latest vs migrations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikhilsaraf latest.sql
isused when you invoke horizon db init
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, just for my curiosity.. do we also then run migrations after that and how would it interact in a case where the latest.sql
already has the correct data-type for the column and we try and update it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, just for my curiosity.. do we also then run migrations after that and how would it interact in a case where the
latest.sql
already has the correct data-type for the column and we try and update it?
latest.sql
also adds rows to gorp_migrations
table which is later used by migrations code. Thanks for reminding me that I should add a new row there, fixed in fe74c26.
@@ -0,0 +1,7 @@ | |||
-- +migrate Up | |||
ALTER TABLE asset_stats | |||
ALTER COLUMN amount SET DATA TYPE character varying; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this need a "using" like below?
-- also we need this to be multiplied by 10^7
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this need a "using" like below?
I tested it, it was only required for down
migration.
also we need this to be multiplied by 10^7?
No, amount
in asset_stats
table is in stroops. We convert it to lumens in resources.AssetStat.Populate
.
@bartekn ok sounds good. this just leaves one issue to be resolved: about the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
OK, on the test front I think I need to create a new DB test scenario with a few accounts with {
"_links": {
"toml": {
"href": ""
}
},
"asset_type": "credit_alphanum4",
"asset_code": "ABC",
"asset_issuer": "GCXECIYXCLVDSGQJJEGCPR6FJVK4DR3GF655KT7LVRPXNRSMY5YILZVO",
"paging_token": "ABC_GCXECIYXCLVDSGQJJEGCPR6FJVK4DR3GF655KT7LVRPXNRSMY5YILZVO_credit_alphanum4",
"amount": "2767011611055.4327421",
"num_accounts": 3,
"flags": {
"auth_required": false,
"auth_revocable": false
}
}, I'll add a test later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Currently we hold sum of asset in circulation in
int64
variable. Giventhat issuer can send
MAX_INT64
of an asset to each of it's trustorsit's very easy to overflow the type.
This commit changes the type a variable that holds DB result for a query
to
string
and adds a new function inamount
package to convertstring integer to Stellar amount.