Skip to content

Commit c035613

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 094912e commit c035613

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
@@ -1167,3 +1167,76 @@ func (m *Manager) publishPendingWithdrawals(ctx context.Context) error {
11671167

11681168
return nil
11691169
}
1170+
1171+
// RevealDepositKeys reveals the internal keys for the given deposit IDs to
1172+
// the swap server.
1173+
func (m *Manager) RevealDepositKeys(ctx context.Context,
1174+
depositIDs []string) error {
1175+
1176+
done, err := m.scheduleNextCall()
1177+
if err != nil {
1178+
return err
1179+
}
1180+
defer done()
1181+
1182+
// First check that all requested deposits are in the required state and
1183+
// collect the keys.
1184+
keys := make(map[string][]byte, len(depositIDs))
1185+
for _, depositID := range depositIDs {
1186+
d, ok := m.deposits[depositID]
1187+
if !ok {
1188+
log.Warnf("Can't reveal key for deposit %v as it is "+
1189+
"not active", depositID)
1190+
}
1191+
1192+
if d.State != StateConfirmed && d.State != StateKeyRevealed {
1193+
return fmt.Errorf("deposit %v key cannot be revealed",
1194+
depositID)
1195+
}
1196+
1197+
internalPubKey, internalPrivKey, err := DeriveSharedDepositKey(
1198+
ctx, m.signer, d.FunderScriptKey,
1199+
)
1200+
if err != nil {
1201+
return err
1202+
}
1203+
1204+
if !d.FunderInternalKey.IsEqual(internalPubKey) {
1205+
log.Errorf("Funder internal key %x does not match "+
1206+
"expected %x for deposit %v",
1207+
d.FunderInternalKey.SerializeCompressed(),
1208+
internalPubKey.SerializeCompressed(), depositID)
1209+
1210+
return fmt.Errorf("funder internal key mismatch")
1211+
}
1212+
1213+
keys[depositID] = internalPrivKey.Serialize()
1214+
}
1215+
1216+
// Update the deposit state before we actually push the keys to the
1217+
// server. Otherwise we may fail to update the state in our database,
1218+
// despite the server accepting the keys.
1219+
for depositID := range keys {
1220+
d := m.deposits[depositID]
1221+
d.State = StateKeyRevealed
1222+
err = m.handleDepositStateUpdate(ctx, d)
1223+
if err != nil {
1224+
return err
1225+
}
1226+
1227+
log.Infof("Revealing deposit key for %v: pub=%x", depositID,
1228+
d.FunderInternalKey.SerializeCompressed())
1229+
}
1230+
1231+
// Now push the keys to the server.
1232+
_, err = m.depositServiceClient.PushAssetDepositKeys(
1233+
ctx, &swapserverrpc.PushAssetDepositKeysReq{
1234+
DepositKeys: keys,
1235+
},
1236+
)
1237+
if err != nil {
1238+
return err
1239+
}
1240+
1241+
return err
1242+
}

assets/deposit/server.go

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

143-
return nil, status.Error(codes.Unimplemented, "unimplemented")
143+
if s.manager == nil {
144+
return nil, ErrAssetDepositsUnavailable
145+
}
146+
147+
err := s.manager.RevealDepositKeys(
148+
ctx, []string{in.DepositId},
149+
)
150+
if err != nil {
151+
return nil, status.Error(codes.Internal, err.Error())
152+
}
153+
154+
return &looprpc.RevealAssetDepositKeyResponse{}, nil
144155
}
145156

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

0 commit comments

Comments
 (0)