diff --git a/README.md b/README.md index 73c2a95f..e7324edf 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,12 @@ -# K2-Task-Template -Tasks run following a periodic structure of 'rounds': -``` -executeTask => { - 1. Do the work - 2. Audit the work of other nodes - 3. Pay rewards and slash stake -} -``` +# Federated Deployer +This [Koii Task](https://docs.koii.network/microservices-and-tasks/what-are-tasks) provides a framework for deploying trusted-execution-environments in a decentralized and trustless way. -Each round is set by a specific time period, and nodes participate by uploading data to IPFS, posting CIDs to the K2 settlement layer, and sending messages across REST APIs and WebSockets. +For context, Koii Tasks provide a framework for: +1. JavaScript [runtime environments](https://docs.koii.network/microservices-and-tasks/what-are-tasks/runtime-environment) on thousands of home computers +2. Incentive and audit mechanisms to provide [feedback towards an intended function](https://docs.koii.network/microservices-and-tasks/what-are-tasks/gradual-consensus) +3. Convenient and efficient [payment rails](https://docs.koii.network/settlement-layer/k2-tick-tock-fast-blocks) for [Decentralized Autonomous Corporations](https://rossdawson.com/futurist/companies-creating-future/top-decentralized-autonomous-organizations-dao/) and community public goods -For more information on how the Task Flow works, check out [the runtime environment docs](https://docs.koii.network/microservices-and-tasks/what-are-tasks/gradual-consensus). -If this is your first time writing a Koii Task, you might want to use the [task organizer](https://www.figma.com/community/file/1220194939977550205/Task-Outline). - -## Requirements - - [Node >=16.0.0](https://nodejs.org) - - [Docker compose](https://docs.docker.com/compose/install/docker) - -## What's in the template? -`index.js` is the hub of your app, and ties together the other pieces. This will be the entrypoint when your task runs on Task Nodes - -`NamespaceWrappers.js` contains the interfaces to make API calls to the core of the task-node. It contains all the necessary functions required to submit and audit the work, as well as the distribution lists - -`coreLogic.js` is where you'll define your task, audit, and distribution logic, and controls the majority of task functionality. You can of course break out separate features into sub-files and import them into the core logic before web-packing. - -## Runtime Options -There are two ways to run your task when doing development: - -1. With Timer ON (see .env-local)- When the timer is ON, IPC calls are made by calculating the average time slots of all the task running your node. - -2. With Timer OFF - This allows you to do manual calls to K2 and disables the triggers for round managemnt on K2. Transactions are only accepted during the correct period. Guide for manual calls is in index.js - -# Modifying CoreLogic.js -Task nodes will trigger a set of predefined functions during operation. - -There are in total 9 functions in CoreLogic which the you can modify according to your needs: - -1. *task()* - The logic for what your task should do goes here. There is a window in round that is dedicated to do work. The code in task is executed in that window. - -2. *fetchSubmission()* - After completing the task , the results/work will be stored somewhere like on IPFS or local levelDB. This function is the place where you can write the logic to fetch that work. It is called in submitTask() function which does the actual submission on K2. - -3. *submitTask()* - It makes the call to namespace function of task-node using the wrapper. - -4. *generateDistributionList()* - You have full freedom to prepare your reward distributions as you like and the logic for that goes here. We have provided a sample logic that rewards 1 KOII to all the needs who did the correct submission for that round. This function is called in submitDistributionList() - -5. *submitDistributionList()* - makes call to the namesapce function of task-node to upload the list and on succesful upload does the transaction to update the state. - -6. *validateNode()* - this function is called to verify the submission value, so based on the value received from the task-state we can vote on the submission. - -7. *validateDistribution()* - The logic to validate the distribution list goes here and the function will receive the distribution list submitted form task-state. - -8. *auditTask()* - makes call to namespace of task-node to raise an audit against the submission value if the validation fails. - -9. *auditDistribution()* - makes call to namespace of task-node to raise an audit against the distribution list if the validation fails. - -# Testing and Deploying -Before you begin this process, be sure to check your code and write unit tests wherever possible to verify individual core logic functions. Testing using the docker container should be mostly used for consensus flows, as it will take longer to rebuild and re-deploy the docker container. - -## Build -Before deploying a task, you'll need to build it into a single file executable by running -`yarn webpack` - -## Deploy your bundle - -Complete the following to deploy your task on the k2 testnet and test it locally with docker compose. - -### To get a web3.storage key -If you have already created an account on [web3.storage](https://web3.storage/docs/#quickstart) you'll just need to enter the API key after the prompts in the deploy process. - -### Find or create a k2 wallet key -If you have already generated a Koii wallet on yoru filesystem you can obtain the path to it by running `koii config get` which should return something similar to the following: -``` -➜ koii config get -Config File: /home//.config/koii/cli/config.yml -RPC URL: https://k2-testnet.koii.live -WebSocket URL: wss://k2-testnet.koii.live/ (computed) -Keypair Path: /home//.config/koii/id.json -Commitment: confirmed - -``` -The `Keypair Path` will be used to pay gas fees and fund your bounty wallet by inputting it into the task CLI. - -If you need to create a Koii wallet you can follow the instructions [here](https://docs.koii.network/koii-software-toolkit-sdk/using-the-cli#create-a-koii-wallet). Make sure to either copy your keypair path from the output, or use the method above to supply the task CLI with the proper wallet path. ### Deploy to K2 To test the task with the [K2 Settlement Layer](https://docs.koii.network/settlement-layer/k2-tick-tock-fast-blocks) you'll need to deploy it. diff --git a/aws-api-sample.js b/aws-api-sample.js new file mode 100644 index 00000000..9d97b6f7 --- /dev/null +++ b/aws-api-sample.js @@ -0,0 +1,74 @@ +const AWS = require('aws-sdk'); + +async function createAndStartInstance() { + // Configure the AWS SDK with your credentials and region + AWS.config.update({ region: 'us-west-2' }); + + // Create an EC2 service object + const ec2 = new AWS.EC2({ apiVersion: '2016-11-15' }); + + // Create the instance params + const instanceParams = { + ImageId: 'ami-0c94855ba95c71c99', + InstanceType: 't2.micro', + KeyName: 'my-key-pair', + MinCount: 1, + MaxCount: 1, + SecurityGroupIds: ['sg-0123456789abcdefg'], + SubnetId: 'subnet-0123456789abcdefg', + UserData: 'IyEvYmluL2Jhc2gKCnNlcnZlcgo=' // Base64-encoded script to run on startup + }; + + // Create the instance + const data = await ec2.runInstances(instanceParams).promise(); + const instanceId = data.Instances[0].InstanceId; + + console.log(`Created instance ${instanceId}`); + + // Wait until the instance is running + await ec2.waitFor('instanceRunning', { InstanceIds: [instanceId] }).promise(); + + console.log(`Instance ${instanceId} is now running`); + + return instanceId; +} + + +function runTest () { + // first, create and start the instance + let instance = createAndStartInstance(); + + /* then, inject the bash script to + 1. create a new user account + 2. install the dependencies + 3. run the docker container or executables + 4. load and configure local keys or certificates + 5. distribute shards of the key for the new user to known trusted nodes + 6. delete the original user account + */ + // note: a sample of this script is stored in bash-after-launch.sh, but will need to be modified according to your use case + + // then, fetch the IP Address of the node + let ip = fetchIpAddress(instance); + + // finally, start a watcher script and stake tokens on behalf of this new node along with it's IP address +} + +const fetchIpAddress(instanceId) { + // Configure the AWS SDK with your credentials and region + AWS.config.update({ region: 'us-west-2' }); + + // Create an EC2 service object + const ec2 = new AWS.EC2({ apiVersion: '2016-11-15' }); + + // Create the instance params + const instanceParams = { + InstanceIds: [instanceId] + }; + + // Create the instance + const data = await ec2.describeInstances(instanceParams).promise(); + const ip = data.Reservations[0].Instances[0].PublicIpAddress; + + return ip; +} \ No newline at end of file diff --git a/bash-after-launch.sh b/bash-after-launch.sh new file mode 100644 index 00000000..2178cd33 --- /dev/null +++ b/bash-after-launch.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Set the new username and password +new_username="newuser" +new_password="$(openssl rand -base64 12)" + +# Create the new user and add to sudoers +adduser --disabled-password --gecos "" ${new_username} +usermod -aG sudo ${new_username} + +# Switch to the new user +su ${new_username} + +# Update the new user's password +echo "${new_username}:${new_password}" | chpasswd + +# Send the new password to an arbitrary URL via HTTPS POST +url="https://example.com/password" +curl -s -X POST -H "Content-Type: application/json" -d "{\"username\": \"${new_username}\", \"password\": \"${new_password}\"}" ${url} + +# Delete the original user +sudo userdel -r $(whoami) \ No newline at end of file