העברת הודעות בין-שרשרת: היכן נשברת מסירת ההודעות
העברת הודעות בין-שרשרת נשברת לא בשליחה, אלא במפגש בין שתי רשתות. תרחיש קלאסי: אישור העסקה ברשת המקור עבר, האירוע נרשם, אך חבילת מסירת ההודעות בין הרשתות לא נאספה כלל — הרילייר לא שלח אותה כלל או שלח אותה עם מגבלת ביצוע נמוכה מדי. הנכס במקור כבר נעול, ובצד המקבל לא הונפק: המשתמש רואה העברה תקועה ולא מבין אם לחזור בה או להמתין.
צוואר הבקבוק השני של האינטגרציה — ביצוע הקריאה ברשת המקבלת. אפילו הודעה שנמסרה עלולה להיכשל: לא היה די gas ללוגיקה מורכבת, הופעל revert בגלל מגבלות או השהיה בחוזה, נפרדו מודלי ה-finality של שתי הרשתות. אם המטפל אינו אידמפוטנטי, מסירה חוזרת מחסלת את המצב במקום לתקן אותו.
קבוצת התקלות השלישית — פער בספי האישור. כללי הוולידציה במקור ובצד המקבל אינם תואמים, ולכן reorg ברשת אחת מותיר נכסים שהונפקו ברשת האחרת ללא ערובה מגובת. במסלולים העוברים דרך מספר רשתות השגיאה מצטברת בכל hop: מקומית הכול נראה תקין, אבל בפלט היתרה אינה מתאזנת.
פרוטוקולי מתווך נבדלים בפרטים, אבל סוג הכשל זהה. אנו מפרקים כיצד זה נסגר: היכן להציב נקודות בקרה, כיצד לתכנן rollback וכיצד לשחזר מסירת הודעות בין רשתות כאשר ההעברה כבר תקועה.
מה מקנה שכבה מנוהלת של חילופי הודעות
העברת הודעות בין-שרשרת מנוהלת מפרידה בין לוגיקת החוזה לתעבורה: את המסלול, האישורים וטיפול השגיאות מחזיק מודול נפרד, ולא אינטגרציה מרוחה על פני קוד האפליקציה.
המפתח מתאר כלל — מה נחשב להודעה שנמסרה ומה לעשות אם האישור לא הגיע. השכבה בוחרת בעצמה את הערוץ לפי סוג הפעולה, ולכן האמינות של הגשר נקבעת לא לפי מספר הרשתות המחוברות, אלא לפי התנהגות צפויה בעת תקלה.
זמן מסירה ו-finality
לכל ערוץ מסירה זמן finality משלו, וערבובם בזרימה אחת הוא סיבה שכיחה להעברות "תקועות". השכבה מפרידה בין פעולות קריטיות (משיכת כספים, שינוי הרשאות) לבין פעולות רקע (רישום סטטיסטיקה): עבור הראשונות — המתנה קשיחה לאי-הפיכות, עבור האחרונות די באישור שליחה. המשתמש רואה את סטטוס הפעולה, ולא "נשלח ודממה".
סוג הכשלים שנעלם
קו טיפול נפרד בשגיאות סוגר את מה שעליו גשרים מאבדים כספים: הודעה שלא נמסרה, שליחה חוזרת, אי-התאמה במצב בין רשתות. לכל הודעה יש מזהה, ולכן שליחה חוזרת של ההודעה אינה מכפילה את הפעולה, והודעה לא תקינה נדחית עוד לפני הביצוע.
ניתוח פומבי של תקלות בגשרים (Chainalysis) מתכנס לנקודה אחת: את ההפסדים גורם לא פריצת ההצפנה, אלא היעדר בדיקה ו-rollback בצד האפליקציה.
במקום לנתח תקלה בדיעבד, הצוות מקבל מערכת כללים ניתנים לבדיקה: מגבלות על נפח, הסגר בעת אי-התאמה, יומן ניסיונות מסירה עם השלמה ידנית.
מצבי מסירת הודעות: השוואת גישות
מצב מסירת ההודעות קובע מי מאשר את עצם השליחה ברשת המקור וכיצד ההוכחה הזו מגיעה לרשת היעד. מכך תלויים זמן המסירה, למי אתם סומכים על אבטחת המסלול וכיצד הוא יתנהג בעת עומס יתר או עצירה של אחת הרשתות.
סכמות ולידטוריות וסכמות אורקל
כאן הודעה נחתמת על ידי קבוצת צמתים בלתי תלויה — רשת ולידטורית, או צירוף של אורקל ורילייר. הקונצנזוס אורך שניות, נזילות בצד היעד אינה נדרשת, ולכן קל להרחיב את המסלול לרשתות חדשות. כך בנויים Axelar ו-Wormhole.
הנקודה החלשה — קבוצת הוולידטורים עצמה: סף החתימות, מודל התמריצים וקצב רוטציית המפתחות. אם הסף נמוך או שהמפעילים קשורים זה לזה, המסירה עובדת פורמלית, אבל האמון בה אינו גבוה מזה שבמתווך.
גשרי נזילות ומגבלותיהם
כאן ההוכחה כלל אינה מועברת: המשתמש מקבל נכס מאושר מהמאגר ברשת היעד, והיתרות מתאזנות בזרימה נפרדת. זה מקנה זיכוי מיידי ואינטגרציה פשוטה לארנק.
מגבלות הגישה — תקרת הנזילות של המאגר, חוסר סנכרון ביתרות וסיכון בעת זרימה חד-כיוונית חדה החוצה. לקוח קל, שבודק בעצמו את כותרות הבלוקים, מסיר את שאלת האמון, אבל דורש תחזוקה יקרה ועמידות לעיכובי finality.
| אפשרות | מתי מתאים | מגבלות |
|---|---|---|
| רשת ולידטורית עם סף חתימות | מסלולים רבים, נדרשת מסירה מהירה ומדיניות אבטחה אחידה | אמון בקבוצת הצמתים, סיכון לקשר והשבתה, מורכב יותר לביקורת חיצונית |
| לקוח קל ואורקל-רילייר | רשתות גדולות, שבהן חשובה בדיקוּת כותרות ללא מתווך | יקר יותר בתחזוקה, רגיש לעיכובי finality |
| גשר נזילות | העברת נכסים עם זיכוי מיידי בצד היעד | תקרת נזילות, חוסר סנכרון ביתרות, ירידה בעת זרימה החוצה |
| החלפה אטומית | עסקה חד-פעמית בין שני צדדים ללא מתווך | נדרשים תרחישים תואמים וצד שכנגד, מתקשה להתרחב |
בחירת המצב היא פשרה בין מהירות, עלות ומודל אמון, ולשנות אותה בדיעבד יקר: עבור כל אפשרות נכתב מחדש שכבת האישורים וטיפול הכשלים.
כיצד אנו מיישמים העברת הודעות בין-שרשרת
את העבודה מתחילים במיפוי מלאי: חוזים, מרשמי טוקנים, תפקידים והרשאות, גשרים פעילים. סדר השלבים זהה גם לפתרון חדש וגם לשדרוג של פתרון קיים — משתנה רק עומק הביקורת של האינטגרציה.
ביקורת ותרשים מסלולים
- ביקורת האינטגרציה. מפרקים חוזים, הרשאות מנהל, טיפול בשגיאות ותגובת האפליקציה לעיכובים. בפלט — רשימת צווארי בקבוק ושינויים הנדרשים לפני חיבור ה-router.
- תרשים המסלולים. קובעים בין אילו רשתות עוברות הודעות, איזה router מסירה מתאים (Axelar, Wormhole, LayerZero), מי מכסה את העמלה בצד המקבל וכיצד מטופל כשל.
- פורמט ההודעה. מקבעים את מבנה החבילה, ניהול גרסאות, מגבלות גודל והגנה מפני מסירה חוזרת — אותה הודעה לא אמורה להעביר את ההעברה פעמיים.
- הגדרת המסירה. מגדירים מתאמי רשת, תור אישורים, ספי עמלה ומדיניות ניסיונות חוזרים בעת timeout.
הגדרה, בדיקה ברשת בדיקות ומסירה
- בדיקה ברשת בדיקות. מריצים תרחישים: מסירה מוצלחת, timeout, חזרה ידנית, rollback. בנפרד בודקים את ההתנהגות בעת פער ב-finality של בלוקים בין רשתות.
- מסירת הפתרון. מוסרים קונפיגורציות, תרשים מסלולים, נהלי ניסיונות חוזרים והוראות לשלילת הרשאות, ומכשירים את צוות התורנות.
- תמיכה לאחר ההשקה. בשבועות הראשונים עוקבים אחר שיעור ההודעות המוצלחות, זמן המעבר הממוצע ומספר ההתערבויות הידניות.
מה נשאר במאגר הקוד ובידי הצוות
אנחנו מוסרים לא רק קוד: במאגר נשאר כל מה שדרוש כדי להוסיף מסלולים ולפרוס כיוונים חדשים בלעדינו. להלן רשימת התוצרים שנקבעת בפרוטוקול הקבלה, והנהלים שלפיהם המערכת ממשיכה לפעול.
תוצרים במאגר
- קונפיגורציית מסלולים: כיוונים נתמכים בין רשתות, מגבלות על גודל ההודעה, סדרי עדיפויות ולוגיקת עמלות.
- מדיניות גישה: תפקידים בחוזי השולח והמקבל, מי מוסמך להוסיף מסלול או לשנות מגבלות, סכמת multi-sig.
- תרשימי זרימה: נתיב ההודעה מהקריאה ועד האישור ברשת היעד, נקודות כשל, התנהגות במסירה חוזרת והגנה מפני כפילויות.
- סקריפטים לפריסה ולמיגרציות: בנייה משוחזרת של סביבות, עדכון חוזים בלי לעצור את הזרימה.
- מערכת בדיקות: רשת מקומית והרצות על עותק של מצב הרשת הנוכחי, תרחישים נפרדים ל-revert ול-rollback.
נהלים וניטור
- נוהל תגובה: רמות אירועים, תפקידי תורנים, חלון תגובה, סדר עצירת המסלול והפעלתו מחדש.
- מדדים: שיעור ההודעות שלא נמסרו, זמן האישור, עומק התור של חבילות שלא טופלו.
- ספי התראות והוראות תורנות: מה לבדוק ראשון, באיזה ערך לקרוא למהנדס.
- הרשאות ורוטציית מפתחות: היכן נשמרים, למי זכות החתימה, כיצד להחליפם ללא השבתה.
תיעוד האינטגרציה מתאר את חיבורו של חוזה או כיוון חדשים, פורמטי הקריאות והמגבלות — לפיו הצוות שלכם מפעיל את הרשת הבאה בעצמו.
מקרה בוחן: סילקנו העברות תקועות בגשר
הפרויקט — העברת הודעות בין-שרשרת עבור שירות העברות בין רשתות: ההודעה יוצאת מרשת אחת ואמורה להתבצע ברשת אחרת. הלקוח הגיע עם בעיה מהתמיכה — חלק מההעברות נתקעו בחוליה הביניימית, וכל מקרה נבדק ידנית. האינטגרציה כבר הייתה בנויה על LayerZero, אך בלי טיפול בכשלים בצד המקבל.
מה היה לפני
הגשר שלח את ההודעה במעבר אחד: החתימה נאספה — החבילה יצאה. אם האישור מהרשת השנייה לא הגיע בחלון שהוקצה, ההעברה נותרה תלויה באוויר: לא שגיאה מפורשת, לא שליחה חוזרת, ולא רישום שמשהו השתבש.
לפי הלוגים של הגשר, שיעור ההעברות התקועות הגיע עד 4% מהנפח היומי, וזמן מסירת ההודעה בבקשות מסוימות נמתח מדקות לשעות.
הסיבות היו שתיים. הראשונה — אין במה לסגור את ההעברה בצד הביצוע כשהנזילות במאגר ברשת הנדרשת נגמרת. השנייה — אישור שאבד בעת עומס ברשת המקבלת: החבילה הגיעה, אבל הקבלה לא. נציג התמיכה השווה hashes, הפעיל ניסיון חוזר ידנית ולא תמיד ידע אם ההעברה בוצעה — את הסיכון לחיוב כפול סגרו ביד.
מה נהיה אחרי וכיצד מדדנו
כתבנו מחדש את הזרימה כמערכת הרצה עמידה. כל הודעה מקבלת מזהה ייחודי, הסטטוס נרשם ביומן מצבים, הניסיונות החוזרים פועלים לפי לוח זמנים עם הגדלת המרווח, ובמיצוי הניסיונות מופעל החזר אוטומטי. האישור נבדק לפני הביצוע, ולכן חיוב כפול נשלל ברמת הלוגיקה, ולא ברמת תשומת הלב של המפעיל.
את המדדים לקחנו מיומן הגשר על נפח העברות בר-השוואה — לפני ואחרי השינויים. שיעור ההעברות התקועות ירד מ-4% ל-0.3%, זמן מסירת ההודעה באחוזון ה-95 התקצר מחצי שעה לשתי דקות, ו-98% מהניסיונות החוזרים שהופעלו אוטומטית מסתיימים בהצלחה בלי מעורבות אדם.
בדיקה ידנית נותרה רק למקרים שבהם נגמרת הנזילות — וזו כבר משימה של מילוי המאגר, ולא של חיפוש חבילה שאבדה.
במה נבדלת שכבה ולידטורית מגשר נזילות?
שכבה ולידטורית מעבירה את ההודעה עצמה ומאשרת אותה בחתימות של קבוצת ולידטורים בלתי תלויה, ואילו גשר נזילות מחזיק ערובה בצד המקור ומנפיק נכס מגובה בצד המקבל. ההבדל אינו במהירות המסירה, אלא במה שאתם נותנים בו אמון: סף החתימות, או ספיקות הערובה ועומק המאגר בצד שממול.
| אפשרות | מודל אמון | מתי מתאים | סיכוני הגשר |
|---|---|---|---|
| שכבה ולידטורית | סף חתימות של ולידטורים | נתונים שרירותיים בין רשתות | קשר בין החותמים, פגיעה במפתחות |
| גשר נזילות | ערובה ונזילות בצד המקבל | העברת נכסים מגובים | חוסר איזון במאגר, עיכוב במשיכה |
| סכמה היברידית | אימות חיצוני בתוספת מאגר מקומי | תרחישים משולבים | כשל של שני הקווים |
בחירת סכמת המסירה נקבעת לפי סוג הכשל שמותר לכם. כשהחשוב יותר הוא תאימות התרחישים — לוקחים שכבה ולידטורית ומגבילים את סמכויותיה בתקיפות; כשנדרש רישום נכסים צפוי — גשר נזילות עם מגבלות על נפח.
אנו נעזרים בסקירה חיצונית של דרישות האבטחה לגשרים בין-שרשרתיים: הפרדת תפקידי החותמים, תקרה על גודל ההודעה, עצירת הזרימה בעת אנומליה.
סיכוני הגשר נמצאים לרוב לא בקוד ההעברה, אלא בקונפיגורציה: כתובת אחת גם מאשרת וגם מבצעת; אין השהיה בעת זינוק; אין יומן החלטות. לכן קודם מקבעים את גבול האמון בתרשים, אחר כך מרימים ניטור על הזרימה — ורק לאחר מכן מחברים את המסלולים.
ספקות טכניים לפני ההתחלה
כשלים בהעברת הודעות בין-שרשרת מתגלים לא בתרחיש השגרתי, אלא ב-rollback-ים, ב-reorg-ים ובחוסר סנכרון של אישורים בין רשתות. להלן שאלות שצוותי הנדסה שואלים לפני ההתחלה, והתשובות שלנו לכל צוואר בקבוק.
מה יקרה אם נצטרך להחליף את פרוטוקול מסירת ההודעות?
שכבת המתאם מפרידה בין הלוגיקה העסקית לבין ה-messenger המסוים: חוזה הקולט עובד מול ממשק, ולא מול שירות המסירה ישירות. החלפת פרוטוקול משמעה החלפת מימוש המתאם ובדיקה חוזרת של המסלולים, בלי לכתוב מחדש את לוגיקת הרישום והטוקנים.
האם הודעה אחת עלולה להימסר פעמיים?
אידמפוטנטיות נשמרת על מזהה ההודעה: הצד הקולט שומר hashes של חבילות שטופלו, וקריאה חוזרת מסתיימת בלי שינוי במצב. בנוסף בדיקת השולח ומונה ההודעות — מסירה כפולה אינה מביאה לזיכוי חוזר.
מה נכלל בביקורת האבטחה?
אנו בודקים את גבולות האמון בין הרשתות, את ההתנהגות כששירות המסירה אינו זמין, את הרשאות הפונקציות הניהוליות ואת הטיפול בכשלים. דוח עם ניתוח הממצאים ואישור סגירת הסעיפים הקריטיים נמסר יחד עם הקוד.
מה עם התמיכה לאחר המסירה?
אנו נשארים בתמיכה: ניטור תור ההודעות, התראות על עיכובי מסירה, עדכון מתאמים בשינוי ממשקים חיצוניים. נוהל התגובה וגבולות האחריות נקבעים בהסכם נפרד.
נדון במשימה ונחזור עם תוכנית עבודה
כדי לחזור עם אומדן עבודה, ולא עם ניסוחים כלליים, עלינו לראות את גבולות המערכת: אילו רשתות מעורבות, אילו נכסים נעים ומי יוזם ההעברה. ככל שנתוני הקלט מדויקים יותר, כך יש פחות הנחות באומדן והמועדים של השלבים מציאותיים יותר.
- רשימת רשתות המקור ורשתות היעד, עם ציון היכן החוזים כבר נפרסו והיכן הם רק מתוכננים.
- הרשאות: צמתי רשת או ספקי גישה לכל רשת, קו בדיקות, מפתחות נפרדים לדיבאג.
- תרחישי העברה: מי יוזם, מה ננעל למשך הפעולה, מה קורה בעת כשל בחוליה הביניימית.
- סכמת הרישום הנוכחית: כיצד מאזנים יתרות, היכן מתנהל יומן הפעולות, מי ולפי איזה כלל מטפל באי-התאמות.
- דרישות לאישור: כמה אישורים אנו רואים כמספקים והאם נדרשת בדיקה ידנית של העברות שנויות במחלוקת.
- מגבלות: דרישות לאחסון נתונים, מגבלות על נפח הפעולות, תאריכים הקשורים לרליזים של המוצר.
בתמורה נשלח אומדן עבודה לפי שלבים, תוכנית יישום עם תלויות בין חוליות המסלול, לוחות זמנים לכל שלב וסכמת חלוקת אחריות. בנפרד נסכם מה אנו עושים ברשתות הבדיקות לפני ההעברה הראשונה עם ערך אמיתי — זוהי בדיוק הנקודה שאחריה אנו יוצאים לדרך.
תארו את המשימה כפי שהיא: רשימת רשתות, מצב החוזים הנוכחי, מגבלות. נחזור עם אומדן ותוכנית יישום.







