plebemineira / plebpool

Other
4 stars 2 forks source link

contabilizacao de shares via IPVM, hashmap duplo, e JSON-RPC #2

Open plebhash opened 10 months ago

plebhash commented 10 months ago

para o problema de contabilizao de shares, proponho um hashmap duplo com interface de leitura via RPC

ShareLedger

o modulo plebpool::share_ledger usaria a crate double-map para uso do DHashMap<K1, K2, V


type MinerId = u32;
type JobId = u32;
type BlockHeight = u32;
type ShareCounter = u32;
type HashRate = u32;
type RelativeHashRate = f32;

type TemplateRoot = sha256;
type Difficulty = u32;

struct Job {
  block_height: BlockHeight,
  share_counter: ShareCounter,
  template_root: TemplateRoot,
  difficulty: Difficulty,
}

type ShareLedger = DHashMap<MinerId, JobId, Job>;

impl ShareLedger {
  pub fn get_hashrate(&self, miner_id: MinerId) -> HashRate {}
  pub fn get_global_hashrate(&self) -> HashRate {}
  pub fn get_relative_hashrate(&self, miner_id: MinerId) -> RelativeHashRate {}
  pub fn get_shares(&self, miner_id: MinerId) -> ShareCounter {}
  pub fn add_share(&self, miner_id: MinerId, job_id: JobId) -> Result {}
  pub async fn run(&self) {}
  async fn share_janitor(&self) {}
}

fn add_share

em pseudorust:

struct Job {
   block_height: BlockHeight,
   share_counter: ShareCounter,
   template_root: TemplateRoot,
   difficulty: Difficulty,
 }

 type ShareLedger = DHashMap<MinerId, JobId, Job>;

impl ShareLedger {
  // ...
  pub fn add_share(&self, miner_id: MinerId, job_id: JobId) -> Result {
    // checa `Job.template_root` para verificar se template obedece políticas de template da pool 
    todo!();
    // checa se `Job.difficulty` segue o limiar de dificuldade acordado com `jd_server`
    todo!();
    // checa se `MinerId` corresponde a chave publica associada a assinatura da share
    todo!();

    let mut share_ledger = self.get_keys_value(miner_id, job_id);
    match share_ledger {
       Some(job) => job.share_counter =  job.share_counter + 1,
       None => job.share_counter = 1,
    }
}

referencia sobre fn DHashMap.get_keys_value(): https://docs.rs/double-map/0.14.0/double_map/struct.DHashMap.html#method.get_keys_value)

fn share_janitor

async, checa as block_height, e se a job for antiga (e.g.: 6 blocos passados) ela é descartada de memoria

em pseudorust:

impl ShareLedger {
  // ...
  async fn share_janitor(&self) {
    loop {
       for (_, job_id, _) in self.iter() {
         if job.block_height < prune_height {
           self.remove_key2(`job_id`)
         }
       }

       // T = algum periodo de tempo otimo
       sleep(T);
    }
  }
}

JSON-RPC

o modulo plebhash::json_rpc consome as APIs fornecidas por plebpool::share_ledger e disponibiliza os seguintes endpoints:

get_hashrate

um minerador enviando 1kH/s faria assim para conferir seu hashrate:

curl -X POST -H "Content-Type: application/json" -d '{
   "jsonrpc": "2.0",
   "method": "get_hashrate",
   "params": {
      "miner_id": "xxx",
   },
   "id": 1
}' http://plebpool.io:1789
1_000 # 1 kH/s 

get_global_hashrate

se o minerador quiser saber o hashrate global (e.g.: 10GH/s):

curl -X POST -H "Content-Type: application/json" -d '{
   "jsonrpc": "2.0",
   "method": "get_global_hashrate",
   "params": {},
   "id": 2
}' http://plebpool.io:1789
1_000_000_000 # 1 GH/s 

get_relative_hashrate

se o minerador quiser saber como o hashrate dele se compara ao global:

curl -X POST -H "Content-Type: application/json" -d '{
   "jsonrpc": "2.0",
   "method": "get_relative_hashrate",
     "params": {
      "miner_id": "xxx",
   },
   "id": 3
}' http://plebpool.io:1789
0.000_001 # 1 kH/s  / 1 GH/s

onde o resultado é igual a get_hashrate / get_global_hashrate:

get_shares

se o minerador quiser saber quantas shares ele ja acumulou no job atual (e.g.: 50MH):

curl -X POST -H "Content-Type: application/json" -d '{
   "jsonrpc": "2.0",
   "method": "get_shares",
   "params": {
       "miner_id": "xxx",
   },
   "id": 4
}' http://plebpool.io:1789
50_000_000 # 50 MH
plebhash commented 9 months ago

TLDR: podemos usar a crate homestar (implementacao referencia da IPVM) pra contabilizacao de shares numa VM distribuida em diferentes nodos plebpool_node


o ShareLedger descrito acima pode ser implementado como um programa de IPVM (vm wasm distribuida, tecnologia irmã do IPFS, cria do Protocol Labs)

O IPVM possui um sistema de DB chamado RhizomeDB, que pode servir de primitiva de armazenamento indexado distribuído, sob o qual ShareLedger pode ser abstraído.

assim, cada minerador poderia rodar seu próprio plebpool_node e contabilizar as shares de todos os outros mineradores da pool, dentro de sua própria instância da wasm vm

para cada share encontrada por um minerador, ele é responsável por atualizar o ShareLedger na IPVM. assim que atualiza, ele propaga essa atualização via gossip

contanto que a dificuldade de mineração esteja calibrada para um valor onde a taxa de submissão de shares seja restrita abaixo de um limiar ótimo pra rede, a tendência da IPVM vai ser de atualizar o estado ShareLedger (abstraído na RhizomeDB) de forma automatizada pela submissão de shares

condições necessárias para execução bem sucedida dessa atualização:

plebpool_node rejeita shares que não possuem essas características, e a execução da IPVM para atualização do ShareLedger

mineradores desonestos rodando versões customizadas de plebpool_node (sobrescrevendo o ShareLedger no IPVM de forma desonesta) terão dificuldade em propagar suas shares, pois pares honestos de plebpool_node detectarão que as shares recém inseridas na atualização de estado não atendem os critérios de share válida (template, dificuldade, assinatura), encerrando assim a conexão e isolando o atacante da rede.

contudo, essa arquitetura seria vulnerável a ataques eclipse, onde todas conexões de p2p dos nós plebpool_node honestos são conexões com nós maliciosos... nesse cenário, o estado da IPVM plebpool (armazenamento distribuído da variável ShareLedger implementada com primitivas do RhizomeDB) seria corrompido


referencias em IPVM

https://github.com/ipvm-wg

Apresentacoes

Specs

plebhash commented 9 months ago

criei uma lista de stars pra crates que considero boas candidatas a dependencias: https://github.com/stars/plebhash/lists/plebpool-design

plebhash commented 4 months ago

acho que viajei um pouco nesse aqui

plebhash commented 2 weeks ago

viajei nada isso eh genial