Multiple pull payment pointers


Please note: This discussion started over Codius and I’ll explain the issue with the Codius use case in mind. However, it could be applied to any subscription model using SPSP pull payments where you want to provide a fallback pointer just in case the primary server is not available or where multiple parties want to contribute to the overall price of a service.

Problem: I’ve been working on an update of Codius that allows for pull payments. If the host support pull payments and the user is willing to pay via pull, the host will request a pull payment pointer on upload and only run the pod/contract for the first pull interval. On expiry, it will try to pull again and if that is possible, it will extend the pod’s life, otherwise it will shut it down.
Especially in the smart contract scenario, it makes sense to include multiple fallback pull payment pointers such that every party in the contract can be certain that as long as their pointer is available and funded, the contract will continue. But also in the general hosting scenario it makes sense to include multiple pointers as fallback option for server outages or if a community wants to jointly contribute to a project.
Having multiple parties involved in a payment process opens the door for attacks and raises a lot of questions. Here is what I’ve already collected, but I’m sure there is even more to consider.


  1. Who is allowed to add additional payment pointers to a pod? Only the uploader or anybody?

  2. How does a second user (not the uploader) request the information to set up a payment pointer accepted by the host?

  3. How is the payment order? Does the host always try the uploader’s pointer first and then continues with the pointer that was added next or does it randomly select a pointer to pull from? Another scenario could be [1,2,3] and then [2,3,1] during the next cycle and so on.

  4. Is there a limit to how many pointers can be added?

  5. If a pointer does not work, is it immediately removed from the list?

  6. Pulling is triggered on expiry but if there are 1000 pointers of which 999 are attackers that are not working, the pod will continue to run for the time that the 999 are all tested, basically being hosted for free during that time. Should the pulling process start before expiry and account for the number of pointers?

  7. Does the uploader have to power to shut down the pod to ultimately end an attack? If yes, how is that realized?

1 Like
  1. I think it’d be fine (with Codius) for anyone to add a payment pointer.

  2. For Codius, this can use the same process as when initially uploading.
    Initial upload:

    1. uploader provides manifest
    2. host provides payment details
    3. uploader sets up payment pointer

    Adding new payment pointer:

    1. user provides manifest hash
    2. host proves payment details based on known manifest
    3. user sets up payment pointer
  3. I think it could try them in the order received [1,2,3]. If the payers want to do something like split the payment evenly, they can set up the pointers accordingly.
    Example: For a service costing $30/month, three payment pointers for $10/month each could be provided.

  4. It depends. Given the attack described in 6, I think it makes sense for Codius hosts to have limit.

  5. I’d vote no, but maybe do remove it after X consecutive failures. Do remove it immediately if a pointer’s known expiration has passed.

  6. Limiting the number of pointers would probably make it ok to pull at the pod expiration.

  7. Limiting the number of pointers should negate such an attack, so I don’t think that should be a use case for shutting down a deployed pod.


In the Codius case: This means if somebody uploads a pod/contract that the community really likes and wants to support, these supporters add their pointers, pay as long as they want and then terminate their endpoints. Now, next supporter is charged and given that there is a limit to the number of pointers, this is almost like a waitlist to support.

Fair enough. We can have some number of tries before removing it. I don’t think there is a way for the pulling entity to know that the pointer is expired, though. The expiry field is optional in query responses and if the pointer is expired, its endpoint is deleted. We could, however, treat a “401 - Unauthorized: Token could not be verified.” as indicator that the token has expired.

If not to end an attack, are you nevertheless in favor for introducing the possibility to end a pod and if so, how is that realized?


It does seem like limiting the number of pointers doesn’t really allow for lots of parties to support a pod. Maybe we just rely on people pushing to the balance with codius extend for that case.


I’m thinking we can add a codius stop cli command (that only works for pods that allow it) as an alternative to only stopping when the balance runs out / pull payments fail.


Fair enough.

Who would be allowed to call that? Only the uploader or everybody whose payment pointer is in the list of payment pointers? How do we ensure that only the right person can stop the pod?


I don’t have a good answer for any of those questions. :grimacing: