Skip to content

Instantly share code, notes, and snippets.

@ayende
Last active May 26, 2020 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayende/cc6ddbcc44e6c072d0e284b4c60a0cf2 to your computer and use it in GitHub Desktop.
Save ayende/cc6ddbcc44e6c072d0e284b4c60a0cf2 to your computer and use it in GitHub Desktop.
using (var session = store.OpenAsyncSession(new SessionOptions
{
TransactionMode = TransactionMode.ClusterWide
}))
{
var src = await session.LoadAsync<Account>("accounts/123-A",
x => x.IncludeCompareExchangeValue(a=>a.PublicKey));
var dst = await session.LoadAsync<Account>("accounts/456-B",
x => x.IncludeCompareExchangeValue(a=>a.PublicKey));
var srcPk = await session.Advanced.ClusterTransaction
.GetCompareExchangeValueAsync<PublicKeyClusterWideState>(src.PublicKey);
var dstPk = await session.Advanced.ClusterTransaction
.GetCompareExchangeValueAsync<PublicKeyClusterWideState>(dst.PublicKey);
if(src.Blocked || dst.Blocked)
throw new InvalidOperationException("Unable to transfer money from/to block");
if(src.Funds < 5)
throw new InvalidOperationException("Insufficient funds");
if(srcPk.Value.Funds != src.Funds ||
dstPk.Value.Funds != dst.Funds)
throw new InvalidOperationException("Document state is not sync with compare exchange value, retry later");
var coins = src.WithdrawCoins(amount);
if (coins.Any(coin => coin.Tainted))
throw new InvalidOperationException("Unable to use tainted coins");
dst.AddCoins(coins);
srcPk.Value.Funds = src.Funds;
dstPk.Value.Funds = dst.Funds;
await session.SaveChangesAsync();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment