private IEnumerable <ICoin> BuildTransaction( TransactionBuildingContext ctx, BuilderGroup group, IEnumerable <Builder> builders, IEnumerable <ICoin> coins) { var originalCtx = ctx.CreateMemento(); var target = builders.Concat(ctx.AdditionalBuilders).Select(b => b(ctx)).Sum(); if (ctx.CoverOnly != null) { target = ctx.CoverOnly + ctx.ChangeAmount; } var selection = CoinSelector.Select(coins, target); if (selection == null) { throw new NotEnoughFundsException("Not enough fund to cover the target"); } var total = selection.Select(s => s.Amount).Sum(); var change = total - target; if (change < Money.Zero) { throw new NotEnoughFundsException("Not enough fund to cover the target"); } if (change > ctx.Dust) { if (group.ChangeScript[(int)ctx.ChangeType] == null) { throw new InvalidOperationException("A change address should be specified (" + ctx.ChangeType + ")"); } ctx.RestoreMemento(originalCtx); ctx.ChangeAmount = change; try { return(BuildTransaction(ctx, group, builders, coins)); } finally { ctx.ChangeAmount = Money.Zero; } } foreach (var coin in selection) { var input = ctx.Transaction.AddInput(new TxIn(coin.Outpoint)); if (_LockTime != null && _LockTime.HasValue && !ctx.NonFinalSequenceSet) { input.Sequence = 0; ctx.NonFinalSequenceSet = true; } } return(selection); }
public TransactionBuilder Then() { _CurrentGroup = null; return(this); }
/// <summary> /// Set the group of the builder property /// </summary> /// <param name="builderGroup">The builder group</param> public BuilderPropertyPosition InGroup(BuilderGroup builderGroup) { BuilderGroup = builderGroup; return(this); }
public BuilderGroup CreateDeepCopy(BuilderGroup copyGroup) { MemoryStream m = new MemoryStream(); BinaryFormatter b = new BinaryFormatter(); b.Serialize(m, copyGroup); m.Position = 0; return (BuilderGroup)b.Deserialize(m); }
public static List<BuilderGroup> GetBuilderGroups() { List<BuilderGroup> groupList = new List<BuilderGroup>(); using (var db = new SNAPDatabaseDataContext()) { var query = from sa in db.SNAP_Actors join sag in db.SNAP_Actor_Groups on sa.actor_groupId equals sag.pkId where sa.isActive == true && sag.isActive == true && sag.actorGroupType < 2 orderby sag.actorGroupType, sag.groupName ascending select new { ActorId = sa.pkId, UserId = sa.userId, DisplayName = sa.displayName, IsDefault = sa.isDefault, IsLargeGroup = sag.isLargeGroup, GroupId = sag.pkId, GroupName = sag.groupName, Description = sag.description, ActorGroupType = sag.actorGroupType }; foreach (var actor in query) { List<BuilderActor> actorList = new List<BuilderActor>(); BuilderActor newActor = new BuilderActor(); newActor.ActorId = actor.ActorId; newActor.UserId = actor.UserId; newActor.DisplayName = actor.DisplayName; newActor.IsDefault = actor.IsDefault; newActor.ActorGroupType = (ActorGroupType)actor.ActorGroupType; BuilderGroup accessGroup = groupList.Find(delegate(BuilderGroup _grp) { if (_grp.GroupId == actor.GroupId) { // group exists return true; } // group doesn't exist return false; }); if (accessGroup != null) { actorList = accessGroup.AvailableActors; actorList.Add(newActor); accessGroup.AvailableActors = actorList; } else { BuilderGroup newGroup = new BuilderGroup(); actorList.Add(newActor); newGroup.GroupId = actor.GroupId; newGroup.GroupName = actor.GroupName; newGroup.Description = actor.Description; newGroup.ActorGroupType = (ActorGroupType)actor.ActorGroupType; newGroup.IsLargeGroup = (bool)actor.IsLargeGroup; newGroup.AvailableActors = actorList; newGroup.ActorGroupType = (ActorGroupType)actor.ActorGroupType; groupList.Add(newGroup); } } } return groupList; }
private IEnumerable<ICoin> BuildTransaction( TransactionBuildingContext ctx, BuilderGroup group, IEnumerable<Builder> builders, IEnumerable<ICoin> coins, IMoney zero) { var originalCtx = ctx.CreateMemento(); var target = builders.Concat(ctx.AdditionalBuilders).Select(b => b(ctx)).Sum(zero); if(ctx.CoverOnly != null) { target = ctx.CoverOnly.Add(ctx.ChangeAmount); } var unconsumed = coins.Where(c => ctx.ConsumedCoins.All(cc => cc.Outpoint != c.Outpoint)); var selection = CoinSelector.Select(unconsumed, target); if(selection == null) throw new NotEnoughFundsException("Not enough fund to cover the target", group.Name, target.Sub(unconsumed.Select(u => u.Amount).Sum(zero)) ); var total = selection.Select(s => s.Amount).Sum(zero); var change = total.Sub(target); if(change.CompareTo(zero) == -1) throw new NotEnoughFundsException("Not enough fund to cover the target", group.Name, change.Negate() ); if(change.CompareTo(ctx.Dust) == 1) { var changeScript = group.ChangeScript[(int)ctx.ChangeType]; if(changeScript == null) throw new InvalidOperationException("A change address should be specified (" + ctx.ChangeType + ")"); if(!(ctx.Dust is Money) || change.CompareTo(GetDust(changeScript)) == 1) { ctx.RestoreMemento(originalCtx); ctx.ChangeAmount = change; try { return BuildTransaction(ctx, group, builders, coins, zero); } finally { ctx.ChangeAmount = zero; } } } foreach(var coin in selection) { ctx.ConsumedCoins.Add(coin); var input = ctx.Transaction.Inputs.FirstOrDefault(i => i.PrevOut == coin.Outpoint); if(input == null) input = ctx.Transaction.AddInput(new TxIn(coin.Outpoint)); if(_LockTime != null && !ctx.NonFinalSequenceSet) { input.Sequence = 0; ctx.NonFinalSequenceSet = true; } } return selection; }
public TransactionBuilder Then() { _CurrentGroup = null; return this; }