## Matchmaking ( context of state channels )
## what is matchmaking?
matchmaking is the process of finding suitable partners for a given task or activity. It is a common problem in many different domains, such as online dating, game matchmaking, and resource allocation.
### Use of matchmaking for Channel4
Users submit urls on our website, currently we don't do any filtering.
1. We can obviously do blacklist with a list of urls. But that can only block adult sites.
2. We don't know about other sites, maybe there are sites that are not marked by crawlers.
3. User might intentionally tag sites wrong or by mistake.
4. direct violation : phising sites, malware distribution, piracy, invalid urls.
**Matchmaking tackles all the above mentioned issues.**
### Implementation idea
There are many ways/algorithm to do matchmaking. Some of them are
- random matchmaking
- technical matchmaking
- role based matchmaking
- skill based matchmaking
For our use case random matchmaking is pretty good in my honest opinion. (Dispute resolution will come later). We need more consideration on adjudicator/moderator ( more on that later)
### why random matchmaking?
1. We don't have any good parameter/metric based on which we can match users
2. Read the user schema below. We can obviously add more fields but currently we only have submitted urls based on which we can match users. Simple matching if users have submitted urls and they are not verified then match those users. Now, you can ask what if some users submit 10 and other submit 100 urls then it's not fair matchmaking, since other user have to work more.
- we can either ignore it to keep the simplicity ( may bite us later )
- make bit more intelligent matchmaking based on number of urls submitted. Still random. like match users who have submitted 5 urls with max 10 urls person.
```
const UserSchema = new mongoose.Schema({
walletAddress: {
type: String,
required: true,
unique: true
},
likedUrls: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Url',
}],
submittedUrls: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Url',
}],
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
},
syncedToBlockchain: {
type: Boolean,
default: false
},
** role: {
type: string,
required: true
default: normal
}**
});
```
### sequence 1 ( url submission )
```sequence
Alice->channel4: submits 5 urls
Bob->channel4: submits 10 urls
Note over channel4: match Alice and Bob
```
### sequence 2 ( matchmaking)
```sequence
Alice-->channel4: stake soulbound token/reputation
Bob-->channel4: stake soulbound token/reputation
note over channel4: create state channel between Alice and Bob.
```
soulbound token is just an example not a necessity, but we need something to stake. It can be reputation/points ( not implemented yet ).
But we do need something to stake. **Open for ideas here.**
### sequence 3 (open channel)
```sequence
Alice->Bob: verify Bob's urls
Bob->Alice: verify Alice's urls
note over Alice,Bob: Alice and Bob both verified urls, initiates close channel
```
### sequence 4 (close channel)
```sequence
note over Alice,Bob: close channel and return staked token/reputation
```
**above sequence(s) diagrams represent ideal scenario**
### Dispute resolution
adjudicator/moderator will be someone with
1. old account (older than 2 weeks maybe)
2. has good reputation
3. submitted urls
4. have verified urls in past.
In the beginning we can be moderator. Later we can give role to community members.
During conflict resolution malicious person will lose their stake and will be distributed between moderator and other party(other person who was in state channel)
### Matchmaking Algorithm (potential implementation )
**Step 1: Fetch Users and their Submitted URL Counts**
- Query the database to retrieve all users who have atleast one submitted url and are not synced to db yet.
- For each user, count the number of URLs they have submitted.
**Step 2: Sort Users by Submitted URL Counts**
~~- Sort the users in ascending order based on the number of URLs they have submitted.~~
~~- This sorting helps in finding users with similar URL submission volumes.~~
- Have a separate document called matchgroups. that is like key value pair. It groups the users based on number of urls submitted where key is no. of urls and value are users.
**Step 3: Find Potential Matches**
~~- Iterate through the sorted list of users.~~
~~- For each user (User A), compare their submitted URL count to other users (User B) in the list.~~~~
~~- Calculate the absolute difference in the submitted URL counts between User A and User B.~~
Users will be matched in their matchgroups. If the match is not found in the group, the backend will try to find match in another group. The match algorithm always goes
1. First try to find in same group
2. top to bottom. e.g. group 2 can find match in group 3 but not vice versa.
**Step 4: Define a Match Threshold**
- Define a match threshold that determines how similar the submitted URL counts must be for users to be considered a match.
- This threshold can be adjusted to control the strictness of the matching.
**Step 5: Create Matches**
- If the absolute difference in submitted URL counts between User A and User B is within the defined match threshold, consider them a match.
- Record the match as a pair of User A and User B, along with the match score (the absolute difference).
**Step 6: Continue Searching for Matches**
- Continue iterating through the list of users, checking for matches with different users.
- Store all matching pairs and their match scores.
**Step 7: Output Matches**
- Return the list of matching pairs along with their match scores.
**Example:**
Let's assume we have five users (A, B, C, D, and E) and the number of URLs they have submitted are as follows:
- User A: 5 URLs
- User B: 20 URLs
- User C: 8 URLs
- User D: 15 URLs
- User E: 2 URLs
We'll set the match threshold to 5 (for demonstration purposes).
**Matching Pairs:**
- User A (5 URLs) matches with User C (8 URLs) with a match score of 3 (abs(5 - 8)).
- User A (5 URLs) matches with User E (2 URLs) with a match score of 3 (abs(5 - 2)).
- User C (8 URLs) matches with User E (2 URLs) with a match score of 6 (abs(8 - 2)).
These matching pairs meet the match threshold criteria, and you have three potential matches based on the submitted URL counts.
Above algorithm time complexity is probably quadratic ( O(N^2)). It can be optimized i think by using some indexing and db tricks.
I will try to make it more optimal. though we will hit significant performance issues with current algorithm for 1 million users and above.
for small numbers like 10k, 50k it should be fine.
# API documentation below
### MatchHandle.ts
## Create Match
- **URL:** `/createMatch`
- **Method:** POST
- **Description:** Creates a new match based on the user's group.
- **Request Parameters:**
- `userId` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the created match.
- 404 Not Found: If the user or group is not found.
## Get Match
- **URL:** `/getMatch/:id`
- **Method:** GET
- **Description:** Retrieves a match based on the user's ID.
- **Request Parameters:**
- `id` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the match.
## Update Match
- **URL:** `/updateMatch`
- **Method:** POST
- **Description:** Updates a match with verified URLs.
- **Request Parameters:**
- `matchId` (string) - The ID of the match to update.
- `userId` (string) - The user's ID.
- `verifiedURLs` (array) - An array of verified URLs.
- **Response:**
- 200 OK: Returns success if the update is acknowledged.
- 400 Bad Request: If the update is not successful.
## Mark Completion
- **URL:** `/markCompletion`
- **Method:** POST
- **Description:** Marks a user's completion status.
- **Request Parameters:**
- `userId` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the updated match after marking completion.
### Routes to call
#### routes/contract.ts file
## Create Match
- **URL:** `/createMatch`
- **Method:** POST
- **Description:** Creates a new match based on the user's group.
- **Request Parameters:**
- `userId` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the created match.
- 404 Not Found: If the user or group is not found.
## Get Match
- **URL:** `/getMatch/:id`
- **Method:** GET
- **Description:** Retrieves a match based on the user's ID.
- **Request Parameters:**
- `id` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the match.
## Update Match
- **URL:** `/updateMatch`
- **Method:** POST
- **Description:** Updates a match with verified URLs.
- **Request Parameters:**
- `matchId` (string) - The ID of the match to update.
- `userId` (string) - The user's ID.
- `verifiedURLs` (array) - An array of verified URLs.
- **Response:**
- 200 OK: Returns success if the update is acknowledged.
- 400 Bad Request: If the update is not successful.
## Mark Completion
- **URL:** `/markCompletion`
- **Method:** POST
- **Description:** Marks a user's completion status.
- **Request Parameters:**
- `userId` (string) - The user's ID.
- **Response:**
- 200 OK: Returns the updated match after marking completion.