From 5cc9ba6816c7e47ddf10004fcfc674093cda3623 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Thu, 16 Dec 2021 17:32:23 -0800 Subject: [PATCH 1/8] #4095: added absBeforeEpoch to ClaimableBalance JSON resource model --- xdr/json.go | 28 +++++++++++++++++++--------- xdr/json_test.go | 14 +++++++------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/xdr/json.go b/xdr/json.go index 78915e0afb..2063a15963 100644 --- a/xdr/json.go +++ b/xdr/json.go @@ -60,13 +60,22 @@ func (t *iso8601Time) UnmarshalJSON(b []byte) error { return nil } +func (t iso8601Time) Epoch() int64 { + return t.UTC().Unix() +} + +func Newiso8601Time(epoch int64) *iso8601Time { + return &iso8601Time{time.Unix(epoch, 0).UTC()} +} + type claimPredicateJSON struct { - And *[]claimPredicateJSON `json:"and,omitempty"` - Or *[]claimPredicateJSON `json:"or,omitempty"` - Not *claimPredicateJSON `json:"not,omitempty"` - Unconditional bool `json:"unconditional,omitempty"` - AbsBefore *iso8601Time `json:"abs_before,omitempty"` - RelBefore *int64 `json:"rel_before,string,omitempty"` + And *[]claimPredicateJSON `json:"and,omitempty"` + Or *[]claimPredicateJSON `json:"or,omitempty"` + Not *claimPredicateJSON `json:"not,omitempty"` + Unconditional bool `json:"unconditional,omitempty"` + AbsBefore *iso8601Time `json:"abs_before,omitempty"` + AbsBeforeEpoch *int64 `json:"abs_before_epoch,string,omitempty"` + RelBefore *int64 `json:"rel_before,string,omitempty"` } func convertPredicatesToXDR(input []claimPredicateJSON) ([]ClaimPredicate, error) { @@ -93,7 +102,7 @@ func (c claimPredicateJSON) toXDR() (ClaimPredicate, error) { result.Type = ClaimPredicateTypeClaimPredicateBeforeRelativeTime result.RelBefore = &relBefore case c.AbsBefore != nil: - absBefore := Int64((*c.AbsBefore).UTC().Unix()) + absBefore := Int64(c.AbsBefore.Epoch()) result.Type = ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime result.AbsBefore = &absBefore case c.Not != nil: @@ -152,8 +161,9 @@ func (c ClaimPredicate) toJSON() (claimPredicateJSON, error) { payload.Not = new(claimPredicateJSON) *payload.Not, err = c.MustNotPredicate().toJSON() case ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime: - payload.AbsBefore = new(iso8601Time) - *payload.AbsBefore = iso8601Time{time.Unix(int64(c.MustAbsBefore()), 0).UTC()} + payload.AbsBefore = Newiso8601Time(int64(c.MustAbsBefore())) + payload.AbsBeforeEpoch = new(int64) + *payload.AbsBeforeEpoch = payload.AbsBefore.Epoch() case ClaimPredicateTypeClaimPredicateBeforeRelativeTime: payload.RelBefore = new(int64) *payload.RelBefore = int64(c.MustRelBefore()) diff --git a/xdr/json_test.go b/xdr/json_test.go index 5576c621ad..1e72912ee7 100644 --- a/xdr/json_test.go +++ b/xdr/json_test.go @@ -46,7 +46,7 @@ func TestClaimPredicateJSON(t *testing.T) { assert.NoError(t, err) assert.JSONEq( t, - `{"and":[{"or":[{"rel_before":"12"},{"abs_before":"2020-08-26T11:15:39Z"}]},{"not":{"unconditional":true}}]}`, + `{"and":[{"or":[{"rel_before":"12"},{"abs_before":"2020-08-26T11:15:39Z","abs_before_epoch":"1598440539"}]},{"not":{"unconditional":true}}]}`, string(serialized), ) @@ -99,28 +99,28 @@ func TestAbsBeforeTimestamps(t *testing.T) { }{ { 0, - `{"abs_before":"1970-01-01T00:00:00Z"}`, + `{"abs_before":"1970-01-01T00:00:00Z","abs_before_epoch":"0"}`, }, { 900 * year, - `{"abs_before":"2869-05-27T00:00:00Z"}`, + `{"abs_before":"2869-05-27T00:00:00Z","abs_before_epoch":"28382400000"}`, }, { math.MaxInt64, - `{"abs_before":"+292277026596-12-04T15:30:07Z"}`, + `{"abs_before":"+292277026596-12-04T15:30:07Z","abs_before_epoch":"9223372036854775807"}`, }, { -10, - `{"abs_before":"1969-12-31T23:59:50Z"}`, + `{"abs_before":"1969-12-31T23:59:50Z","abs_before_epoch":"-10"}`, }, { -9000 * year, - `{"abs_before":"-7025-12-23T00:00:00Z"}`, + `{"abs_before":"-7025-12-23T00:00:00Z","abs_before_epoch":"-283824000000"}`, }, { math.MinInt64, // this serialization doesn't make sense but at least it doesn't crash the marshaller - `{"abs_before":"+292277026596-12-04T15:30:08Z"}`, + `{"abs_before":"+292277026596-12-04T15:30:08Z","abs_before_epoch":"-9223372036854775808"}`, }, } { xdrSec := Int64(testCase.unix) From 728f5b3df34c9ed6f47b3ca2127023aa4484570d Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Thu, 16 Dec 2021 19:29:59 -0800 Subject: [PATCH 2/8] #4095: added more test coverage on json serialization for absBeforeEpoch --- .../claimable_balances_test.go | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/services/horizon/internal/resourceadapter/claimable_balances_test.go b/services/horizon/internal/resourceadapter/claimable_balances_test.go index d83b6036c1..1bab806bdc 100644 --- a/services/horizon/internal/resourceadapter/claimable_balances_test.go +++ b/services/horizon/internal/resourceadapter/claimable_balances_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestPopulateClaimableBalance(t *testing.T) { +func TestPopulateClaimableBalanceUnconditional(t *testing.T) { tt := assert.New(t) ctx, _ := test.ContextWithLogBuffer() resource := ClaimableBalance{} @@ -21,6 +21,12 @@ func TestPopulateClaimableBalance(t *testing.T) { Type: xdr.ClaimableBalanceIdTypeClaimableBalanceIdTypeV0, V0: &xdr.Hash{1, 2, 3}, } + unconditional := &xdr.ClaimPredicate{ + Type: xdr.ClaimPredicateTypeClaimPredicateUnconditional, + } + relBefore := xdr.Int64(12) + absBefore := xdr.Int64(1598440539) + id, err := xdr.MarshalHex(&balanceID) tt.NoError(err) claimableBalance := history.ClaimableBalance{ @@ -32,7 +38,26 @@ func TestPopulateClaimableBalance(t *testing.T) { { Destination: "GC3C4AKRBQLHOJ45U4XG35ESVWRDECWO5XLDGYADO6DPR3L7KIDVUMML", Predicate: xdr.ClaimPredicate{ - Type: xdr.ClaimPredicateTypeClaimPredicateUnconditional, + Type: xdr.ClaimPredicateTypeClaimPredicateAnd, + AndPredicates: &[]xdr.ClaimPredicate{ + { + Type: xdr.ClaimPredicateTypeClaimPredicateOr, + OrPredicates: &[]xdr.ClaimPredicate{ + { + Type: xdr.ClaimPredicateTypeClaimPredicateBeforeRelativeTime, + RelBefore: &relBefore, + }, + { + Type: xdr.ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime, + AbsBefore: &absBefore, + }, + }, + }, + { + Type: xdr.ClaimPredicateTypeClaimPredicateNot, + NotPredicate: &unconditional, + }, + }, }, }, }, @@ -74,5 +99,5 @@ func TestPopulateClaimableBalance(t *testing.T) { predicate, err := json.Marshal(resource.Claimants[0].Predicate) tt.NoError(err) - tt.JSONEq(`{"unconditional":true}`, string(predicate)) + tt.JSONEq(`{"and":[{"or":[{"rel_before":"12"},{"abs_before":"2020-08-26T11:15:39Z","abs_before_epoch":"1598440539"}]},{"not":{"unconditional":true}}]}`, string(predicate)) } From 59e378b95afb837c5a96c5a05ebf03a1d70f9432 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Thu, 16 Dec 2021 19:38:43 -0800 Subject: [PATCH 3/8] #4095: added changelog for absBeforeEpoch --- services/horizon/CHANGELOG.md | 4 +++- .../internal/resourceadapter/claimable_balances_test.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/services/horizon/CHANGELOG.md b/services/horizon/CHANGELOG.md index 1e761f9f4c..ca07278d50 100644 --- a/services/horizon/CHANGELOG.md +++ b/services/horizon/CHANGELOG.md @@ -6,7 +6,9 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased * Generate Http Status code of 499 for Client Disconnects, should propagate into `horizon_http_requests_duration_seconds_count` - metric key with status=499 label. ([4098](horizon_http_requests_duration_seconds_count)) + metric key with status=499 label. ([4098](https://github.com/stellar/go/pull/4098)) + +* Added `absBeforeEpoch` to ClaimableBalance API Resources. It will contain the Unix epoch representation of absolute before date. ([TBD](TBD)) ## v2.12.1 diff --git a/services/horizon/internal/resourceadapter/claimable_balances_test.go b/services/horizon/internal/resourceadapter/claimable_balances_test.go index 1bab806bdc..c7525b828b 100644 --- a/services/horizon/internal/resourceadapter/claimable_balances_test.go +++ b/services/horizon/internal/resourceadapter/claimable_balances_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestPopulateClaimableBalanceUnconditional(t *testing.T) { +func TestPopulateClaimableBalance(t *testing.T) { tt := assert.New(t) ctx, _ := test.ContextWithLogBuffer() resource := ClaimableBalance{} From ce2c8d68b9d5cce89b7a42c055d7715ee931b520 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Thu, 16 Dec 2021 21:35:26 -0800 Subject: [PATCH 4/8] #4095: updated changelog for absBeforeEpoch --- services/horizon/CHANGELOG.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/horizon/CHANGELOG.md b/services/horizon/CHANGELOG.md index ca07278d50..cfbc00a6b4 100644 --- a/services/horizon/CHANGELOG.md +++ b/services/horizon/CHANGELOG.md @@ -5,9 +5,6 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased -* Generate Http Status code of 499 for Client Disconnects, should propagate into `horizon_http_requests_duration_seconds_count` - metric key with status=499 label. ([4098](https://github.com/stellar/go/pull/4098)) - * Added `absBeforeEpoch` to ClaimableBalance API Resources. It will contain the Unix epoch representation of absolute before date. ([TBD](TBD)) ## v2.12.1 From 3c1f031c5d0d3334a45dd2a2d89aaaf3a004d904 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Fri, 17 Dec 2021 11:43:00 -0800 Subject: [PATCH 5/8] #4095: access epoch from xdr direct rather than helper function --- xdr/json.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xdr/json.go b/xdr/json.go index 2063a15963..b4a85ae407 100644 --- a/xdr/json.go +++ b/xdr/json.go @@ -102,7 +102,7 @@ func (c claimPredicateJSON) toXDR() (ClaimPredicate, error) { result.Type = ClaimPredicateTypeClaimPredicateBeforeRelativeTime result.RelBefore = &relBefore case c.AbsBefore != nil: - absBefore := Int64(c.AbsBefore.Epoch()) + absBefore := Int64(c.AbsBefore.UTC().Unix()) result.Type = ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime result.AbsBefore = &absBefore case c.Not != nil: @@ -161,9 +161,10 @@ func (c ClaimPredicate) toJSON() (claimPredicateJSON, error) { payload.Not = new(claimPredicateJSON) *payload.Not, err = c.MustNotPredicate().toJSON() case ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime: - payload.AbsBefore = Newiso8601Time(int64(c.MustAbsBefore())) + absBeforeEpoch := int64(c.MustAbsBefore()) + payload.AbsBefore = Newiso8601Time(absBeforeEpoch) payload.AbsBeforeEpoch = new(int64) - *payload.AbsBeforeEpoch = payload.AbsBefore.Epoch() + *payload.AbsBeforeEpoch = absBeforeEpoch case ClaimPredicateTypeClaimPredicateBeforeRelativeTime: payload.RelBefore = new(int64) *payload.RelBefore = int64(c.MustRelBefore()) From 69b77e345b0763f67506491f9678b7eda70a0bb1 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Fri, 17 Dec 2021 11:58:14 -0800 Subject: [PATCH 6/8] #4095: updated CHANGELOG with PR info --- services/horizon/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/horizon/CHANGELOG.md b/services/horizon/CHANGELOG.md index cfbc00a6b4..abf63a7c65 100644 --- a/services/horizon/CHANGELOG.md +++ b/services/horizon/CHANGELOG.md @@ -5,7 +5,7 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased -* Added `absBeforeEpoch` to ClaimableBalance API Resources. It will contain the Unix epoch representation of absolute before date. ([TBD](TBD)) +* Added `absBeforeEpoch` to ClaimableBalance API Resources. It will contain the Unix epoch representation of absolute before date. ([4148](https://github.com/stellar/go/pull/4148)) ## v2.12.1 From 35da09716e98ca83982bcdc76ea478ce04cb1763 Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Fri, 17 Dec 2021 14:45:55 -0800 Subject: [PATCH 7/8] #4095: use recommended pointer on absBefore from review --- xdr/json.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xdr/json.go b/xdr/json.go index b4a85ae407..753d711933 100644 --- a/xdr/json.go +++ b/xdr/json.go @@ -163,11 +163,10 @@ func (c ClaimPredicate) toJSON() (claimPredicateJSON, error) { case ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime: absBeforeEpoch := int64(c.MustAbsBefore()) payload.AbsBefore = Newiso8601Time(absBeforeEpoch) - payload.AbsBeforeEpoch = new(int64) - *payload.AbsBeforeEpoch = absBeforeEpoch + payload.AbsBeforeEpoch = &absBeforeEpoch case ClaimPredicateTypeClaimPredicateBeforeRelativeTime: - payload.RelBefore = new(int64) - *payload.RelBefore = int64(c.MustRelBefore()) + relBefore := int64(c.MustRelBefore()) + payload.RelBefore = &relBefore default: err = fmt.Errorf("invalid predicate type: " + c.Type.String()) } From 613865f5da6078bf10f9d9167b32e20aa755e47a Mon Sep 17 00:00:00 2001 From: Shawn Reuland Date: Sun, 19 Dec 2021 13:06:07 -0800 Subject: [PATCH 8/8] #4095: review feedback, clean up iso8601time usage --- xdr/json.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/xdr/json.go b/xdr/json.go index 753d711933..a22fbed0b6 100644 --- a/xdr/json.go +++ b/xdr/json.go @@ -60,11 +60,7 @@ func (t *iso8601Time) UnmarshalJSON(b []byte) error { return nil } -func (t iso8601Time) Epoch() int64 { - return t.UTC().Unix() -} - -func Newiso8601Time(epoch int64) *iso8601Time { +func newiso8601Time(epoch int64) *iso8601Time { return &iso8601Time{time.Unix(epoch, 0).UTC()} } @@ -162,7 +158,7 @@ func (c ClaimPredicate) toJSON() (claimPredicateJSON, error) { *payload.Not, err = c.MustNotPredicate().toJSON() case ClaimPredicateTypeClaimPredicateBeforeAbsoluteTime: absBeforeEpoch := int64(c.MustAbsBefore()) - payload.AbsBefore = Newiso8601Time(absBeforeEpoch) + payload.AbsBefore = newiso8601Time(absBeforeEpoch) payload.AbsBeforeEpoch = &absBeforeEpoch case ClaimPredicateTypeClaimPredicateBeforeRelativeTime: relBefore := int64(c.MustRelBefore())