Skip to content

Commit

Permalink
payment warden for encrypted channels
Browse files Browse the repository at this point in the history
  • Loading branch information
fireduck64 committed Aug 29, 2020
1 parent 843bba7 commit 457763a
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 14 deletions.
2 changes: 1 addition & 1 deletion WORKSPACE
Expand Up @@ -69,7 +69,7 @@ pinned_maven_install()
git_repository(
name = "snowblossom",
remote = "https://github.com/snowblossomcoin/snowblossom",
commit = "595296b74598461034f0051d18f1e7c73a78b783",
commit = "36692b415f1fe901d32680704ceba7e3d7fd27b2",
shallow_since = "1595994852 -0700"
)

Expand Down
24 changes: 24 additions & 0 deletions src/ChannelAccess.java
Expand Up @@ -22,6 +22,7 @@
import snowblossom.proto.WalletDatabase;
import snowblossom.proto.WalletKeyPair;
import snowblossom.util.proto.SymmetricKey;
import com.google.common.collect.ImmutableList;

/**
* Main view and access to a channel for modules that shouldn't have full low level access
Expand Down Expand Up @@ -66,6 +67,11 @@ public StubHolder getSnowStub()
return snow_stub;
}

public ChannelID getChannelID()
{
return ctx.cid;
}

public List<SignedMessage> getOutsiderByTime(int max_return, boolean oldest_first)
{
TreeMap<Double, SignedMessage> message_map = new TreeMap<>();
Expand Down Expand Up @@ -236,4 +242,22 @@ public String getCommonKeyId()
return ChannelCipherUtils.getCommonKeyID(ctx);
}

public void addKey(AddressSpec hash)
throws ValidationException
{
addKeys(ImmutableList.of(hash));
}
public void addKeys(List<AddressSpec> addrs)
throws ValidationException
{
ChannelCipherUtils.addKeys(node, ctx, addrs);
}

public boolean hasKeyInChannel(AddressSpecHash addr)
{
String key_id = ChannelCipherUtils.getCommonKeyID(ctx);
return ChannelCipherUtils.hasKeyInChannel(ctx, key_id, addr);

}

}
2 changes: 1 addition & 1 deletion src/ChannelGlobals.java
Expand Up @@ -3,7 +3,7 @@

public class ChannelGlobals
{
public static final String VERSION = "v0.6.0-2020.08.28.00";
public static final String VERSION = "v0.6.0-2020.08.28.02";

public static final String USER_ADDRESS_STRING="user";
public static final String NODE_ADDRESS_STRING="node";
Expand Down
14 changes: 14 additions & 0 deletions src/ChannelSubscriber.java
Expand Up @@ -14,6 +14,7 @@
import java.util.concurrent.TimeUnit;
import snowblossom.channels.proto.*;
import snowblossom.lib.DaemonThreadFactory;
import snowblossom.channels.warden.PremiumContentWarden;

/**
* Manage channels we are tracking
Expand Down Expand Up @@ -69,8 +70,11 @@ public ChannelContext openChannel(ChannelID cid)
if (opened)
{
node.getChannelPeerMaintainer().wake();
checkForWardens(ctx);
}



return ctx;
}

Expand Down Expand Up @@ -103,6 +107,16 @@ public void dropChannel(ChannelID cid)

}

private void checkForWardens(ChannelContext ctx)
{
ChannelAccess ca = new ChannelAccess(node, ctx);

if (PremiumContentWarden.wantsToRun(ca))
{
new PremiumContentWarden(ca);
}
}

public Set<ChannelID> getChannelSet()
{
HashSet<ChannelID> s = new HashSet<>(16,0.5f);
Expand Down
1 change: 1 addition & 0 deletions src/JsonTest.java
Expand Up @@ -19,6 +19,7 @@ public static void main(String args[]) throws Exception
Offer.Builder offer = Offer.newBuilder();
offer.setOfferMode( Offer.OfferMode.FOREVER_ACCESS );
offer.putOfferPrice("SNOW", OfferCurrency.newBuilder().setPrice(1.0).setAddress("snow:x").build());
offer.setOfferId("bzzzz");

conf.setOffer(offer.build());

Expand Down
135 changes: 123 additions & 12 deletions src/warden/PremiumContentWarden.java
@@ -1,14 +1,39 @@
package snowblossom.channels.warden;

import com.google.protobuf.ByteString;
import com.google.protobuf.util.JsonFormat;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Map;
import java.util.logging.Logger;
import snowblossom.channels.ChannelAccess;
import snowblossom.channels.ChannelID;
import snowblossom.channels.proto.ChannelBlock;
import snowblossom.channels.proto.EncryptedChannelConfig;
import snowblossom.channels.proto.Offer;
import snowblossom.channels.proto.OfferCurrency;
import snowblossom.channels.proto.SignedMessage;
import snowblossom.client.MonitorInterface;
import snowblossom.client.MonitorTool;
import snowblossom.lib.AddressSpecHash;
import snowblossom.lib.ChainHash;
import snowblossom.lib.Globals;
import snowblossom.lib.NetworkParams;
import snowblossom.lib.NetworkParamsProd;
import snowblossom.lib.TransactionUtil;
import snowblossom.lib.AddressUtil;
import snowblossom.proto.Transaction;
import snowblossom.proto.AddressSpec;
import snowblossom.proto.TransactionInner;
import snowblossom.proto.TransactionOutput;
import snowblossom.util.proto.SymmetricKey;
import snowblossom.util.proto.OfferAcceptance;

public class PremiumContentWarden extends BaseWarden
public class PremiumContentWarden extends BaseWarden implements MonitorInterface
{
private static final Logger logger = Logger.getLogger("snowblossom.channels.warden");

public PremiumContentWarden(ChannelAccess channel_access)
{
super(channel_access);
Expand All @@ -22,6 +47,9 @@ public static boolean wantsToRun(ChannelAccess channel_access)

if (encryption_json_data == null) return false;
if (!channel_access.amIBlockSigner()) return false;
if (channel_access.getCommonKeyForChannel() == null) return false;

logger.info("We want to run for " + channel_access.getChannelID());

return true;
}
Expand All @@ -32,34 +60,117 @@ public static boolean wantsToRun(ChannelAccess channel_access)

}

private SymmetricKey sym_key;
private SymmetricKey sym_key;
private EncryptedChannelConfig channel_config;
private MonitorTool snow_monitor_tool;

@Override
public void periodicRun() throws Exception
{
// Read encryption settings file
ByteString encryption_json_data = channel_access.readFile("/web/encryption.json");
logger.info("Running on " + channel_access.getChannelID());
if (sym_key == null)
{
// if exists, load sym key
sym_key = channel_access.getCommonKeyForChannel();
}

// maybe we want to re-read this config on occasion
if (channel_config == null)
{
// Read encryption settings file
ByteString encryption_json_data = channel_access.readFile("/web/encryption.json");

EncryptedChannelConfig.Builder new_config = EncryptedChannelConfig.newBuilder();

JsonFormat.Parser parser = JsonFormat.parser();
Reader input = new InputStreamReader(new ByteArrayInputStream(encryption_json_data.toByteArray()));
parser.merge(input, new_config);

// if exists, load sym key
SymmetricKey sym_key = channel_access.getCommonKeyForChannel();
this.channel_config = new_config.build();

// watch snow address
// on payments to address, compare to required amount
// if so, addKey for recipient
}

Offer offer = channel_config.getOffer();
for(Map.Entry<String, OfferCurrency> me : offer.getOfferPriceMap().entrySet())
{
String currency = me.getKey();
OfferCurrency oc = me.getValue();
if (currency.equals("SNOW"))
{
if (snow_monitor_tool == null)
{
NetworkParams params = new NetworkParamsProd();
snow_monitor_tool = new MonitorTool(params, channel_access.getSnowStub(), this);
AddressSpecHash hash = new AddressSpecHash( oc.getAddress(), params);

snow_monitor_tool.addAddress(hash);

}
}
else
{
logger.warning("PremiumContentWarden: Don't know how to handle currency: " + currency);
}
}

}

@Override
public void onContent(ChannelID cid, SignedMessage sm)
{

}
{}

@Override
public void onBlock(ChannelID cid, ChannelBlock sm)
{}

@Override
public void onInbound(Transaction tx, int tx_out_idx)
{
try
{
ChainHash tx_hash = new ChainHash(tx.getTxHash());
logger.info("Examining payment: " + tx_hash + ":" + tx_out_idx);

Offer offer = channel_config.getOffer();
OfferCurrency oc = offer.getOfferPriceMap().get("SNOW");

TransactionInner inner = TransactionUtil.getInner(tx);

TransactionOutput output = inner.getOutputs(tx_out_idx);

long out_val = output.getValue();
long required_val = (long)Math.round( oc.getPrice() * Globals.SNOW_VALUE_D);
if (out_val < required_val)
{
logger.info(String.format("Payment value too low %d %d", out_val, required_val));
return;
}

OfferAcceptance oa = OfferAcceptance.parseFrom(inner.getExtra());

AddressSpec addr_spec = oa.getForAddressSpec();
AddressSpecHash spec_hash = AddressUtil.getHashForSpec(addr_spec);

if (channel_access.hasKeyInChannel(spec_hash))
{
logger.info("Key already saved");
return;
}

channel_access.addKey(addr_spec);
logger.info("Key added");
}
catch(Exception e)
{
logger.info("Exception in TX processing: " + e);

}
}

@Override
public void onOutbound(Transaction tx, int tx_in_idx)
{}



}

0 comments on commit 457763a

Please sign in to comment.