diff --git a/daemon/algod/api/server/v2/account.go b/daemon/algod/api/server/v2/account.go index 9c25021b9c..c722ab6825 100644 --- a/daemon/algod/api/server/v2/account.go +++ b/daemon/algod/api/server/v2/account.go @@ -26,6 +26,7 @@ import ( "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model" "github.com/algorand/go-algorand/data/basics" + "github.com/algorand/go-algorand/ledger/ledgercore" ) // AssetHolding converts between basics.AssetHolding and model.AssetHolding @@ -139,6 +140,57 @@ func AccountDataToAccount( }, nil } +// ledgercoreADToAccount converts a ledgercore.AccountData to model.Account +func ledgercoreADToAccount(addr string, amntWithoutPendingRewards uint64, rnd uint64, + consensus *config.ConsensusParams, ad ledgercore.AccountData) (model.Account, error) { + pendingRewards, overflowed := basics.OSubA(ad.MicroAlgos, basics.MicroAlgos{Raw: amntWithoutPendingRewards}) + if overflowed { + return model.Account{}, errors.New("overflow on pending reward calculation") + } + var apiParticipation *model.AccountParticipation + if ad.VoteID != (crypto.OneTimeSignatureVerifier{}) { + apiParticipation = &model.AccountParticipation{ + VoteParticipationKey: ad.VoteID[:], + SelectionParticipationKey: ad.SelectionID[:], + VoteFirstValid: uint64(ad.VoteFirstValid), + VoteLastValid: uint64(ad.VoteLastValid), + VoteKeyDilution: ad.VoteKeyDilution, + } + if !ad.StateProofID.IsEmpty() { + tmp := ad.StateProofID[:] + apiParticipation.StateProofKey = &tmp + } + } + var authAddr *string = nil + if !ad.AuthAddr.IsZero() { + authAddr = strOrNil(ad.AuthAddr.String()) + } + return model.Account{ + Address: addr, + Amount: ad.MicroAlgos.Raw, + AmountWithoutPendingRewards: amntWithoutPendingRewards, + AppsTotalExtraPages: numOrNil(uint64(ad.TotalExtraAppPages)), + AppsTotalSchema: &model.ApplicationStateSchema{ + NumUint: ad.TotalAppSchema.NumUint, + NumByteSlice: ad.TotalAppSchema.NumByteSlice, + }, + AuthAddr: authAddr, + MinBalance: ad.MinBalance(consensus).Raw, + Participation: apiParticipation, + PendingRewards: pendingRewards.Raw, + RewardBase: numOrNil(ad.RewardsBase), + Rewards: ad.RewardedMicroAlgos.Raw, + Round: rnd, + Status: ad.Status.String(), + TotalAppsOptedIn: ad.TotalAppLocalStates, + TotalAssetsOptedIn: ad.TotalAssets, + TotalBoxBytes: numOrNil(ad.TotalBoxBytes), + TotalBoxes: numOrNil(ad.TotalBoxes), + TotalCreatedApps: ad.TotalAppParams, + TotalCreatedAssets: ad.TotalAssetParams, + }, nil +} + func convertTKVToGenerated(tkv *basics.TealKeyValue) *model.TealKeyValueStore { if tkv == nil || len(*tkv) == 0 { return nil diff --git a/daemon/algod/api/server/v2/delta.go b/daemon/algod/api/server/v2/delta.go index ae1d2d43e5..4c4058fcde 100644 --- a/daemon/algod/api/server/v2/delta.go +++ b/daemon/algod/api/server/v2/delta.go @@ -19,7 +19,6 @@ package v2 import ( "errors" "fmt" - "github.com/algorand/go-algorand/config" "github.com/algorand/go-algorand/daemon/algod/api/server/v2/generated/model" "github.com/algorand/go-algorand/data/basics" @@ -101,9 +100,7 @@ func StateDeltaToLedgerDelta(sDelta ledgercore.StateDelta, consensus config.Cons return response, errors.New("overflow on pending reward calculation") } - ad := basics.AccountData{} - ledgercore.AssignAccountData(&ad, record.AccountData) - a, err := AccountDataToAccount(record.Addr.String(), &ad, basics.Round(round), &consensus, amountWithoutPendingRewards) + a, err := ledgercoreADToAccount(record.Addr.String(), amountWithoutPendingRewards.Raw, uint64(round), &consensus, record.AccountData) if err != nil { return response, err } diff --git a/daemon/algod/api/server/v2/delta_test.go b/daemon/algod/api/server/v2/delta_test.go index 31154b951d..061912ac61 100644 --- a/daemon/algod/api/server/v2/delta_test.go +++ b/daemon/algod/api/server/v2/delta_test.go @@ -48,13 +48,13 @@ func TestDelta(t *testing.T) { MicroAlgos: basics.MicroAlgos{Raw: 5000}, RewardsBase: 2, RewardedMicroAlgos: basics.MicroAlgos{Raw: 0}, - TotalExtraAppPages: 0, - TotalAppParams: 0, - TotalAppLocalStates: 0, - TotalAssetParams: 0, - TotalAssets: 0, - TotalBoxes: 0, - TotalBoxBytes: 0, + TotalExtraAppPages: 1, + TotalAppParams: 2, + TotalAppLocalStates: 3, + TotalAssetParams: 4, + TotalAssets: 5, + TotalBoxes: 6, + TotalBoxBytes: 7, }, }, }, @@ -69,7 +69,7 @@ func TestDelta(t *testing.T) { ClearStateProgram: []byte("2"), GlobalState: basics.TealKeyValue{}, StateSchemas: basics.StateSchemas{}, - ExtraProgramPages: 0, + ExtraProgramPages: 2, }, Deleted: false, }, @@ -125,6 +125,10 @@ func TestDelta(t *testing.T) { actAccDelta := (*converted.Accts.Accounts)[0] require.Equal(t, expAccDelta.Addr.String(), actAccDelta.Address) require.Equal(t, expAccDelta.Status.String(), actAccDelta.AccountData.Status) + require.Equal(t, expAccDelta.TotalAppLocalStates, actAccDelta.AccountData.TotalAppsOptedIn) + require.Equal(t, expAccDelta.TotalAppParams, actAccDelta.AccountData.TotalCreatedApps) + require.Equal(t, expAccDelta.TotalAssetParams, actAccDelta.AccountData.TotalCreatedAssets) + require.Equal(t, expAccDelta.TotalAssets, actAccDelta.AccountData.TotalAssetsOptedIn) require.Equal(t, uint64(0), actAccDelta.AccountData.PendingRewards) require.Equal(t, len(original.Accts.AssetResources), len(*converted.Accts.Assets)) expAssetDelta := original.Accts.AssetResources[0] diff --git a/daemon/algod/api/server/v2/test/helpers.go b/daemon/algod/api/server/v2/test/helpers.go index 51467b65d9..f27940f33a 100644 --- a/daemon/algod/api/server/v2/test/helpers.go +++ b/daemon/algod/api/server/v2/test/helpers.go @@ -116,13 +116,8 @@ var poolDeltaResponseGolden = model.LedgerStateDelta{ Amount: 50000000000, AmountWithoutPendingRewards: 50000000000, MinBalance: 100000, - CreatedApps: &[]model.Application{}, AppsTotalSchema: &appsTotalSchema, - AppsLocalState: &[]model.ApplicationLocalState{}, Status: "Not Participating", - RewardBase: &poolAddrRewardBaseGolden, - CreatedAssets: &[]model.Asset{}, - Assets: &[]model.AssetHolding{}, }, Address: poolAddr.String(), },