Skip to main content
Post Undeleted by forgetso
Answer was wrong
Source Link
forgetso
  • 1.5k
  • 5
  • 18

It seems this is related to running sub calls in transactions. The batch is somewhat unrelated although it exacerbates the issue by doubling the transaction fees. There is no difference between the contracts node and aura node - I was previously confused by the difference in decimal places between the two types of nodeEdited after feedback from @German Nikolishin below.

The fee is small when calling an ink! function that does not call another ink! message (a sub-call).

        #[ink(message)]
        pub fn faucet(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;
            Ok(())
        }

Tx Cost: 1 UNIT for extrinsic without sub call

The fee is doubled when the above call is batched butIt seems this transfer is still small:

Tx Cost: 2 UNIT for extrinsic without sub call in batch

The fee explodes when calling an ink! function that makes a sub-call.

        /// Faucet function for sending tokens to humans that includes a call         #[ink(message)]
        pub fn faucet_with_subcall(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;

            // SUB-CALL to a second #[ink(message)]

            // record transfer or return error
            match self.record_transfer(Transfer {

Tx Cost: 481 UNIT for extrinsic with sub call

And batching the txcost associated with the sub-call causes the fee to double again.

Tx Cost: 962 UNIT for extrinsic with sub call in batch`

The .Transfer eventsstoring data in the block appear when the transactions contain sub-calls:

balances.Transfer

contract. The value inside themthe transfer is sent to what I presume is the contract's deposit_account, which is why it isn't a contract itself.

faucetWithSubcallfaucetWithStore response.storageDeposit { Charge: '480.0000 Unit' }

The deposit stays in the deposit account until the contract is terminated, at which point the deposit account uses the funds to remove any storage associated with the contract and then sends the remaining funds back to the recipient.

            ink::env::terminate_contract::<ink::env::DefaultEnvironment>(recipient);

I've created a demo repo to demonstrate the fees shown above.

It would be nice if the ink! developers could comment on the preferred approach when calling additional functions inside ink!.

It seems this is related to running sub calls in transactions. The batch is somewhat unrelated although it exacerbates the issue by doubling the transaction fees. There is no difference between the contracts node and aura node - I was previously confused by the difference in decimal places between the two types of node.

The fee is small when calling an ink! function that does not call another ink! message (a sub-call).

        #[ink(message)]
        pub fn faucet(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;
            Ok(())
        }

Tx Cost: 1 UNIT for extrinsic without sub call

The fee is doubled when the above call is batched but this is still small:

Tx Cost: 2 UNIT for extrinsic without sub call in batch

The fee explodes when calling an ink! function that makes a sub-call.

        /// Faucet function for sending tokens to humans that includes a call         #[ink(message)]
        pub fn faucet_with_subcall(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;

            // SUB-CALL to a second #[ink(message)]

            // record transfer or return error
            match self.record_transfer(Transfer {

Tx Cost: 481 UNIT for extrinsic with sub call

And batching the tx with the sub-call causes the fee to double again.

Tx Cost: 962 UNIT for extrinsic with sub call in batch`

The .Transfer events in the block appear when the transactions contain sub-calls:

balances.Transfer

The value inside them is sent to what I presume is the contract's deposit_account, which is why it isn't a contract itself.

faucetWithSubcall response.storageDeposit { Charge: '480.0000 Unit' }

I've created a demo repo to demonstrate the fees shown above.

It would be nice if the ink! developers could comment on the preferred approach when calling additional functions inside ink!.

Edited after feedback from @German Nikolishin below.

It seems this transfer is the cost associated with storing data in the contract. The value inside the transfer is sent to what I presume is the contract's deposit_account, which is why it isn't a contract itself.

faucetWithStore response.storageDeposit { Charge: '480.0000 Unit' }

The deposit stays in the deposit account until the contract is terminated, at which point the deposit account uses the funds to remove any storage associated with the contract and then sends the remaining funds back to the recipient.

            ink::env::terminate_contract::<ink::env::DefaultEnvironment>(recipient);

I've created a demo repo to demonstrate the fees shown above.

Post Deleted by forgetso
Source Link
forgetso
  • 1.5k
  • 5
  • 18

It seems this is related to running sub calls in transactions. The batch is somewhat unrelated although it exacerbates the issue by doubling the transaction fees. There is no difference between the contracts node and aura node - I was previously confused by the difference in decimal places between the two types of node.

The fee is small when calling an ink! function that does not call another ink! message (a sub-call).

        #[ink(message)]
        pub fn faucet(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;
            Ok(())
        }

Tx Cost: 1 UNIT for extrinsic without sub call

The fee is doubled when the above call is batched but this is still small:

Tx Cost: 2 UNIT for extrinsic without sub call in batch

The fee explodes when calling an ink! function that makes a sub-call.

        /// Faucet function for sending tokens to humans that includes a call         #[ink(message)]
        pub fn faucet_with_subcall(&mut self, accountid: AccountId) -> Result<(), Error> {
            let token_holder = self.token_holder;
            self.transfer_from_to(&token_holder, &accountid, self.faucet_amount)?;

            // SUB-CALL to a second #[ink(message)]

            // record transfer or return error
            match self.record_transfer(Transfer {

Tx Cost: 481 UNIT for extrinsic with sub call

And batching the tx with the sub-call causes the fee to double again.

Tx Cost: 962 UNIT for extrinsic with sub call in batch`

The .Transfer events in the block appear when the transactions contain sub-calls:

balances.Transfer

The value inside them is sent to what I presume is the contract's deposit_account, which is why it isn't a contract itself.

The value sent to the deposit_account is the storageDeposit

faucetWithSubcall response.storageDeposit { Charge: '480.0000 Unit' }

I've created a demo repo to demonstrate the fees shown above.

It would be nice if the ink! developers could comment on the preferred approach when calling additional functions inside ink!.