Skip to content

Commit

Permalink
Merge pull request #241 from aergoio/topic/normal-txn-do-not-call-con…
Browse files Browse the repository at this point in the history
…tract

txns of type NORMAL should not call contracts
  • Loading branch information
kroggen committed May 17, 2024
2 parents b766a2f + b173fad commit 9b24dcb
Show file tree
Hide file tree
Showing 6 changed files with 484 additions and 22 deletions.
11 changes: 11 additions & 0 deletions contract/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ func Execute(execCtx context.Context, bs *state.BlockState, cdb ChainAccessor, t
// check if the tx is valid and if the code should be executed
func checkExecution(txType types.TxType, amount *big.Int, payloadSize int, version int32, isDeploy, isContract bool) (do_execute bool, err error) {

// transactions with type NORMAL should not call smart contracts
// transactions with type TRANSFER can only call smart contracts when:
// * the amount is greater than 0
// * the payload is empty (only transfer to "default" function)
if version >= 4 && isContract {
if txType == types.TxType_NORMAL || (txType == types.TxType_TRANSFER && (payloadSize > 0 || types.IsZeroAmount(amount))) {
// emit an error
return false, newVmError(types.ErrTxNotAllowedRecipient)
}
}

// check if the receiver is a not contract
if !isDeploy && !isContract {
// before the hardfork version 3, all transactions in which the recipient
Expand Down
71 changes: 49 additions & 22 deletions contract/contract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,57 @@ func TestCheckExecution(t *testing.T) {
expectExec bool
}{
// deploy
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_DEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_DEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_DEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_DEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_DEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_REDEPLOY, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: true, isContract: false, expectErr: nil, expectExec: true},
// recipient is contract
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(0,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(0,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(0,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(0,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: newVmError(types.ErrTxNotAllowedRecipient), expectExec: false},
{version: 4, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: true, expectErr: nil, expectExec: true},
// recipient is not a contract
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1, types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 2, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 3, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: true},
{version: 3, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(0,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(0,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_NORMAL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(0,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_TRANSFER, amount: types.NewAmount(0,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_CALL, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: true},
{version: 4, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 1000, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
{version: 4, txType: types.TxType_FEEDELEGATION, amount: types.NewAmount(1,types.Aergo), payloadSize: 0, isDeploy: false, isContract: false, expectErr: nil, expectExec: false},
} {
do_execute, err := checkExecution(test.txType, test.amount, test.payloadSize, test.version, test.isDeploy, test.isContract)
assert.Equal(t, test.expectErr, err, "checkExecution(version:%d, txType:%d, amount:%s, payloadSize:%d)", test.version, test.txType, test.amount, test.payloadSize)
Expand Down
3 changes: 3 additions & 0 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ check ./test-gas-bf.sh
check ./test-gas-verify-proof.sh
check ./test-gas-per-function-v2.sh
check ./test-contract-deploy.sh
check ./test-transaction-types.sh

# change the hardfork version
set_version 3
Expand All @@ -142,6 +143,7 @@ check ./test-gas-bf.sh
check ./test-gas-verify-proof.sh
check ./test-gas-per-function-v3.sh
check ./test-contract-deploy.sh
check ./test-transaction-types.sh

# change the hardfork version
set_version 4
Expand All @@ -154,6 +156,7 @@ check ./test-gas-bf.sh
check ./test-gas-verify-proof.sh
check ./test-gas-per-function-v4.sh
check ./test-contract-deploy.sh
check ./test-transaction-types.sh

# terminate the server process
echo ""
Expand Down

0 comments on commit 9b24dcb

Please sign in to comment.