Skip to content

Commit

Permalink
Merge pull request #124 from ltonetwork/fix-smart-account
Browse files Browse the repository at this point in the history
Fix smart account
  • Loading branch information
jasny authored Feb 11, 2022
2 parents ec15264 + 2a2b584 commit 789f696
Show file tree
Hide file tree
Showing 73 changed files with 364 additions and 121 deletions.
4 changes: 2 additions & 2 deletions e2e/features/lease.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Feature: Lease
Scenario Outline: Successful cancel lease transaction
Given Karen has an <key_type> account with 10 lto
And Karen is leasing 10 lto to Bob
When Karen cancel the lease (<version>) to Bob
When Karen cancels the lease (<version>) to Bob
Then Karen has 9 lto
And Karen is not leasing to Bob

Expand All @@ -36,7 +36,7 @@ Feature: Lease
| v3 | secp256r1 |

Scenario: Unable to cancel an nonexistent lease
When Alice tries to cancel the lease to Bob
When Alice tries to cancels the lease to Bob
Then the transaction fails

Scenario: Transfer fails because LTO intended for transfer is being leased
Expand Down
69 changes: 69 additions & 0 deletions e2e/features/smart_account.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
Feature: Smart account

Background: Anchor setup
Given Alice has an account with 100 lto
Given Bob has a new account
Given Charlie has a new account

Scenario: Create smart account
When Alice creates a smart account with script
"""
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
"""
Then Alice has a smart account
And Alice has 95 lto


Scenario: Clear smart account
Given Alice has a smart account with script
"""
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
"""
When Alice removes the account script
Then Alice doesn't have a smart account
And Alice has 95 lto

Scenario: Modify smart account
Given Alice has a smart account with script
"""
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
"""
When Alice creates a smart account with script
"""
true
"""
Then Alice has a smart account
And Alice has 95 lto

Scenario: Transactions with smart account
Given Alice has a smart account with script
"""
sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
"""
When Alice transfers 10 LTO to Bob
And Alice does a mass-transfer of 2 lto to Bob and 1 lto to Charlie
And Alice issues an association with Bob of type 1
And Alice revokes the association with Bob of type 1
And Alice sets data "foo" to "bar"
And Alice leases 10 lto to Bob
And Alice cancels the lease to Bob
And Alice sponsors Bob
And Alice cancels the sponsorship for Bob
And Alice registers an account

Scenario: Restricted account
Given Alice has a smart account with script
"""
match tx {
case t: TransferTransaction => false
case mt: MassTransferTransaction => false
case ss: SetScriptTransaction => false
case _ => sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
}
"""
When Alice tries to transfer 10 LTO to Bob
Then the transaction fails
When Alice tries to remove the account script
Then the transaction fails
When Alice tries to anchor
Then the transaction is successful
2 changes: 1 addition & 1 deletion e2e/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
lto~=1.1.2
lto~=1.2.1
behave~=1.2.6
polling~=0.3.2
2 changes: 1 addition & 1 deletion e2e/steps/anchor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from behave import *
from e2e.common.tools import *
from lto.transactions.anchor import Anchor
from lto.transactions import Anchor
import random


Expand Down
5 changes: 1 addition & 4 deletions e2e/steps/association.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import lto
from behave import *
from e2e.common.tools import broadcast
from e2e.common.tools import NODE
from e2e.common.tools import funds_for_transaction
from e2e.common.tools import broadcast, NODE, funds_for_transaction
from lto.transactions import Association, RevokeAssociation


Expand Down
2 changes: 1 addition & 1 deletion e2e/steps/data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from behave import *
from e2e.common.tools import *
from lto.transactions.data import Data
from lto.transactions import Data


def __cast_value(value):
Expand Down
6 changes: 3 additions & 3 deletions e2e/steps/lease.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def step_impl(context, user1, user2):
cancel_lease(context, user1, user2)


@when('{user1} tries to cancel the lease to {user2}')
@when('{user1} tries to cancels the lease to {user2}')
def step_impl(context, user1, user2):
try:
cancel_lease(context, user1, user2)
Expand All @@ -82,8 +82,8 @@ def step_impl(context, user1, amount, user2, version=None):
lease(context, user1, user2, amount, version)


@when('{user1} cancel the lease to {user2}')
@when('{user1} cancel the lease (v{version:d}) to {user2}')
@when('{user1} cancels the lease to {user2}')
@when('{user1} cancels the lease (v{version:d}) to {user2}')
def step_impl(context, user1, user2, version=None):
cancel_lease(context, user1, user2, version)

Expand Down
5 changes: 2 additions & 3 deletions e2e/steps/mass_transfer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from behave import *
from e2e.common.tools import convert_balance
from e2e.common.tools import broadcast
from lto.transactions.mass_transfer import MassTransfer
from e2e.common.tools import convert_balance, broadcast
from lto.transactions import MassTransfer


def process_input(context, transfers):
Expand Down
2 changes: 1 addition & 1 deletion e2e/steps/register.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from behave import *
from e2e.common.tools import *
from lto.transactions.register import Register
from lto.transactions import Register


def register(context, user=None, key_type="ed25519", public_key=None, version=None):
Expand Down
47 changes: 47 additions & 0 deletions e2e/steps/smart_account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from behave import *
from e2e.common.tools import NODE, funds_for_transaction, broadcast
from lto.transactions import SetScript


def set_script(context, user, script):
transaction = NODE.compile(script)
transaction.sign_with(context.users[user])
broadcast(context, transaction)

def clear_script(context, user):
transaction = SetScript()
transaction.sign_with(context.users[user])
broadcast(context, transaction)

def has_script(context, user):
response = NODE.wrapper('/addresses/scriptInfo/{}'.format(context.users[user].address))
return 'script' in response

@given("{user} has a smart account with script")
def step_impl(context, user):
funds_for_transaction(context, user, SetScript.DEFAULT_FEE)
set_script(context, user, context.text)
assert has_script(context, user), "No script set for account {}".format(context.users[user].address)

@when("{user} creates a smart account with script")
def step_impl(context, user):
set_script(context, user, context.text)

@when("{user} removes the account script")
def step_impl(context, user):
clear_script(context, user)

@when("{user} tries to remove the account script")
def step_impl(context, user):
try:
clear_script(context, user)
except:
pass

@then("{user} has a smart account")
def step_impl(context, user):
assert has_script(context, user), "No script set for account {}".format(context.users[user].address)

@then("{user} doesn't have a smart account")
def step_impl(context, user):
assert not has_script(context, user), "Account {} has a script".format(context.users[user].address)
4 changes: 1 addition & 3 deletions e2e/steps/sponsorship.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from behave import *
from e2e.common.tools import funds_for_transaction
from e2e.common.tools import NODE
from e2e.common.tools import broadcast
from e2e.common.tools import funds_for_transaction, NODE, broadcast
from lto.transactions import Sponsorship, CancelSponsorship


Expand Down
15 changes: 5 additions & 10 deletions e2e/steps/transfer.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
from behave import *
from e2e.common.tools import ROOT_ACCOUNT
from e2e.common.tools import convert_balance
from e2e.common.tools import get_balance
from e2e.common.tools import broadcast
from e2e.common.tools import assert_equals

from lto.transactions.transfer import Transfer
from e2e.common.tools import ROOT_ACCOUNT, convert_balance, get_balance, broadcast, assert_equals
from lto.transactions import Transfer


def transfer_to(context, recipient="", amount=0, sender="", version=None):
Expand All @@ -31,12 +26,12 @@ def step_impl(context, user, balance):
user_balance = get_balance(context.users[user].address)

if user_balance < balance:
transfer = transfer_to(context, recipient=user, amount=balance - user_balance)
transfer_to(context, recipient=user, amount=balance - user_balance)
elif user_balance > balance:
if user_balance - balance <= Transfer.DEFAULT_FEE:
transfer = transfer_to(context, recipient=user, amount=Transfer.DEFAULT_FEE)
transfer_to(context, recipient=user, amount=Transfer.DEFAULT_FEE)
user_balance = get_balance(context.users[user].address)
transfer = transfer_to(context, amount=user_balance - (balance + Transfer.DEFAULT_FEE), sender=user)
transfer_to(context, amount=user_balance - (balance + Transfer.DEFAULT_FEE), sender=user)

assert_equals(get_balance(context.users[user].address), balance)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,29 @@ object Bindings {

def transactionObject(tx: Tx): CaseObj =
tx match {
case Tx.Genesis(h, amount, recipient) =>
case Genesis(h, amount, recipient) =>
CaseObj(genesisTransactionType.typeRef, Map("amount" -> amount) ++ headerPart(h) + mapRecipient(recipient))
case Tx.Transfer(p, amount, recipient, attachment) =>

case Transfer(p, amount, recipient, attachment) =>
CaseObj(
transferTransactionType.typeRef,
Map(
"amount" -> amount,
"attachment" -> attachment
) ++ provenTxPart(p) + mapRecipient(recipient)
)

case Lease(p, amount, recipient) =>
CaseObj(
leaseTransactionType.typeRef,
Map(
"amount" -> amount,
) ++ provenTxPart(p) + mapRecipient(recipient)
)
case LeaseCancel(p, leaseId) =>

case CancelLease(p, leaseId) =>
CaseObj(
leaseCancelTransactionType.typeRef,
cancelLeaseTransactionType.typeRef,
Map(
"leaseId" -> leaseId,
) ++ provenTxPart(p)
Expand All @@ -69,8 +72,53 @@ object Bindings {
"attachment" -> attachment
) ++ provenTxPart(p)
)

case SetScript(p, scriptOpt) =>
CaseObj(setScriptTransactionType.typeRef, Map("script" -> fromOption(scriptOpt)) ++ provenTxPart(p))

case Anchor(p, anchorCount, anchors) =>
CaseObj(
anchorTransactionType.typeRef,
Map("anchorCount" -> anchorCount, "anchors" -> anchors) ++ provenTxPart(p)
)

case Data(p, data) =>
CaseObj(
dataTransactionType.typeRef,
Map("data" -> data.map(e => CaseObj(dataEntryType.typeRef, Map("key" -> e.key, "value" -> e.value)))) ++ provenTxPart(p)
)

case IssueAssociation(p, assocType, recipient) =>
CaseObj(
issueAssociationTransactionType.typeRef,
Map("assocType" -> assocType, "recipient" -> recipient) ++ provenTxPart(p)
)

case RevokeAssociation(p, assocType, recipient) =>
CaseObj(
revokeAssociationTransactionType.typeRef,
Map("assocType" -> assocType, "recipient" -> recipient) ++ provenTxPart(p)
)

case Sponsorship(p, recipient) =>
CaseObj(
sponsorshipTransactionType.typeRef,
Map("recipient" -> recipient) ++ provenTxPart(p)
)

case CancelSponsorship(p, recipient) =>
CaseObj(
cancelSponsorshipTransactionType.typeRef,
Map("recipient" -> recipient) ++ provenTxPart(p)
)

case Register(p, accounts) =>
CaseObj(
registerTransactionType.typeRef,
Map("accounts" -> accounts) ++ provenTxPart(p)
)

case _ => ???
}

}
Loading

0 comments on commit 789f696

Please sign in to comment.