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

Spike: Payment channel authorization grants #36 #41

Merged
merged 8 commits into from
Aug 19, 2024

Conversation

revoltez
Copy link
Contributor

@revoltez revoltez commented Aug 2, 2024

This pull request attempts to fix payment issue #36

Smart Contract

  • Smart contract have been extended with the ability to create payment channels from others
  • SubChannels could be created from a channel only after the publisher authorizes the caller address.
  • SubChannels are treated exactly like a regular channel and their lifecycle is not dependent on the main channel.
  • Publisher of the main channel is authorized to manage SubChannels.
  • Closing a channel will transfer the remaining funds to the caller as long as he is authorized to manage the channel.
  • Extended test suite and refactored existing tests

To run test you can run the following command : forge test --root ./contracts

Publisher Updates

  • Added --authorize flag to the deploy command which will create an asymmetric key pair.
  • The public address will be authorized to create subChannels.
  • The address is funded with ETH to be able to make calls to the smart contract.
  • The Key pair is sent encrypted with an AES key in the provision pod request .
  • The key pair is saved in deployment configuration.

Provider Updates

  • Provider checks the presence of a keypair, if so will save it save it as environment variables alongside the main payment channel informations for which the application is authorized to manipulate.

Autoscaler

  • Retreive the payment channel informations from the environment variables and save them in PaymentChanneManger
  • Implemented test SubChannel creation call in the main loop

Testing

Proto files have been updated, sync the new generated files with turbo sync

You can re-run the e2e test in test/e2e/autoscaler.

If the test has already been run before, you can restart the clusters (if they are not already running) with start-clusters.sh. Then, redeploy the tpodserver and autoscaler using redeploy-images.sh. After that, skip to deploying the autoscaler with run-test 5.0.


// fund the new sub channel with the deducted amount from the main channel
subChannel.investedByPublisher += amount;
subChannel.unlockTime = channel.unlockTime; // Inherit unlock time from main channel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading the code right, this lets the publisher instantly unlock any channel, by doing (in all below calls, msg.sender == publisher):
0. createChannel(provider, podId, ...) (created earlier)

  1. createChannel(publisher, 0x0, 0, 1) (create a dummy channel with unlock time 0)
  2. authorize(publisher, publisher, 0x0) (authorize someone for it (in this case, ourselves))
  3. createSubChannel(publisher, publisher, 0x0, provider, podId) (oops! resets unlockTime on the original channel to 0)
  4. unlock(publisher, provider, podId) (regular unlock)
  5. withdrawUnlocked(publisher, provider, podId) (oops! can withdraw supposedly-locked funds without waiting for unlockTime) (would work even if made in the same block as all the other commands, with no chance for the provider to cash out any work done since the last withdraw(..) call)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, Should be Fixed now.

if (channel.investedByPublisher < amount) revert InsufficientFunds();

// Deduct the amount from the main channel's funds
channel.investedByPublisher -= amount;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decreasing the amount invested by the publisher without requiring the channel to be unlocked first allows the publisher to drain the channel of any funds within it, by creating a subchannel with all the funds they can, then unlocking that subchannel, and withdrawing from it at a leisurely pace, without the provider able to submit a withdraw() call.

Also, since the code never checks whether channel.investedByPublisher - channel.withdrawnByProvider < amount (see, e.g. line 121, leftoverFunds = ..), it's possible to withdraw more than was initially invested into a channel, thus draining the whole contract of funds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed as well

@revoltez revoltez merged commit 0fa6078 into master Aug 19, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants