Final Project - University of Calgary (Winter 2023)
Table of Contents
Web advertising is everywhere these days, from banner ads to pop-ups and even videos. But did you know that the industry is dominated by a few big players, like Google, Amazon and Ezoic, who control all the ad hosting from their massive data centers? For small businesses, it's an uphill battle to compete with these giants and turn a meaningful profit. Introducing AdShare!
Our platform is a solution for the challenges posed by the current centralized approach to web advertising. With the rise of Web3.0 and the push towards decentralization, we believe that our decentralized advertising platform aligns with the future of the web. Anyone can use some spare computing power to host ads and earn money, making it easier and more affordable for smaller players to get their message out there. Plus, by cutting out the middleman, we're reducing the overhead costs for everyone involved. It's a win-win for advertisers and users alike!
-
- For the simplest way, ensure Docker and Docker Compose are installed locally.
- For the long way, ensure Node and npm are installed locally.
-
-
Using pre-built images 📷 (recommended)
-
Container images for both the Proxy and Peer are available on GHCR which can be pulled and used directly.
-
Peer:
- Create a new local directory for storing ads.
- Run
docker run -v /path/to/local/ads:peer/ads -p 3000:3000/tcp bgunson/as-peer
- Terminate at any time by pressing Ctrl+C.
- NB: If you want to run multiple Peers simultaneously, make sure you run the commands on separate directories and change the ports.
-
Proxy:
- In a terminal, run
docker run -p 50000:50000/tcp bgunson/as-proxy
- NB: This will start the container in foreground mode and your terminal will be attached to the container's process.
- To avoid this, add a
-d
option afterrun
so that the container will run in the background.
- Terminate at any time by pressing Ctrl+C.
- In a terminal, run
-
-
Using Docker Compose 📚
- To run the Peer as a Docker container:
- Clone the project repository and
cd
toas/peer
via terminal/console. - Run
docker-compose up
in the root directory. - Terminate at any time by pressing Ctrl+C.
- Clone the project repository and
- To run the Peer as a Docker container:
-
-
If you want to get things set up and running locally this way, you need to clone the project repository.
-
To run a Peer:
- Open a terminal,
cd
into where you cloned the repo. cd
intoas/peer
folder.- Run
npm install
to install the project dependencies. - Run
npm start
to start the Peer server.- You can run any number of these in multiple terminals.
- Open a terminal,
-
To setup the GUI for the Peer:
- Open another terminal,
cd
into where you cloned the repo. cd
intoas/peer/frontend
folder.- Run
npm run build
- Open another terminal,
-
To run a Proxy:
- Open another terminal, again
cd
into where you cloned the repo. cd
intoas/proxy
folder.- Run
npm install
followed bynpm start
- Open another terminal, again
Once a Peer is running and connected to a Proxy's swarm, you can access the GUI by visiting http://localhost:3000.
Then finally, open the client by going cloning the repo locally and opening
docs/index.html
in your preferred web browser.You can also visit https://bengunson.me/as-example-client
You should then see an iframed ad which was given by the to the client from the peer server(s) via the proxy.
To learn more about changing the port to something else and for configuring stuff, read this section.
-
AdShare works by allowing users to download a client, called the Peer, that turns their computer into a peer server. Once this peer joins a Swarm network of other Peers, they can host and exchange ads with each other. We use Docker for improved scalability and portability, so our application can work seamlessly in different environments.
Users can upload their own ads and choose how much they want to pay to ensure their ad gets replicated and seen by more people. The more replication, the more money they can earn. Users running the peer server are paid according to how many ads they serve to clients, creating a supply and demand system in the marketplace.
A Proxy server is used to "broker" connections between clients and peer servers. If no peers are available, the proxy server will serve an advertisement for our service.
You can read our Proof of Concept here to get a better idea of what's going on under the hood!
You can read in-depth about our system architecture and communication model here.
Replication
Users running the peer app on their machines can host ads for clients not originally assigned to them. To enable this, we've created a mechanism for replicating ads between peers. When a peer is empty, it simply sends a request to the proxy to replicate ads from other peers. The proxy then sends a request to all non-empty peers to send an ad, which is then replicated to the empty peer. The first peer request to reach the proxy is the first ad sent to the empty peer. Need more ads? Just send another replication request. And if there's a new ad in the system, send a replication request to the proxy to share it with other peers.Additionally, replication serves the purpose of maintaining fault tolerance within the system. Once a new server joins the swarm, it is immediately replicated to ensure that the system remains stable and available to clients. The proxy server maintains a dynamic list of active peers in the swarm.
Scalability
By leveraging the distributed nature of peer-to-peer networks, we can seamlessly scale the system as more users and ads are added, without the need for a central server or a single point of failure. To further simplify deployment and management, we use Docker containers to ensure consistency across different machines and environments. This also allows for easier scaling by allowing for the creation of new instances of the app on-demand!Fault Tolerance
The decentralized nature of our ad-swarm means that we can withstand the failure of up to n-1 peers. Here's how it works: when a request is sent out for an ad, all peers in the swarm respond. If one fails to respond, the proxy simply ignores it and serves the next response it receives. And don't worry if one of your peers does fail - simply reboot the application and rejoin the swarm!Consistency
With large amounts of ads and peers, storing every file on every machine becomes impractical. Our solution? A weak consistency mode! This ensures that all ad copies are dispersed throughout the swarm, so no peer misses out on the latest ads!Synchronization
Synchronization is passively implemented in the swarm as we are not interchanging time-dependent information and just static image files. Logical timestamps, based on Lamport algorithm, are incorporated in order to keep track of which ads are on each peer, and to be able to determine when each ad was placed (either through direct upload or replication) on each peer.GUI
Built with React, our GUI provides a streamlined way to manage ads directly from the peer. With intuitive features and a clean interface, managing ads is as easy as pie!You can tweak the Docker Compose file and tweak the values defined in environment
.
It is recommended to use the --no-cache
option when building images.
To make things even simpler, a .env
file which contains the necessary configuration for the application to run, can be used.
This way, you can build a image by running: docker-compose --env-file ./path/to/.env build --no-cache --force-rm
You can create the .env file and place them in the peer
folder (and the proxy
folder as well if you want to run the Proxy locally!).
The general format of a .env
file is:
VARIABLE1=YOUR_VALUE1
VARIABLE2=YOUR_VALUE2
You can read more about the environment variables here.
We would love some constructive feedback. This was a great learning experience for us all and we would love to see how we could improve the project.
- Bennett Gunson
- Kirill Larshin
- Steven Susanto
- Taylor Jones
- Ranadip Chatterjee