Skip to content

Commit b017b49

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 78e02d4 commit b017b49

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

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

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)