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

Restore compatibility between go-perun post-0.10.6 and eth-backend #44

Merged
merged 7 commits into from
Jan 31, 2024

Conversation

iljabvh
Copy link
Contributor

@iljabvh iljabvh commented Jan 12, 2024

Two changes have been implemented in go-perun that break the eth-backend. This PR restores the compatibility by adapting to the changes made in go-perun:

  • Removal of the Secondary field in channel.AdjudicatorReq here.
  • Creation of an AppID type to generalize App identifiers instead of using Ethereum addresses here

Note that this PR aims to close issue #38 .

@iljabvh iljabvh closed this Jan 12, 2024
@iljabvh iljabvh deleted the fix-for-goperun-0.10.7 branch January 12, 2024 13:24
@iljabvh iljabvh restored the fix-for-goperun-0.10.7 branch January 12, 2024 13:29
@iljabvh iljabvh reopened this Jan 12, 2024
@iljabvh iljabvh force-pushed the fix-for-goperun-0.10.7 branch 3 times, most recently from 80432b3 to 64796c1 Compare January 12, 2024 18:30
channel/conclude.go Outdated Show resolved Hide resolved
@@ -73,11 +82,24 @@ type ContractBackend struct {
// txFinalityDepth defines in how many consecutive blocks a TX has to be
// included to be considered final. Must be at least 1.
func NewContractBackend(cf ContractInterface, chainID ChainID, tr Transactor, txFinalityDepth uint64) ContractBackend {
// Check if the shared maps are initialized, if not, initialize them.
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this be under a SharedMutex lock?
If it is allowed to call this function in paralell (as the == nil checks suggest) you would end up with a race condition when writing to the maps in line 95 and 96.

@@ -45,6 +45,15 @@ const (
// create a TxTimedoutError with additional context.
var errTxTimedOut = errors.New("")

// SharedExpected Nonce is a map of each expected next nonce of all clients.
var (
SharedExpectedNonces map[ChainID]map[common.Address]uint64
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason those two are separate maps instead of a map[ChainID]map[common.Address]struct{uint64,*sync.Mutex} (assuming a per-item mutex is needed)? As far as I can tell those two always work in tandem and you basically never need/use SharedExpectedNonces[a][b] without using SharedNonceMtx[a][b] (though I could be wrong and different parts of perun already use separate maps for a different reason).

Even then the following could be an option, too, grouping them and removing an extra lookup due to having two outer maps:

type PerChainData struct {
    expectedNonces map[common.Address]uint64
    mutexes map[common.Address]*sync.Mutex
}
map[chainID]PerChainData

Copy link
Contributor

Choose a reason for hiding this comment

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

Another note: Do those need to be public? Might be easier to reason about the mutex behavior if only this package can access them.

// Look up expected next nonce locally.
c.nonceMtx.Lock()
defer c.nonceMtx.Unlock()
SharedMutex.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

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

The previous defer Unlock is probably more idiomatic Go (as it enforces the unlock should a panic happen, too).

Though as I don't think the code in between can panic (besides an out of memory error) they should be functionally equivalent. I don't know which one you usually use in perun code.

func lockAndUnlock(lock *sync.Mutex, fn func()) {
mu.Lock()
defer mu.Unlock()
lock.Lock()
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused: Why do we have individual mutexes if they are only locked while mu is locked? Shouldn't it be sufficient to always lock mu and throw away the individual mutexes? As the mu.Lock() already guarantees that only a single thread/goroutine is in fn, thus guaranteeing that only a single individual mutex (in locks) is ever locked at the same time, making the locks mutexes effectively useless?

@iljabvh iljabvh marked this pull request as ready for review January 30, 2024 18:35
… uses the AdjudicatorReq object during conclusion of a channel. Also remove functions that are necessary for the Secondary option.

Update(go.mod/go.sum): Update go.mod and go.sum to the most recent go-perun commit.

Signed-off-by: Ilja von Hoessle <ilja@perun.network>
…ce since v0.10.7.

* fix(channel/test): Include Randomizer for AppID type to generate random AppIDs for tests.
* fix(client/client_test.go): Adapt appID to the new AppID type.
* fix(channel/backend.go): Adapt app generation to new AppID type, include NewAppID method.
* fix(channel/subscription.go): Adapt convertEvent to new AppID type.
* chore(go.mod, go.sum): Update go-perun version to a v0.10.7 commit.

Signed-off-by: Ilja von Hoessle <ilja@perun.network>
Signed-off-by: Ilja von Hoessle <ilja@perun.network>
Signed-off-by: Ilja von Hoessle <ilja@perun.network>
Signed-off-by: Ilja von Hoessle <ilja@perun.network>
…nction

Signed-off-by: Ilja von Hoessle <ilja@perun.network>
Signed-off-by: Ilja von Hoessle <ilja@perun.network>
@iljabvh iljabvh merged commit d746e4a into hyperledger-labs:main Jan 31, 2024
6 checks passed
@iljabvh iljabvh mentioned this pull request Jan 31, 2024
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