Skip to content

Commit d0d8ace

Browse files
committed
assets: implement asset deposit key reveal
With this commit, the client can now reveal the keys of asset deposits to the server. This allows the server to sweep the deposits as needed, without requiring further interaction with the client.
1 parent 508b78d commit d0d8ace

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

assets/deposit/manager.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,3 +1096,76 @@ func (m *Manager) publishPendingWithdrawals(ctx context.Context) error {
10961096

10971097
return nil
10981098
}
1099+
1100+
// RevealDepositKeys reveals the internal keys for the given deposit IDs to
1101+
// the swap server.
1102+
func (m *Manager) RevealDepositKeys(ctx context.Context,
1103+
depositIDs []string) error {
1104+
1105+
done, err := m.scheduleNextCall()
1106+
if err != nil {
1107+
return err
1108+
}
1109+
defer done()
1110+
1111+
// First check that all requested deposits are in the required state and
1112+
// collect the keys.
1113+
keys := make(map[string][]byte, len(depositIDs))
1114+
for _, depositID := range depositIDs {
1115+
d, ok := m.deposits[depositID]
1116+
if !ok {
1117+
log.Warnf("Can't reveal key for deposit %v as it is "+
1118+
"not active", depositID)
1119+
}
1120+
1121+
if d.State != StateConfirmed && d.State != StateKeyRevealed {
1122+
return fmt.Errorf("deposit %v key cannot be revealed",
1123+
depositID)
1124+
}
1125+
1126+
internalPubKey, internalPrivKey, err := DeriveSharedDepositKey(
1127+
ctx, m.signer, d.FunderScriptKey,
1128+
)
1129+
if err != nil {
1130+
return err
1131+
}
1132+
1133+
if !d.FunderInternalKey.IsEqual(internalPubKey) {
1134+
log.Errorf("Funder internal key %x does not match "+
1135+
"expected %x for deposit %v",
1136+
d.FunderInternalKey.SerializeCompressed(),
1137+
internalPubKey.SerializeCompressed(), depositID)
1138+
1139+
return fmt.Errorf("funder internal key mismatch")
1140+
}
1141+
1142+
keys[depositID] = internalPrivKey.Serialize()
1143+
}
1144+
1145+
// Update the deposit state before we actually push the keys to the
1146+
// server. Otherwise we may fail to update the state in our database,
1147+
// despite the server accepting the keys.
1148+
for depositID := range keys {
1149+
d := m.deposits[depositID]
1150+
d.State = StateKeyRevealed
1151+
err = m.handleDepositStateUpdate(ctx, d)
1152+
if err != nil {
1153+
return err
1154+
}
1155+
1156+
log.Infof("Revealing deposit key for %v: pub=%x", depositID,
1157+
d.FunderInternalKey.SerializeCompressed())
1158+
}
1159+
1160+
// Now push the keys to the server.
1161+
_, err = m.depositServiceClient.PushAssetDepositKeys(
1162+
ctx, &swapserverrpc.PushAssetDepositKeysReq{
1163+
DepositKeys: keys,
1164+
},
1165+
)
1166+
if err != nil {
1167+
return err
1168+
}
1169+
1170+
return err
1171+
}

assets/deposit/server.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,18 @@ func (s *Server) RevealAssetDepositKey(ctx context.Context,
129129
in *looprpc.RevealAssetDepositKeyRequest) (
130130
*looprpc.RevealAssetDepositKeyResponse, error) {
131131

132-
return nil, status.Error(codes.Unimplemented, "unimplemented")
132+
if s.manager == nil {
133+
return nil, ErrAssetDepositsUnavailable
134+
}
135+
136+
err := s.manager.RevealDepositKeys(
137+
ctx, []string{in.DepositId},
138+
)
139+
if err != nil {
140+
return nil, status.Error(codes.Internal, err.Error())
141+
}
142+
143+
return &looprpc.RevealAssetDepositKeyResponse{}, nil
133144
}
134145

135146
// WithdrawAssetDeposits is the rpc endpoint for loop clients to withdraw their

0 commit comments

Comments
 (0)