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

Minimum Account Balance in Algod #3287

Merged
merged 39 commits into from
Dec 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
c8e17b7
initial commit
Dec 8, 2021
f247cbe
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 8, 2021
f8edde8
don't run the debugger on circle
Dec 8, 2021
ee5451c
can query TEAL for stateful min_balance. Next up: get algod to do the…
Dec 9, 2021
7e4daef
adding facade, but no content
Dec 9, 2021
5dafabb
revert
Dec 9, 2021
4ed0617
remote debugging
Dec 9, 2021
88544cf
add get_endpoint_info to e2e python Goal
Dec 9, 2021
d0cacfe
add get_endpoint_info to e2e python Goal
Dec 9, 2021
1f1fc88
testing
Dec 9, 2021
bd90ea6
tests basically passing
Dec 10, 2021
035432d
simple goal e2e test is passing
Dec 10, 2021
85de603
test passing -knock on wood-
Dec 10, 2021
d6034e5
Update daemon/algod/api/algod.oas2.json
tzaffi Dec 10, 2021
3bcb8bc
better wording
Dec 10, 2021
2139807
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 10, 2021
2b7a8b5
comment on its own line
Dec 11, 2021
9edf2e0
improvments in python abi e2e test wrapper
Dec 13, 2021
aa2196b
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 13, 2021
4894d95
per reviewer suggestions - use block header instead of block + add co…
Dec 13, 2021
42adb53
longer if clearer name for execute_singleton()
Dec 13, 2021
7dd6db4
Pass one .exp test and update the README
Dec 14, 2021
9c71612
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 14, 2021
5ecd5b0
Less TEAL, more python testing comments.
Dec 14, 2021
277c6ce
notFound --> internalError
Dec 15, 2021
395a6e4
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 15, 2021
992609b
removing ABI dependency
Dec 16, 2021
d15fc97
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 16, 2021
5d20acb
remove the teal file
Dec 16, 2021
c12a0ed
Merge branch 'master' of https://github.com/algorand/go-algorand into…
Dec 16, 2021
19ed866
revert
Dec 16, 2021
19e2a40
reorder functions
Dec 16, 2021
084adf0
better endpoint description
Dec 16, 2021
125bfbf
INTERACTIVE switch at the top
Dec 16, 2021
ae82da2
revert formatting changes
Dec 16, 2021
5efca2c
more realistic consensus params
Dec 16, 2021
bb5d4a9
Per reviewer suggestions
Dec 17, 2021
c50f1f8
Update test/scripts/e2e_subs/min_balance.py
tzaffi Dec 17, 2021
af2acec
Update test/scripts/e2e_subs/min_balance.py
tzaffi Dec 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tests basically passing
  • Loading branch information
Zeph Grunschlag committed Dec 10, 2021
commit bd90ea6a36c386739a2b60482be3a443813d2d8d
2 changes: 1 addition & 1 deletion cmd/tealdbg/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ func TestLocalBalanceAdapterIndexer(t *testing.T) {
case strings.HasPrefix(r.URL.Path, accountPath):
w.WriteHeader(200)
if r.URL.Path[len(accountPath):] == brs.Addr.String() {
account, err := v2.AccountDataToAccount(brs.Addr.String(), &brs.AccountData, map[basics.AssetIndex]string{}, 100, basics.MicroAlgos{Raw: 0})
account, err := v2.AccountDataToAccount(brs.Addr.String(), &brs.AccountData, map[basics.AssetIndex]string{}, 100, basics.MicroAlgos{Raw: 0}, basics.MicroAlgos{Raw: 100000})
a.NoError(err)
accountResponse := AccountIndexerResponse{Account: account, CurrentRound: 100}
response, err := json.Marshal(accountResponse)
Expand Down
3 changes: 2 additions & 1 deletion daemon/algod/api/server/v2/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
// AccountDataToAccount converts basics.AccountData to v2.generated.Account
func AccountDataToAccount(
address string, record *basics.AccountData, assetsCreators map[basics.AssetIndex]string,
lastRound basics.Round, amountWithoutPendingRewards basics.MicroAlgos,
lastRound basics.Round, amountWithoutPendingRewards basics.MicroAlgos, minBalance basics.MicroAlgos,
) (generated.Account, error) {

assets := make([]generated.AssetHolding, 0, len(record.Assets))
Expand Down Expand Up @@ -126,6 +126,7 @@ func AccountDataToAccount(
AppsLocalState: &appsLocalState,
AppsTotalSchema: &totalAppSchema,
AppsTotalExtraPages: numOrNil(totalExtraPages),
MinBalance: minBalance.Raw,
}, nil
}

Expand Down
4 changes: 2 additions & 2 deletions daemon/algod/api/server/v2/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestAccount(t *testing.T) {
b := a.WithUpdatedRewards(proto, 100)

addr := basics.Address{}.String()
conv, err := AccountDataToAccount(addr, &b, map[basics.AssetIndex]string{}, round, a.MicroAlgos)
conv, err := AccountDataToAccount(addr, &b, map[basics.AssetIndex]string{}, round, a.MicroAlgos, basics.MicroAlgos{Raw: 100000})
require.NoError(t, err)
require.Equal(t, addr, conv.Address)
require.Equal(t, b.MicroAlgos.Raw, conv.Amount)
Expand Down Expand Up @@ -196,7 +196,7 @@ func TestAccount(t *testing.T) {
// convert the same account a few more times to make sure we always
// produce the same generated.Account
for i := 0; i < 10; i++ {
anotherConv, err := AccountDataToAccount(addr, &b, map[basics.AssetIndex]string{}, round, a.MicroAlgos)
anotherConv, err := AccountDataToAccount(addr, &b, map[basics.AssetIndex]string{}, round, a.MicroAlgos, basics.MicroAlgos{Raw: 100000})
require.NoError(t, err)

require.Equal(t, protocol.EncodeJSON(conv), protocol.EncodeJSON(anotherConv))
Expand Down
12 changes: 11 additions & 1 deletion daemon/algod/api/server/v2/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@ func (v2 *Handlers) AccountInformation(ctx echo.Context, address string, params
if err != nil {
return internalError(ctx, err, errFailedLookingUpLedger, v2.Log)
}
block, _, err := myLedger.BlockCert(basics.Round(lastRound))
tzaffi marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return internalError(ctx, err, errFailedLookingUpLedger, v2.Log)
}
consensus, ok := config.Consensus[block.CurrentProtocol]
if !ok {
return notFound(ctx, errors.New(errInternalFailure), errInternalFailure, v2.Log)
}

if handle == protocol.CodecHandle {
data, err := encode(handle, record)
Expand Down Expand Up @@ -270,7 +278,9 @@ func (v2 *Handlers) AccountInformation(ctx echo.Context, address string, params
}
}

account, err := AccountDataToAccount(address, &record, assetsCreators, lastRound, amountWithoutPendingRewards)
minBalance := record.MinBalance(&consensus)
tzaffi marked this conversation as resolved.
Show resolved Hide resolved

account, err := AccountDataToAccount(address, &record, assetsCreators, lastRound, amountWithoutPendingRewards, minBalance)
if err != nil {
return internalError(ctx, err, errInternalFailure, v2.Log)
}
Expand Down
56 changes: 32 additions & 24 deletions test/scripts/e2e_subs/goal/atomic_abi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
tzaffi marked this conversation as resolved.
Show resolved Hide resolved
from subprocess import call
from typing import Callable, Dict, List, Union, Tuple
from pathlib import Path
import types
Expand All @@ -18,28 +19,30 @@ def __init__(
goal: Goal,
app_id: int,
contract_abi_json: Union[Path, str],
sender: str,
signer: atc.TransactionSigner = None,
caller_acct: str,
sp: txn.SuggestedParams = None,
):
"""
Note: app_id will over-write whatever app_id was defined in `contract_abi_json`

Also, I'm assuming a single signer for all the methods in the atomic transaction.
Also, we're assuming a single caller_account which is also the signer for all the transactions.
"""
self.goal = goal
self.app_id = app_id
self.contract_abi_json = contract_abi_json # for cloning only
self.contract_abi_json_path: str = None
self.caller_acct = caller_acct
self.sp = sp

self.method_args: List[list] = []
self.sigs2selector: Dict[str, str] = {}
self.handle2meth: Dict[str, dict] = {}
assert (
self.app_id and self.app_id > 0
), f"must have already created the app but have app_id {self.app_id}"

self.execution_results: atc.AtomicTransactionResponse = None
self.execution_summaries: List[MethodCallSummary] = None
assert (
self.caller_acct in self.goal.internal_wallet
), "aborting AtomicABI - will not be able to transact without signing authority"

# try very hard to parse the ABI contract
self.contract_abi_json_path: str = None
cajson = text(contract_abi_json)
if cajson:
self.contract_abi_json_path = contract_abi_json
Expand All @@ -49,13 +52,18 @@ def __init__(
cadict["appId"] = self.app_id
self.contract: abi.Contract = abi.Contract.from_json(json.dumps(cadict))

self.sender = sender
self.sp = sp
self.signer = signer
assert (
self.caller_acct
), "aborting AtomicABI - cannot execute without a caller_acct"
self.signer = self.get_atxn_signer()

if not self.signer:
# gonna just try and get the signer from the sender
self.signer = self.get_atxn_signer(sender)
self.method_args: List[list] = []
self.sigs2selector: Dict[str, str] = {}
self.handle2meth: Dict[str, dict] = {}

self.execution_results: atc.AtomicTransactionResponse = None
self.execution_summaries: List[MethodCallSummary] = None

self.atomic_transaction_composer = atc.AtomicTransactionComposer()

Expand All @@ -75,23 +83,23 @@ def __init__(
}

@classmethod
def factory(cls, obj):
def factory(cls, obj, caller_acct: str = None):
return cls(
obj.goal,
obj.app_id,
obj.contract_abi_json,
obj.sender,
signer=obj.signer,
caller_acct if caller_acct else obj.caller_acct,
sp=obj.sp,
)

def clone(self):
return self.factory(self)
def clone(self, caller_acct: str = None):
return self.factory(self, caller_acct=caller_acct)

def execute_atomic_group(
self, wait_rounds: int = 5
) -> Tuple[atc.AtomicTransactionResponse, List["MethodCallSummary"]]:
assert self.execution_results is None, self.CALL_TWICE_ERROR

self.execution_results = self.atomic_transaction_composer.execute(
self.goal.algod, wait_rounds
)
Expand Down Expand Up @@ -172,10 +180,10 @@ def get_suggested_params(self) -> txn.SuggestedParams:

return self.sp

def get_atxn_signer(self, sender: str = None) -> atc.AccountTransactionSigner:
if not sender:
sender = self.sender
sk = self.goal.internal_wallet.get(sender)
def get_atxn_signer(self, caller_acct: str = None) -> atc.AccountTransactionSigner:
if not caller_acct:
caller_acct = self.caller_acct
sk = self.goal.internal_wallet.get(caller_acct)
if not sk:
raise Exception("Cannot create AccountTransactionSigner")
# TODO: handle querying kmd in the case that sk isn't in the internal wallet
Expand Down Expand Up @@ -206,7 +214,7 @@ def add_method_call(
self.atomic_transaction_composer.add_method_call(
self.app_id,
method,
self.sender,
self.caller_acct,
sp,
self.signer,
method_args=method_args,
Expand Down
Loading