פיתוח סנייפר בוט: מדוע הזמנות מפסידות בממפול
טוקן זה עתה הופיע במאגר הנזילות, ובשניות הראשונות עשרות בוטים נכנסים אליו בו-זמנית.
ההזמנה נשלחת לממפול — התור המשותף של טרנזקציות שאינן מאושרות — ומתחילה תחרות על הבלוק: את המקום מקבל לא מי שלחץ על הכפתור מוקדם יותר, אלא מי שהטרנזקציה שלו הגיעה למאמתים מהר יותר ובמחיר גז גבוה יותר.
ההפסד במחיר הכניסה נראה שגרתי: העסקה עוברת, אך בשער שכבר עלה, או שהיא מתבטלת — בינתיים הנזילות נקנתה כולה. שורש הבעיה הוא השהיית שליחת הטרנזקציה: בזמן שהקוד מרכיב את החתימה, ממתין לתשובת הצומת ולאישור, המתחרה שולח חבילה לכמה כתובות בבת אחת ולוקח את הבלוק. בוט בלי שליטה בהשהיה הזו קונה במחיר גרוע לא מדי פעם, אלא באופן שיטתי.
הערמומיות היא שהכשל אינו נראה בסביבת הבדיקות: מקומית הכול עובר באופן מיידי, ואילו ברשת האמיתית כל פעולה מיותרת לפני השליחה היא מקום אבוד בבלוק. הדחייה במקרה כזה נראית כמו «השוק לא אפשר להיכנס», אף שההחלטה התקבלה לאט ובהתבסס על נתונים מיושנים. אי אפשר להחזיר את רגע הכניסה: מחיר הטעות נקבע לכל משך חיי הפוזיציה.
נבחן כיצד זה נסגר בפיתוח סנייפר בוט — מהכנת הטרנזקציה ועד לאישור.
מה נותן ביצוע מבוקר: מהירות, שיעור פגיעות, דחיות
ביצוע מבוקר אינו «סקריפט מהיר», אלא מערך של ארבע חוליות: מאזין הממפול, סימולציה מקומית על עותק של המצב העדכני של Ethereum, הרכבה וחתימה של הטרנזקציה, ושליחה בכמה מסלולים בלתי תלויים. כל חוליה אחראית למדד משלה ונשברת בדרכה שלה.
את זמן התגובה לאירוע אנו מודדים לא מרגע «הבחנת הטוקן», אלא מרגע הופעת הטרנזקציה בתור ההמתנה. את מצב הצומת אנו מחזיקים מחומם מראש, את מטען הטרנזקציה מרכיבים בלי פניות ביניים, והחתימה והסריאליזציה מתבצעות בזרם אחד. התגובה מסתכמת בשברירי שנייה — זה מספיק כדי להיכנס לאותו בלוק, ולא לבלוק הבא.
את שיעור ההזמנות המבוצעות קובעת הסימולציה: לפני השליחה אנו מריצים את העסקה על עותק של המצב העדכני ופוסלים מקרים שבהם היעד כבר נקנה, מסלול ההחלפה ריק, או שהטרנזקציה תוחזר בוודאות (revert). זה מסיר את רוב ניסיונות הסרק ושומר על מחיר הכניסה סמוך למחיר האירוע המפעיל, ולא בשיא התנופה.
בנפרד אנו מנהלים מעקב אחר סוגי הדחיות. נעלמות הדחיות בשל מצב מיושן, חוסר בגז ושליחה חוזרת עם אותו מונה (nonce). נותרות אלו שתלויות בתחרות: בלוק של אחר הקדים אותנו, או שהנזילות נוצלה לפני ההכללה. אותן איננו מסתירים, אלא מסמנים ביומן — דרכן רואים היכן בדיוק המערך מאבד מהירות.
לסיכום: ההזמנה או מבוצעת במחיר הצפוי, או נרשמת עם סיבת דחייה ברורה. בהמשך נבחן ממה מורכב מערך כזה ומה נשאר באחריות הלקוח.
שיטות למעקב אחר נזילות: השוואת גישות
במעקב אחר נזילות לא הלוגיקה של הקנייה היא הקובעת, אלא כמה מוקדם הבוט רואה את הופעת הצמד ומספיק להיכנס לאותו בלוק. להלן ארבע סכמות — כיצד בנויה כל אחת, לאיזו משימה היא מתאימה והיכן היא נתקלת במגבלות תשתית ופרטיות.
| אפשרות | כיצד בנויה | מתי מתאימה | מגבלות |
|---|---|---|---|
| מנוי לזרם טרנזקציות דרך ספק חיצוני | שירות מוכן מספק טרנזקציות שאינן מאושרות, הבוט מסנן לפי כתובות של factories | התחלה מהירה, בדיקות אסטרטגיה, זרם קטן | אפיק משותף: הפניות גלויות לספק, הסינון מתבצע אחריו, חלק מהאירועים מגיע מאוחר יותר |
| צומת צופה בתשתית שלך | צומת מלא במצב המתנה לטרנזקציות שאינן מאושרות, הזרם נקרא מקומית | מסחר שוטף, נדרשת השהיה מזערית | דורש משאבים ותחזוקה: סנכרון, עדכונים, נפח נתונים גדל |
| ערוץ שליחה פרטי | הטרנזקציה יוצאת במסלול סגור בעקיפין לממפול המשותף, ישירות ליצרן הבלוק | הגנה מפני הקדמה והעתקת העסקה | אינו מבטיח הכללה בבלוק: נדרש מסלול גיבוי ובקרת סטטוס |
| טריגר אירועי לפי לוגים של החוזה | מנוי להוספת נזילות ולשינוי הרשאות, הבוט מגיב למאושר | בקרת סיכון, בדיקת טוקן, יציאה על פי עובדה | האירוע נראה רק לאחר ההכללה בבלוק — לא מתאים לכניסה באותה שנייה |
תצורה עובדת היא שילוב: צומת צופה נותן את הזרם המוקדם ביותר, טריגר אירועי סוגר את בקרת הסיכון, וערוץ פרטי אחראי על המסירה. תארו את תרחיש המסחר — נחזור עם הערכה ותוכנית הרכבה.
שלבי ההטמעה: מביקורת הזרם ועד למסירת הנהלים
את העבודה על הסנייפר בוט אנו בונים כך שנקודות בעייתיות נחשפות לפני היציאה לכספים אמיתיים. כל שלב נסגר בנקודת בקרה — ארטפקט שממנו רואים אם אפשר להמשיך הלאה.
מה בודקים בכל שלב
- ביקורת זרם הטרנזקציות. מנתחים כיצד יוצאות ההנפקות המטרה: אילו חוזים מקבלים גישה ראשונים, באיזו השהיה מגיע האירוע והיכן מתבזבז הזמן בין הופעת ההזמנה בתור לבין הכללתה בבלוק. בקרה — תרשים המסלול עם צווארי הבקבוק המסומנים.
- תרשים הפתרון. מפרידים בין המנוי לאירועים, קבלת ההחלטה והשליחה, כך שכשל בבלוק אחד לא יעצור את האחרים. בקרה — תרשים עם אזורי כשל ועומס מרבי לכל חלק.
- הגדרת הגישה. מחברים ערוץ ראשי וערוץ גיבוי לרשת, קובעים ספים לגודל ההזמנה, להחלקה (סליפאז') המותרת ולמספר הניסיונות במקביל.
- סימולציה של העסקה. מריצים תרחישים על תמונת מצב של הרשת: האם ההזמנה עוברת במחיר הצפוי, האם ההגנה מפני תנודות חדות מופעלת. בקרה — דוח על שיעור ההרצות המוצלחות וניתוח הנדחות.
- רשת בדיקות. בודקים את המחזור המלא במערך ציבורי, כולל עצירה, הפעלה מחדש ושחזור הגדרות.
- מסירת נהלים. מוסרים תיעוד: כיצד להסיר הזמנה תקועה, לכבות את הבוט, לשנות מגבלות בלי מפתח.
נקודות הבקרה נותנות ללקוח את הזכות לעצור את העבודה בכל שלב. עד היציאה לרשת הראשית התנהגות הבוט כבר ידועה מתוך הסימולציות ומהמערך בבדיקות — ההשקה מפסיקה להיות הגרלה.
מה מוסרים לידיים: תצורות, תרשיםים, מדיניויות, נהלים
את הפרויקט מוסרים לא בהדגמה של «ראו איך זה עובד», אלא כמערכת של ארטפקטים במאגר (repository) שלכם. מהנדס מהצוות שלכם או קבלן בתחזוקה פורס את המערך לפי התיעוד ומשחזר את התנהגות הבוט אחד לאחד — בלי התכתבות עם המחבר.
- תצורת המערך — פרופילים לרשת הראשית ולסטנד מבודד: ספי גז, מגבלות גודל עסקה, מספר ניסיונות וההשהיות ביניהם. נערכים בקובץ אחד, בלי שינוי בקוד.
- תרשים זרמי הטרנזקציות — המסלול מגילוי המועמד בממפול ועד לאישור או ביטול: היכן מחושבת הסימולציה, באיזה רגע מוצבת החתימה, אילו ענפים מופעלים במקרה של כישלון והחלפת טרנזקציה.
- מדיניויות גישה למפתחות — היכן נשמרים מפתחות החתימה, מי וכיצד מקבל אותם, כיצד מתבצעת רוטציה, וכיצד מופרדים תפקידי המפעיל והמנהל.
- תרחישי סימולציה — הרצה על בלוקים היסטוריים: תחרות על נזילות, זינוק חד בגז, טרנזקציות שנדחו. חוזרים עליהם לפני כל עדכון לוגיקה.
- מדדים והתראות — שיעור הפגיעות המוצלחות, הזמן מהגילוי ועד לאישור, הפעלות של מפסקי מגן ומגבלות.
- תיעוד תחזוקה — נהלים: פעולות במקרה של טרנזקציה תקועה, בירידה בתפקוד הצומת, סדר הפריסה של גרסה חדשה והשחזור לקודמת.
- צ'קליסט קבלה — מערך בדיקות שלפיהן אתם מקבלים את העבודה וחוזרים עליהן לאחר כל שינוי בתצורה.
מקרה בוחן: השקת טוקן, שיעור ההזמנות המבוצעות גדל פי כמה
הלקוח — צוות שהשיק טוקן ברשת הראשית של Ethereum — הגיע עם בעיה שבה יותר ממחצית ההזמנות לא הגיעו לבלוק. ברגע תחילת המסחר נכנסו למאגר עשרות טרנזקציות בו-זמנית, הסנייפר בוט שלנו נכנס לתור והפסיד: שיעור הדחיות עמד על 30–40%, וההחלקה במחיר הכניסה הגיעה ל-15%.
הסיבה לא הייתה במהירות הסקריפט, אלא בכך שהלוגיקה לא הסתכלה על הממפול ולא בדקה את התוצאה לפני החתימה.
מה שינינו בארכיטקטורה
בנינו מחדש את התרחיש לשלושה מערכים. הראשון — מאזין הממפול: הוא עוקב אחר יצירת הצמד וההזמנות הראשונות, ולא ממתין לאישור הבלוק. השני — סימולציה של העסקה על עותק מקומי של מצב הרשת לפני השליחה: היא מציגה את מחיר הכניסה הסופי ואת הספיקות העמלה.
השלישי — ניהול העמלה: תעריף בסיס בתוספת תוספת עדיפות בהתאם לעומס הנוכחי, והחלפה אוטומטית של הטרנזקציה אם לא נכנסה לבלוק.
מה יצא
לאחר העברת הבדיקות למערך הסימולציה ירד שיעור הדחיות ל-4–6%, ושיעור ההזמנות המבוצעות גדל פי כמה באותן השקות. ההחלקה במחיר הצטמצמה ל-0,5–1,2%: חלק מהעסקאות נפסלות על ידי הסימולציה עוד לפני השליחה, כשהתנאים גרועים מהסף שהוגדר.
מקרה ההטמעה מאלף בכך שצוואר הבקבוק התגלה לא במהירות החתימה, אלא בהיעדר בדיקה לפניה — כניסה צפויה למאגר וסיכון מבוקר במקום ניסיונות חוזרים עיוורים.
במה נבדלת לוגיקת סנייפר מלוגיקת ארביטראז'
מבחינת תשתית, שני המערכים עומדים על אותו דבר: נודה משלך, מנוי לממפול, סימולציה מוקדמת של הטרנזקציה על המצב העדכני של השרשרת, ניהול סדר העדיפויות וחתם משותף. ההבדל מתחיל ברמת כלל קבלת ההחלטה: בלוגיקת סנייפר זו תגובה לאירוע בודד, ובמערך ארביטראז' — חישוב חוזר ומתמשך של צירופים.
מערך הסנייפר ממתין ליצירת צמד או להוספת נזילות ועליו להיכנס לאותו בלוק או לבלוק הבא. חלון ההחלטה הוא שברירי שנייה, ולכן המסננים שטחיים: כתובת היוצר, סף הנזילות, בדיקת מגבלות מכירה בתוך החוזה. מחיר הטעות הוא כניסה לטוקן לא נזיל, ומכאן ההימור על סימולציה ורשימות לבנות במקום אנליטיקה מורכבת.
מערך הארביטראז' פועל ללא הרף ומשווה מחירים בכמה מאגרים בבת אחת. לו חשובה לא מהירות הירי הבודד, אלא תפוקה: כמה צירופים חושבו מחדש לכל בלוק וכמה מהם נותרו רווחיים לאחר עמלת הרשת וההחלקה. מכאן גם היחס השונה לדחיות — הארביטראז' מחזיק revert כמצב שגרתי, הסנייפר אינו מתיר אותו.
| מה משווים | לוגיקת סנייפר | מערך ארביטראז' |
|---|---|---|
| טריגר | מאגר חדש, הוספת נזילות | פער מחירים בין מאגרים |
| חלון ההחלטה | בלוק אחד-שניים | כל בלוק, ברצף |
| חישוב לפני שליחה | סיכוני החוזה וסף הנזילות | מרווח הצירוף עם עמלה והחלקה |
| מחיר הטעות | כניסה לנכס לא נזיל | גז שנשרף |
| מדד מרכזי | השהיה מהאירוע ועד החתימה | מספר הצירופים שחושבו מחדש לכל בלוק |
בפועל, ברשתות בסדר גודל של Ethereum, מעבירים ממערך אחד למשנהו את הנודה, הסימולטור ומבצע הטרנזקציות — הם תואמים. נכתבים מחדש שכבת ההחלטה והמדיניות בנוגע לגז: הסנייפר צריך מרווח להכללה מובטחת בבלוק, והארביטראז' — חישוב מחדש של המגבלה בכל איטרציה.
ספקות טכניים: עמלות רשת, מגבלות, ערוצים פרטיים
ספקות בשלב בחירת הקבלן כמעט תמיד נוגעים לא ללוגיקת הכניסה, אלא להתנהגות הבוט תחת עומס: עמלת הרשת, מגבלות הצומת, נראות ההזמנה, הגישה למפתחות. להלן תשובות ישירות לכל סעיף.
מה אם עמלת הרשת תעלה ברגע הכניסה?
העמלה מחושבת לפי מצב התור הנוכחי ואינה קבועה מראש: לפני השליחה הטרנזקציה עוברת סימולציה על הבלוק העדכני. אם מחיר הכניסה הצפוי חורג מהגבול שהוגדר, ההזמנה אינה יוצאת — קפיצה ברשת אינה הופכת להפסד.
האם ניתקל במגבלות הצומת בעת זינוק?
השליחה מתבצעת דרך כמה צמתים בלתי תלויים עם פיזור פניות, והתור מפוצל לפי חשבונות-משלמים, כדי לא להיתקל ברצף מספור אחד. צומת שמפגר אחרי הבלוק העדכני מוצא מהרוטציה באופן אוטומטי.
עד כמה השליחה פרטית?
בממפול הציבורי ההזמנה גלויה לפני הכניסה לבלוק — מספיקים לקרוא אותה ולהקדים אותה. כניסות קריטיות יוצאות בערוץ פרטי ישירות לבוני הבלוקים: הטרנזקציה מופיעה ברשימה המשותפת רק לאחר ההכללה, כשאין מה להקדים.
כיצד מוגנים המפתחות?
המפתחות אינם נשמרים בצורה גלויה ואינם יוצאים מהמערך שלכם: החתימה מתבצעת בשירות מבודד, והחוצה יוצאת רק הטרנזקציה המוכנה. הגישה מופרדת לפי תפקידים, ופעולות עם מפתחות נרשמות ביומן.
נדון במשימה: מה נדרש להתחלה וכיצד אנו מחשבים סיכונים
כדי שהתחלת העבודה לא תהפוך לשורה של ניחושים, אנו זקוקים למינימום של נתוני מוצא. סנייפר בוט אינו תוכנה נפרדת, אלא חיבור של «מקור אירועים — לוגיקת סינון — חתימת טרנזקציה», והחוליה החלשה בשרשרת הזו נראית רק ברשת חיה. לכן אנו אוספים את נתוני המוצא של הפרויקט לפני ההערכה, ולא אחריה.
מה נדרש מכם בהתחלה:
- רשת ותרחיש ההשקה: צמד חדש, ליסטינג בבורסה, כניסה חוזרת למאגר קיים;
- כתובות של חוזי המטרה או כללים שלפיהם הבוט בוחר טוקנים בעצמו;
- גישה לצומת: שלכם או של ספק, עם אילו מגבלות פניות ועומק היסטוריית הממפול;
- ארנק ומודל החתימה: היכן נשמר המפתח, מי מאשר כל טרנזקציה;
- מסגרת הסיכון: גודל פוזיציה מרבי, החלקה מותרת, מספר ניסיונות לאות אחד;
- מדדי מטרה: שיעור הטרנזקציות שהובאו עד להכללה, הזמן מגילוי האירוע ועד השליחה;
- מי בצד שלכם אחראי על הכספים ועל ההיבט המשפטי של עבודה עם טוקנים.
לאחר הניתוח אנו חוזרים עם הערכה לפי שלבים, תוכנית עבודה עם נקודות בקרה ורשימת סיכונים — בנפרד לכל סוג: הסימולציה לא עברה, הקדימו את הטרנזקציה בתור, מחיר הגז עלה בין החישוב לשליחה. בנוסף אנו מתארים כיצד נבדוק את הלוגיקה ברשת בדיקות לפני הוצאת כספים אמיתיים.
תארו את המשימה בצורה חופשית — נחזור עם הערכה, תוכנית ורשימת סיכונים.







