assetStore *database.AssetStore
txCh chan *orm.CrossTransaction
fedProg []byte
+ quorum int
position uint8
xpub chainkd.XPub
xprv chainkd.XPrv
assetStore: assetStore,
txCh: make(chan *orm.CrossTransaction),
fedProg: util.ParseFedProg(cfg.Warders, cfg.Quorum),
+ quorum: cfg.Quorum,
position: local.Position,
xpub: local.XPub,
xprv: string2xprv(xprvStr),
return err
}
+ approvalCnt := 0
signersSigns := make([][][]byte, getInputsCnt(destTx))
-
signerSigns, err := w.getSigns(destTx, ormTx)
if err != nil {
log.WithFields(log.Fields{"err": err, "cross-chain tx": ormTx}).Warnln("getSigns")
return err
}
- // TODO: err?
- w.attachSignsForTx(ormTx, signersSigns, w.position, signerSigns)
+ if err := w.attachSignsForTx(ormTx, signersSigns, w.position, signerSigns); err != nil {
+ log.WithFields(log.Fields{"err": err, "cross-chain tx": ormTx}).Warnln("attachSignsForTx")
+ return err
+ }
+
+ approvalCnt += 1
- // TODO: should we always request?
for _, remote := range w.remotes {
signerSigns, err := remote.RequestSigns(destTx, ormTx)
if err != nil {
log.WithFields(log.Fields{"err": err, "remote": remote, "cross-chain tx": ormTx}).Warnln("RequestSign")
- return err
+ continue
+ }
+
+ if err := w.attachSignsForTx(ormTx, signersSigns, remote.Position, signerSigns); err != nil {
+ log.WithFields(log.Fields{"err": err, "remote position": remote.Position, "cross-chain tx": ormTx}).Warnln("attachSignsForTx")
+ continue
}
- // TODO: err?
- w.attachSignsForTx(ormTx, signersSigns, remote.Position, signerSigns)
+ approvalCnt += 1
}
- if w.isTxSignsReachQuorum(signersSigns) && w.isLeader() {
- // TODO: check err
- w.finalizeTx(destTx, signersSigns)
+ if approvalCnt >= w.quorum && w.isLeader() {
+ if err := w.finalizeTx(destTx, signersSigns); err != nil {
+ log.WithFields(log.Fields{"err": err, "cross-chain tx": ormTx, "dest tx": destTx}).Warnln("finalizeTx")
+ return err
+ }
+
submittedTxID, err := w.submitTx(destTx)
if err != nil {
log.WithFields(log.Fields{"err": err, "cross-chain tx": ormTx, "dest tx": destTx}).Warnln("submitTx")
return signs, nil
}
-// destTx interface{}
-// TODO:
func (w *warder) attachSignsForTx(ormTx *orm.CrossTransaction, signersSigns [][][]byte, position uint8, signerSigns [][]byte) error {
- // TODO: rename
- // signWitness := make([][]string, len(signersSigns))
-
- // TODO:
+ for inpIdx := range signerSigns {
+ signerSigns[inpIdx][position] = signerSigns[inpIdx]
+ }
var signsStrs []string
for _, signerSign := range signerSigns {
}).Error
}
-// TODO:
-func (w *warder) isTxSignsReachQuorum(destTx interface{}) bool {
- return false
-}
-
func (w *warder) isLeader() bool {
return w.position == 1
}