Skip to content

Commit

Permalink
Groundwork for mining pool
Browse files Browse the repository at this point in the history
  • Loading branch information
fireduck64 committed Jun 6, 2018
1 parent ad929ae commit 8ede8f5
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 17 deletions.
87 changes: 79 additions & 8 deletions node/src/BlockForge.java
Expand Up @@ -9,6 +9,13 @@
import java.security.MessageDigest;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.ArrayList;
import org.junit.Assert;
import java.util.Random;

import com.google.common.collect.ImmutableList;

/**
* This class creates new blocks for miners to work on
Expand All @@ -24,7 +31,7 @@ public BlockForge(SnowBlossomNode node)
this.params = node.getParams();
}

public Block getBlockTemplate(AddressSpecHash mine_to, CoinbaseExtras extras)
public Block getBlockTemplate(SubscribeBlockTemplateRequest mine_to)
{
BlockSummary head = node.getBlockIngestor().getHead();

Expand Down Expand Up @@ -70,7 +77,7 @@ public Block getBlockTemplate(AddressSpecHash mine_to, CoinbaseExtras extras)
fee_sum += Validation.deepTransactionCheck(tx, utxo_buffer);
}

Transaction coinbase = buildCoinbase( header_builder.getBlockHeight(), fee_sum, mine_to, extras);
Transaction coinbase = buildCoinbase( header_builder.getBlockHeight(), fee_sum, mine_to);
Validation.deepTransactionCheck(coinbase, utxo_buffer);

block_builder.addTransactions(coinbase);
Expand All @@ -96,7 +103,8 @@ public Block getBlockTemplate(AddressSpecHash mine_to, CoinbaseExtras extras)

}

private Transaction buildCoinbase(int height, long fees, AddressSpecHash mine_to, CoinbaseExtras extras)
private Transaction buildCoinbase(int height, long fees, SubscribeBlockTemplateRequest mine_to)
throws ValidationException
{
Transaction.Builder tx = Transaction.newBuilder();

Expand All @@ -105,7 +113,7 @@ private Transaction buildCoinbase(int height, long fees, AddressSpecHash mine_to
inner.setIsCoinbase(true);

CoinbaseExtras.Builder ext = CoinbaseExtras.newBuilder();
ext.mergeFrom(extras);
ext.mergeFrom(mine_to.getExtras());

if (height == 0)
{
Expand All @@ -117,10 +125,8 @@ private Transaction buildCoinbase(int height, long fees, AddressSpecHash mine_to

long total_reward = PowUtil.getBlockReward(params, height) + fees;

inner.addOutputs( TransactionOutput.newBuilder()
.setValue(total_reward)
.setRecipientSpecHash(mine_to.getBytes())
.build());
inner.addAllOutputs( makeCoinbaseOutputs( params, total_reward, mine_to));


ByteString inner_data = inner.build().toByteString();

Expand All @@ -133,6 +139,71 @@ private Transaction buildCoinbase(int height, long fees, AddressSpecHash mine_to
return tx.build();
}

public static List<TransactionOutput> makeCoinbaseOutputs(NetworkParams params, long total_reward, SubscribeBlockTemplateRequest req)
throws ValidationException
{
if (req.getPayRewardToSpecHash().size() > 0)
{
AddressSpecHash addr = new AddressSpecHash(req.getPayRewardToSpecHash());

return ImmutableList.of(
TransactionOutput.newBuilder()
.setValue(total_reward)
.setRecipientSpecHash(addr.getBytes())
.build());
}
double total_weight = 0.0;
Map<String, Double> ratio_input_map = req.getPayRatios();

for(Double d : ratio_input_map.values())
{
total_weight += d;
}

Map<String, Long> amount_output_map = new TreeMap<>();
ArrayList<String> names_with_funds = new ArrayList<>();
double total_reward_dbl = total_reward;
long spent_reward = 0;
for(Map.Entry<String, Double> me : ratio_input_map.entrySet())
{
String s = me.getKey();
double ratio = me.getValue();

long val = (long)(total_reward_dbl * ratio / total_weight);
if (val > 0)
{
spent_reward +=val;
names_with_funds.add(s);
amount_output_map.put(s,val);
}
}

long diff = total_reward - spent_reward;
Assert.assertTrue(spent_reward <= total_reward);

if (diff != 0)
{
Random rnd = new Random();
String name = names_with_funds.get(rnd.nextInt(names_with_funds.size()));
amount_output_map.put(name, amount_output_map.get(name) + diff);

}

LinkedList<TransactionOutput> outs = new LinkedList<>();
for(Map.Entry<String, Long> me : amount_output_map.entrySet())
{
AddressSpecHash addr = AddressUtil.getHashForAddress(params.getAddressPrefix(), me.getKey());
outs.add(
TransactionOutput.newBuilder()
.setValue(me.getValue())
.setRecipientSpecHash(addr.getBytes())
.build());
}

return outs;

}

private List<Transaction> getTransactions(ChainHash prev_utxo_root)
{
return node.getMemPool().getTransactionsForBlock(prev_utxo_root, Globals.MAX_BLOCK_SIZE);
Expand Down
13 changes: 5 additions & 8 deletions node/src/SnowUserService.java
Expand Up @@ -39,9 +39,8 @@ public void start()
public void subscribeBlockTemplate(SubscribeBlockTemplateRequest req, StreamObserver<Block> responseObserver)
{
logger.info("Subscribe block template called");
AddressSpecHash pay_to = new AddressSpecHash(req.getPayRewardToSpecHash());

BlockSubscriberInfo info = new BlockSubscriberInfo(pay_to, req.getExtras(), responseObserver);
BlockSubscriberInfo info = new BlockSubscriberInfo(req, responseObserver);

synchronized(block_subscribers)
{
Expand All @@ -55,7 +54,7 @@ protected void sendBlock(BlockSubscriberInfo info)
{
if (node.areWeSynced())
{
Block block = node.getBlockForge().getBlockTemplate(info.mine_to, info.extras);
Block block = node.getBlockForge().getBlockTemplate(info.req);
info.sink.onNext(block);
}
else
Expand Down Expand Up @@ -278,15 +277,13 @@ public void getMempoolTransactionList(RequestAddress req, StreamObserver<Transac

class BlockSubscriberInfo
{
final AddressSpecHash mine_to;
final CoinbaseExtras extras;
final SubscribeBlockTemplateRequest req;
final StreamObserver<Block> sink;

public BlockSubscriberInfo(AddressSpecHash mine_to, CoinbaseExtras extras, StreamObserver<Block> sink)
public BlockSubscriberInfo(SubscribeBlockTemplateRequest req, StreamObserver<Block> sink)
{
this.mine_to = mine_to;
this.req = req;
this.sink = sink;
this.extras = extras;
}
}

Expand Down
1 change: 1 addition & 0 deletions node/test/AllTests.java
Expand Up @@ -8,6 +8,7 @@
@SuiteClasses({
MemPoolTest.class,
BlockIngestorTest.class,
BlockForgeTest.class
})
public class AllTests
{}
3 changes: 2 additions & 1 deletion protolib/snowblossom.proto
Expand Up @@ -199,8 +199,9 @@ message SubmitReply {

message SubscribeBlockTemplateRequest {
bytes pay_reward_to_spec_hash = 1;
int64 refresh_delay = 2; // time in ms to get updated block templates of the same block number
int64 refresh_delay = 2; // time in ms to get updated block templates of the same block number - ignored
CoinbaseExtras extras = 3;
map<string, double> pay_ratios = 4;
}

message GetUTXONodeRequest {
Expand Down

0 comments on commit 8ede8f5

Please sign in to comment.