Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/DZ Mainnet-beta Connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,6 @@ default via 149.28.38.1 dev enp1s0 proto dhcp src 149.28.38.64 metric 100

</div>

### Up Next: Multicast
### Up Next: Publishing Shreds via Multicast

If you have completed this setup and plan to use Multicast, proceed to the [next page](Multicast%20Connection.md).
If you have completed this setup and plan publishing shreds via multicast, proceed to the [next page](DoubleZero%20Validator%20Multicast.md).
4 changes: 2 additions & 2 deletions docs/DZ Testnet Connection.md
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,6 @@ default via 149.28.38.1 dev enp1s0 proto dhcp src 149.28.38.64 metric 100

</div>

### Up Next: Multicast
### Up Next: Publishing Shreds via Multicast

If you have completed this setup and plan to use Multicast, proceed to the [next page](Multicast%20Connection.md).
If you have completed this setup and plan publishing shreds via multicast, proceed to the [next page](DoubleZero%20Validator%20Multicast.md).
47 changes: 47 additions & 0 deletions docs/DoubleZero Validator Multicast.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# DoubleZero Validator Multicast
!!! warning "By connecting to DoubleZero I agree to the [DoubleZero Terms of Service](https://doublezero.xyz/terms-protocol)"




### Publishing shreds to bebop (validators)

After following [setup](setup.md), and the relevant [testnet](DZ%20Testnet%20Connection.md) or [mainnet-beta](DZ%20Mainnet-beta%20Connection.md) validator connection documentation you may publish shreds to the DoubleZero multicast group. Validators can publish shreds to the **bebop** multicast group. The multicast destination is `233.84.178.1:7733`. Configure your validator client as follows:

#### Jito Agave (version x.x.x or higher)

1. Connect to the DoubleZero multicast group bebop as a publisher:
`doublezero connect multicast --publish bebop`
2. In your validator start script, add:
`--shred-receiver-address 233.84.178.1:7733`
3. Restart your validator.

#### Frankendancer

1. Connect to the DoubleZero multicast group bebop as a publisher:
`doublezero connect multicast --publish bebop`
2. In `config.toml`, add:
```toml
[tiles.shred]
additional_shred_destinations_leader = [ "233.84.178.1:7733", ]
```
3. Restart your validator.

#### Confirm you are publishing

During your next leader slot, confirm you are publishing to the multicast group, use tcpdump during your next leader slot. You should see a heartbeat every 30 seconds.

Run: `sudo tcpdump -c5 -ni doublezero1 port 7733 or port 4096 or port 5765 -vv`

Example output when publishing:

```
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on doublezero1, link-type LINUX_SLL (Linux cooked v1), snapshot length 262144 bytes
23:13:37.189797 IP 147.51.126.79.8015 > 233.84.178.1.7733: UDP, length 1203
23:13:37.189816 IP 147.51.126.79.8015 > 233.84.178.1.7733: UDP, length 1203
...
5 packets captured
64 packets received by filter
0 packets dropped by kernel
```
9 changes: 3 additions & 6 deletions docs/Multicast Connection.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
# Multicast Connections
# Other Multicast
!!! warning "By connecting to DoubleZero I agree to the [DoubleZero Terms of Service](https://doublezero.xyz/terms-protocol)"

The DoubleZero Network supports public and private Multicast services. Using Multicast, data published from one source can be efficiently distributed to multiple consumers (subscribers). Publishers do not need to send individual streams to each subscriber. Multicast is a capability which is not available on the Internet.


|Use Case | First Step | When Approve, connect via:|
|---------|------------|---------------------------|
|Subscribe to Jito Shredstream | Contact Jito for approval. | ```doublezero connect multicast --subscribe jito-shredstream``` |
|Publish to a Private Service | If you'd like to publish to a private service, please contact the DZ Foundation here. When approved, you connect via | ```doublezero connect multicast --publish <feed name>``` [optional additional feed names space separated] |
|Subscribe to a Private Service | If you'd like to subscribe to a private service, please contact the owner of that Service or fill in this form to be directed. | ```doublezero connect multicast --subscribe <feed name>``` [optional additional feed names space separated] |

Detailed connection information:

Expand Down Expand Up @@ -70,4 +67,4 @@ doublezero user list --client-ip <your ip>

|account | user_type | groups | device | location | cyoa_type | client_ip | dz_ip | accesspass | tunnel_id | tunnel_net | status | owner |
|----|----|----|----|----|----|----|----|----|----|----|----|----|
|wQWmt7L6mTyszhyLywJeTk85KJhe8BGW4oCcmxbhaxJ | Multicast | P:mg02 | ams-dz001 | Amsterdam | GREOverDIA | 137.174.145.145 | 198.18.0.1 | Prepaid: (MAX) | 515 | 169.254.3.58/31 | activated | DZfHfcCXTLwgZeCRKQ1FL1UuwAwFAZM93g86NMYpfYan|
|wQWmt7L6mTyszhyLywJeTk85KJhe8BGW4oCcmxbhaxJ | Multicast | P:mg02 | ams-dz001 | Amsterdam | GREOverDIA | 137.174.145.145 | 198.18.0.1 | Prepaid: (MAX) | 515 | 169.254.3.58/31 | activated | DZfHfcCXTLwgZeCRKQ1FL1UuwAwFAZM93g86NMYpfYan|
44 changes: 44 additions & 0 deletions docs/ValidatorShredPublishing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# DoubleZero Validator Multicast
!!! warning "By connecting to DoubleZero I agree to the [DoubleZero Terms of Service](https://doublezero.xyz/terms-protocol)"

### Publishing shreds to bebop (validators)

After following [setup](setup.md), and the relevant [testnet](DZ%20Testnet%20Connection.md) or [mainnet-beta](DZ%20Mainnet-beta%20Connection.md) validator connection documentation you may publish shreds to the DoubleZero multicast group. Validators can publish shreds to the **bebop** multicast group. The multicast destination is `233.84.178.1:7733`. Configure your validator client as follows:

#### Jito Agave (version x.x.x or higher)

1. Connect to the DoubleZero multicast group bebop as a publisher:
`doublezero connect multicast --publish bebop`
2. In your validator start script, add:
`--shred-receiver-address 233.84.178.1:7733`
3. Restart your validator.

#### Frankendancer

1. Connect to the DoubleZero multicast group bebop as a publisher:
`doublezero connect multicast --publish bebop`
2. In `config.toml`, add:
```toml
[tiles.shred]
additional_shred_destinations_leader = [ "233.84.178.1:7733", ]
```
3. Restart your validator.

#### Confirm you are publishing

During your next leader slot, confirm you are publishing to the multicast group, use tcpdump during your next leader slot. You should see a heartbeat every 30 seconds.

Run: `sudo tcpdump -c5 -ni doublezero1 port 7733 or port 4096 or port 5765 -vv`

Example output when publishing:

```
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on doublezero1, link-type LINUX_SLL (Linux cooked v1), snapshot length 262144 bytes
23:13:37.189797 IP 147.51.126.79.8015 > 233.84.178.1.7733: UDP, length 1203
23:13:37.189816 IP 147.51.126.79.8015 > 233.84.178.1.7733: UDP, length 1203
...
5 packets captured
64 packets received by filter
0 packets dropped by kernel
```
174 changes: 35 additions & 139 deletions docs/javascripts/page-toolbar.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
// Page toolbar functionality for documentation pages
// Adds toolbar with Copy Page, View Markdown, Ask in ChatGPT, and Ask in Claude
// Page toolbar: Copy Page, View Markdown, Ask in ChatGPT, Ask in Claude (all pages)
(function() {
'use strict';

// Check if we're on the setup page
function isSetupPage() {
// Check if current page path includes 'setup'
var path = window.location.pathname;
// Handle various URL formats: /setup/, /setup, /setup.html, /users/setup/, etc.
var normalizedPath = path.replace(/\/$/, '').replace(/\.html$/, '').toLowerCase();
return normalizedPath.endsWith('/setup') || normalizedPath.endsWith('setup') ||
normalizedPath === '/setup' || normalizedPath === 'setup';
}

// Create the toolbar HTML
function createToolbar() {
var toolbar = document.createElement('div');
toolbar.className = 'page-toolbar';
toolbar.innerHTML =
toolbar.innerHTML =
'<a href="#" class="page-toolbar-link" id="copy-page-btn">' +
'<img src="data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'16\' height=\'16\' viewBox=\'0 0 24 24\' fill=\'none\' stroke=\'%23ffffff\' stroke-width=\'2\' stroke-linecap=\'round\' stroke-linejoin=\'round\'%3E%3Crect x=\'9\' y=\'9\' width=\'13\' height=\'13\' rx=\'2\' ry=\'2\'%3E%3C/rect%3E%3Cpath d=\'M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\'%3E%3C/path%3E%3C/svg%3E" class="page-toolbar-icon" alt="" />' +
'Copy Page' +
Expand All @@ -40,171 +28,79 @@
return toolbar;
}

// Get page content as text
function getPageContent() {
var content = document.querySelector('.md-content__inner');
if (!content) {
content = document.querySelector('main');
}
if (!content) {
content = document.body;
}
if (!content) content = document.querySelector('main');
if (!content) content = document.body;
return content ? content.innerText || content.textContent : '';
}

// Get page title
function getPageTitle() {
var title = document.querySelector('h1');
return title ? title.textContent.trim() : document.title;
}

// Copy page content to clipboard
function copyPageToClipboard() {
var content = getPageContent();
var title = getPageTitle();
var textToCopy = title + '\n\n' + content;

var textToCopy = getPageTitle() + '\n\n' + getPageContent();
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(textToCopy).then(function() {
showCopyFeedback('copy-page-btn');
}).catch(function(err) {
console.error('Failed to copy:', err);
fallbackCopy(textToCopy);
});
} else {
fallbackCopy(textToCopy);
}
}).catch(function() { fallbackCopy(textToCopy); });
} else { fallbackCopy(textToCopy); }
}

// Fallback copy method for older browsers
function fallbackCopy(text) {
var textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
showCopyFeedback('copy-page-btn');
} catch (err) {
console.error('Fallback copy failed:', err);
}
document.body.removeChild(textArea);
var ta = document.createElement('textarea');
ta.value = text;
ta.style.position = 'fixed';
ta.style.left = '-999999px';
document.body.appendChild(ta);
ta.select();
try { document.execCommand('copy'); showCopyFeedback('copy-page-btn'); } catch (e) {}
document.body.removeChild(ta);
}

// Show copy feedback
function showCopyFeedback(buttonId) {
var btn = document.getElementById(buttonId);
if (btn) {
var icon = btn.querySelector('.page-toolbar-icon');
var textNode = Array.from(btn.childNodes).find(function(node) {
return node.nodeType === 3 && node.textContent.trim();
});
if (textNode) {
var originalText = textNode.textContent.trim();
textNode.textContent = 'Copied!';
btn.classList.add('copied');
setTimeout(function() {
textNode.textContent = originalText;
btn.classList.remove('copied');
}, 2000);
}
var originalText = btn.textContent;
btn.textContent = 'Copied!';
btn.classList.add('copied');
setTimeout(function() { btn.textContent = originalText; btn.classList.remove('copied'); }, 2000);
}
}

// View markdown source
function viewMarkdown() {
// Get the current page path
var path = window.location.pathname;
// Remove leading/trailing slashes and .html extension
path = path.replace(/^\/|\/$/g, '').replace(/\.html$/, '');

// Default to setup.md if path is empty or just 'setup'
if (!path || path === 'setup') {
path = 'setup';
}

// Construct GitHub raw URL
// Repository: malbeclabs/docs
var repoOwner = 'malbeclabs';
var repoName = 'docs';
var branch = 'main';

// Try to construct GitHub raw URL
var markdownUrl = 'https://raw.githubusercontent.com/' + repoOwner + '/' + repoName + '/' + branch + '/docs/' + path + '.md';

// Open in new tab
var path = window.location.pathname.replace(/^\/|\/$/g, '').replace(/\.html$/, '') || 'index';
var markdownUrl = 'https://raw.githubusercontent.com/malbeclabs/docs/main/docs/' + path + '.md';
window.open(markdownUrl, '_blank');
}

// Ask in ChatGPT
function askInChatGPT() {
var content = getPageContent();
var title = getPageTitle();
var prompt = 'I\'m reading this documentation page: "' + title + '"\n\n' + content.substring(0, 3000) + (content.length > 3000 ? '...' : '');
var url = 'https://chat.openai.com/?q=' + encodeURIComponent(prompt);
window.open(url, '_blank');
var prompt = 'I\'m reading this documentation page: "' + getPageTitle() + '"\n\n' + getPageContent().substring(0, 3000) + (getPageContent().length > 3000 ? '...' : '');
window.open('https://chat.openai.com/?q=' + encodeURIComponent(prompt), '_blank');
}

// Ask in Claude
function askInClaude() {
var content = getPageContent();
var title = getPageTitle();
var prompt = 'I\'m reading this documentation page: "' + title + '"\n\n' + content.substring(0, 3000) + (content.length > 3000 ? '...' : '');
var url = 'https://claude.ai/new?prompt=' + encodeURIComponent(prompt);
window.open(url, '_blank');
var prompt = 'I\'m reading this documentation page: "' + getPageTitle() + '"\n\n' + getPageContent().substring(0, 3000) + (getPageContent().length > 3000 ? '...' : '');
window.open('https://claude.ai/new?prompt=' + encodeURIComponent(prompt), '_blank');
}

// Initialize toolbar
function initToolbar() {
// Only add toolbar on setup page
if (!isSetupPage()) {
return;
}

// Wait for page to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
addToolbar();
});
} else {
addToolbar();
}
}

// Add toolbar to page
function addToolbar() {
// Create a fixed footer at the bottom of the screen
var footer = document.createElement('footer');
footer.className = 'page-toolbar-footer';

// Create and insert toolbar
var toolbar = createToolbar();
footer.appendChild(toolbar);

// Insert at the end of body
footer.appendChild(createToolbar());
document.body.appendChild(footer);

// Attach event listeners
document.getElementById('copy-page-btn').addEventListener('click', function(e) {
e.preventDefault();
copyPageToClipboard();
});
document.getElementById('view-markdown-btn').addEventListener('click', function(e) {
e.preventDefault();
viewMarkdown();
});
document.getElementById('ask-chatgpt-btn').addEventListener('click', function(e) {
e.preventDefault();
askInChatGPT();
});
document.getElementById('ask-claude-btn').addEventListener('click', function(e) {
e.preventDefault();
askInClaude();
});
document.getElementById('copy-page-btn').addEventListener('click', function(e) { e.preventDefault(); copyPageToClipboard(); });
document.getElementById('view-markdown-btn').addEventListener('click', function(e) { e.preventDefault(); viewMarkdown(); });
document.getElementById('ask-chatgpt-btn').addEventListener('click', function(e) { e.preventDefault(); askInChatGPT(); });
document.getElementById('ask-claude-btn').addEventListener('click', function(e) { e.preventDefault(); askInClaude(); });
}

// Initialize when script loads
initToolbar();
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', addToolbar);
} else {
addToolbar();
}
})();
Loading